Whenever a button is clicked in my application, it triggers a $timeout and requires me to work with ignoreSynchronization set to true. However, I have noticed some interesting behavior during the waiting process for elements to be added to the page:
Surprisingly, the wait timeout specified in browser.wait(element, timeout, error message) does not have any effect at all. The only timeout that actually matters is the implicitTimeout set on the browser. Moreover, the ENTIRE implicit timeout is utilized, even if the element is found before the timeout ends. This results in tests always running slowly, utilizing the maximum time given.
describe('Cool Page', () =>{
beforeEach(function(){
browser.ignoreSynchronization = true;
return browser.sleep(250);
});
afterEach(function(){
browser.ignoreSynchronization = false;
return browser.sleep(250);
});
it('can open menu with timeout', function(){
// No timeout at this point
coolPage.wait.ellipsesIcons().then(() =>{
// Clicking the ellipses icons kicks off a $timeout of 100 seconds
coolPage.ellipsesIcons.click().then(() =>{
coolPage.wait.dropdownOptions().then(() => {
expect(coolPage.dropdownOptions.getText()).toContain('Option 1');
});
});
});
});
})
.
export = new CoolPage;
class CoolPageextends PageObject {
private elements;
constructor(){
super();
... // Lots of other stuff
this.initWait();
}
... // Initializing elements and other things
private initWait() {
this.wait = {
ellipsesIcons: () => {
// Timeout of 5 seconds will be used - regardless of isPresent resolving as true or false, the entire 5 seconds will be used
browser.manage().timeouts().implicitlyWait(5000);
// The 2 milliseconds passed in here does nothing at all
browser.wait(element(by.css('.fa-ellipses-h')).isPresent(), 2, 'Ellipses Icon(...) was not present in time');
// Must reset implicit wait back to the original 25 seconds it was set too in the conf
browser.manage().timeouts().implicitlyWait(25000);
return browser.sleep(150);
},
dropdownOptions: () => {
// This two seconds wait WILL be used
browser.manage().timeouts().implicitlyWait(2000);
// This five second wait WILL NOT be used
browser.wait(element(by.css('[name="change-status"]')).isPresent(), 5000, 'Options actions menu item was not present in time');
browser.manage().timeouts().implicitlyWait(25000);
return browser.sleep(150);
},
}
}
Interestingly, the timeouts passed in through browser.wait have no impact here. This raises the following questions:
- What is the actual purpose of the browser.wait timeout?
- When and why is the implicit wait used? I thought it was solely for waiting for pages to load.
- Is there any method to pass in a timeout that will be utilized effectively?
- If not, is there a way for the wait to exit as soon as the condition is met, rather than running the entire timeout?