简体   繁体   中英

Wait for page redirection in Protractor / Webdriver

I have a test that clicks a button and redirects to a user dashboard. When this happens Webdriver returns: javascript error: document unloaded while waiting for result.

To fix this I insert browser.sleep(2000) at the point where redirection occurs and assuming my CPU usage is low, this solves the issue. However, 2000 ms is arbitrary and slow. Is there something like browser.waitForAngular() that will wait for the angular to load on the redirected page before the expect(..) ?

 it('should create a new user', () => { $signUp.click(); $email.sendKeys((new Date().getTime()) + '@.com'); $password.sendKeys('12345'); $submit.click(); browser.sleep(2000); // Need alternative to sleep... // This doesn't do it... // browser.sleep(1); // browser.waitForAngular(); $body.evaluate('user') .then((user) => { expect(user).toBe(true); }); }); 

do you think something like this could work for you? This will wait up to 10 seconds for the url to include the text 'pageTwo', or whatever you put in.

var nextPageButton = $('#nextPage');
nextPageButton.click().then(function(){
    return browser.driver.wait(function() {
      return browser.driver.getCurrentUrl().then(function(url) {
        return /pageTwo/.test(url);
      });
    }, 10000);
};

Just stick in the regex of the url you are expecting.

Alternatively, you could wait for an element from the next page to appear as well:

var nextPageButton = $('#nextPage');
nextPageButton.click();

var elementFromSecondPage = $('#coolElement');
browser.wait(protractor.until.elementIsVisible(elementFromSecondPage), 5000, 'Error: Element did not display within 5 seconds');

When using .click, protractor will naturally wait for angular to finish the action attached to the click, such as changing the page. But, while the page change, you may still be needing something specific to be loaded, so the test fails before that part is available. Using this, it should wait for the click part to finish, then wait for the element to appear.

To expand on user2020347's answer: Thanks that solved my issue. I wonder why this isn't a built in function. I'll be using this in many places to wait for browser navigation.

To make it more concise, I made a little helper:

Object.assign(global, {
  waitUntilURLContains: string => {
    let fn = () => {
      return browser.driver.wait(() => {
        return browser.driver.getCurrentUrl().then((url) => {
          return url.includes(string);
        });
      }, waitDelay);
    }

    return fn.bind(null, string);
  }
});

In my test:

$button.click().then(waitUntilURLContains('dashboard'));

keeping it very simple. I was also running into the same problem but was able to solve it using the following code :

      page.setUsername(objectrepository.userdetails.useremail);
      page.setPassword(objectrepository.userdetails.userpassword);
      page.login().click();
      **browser.wait(EC.visibilityOf(page.greetingMessageElement()), 5000);**

      page.greetingMessageElement().getText()
      .then(function (value){
         expect(browser.getCurrentUrl()).toContain("#/mytickets");
      }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM