Protractor: Click link and wait for URL to change?

Created on 8 Apr 2014  路  10Comments  路  Source: angular/protractor

I'm trying to do something seemingly simple, yet I can't get it to work properly. Others have asked similar questions, but the solutions haven't fixed things for me.

I want to do the following:

  1. Click a form submit button
  2. Wait for the new page to load
  3. Expect the URL to be something else

Here is the relevant code:

 beforeEach(function () {
        ptor = protractor.getInstance();
        ptor.ignoreSynchronization = true;
        ptor.get('/campaigns');
    }, 60000);

it("selecting continue", function() {
       var continueBtn = element(by.id('continue'));
        continueBtn.click().then(function() {
            expect(ptor.getCurrentUrl()).toContain(ptor.baseUrl + '/templates');
        });
    });

Clicking the submit button can take some time (anywhere from 1 - 10+ secs on my local machine), before the new page is loaded.

The expect statement consistently leads to an error:

Message:
     Expected 'http://localhost:9000/campaigns' to contain 'http://localhost:9000/templates'.

Any thoughts on the correct way to resolve this?

question

Most helpful comment

Wait doesn't understand expectations, you need to return a 'true' or 'false' value:

    it("should link to templates", function() {
        var continueBtn = element(by.id('continue'));
        continueBtn.click();

        ptor.wait(function() {
            return ptor.getCurrentUrl().then(function(url) {
                return (url.indexOf(ptor.baseUrl + '/templates?campaignId=') !== -1);
            });
        });
    });

All 10 comments

Hi @andrewboni,

You just need to apply some wait till the new page is loaded.
After clicking on button and before next page loads, is there any kind of Loader?
If Yes, you can wait till Loader is removed from the screen.

Thanks,
Mohit

Yup, try using wait. There's an example of this here.

Hi Julie, thanks for the suggestion. Still running into an issue though, after implementing wait:

 beforeEach(function () {
        ptor = protractor.getInstance();
        ptor.ignoreSynchronization = true;
        ptor.get('/campaigns/create');
    }, 60000); 


    it("should link to templates", function() {
        var continueBtn = element(by.id('continue'));
        continueBtn.click();

        ptor.wait(function() {
            return ptor.getCurrentUrl().then(function(url) {
                expect(url).toContain(ptor.baseUrl + '/templates?campaignId=');
            });
        });
    });

Running this causes Selenium to spit out a ton of messages in rapid succession:

...
12:57:05.541 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url
12:57:05.559 INFO - Executing: [get current url] at URL: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url)
12:57:05.561 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url
12:57:05.580 INFO - Executing: [get current url] at URL: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url)
12:57:05.583 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url
12:57:05.602 INFO - Executing: [get current url] at URL: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url)
12:57:05.604 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url
12:57:05.623 INFO - Executing: [get current url] at URL: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url)
12:57:05.625 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d/url
12:57:05.640 INFO - Executing: [delete session: 436cc76f-2892-4af7-b36b-e26c75caf42d] at URL: /session/436cc76f-2892-4af7-b36b-e26c75caf42d)
12:57:06.199 INFO - Done: /session/436cc76f-2892-4af7-b36b-e26c75caf42d
...

and

Failures:

  1) Create a new campaign should link to templates
   Message:
     timeout: timed out after 20000 msec waiting for spec to complete
   Stacktrace:
     undefined

Any ideas?

FWIW, up until this issue, I was getting away with something like

...
button.click();
ptor.sleep(2000);
expect(ptor.getCurrentUrl()).toContain(ptor.baseUrl + '/my/awesome/route');
...

in other tests, with no issues. Is using wait the canonical way to check for a url change after clicking a link or a button?

Wait doesn't understand expectations, you need to return a 'true' or 'false' value:

    it("should link to templates", function() {
        var continueBtn = element(by.id('continue'));
        continueBtn.click();

        ptor.wait(function() {
            return ptor.getCurrentUrl().then(function(url) {
                return (url.indexOf(ptor.baseUrl + '/templates?campaignId=') !== -1);
            });
        });
    });

Got it, thanks Julie. I was able to resolve my issue- thanks!

Thanks a ton @juliemr.. You've been an awesome reference to me whenever I'm stuck at something in Protractor js..

Sometimes URLs don't change when you click on something on the screen. In such a case, it doesn't make sense to return a promise on wait to see if the URL changes. How does one induce wait in that case? what is the difference between browser.driver.wait() vs ptor.wait ?

i an having an issue - the URL i need to wait for is not static. The base URL is same but then there are some numbers which is issued randomly . My question how can i put a wait for specific URL with giving the partial URL .
Example : baseURL/some_random_number/someStaticText

@AEIOU-1 I had a similar issue, and here is my solution.

function waitForUrl(newUrl) {
      browser.getCurrentUrl().then(function () {
          browser.wait(function () {
              return browser.getCurrentUrl().then(function (url) {
                  return newUrl.test(url);
              });
          });
      });
}

it('opens up the url', () => {
    browser.get('yoururlhere');
    // call the wait function and pass a part of your url, 
    // in my case it was /app#/app/inbox/empty
    waitForUrl(/app#\/app\/inbox\/empty/);
}); 
Was this page helpful?
0 / 5 - 0 ratings