1

I have been using/learning protractor for more than a month now.

I know that protractor documentation says,it waits for angular calls to complete (http://www.protractortest.org/#/) , it will make sure all steps are executed synchronously etc..

But I don't find it that way. Or at least, I don't find it that way in my scripts Many a time protractor runs ahead, for example if I click on a link, get the current url and then verify the url.

Most of the time, URL value will be stale, i.e it was not executed after clicking on link. Below is my code sample from page object and corresponding test.

Please suggest how to make sure, all test steps are executed in serial order.

Page Object
this.getSPageLink(){
    return element(by.xpath("//a[@title='S']"));
};
this.getLPageLink(){
    return element(by.xpath("//a[@title='L']"));
};
this.goToSPage = function() {
    (this.getSPageLink()).click();
    *//ERROR here, sometimes second click (below) doesn't wait for first 
    click to complete, and complains that link for 2 click (below) is 
    not   found*
    (this.getSLPageLink()).click();
    return browser.currentURL();
    *//ERROR HERE url line (e) is sometimes executed before*
}

Test Class
it('::test SL  page', function() {
        pageObject.goToSpage();
        var currentURL=browser.getCurrentURL();
        expect(currentURL).toContain("SLink");
        *//ERROR HERE value in this variable "currentURL" is most of the 
        times Stale*
});

it('::test SL2  page', function() {
        pageObject.goToLpage();
        var currentURL=browser.getCurrentURL();
        expect(currentURL).toContain("Link");
        console.log("this line is always executed first"));
        //ERROR here , this print line is always executed first
});
sathya
  • 33
  • 3

1 Answers1

1

It is rather confusing and Protractor documentation is not very clear on this but Protractor waits for page to synchronize only when using get or refresh commands. In your case, you are using click command to load a new page so Protractor won't wait for the new page to synchronize before proceeding. See the reasoning for this behaviour from a Protractor developer.

So in your case, you need to take care of that either in your test or in page object. In either case you can use something like this after the click:

browser.wait(function () {
    return browser.driver.getCurrentUrl().then(function (url) {
        return /SLink/.test(url);
    });
}, 10000);

This will poll for the current URL as often as possible (in practice around once every 500ms) for up to 10 seconds. When it finds the "Slink" string in the current URL it will proceed on to the next command.

finspin
  • 4,021
  • 6
  • 38
  • 66
  • Thank you for great explanation. – sathya May 13 '16 at 06:17
  • Also, is there a preferred way to make sure all lines of test ( IT block) are executed serially? For example, console.log is always executed first, not in the order it is present. – sathya May 13 '16 at 06:18
  • There actually is not a 500 ms polling interval in the webdriverjs/protractor bindings..http://stackoverflow.com/a/34377095/771848. Thanks. – alecxe May 14 '16 at 03:13
  • @alecxe That's why I wrote "as often as possible" in my original post. – finspin May 15 '16 at 07:26