Protractor: how to write a test that waits for a screen element to change?

9,597 views
Skip to first unread message

Matt Calthrop

unread,
Mar 12, 2014, 8:26:35 AM3/12/14
to ang...@googlegroups.com
Hi

I have a requirement to write several e2e tests that wait until the contents of an element on the page change.

The time this takes cannot be predetermined – but if it doesn't change before the browser times out, then the test will be deemed to have failed.

I could use setInterval() and clearInterval() to implement simple polling functionality, but that doesn't quite seem the right way to go about it.

Anybody got any better suggestions?

I'm using Protractor 0.20.1.

cheers

Matt

Demetrius Nunes

unread,
Mar 13, 2014, 10:00:19 AM3/13/14
to ang...@googlegroups.com
Why not user browser.wait(fn, timeout) and set a really long timeout as the 2nd paremeter?

Matt Calthrop

unread,
Mar 13, 2014, 10:03:14 AM3/13/14
to ang...@googlegroups.com
Thanks Demetrius... I had stumbled upon that function, and was going to give it a go.

cheers!

Matt

Matt Calthrop

unread,
Mar 13, 2014, 12:16:22 PM3/13/14
to ang...@googlegroups.com
I've been trying this, and hit a wall.

What I want to do is to wait until the URL changes.

So the pseudo-code would look something like this:

var currentUrl = browser.getCurrentUrl();
browser.wait(function () {
    var newUrl = browser.getCurrentUrl();
    return (newUrl !== currentUrl);
});
// then continue doing stuff

However, I'm not sure how to use browser.getCurrentUrl() (which returns a promise) within browser.wait().

Here's my first go, but as I expected, it didn't work (the browser timed out) :

var currentUrl;
browser.getCurrentUrl().then(function (url) {
    currentUrl = url;
}).then(function () {
    return browser.wait(function () {
        return browser.getCurrentUrl().then(function (url) {
            return url !== currentUrl;
        });
    });
});

I've looked at the object returned by browser.getCurrentUrl(), and it doesn't have any methods that allow comparison with another value.

Any suggestions?  I'm still getting to grips with the new frontier of JS Promises...

cheers

Matt

Demetrius Nunes

unread,
Mar 14, 2014, 11:24:16 AM3/14/14
to ang...@googlegroups.com
Here is the modified version of your code that should work:

browser.getCurrentUrl().then(function (currentUrl) {
    browser.wait(function () {
       return browser.getCurrentUrl().then(function (newUrl) {
           return (newUrl !== currentUrl);
       });
    });
});

In my test code I also have a utility function similar to this one:

browser.waitForUrl = function (expectedUrl) {
    browser.wait(function () { 
        return browser.getCurrentUrl().then(function (url) {
            return url.indexOf(expectedUrl) !== -1;
        }); 
    });
};

and then I simply do:

browser.waitForUrl("/login");

Matt Calthrop

unread,
Mar 19, 2014, 5:51:24 AM3/19/14
to ang...@googlegroups.com
Thanks Demetrius.

Here's what I ended up with:

function waitForUrlToChangeTo(urlRegex) {
    var currentUrl;

    return browser.getCurrentUrl().then(function storeCurrentUrl(url) {
            currentUrl = url;
        }
    ).then(function () {
            return browser.wait(function () {
                return browser.getCurrentUrl().then(function (url) {
                    return urlRegex.test(url);
                });
            });
        }
    );
}

Which is very much like your solution, except that the URL we are waiting to change to is specified as a regex, which for my use case makes it more flexible.

Thanks again!

Matt


Jason Hao

unread,
Aug 13, 2014, 10:03:12 PM8/13/14
to ang...@googlegroups.com
Hi all,
I know this is too out of date, but I just want to mention that, the below link includes all kinds of timeout issues and solutions for them.

Also, I found that, for the links which will redirect us out of our application, we should use browser.driver.getCurrentUrl(); rather than browser.getCurrentUrl(); to grab the url and check if that is the same one from the requirement.


Thank you,
Jason
Reply all
Reply to author
Forward
0 new messages