I am new to Protractor. I think I have this down when dealing with an Angular page, but can't figure it out for a non-Angular page. Any help would be appreciated.
describe('Search', function() {
it('should click Search button and wait for results', function() {
browser.driver.findElement(by.id('search')).click();
});
});
pageLoadTimeout() method in protractor waits for an page to load within given time limit when we use get() or navigate().to() method to load a webpage.
Protractor works well on non-AngularJS pages as well. The first step is to set browser. ignoreSynchronization = true; inside the beforeEach() block in the spec file, to signal Protractor not to wait for Angular components to load.
Instead use ExpectedConditions in order to with Protractor. This means, it will wait up to 3500 ms, until the element is rendered. If the element is rendered within 1000ms, it will skip the rest of 2500 waiting ms. Therefore, you saved 2500ms.
How do you stop Page Loading in Protractor when an element is loaded? By using Key. ESC to body element in Protractor.
Testing non-angular pages with Protractor can be tricky regarding waiting for stuff.
I suggest you upgrade Protractor to latest (1.5.0 as of now), use a custom function waitReady() that browser.wait
for elements ready and rewrite your test like below. Note you can put everything within 1 spec if you like so.
// TODO: use page objects
var searchBtnElm = $('#search'); // use element(by.id('search')) if you prefer
it('waits for the elements present and visible (non-angular)', function() {
expect(searchBtnElm.waitReady()).toBeTruthy();
});
it('should click Search button', function() {
searchBtnElm.click();
});
it('wait for more results', function() {
// keep using waitReady() before interacting with the elements
// and before performing expectations on them
});
More details of why waitReady
here.
Note: remember to set ignore synchronization for testing a non-angular page:
browser.ignoreSynchronization = true;
You can set it before browser.get
the non-angular page.
I've suggested setting a high implicit wait in the past, e.g.
browser.manage().timeouts().implicitlyWait(5000);
That hack allows to you avoid waitReady
and keep using the standard
expect(searchBtnElm.isPresent()).toBeTruthy();
But has an ugly disadvantage when testing for elements NOT present, i.e. when testing for absent or non visible elements in which case it will wait 5 seconds (5000ms) in vane, e.g. when doing
expect(someNonExistingElm.isPresent()).toBeFalsy();
Figured this out. I simply added the code below, after the click method:
describe('Search', function() {
it('should click Search button and wait for results', function() {
browser.driver.findElement(by.id('search')).click();
dvr.wait(function() {
return dvr.isElementPresent(by.xpath(
'/html/body/div/div[4]/div/div[2]/div/div/div/span'));
}, 20000);
});
});
Another Neat approach is to use "Expected Conditions" inside browser.wait - something like this:
var EC = protractor.ExpectedConditions;
var search = element(by.id('search'))
browser.wait(EC.visibilityOf(search), 2000).then(function(){
search.click()
})
You can get more details here: https://angular.github.io/protractor/#/api?view=ExpectedConditions
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