I'm having trouble getting protractor to behave as expected when testing my angular app. My spec file looks like this:
describe('app login', function() {
it('should allow admin user to log in', function() {
browser.get('http://localhost:3008');
//we can find the log in link
expect(element(by.id('login-link')).getText()).toContain('Log in');
//open login dialog
element(by.id('login-link')).click();
browser.ignoreSynchronization = true;
browser.sleep(1000);
//enter credentials
element(by.id('login-username')).sendKeys('User1');
element(by.id('login-password')).sendKeys('Password1');
browser.sleep(1000);
//log in
var el = element(by.id('login-btn'));
//WORKS IF BELOW LINE IS COMMENTED OUT
el.click();
browser.sleep(1000);
//display confirms login
expect(element(by.id('user-display')).getText()).toContain('User1');
});
});
Note that I was getting synchronization errors at the start which is why I have the ignoreSynchronization flag set to true and all those browser.sleeps.
Now here's the thing: The test will go through fine if I remove the el.click() statement (and the final expect call). However, once that line is included, I get NoSuchElementError: No element found using locator: By.id("login-username"). Notice that this element is not the one I am actually trying to click, which is part of the bizarreness.
let me start by breaking down your question in 3 parts.
Let's take it a step at a time:
1)ignoreSynchronization flag set to true
: It instructs protractor to not wait for Angular promises. This is used when you are i)testing scenarios around waiting for $http or $timeout to resolve ii)testing against a non-angular site. These are the times when you should set ignoreSynchronization setting to true. Ask yourself is it needed for your test pre-requisite? Going by your explanation above, I believe you can set it to false and continue your testing safely. By setting this to true when it is not needed you are instructing protractor to not attempt to synchronize with the page before performing actions. This can be harmful because Protractor will not wait until $timeouts and $http calls have been processed, which can cause tests to become flaky. more on: https://github.com/angular/protractor/blob/9891d430aff477c5feb80ae01b48356866820132/lib/protractor.js#L158
You can do away with unnecessary browser.sleep() once you set this flag to False
.
2)Protractor not finding element
: There are various reasons for which an element is not detected by Protractor:
-Element does not fit it the display window.
-Element is not visible, but present.
-Asynchronous task not handled properly.
-Another element is overlayed on the other element
I suggest you try out:
describe('app login', function() {
it('should allow admin user to log in', async() => {
await browser.get('http://localhost:3008');
//we can find the log in link
expect(await element(by.id('login-link')).getText()).toContain('Log in');
//open login dialog
await element(by.id('login-link')).click();
//try putting this setting in your protractor.conf file instead of describe
//block
//browser.ignoreSynchronization = false;
//enter credentials
await element(by.id('login-username')).sendKeys('User1');
await element(by.id('login-password')).sendKeys('Password1');
//log in
var el = element(by.id('login-btn'));
//WORKS IF BELOW LINE IS COMMENTED OUT
await el.click();
//display confirms login
expect(await element(by.id('user-display')).getText()).toContain('User1');
});
});
More info on how to change your code: https://jasmine.github.io/tutorials/async
3)Excessive use of browser.sleep(1000);
: In your code, using sleep() renders it fragile and will sometimes fail if the system runs slower than normal. It is an invitation to making your test fail flaky, often in non-reproducible scenarios. So unless you want to spend your time in futile debugging, stop using it.
Instead use these wait strategies: explicit waits, waitforAngular; to make sure your asynchronous events are completed before going to the next step. Incase you need to know more on this, leave a comment below, otherwise I am keeping this answer strictly to the question you have asked. Ask away!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With