Reputation: 1736
I've only just started with Protractor.
This is my problem:
I want to log in to a website. When the page loads, it displays a spinning loading wheel before displaying the Username and Password fields, and a Sign in button.
My problem is that any attempts to clear()
or sendKeys()
fail because the fields are not yet visible on the screen, and protractor is trying to interact with them.
InvalidElementStateError: invalid element state: Element is not currently interactable and may not be manipulated.
What I have noticed is in the page source initially the spinning wheel has class='ngscope'
and after a while it changes to class='ng-scope ng-hide'
The whole thing is this:
<div ng-show="Model.Busy" class="ng-scope ng-hide">
<div ng-class="{'control--inline': small, 'div-centre': !small}" class="div-centre">
<img ng-src="/assets/img/loading.gif" ng-class="{'very-small-loading': small}" src="/assets/img/loading.gif">
</div>
</div>
The piece of code that I'm using is:
describe('Testing', function() {
browser.driver.manage().window().maximize();
var username = element(by.model('Model.Username'));
var password = element(by.model('Model.Password'));
var loginbutton = element(by.css('[ng-click="Model.Logon()"]'));
beforeEach(function() {
browser.get('MY WEBSITE');
});
it('should log me in', function() {
// expect($('[ng-show=Model.Busy].ng-hide').isDisplayed()).toBeTruthy(); <-- this fails
username.clear();
password.clear()
username.sendKeys('1');
password.sendKeys('2');
loginbutton.click();
});
});
How to make this work?
Upvotes: 1
Views: 3224
Reputation: 6962
You have to wait until the loading animation hides and then try to work on the elements that appear on the page using protractor's inbuilt wait()
function. One way is to wait until an element shows up using presenceOf()
feature. Here's how -
browser.ignoreSynchronization = true; //Its Kendo UI coupled with Angular, so ignore the angular load
//There are 2 login forms with same attributes so using by.model wouldn't work in this case
var username = $('#MainView .form-input[name="txtUsername"]');
var password = $('#MainView .form-input[name="txtPassword"]');
var loginbutton = $('[ng-click="Model.Logon()"]');
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(username), 20000).then(function(){
username.clear().then(function(){
username.sendKeys('1');
});
password.clear().then(function(){
password.sendKeys('2');
});
loginbutton.click();
});
Hope it helps.
Upvotes: 3