[jasmine] Protractor : How to wait for page complete after click a button?

In a test spec, I need to click a button on a web page, and wait for the new page completely loaded.

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

// ...Here need to wait for page complete... How?

ptor.waitForAngular();
expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

This question is related to jasmine protractor wait

The answer is


to wait until the click itself is complete (ie to resolve the Promise), use await keyword

it('test case 1', async () => {
  await login.submit.click();
})

This will stop the command queue until the click (sendKeys, sleep or any other command) is finished

If you're lucky and you're on angular page that is built well and doesn't have micro and macro tasks pending then Protractor should wait by itself until the page is ready. But sometimes you need to handle waiting yourself, for example when logging in through a page that is not Angular (read how to find out if page has pending tasks and how to work with non angular pages)

In the case you're handling the waiting manually, browser.wait is the way to go. Just pass a function to it that would have a condition which to wait for. For example wait until there is no loading animation on the page

let $animation = $$('.loading');

await browser.wait(
  async () => (await animation.count()) === 0, // function; if returns true it stops waiting; can wait for anything in the world if you get creative with it
  5000, // timeout
  `message on timeout`
);

Make sure to use await


you can do something like this

_x000D_
_x000D_
emailEl.sendKeys('jack');_x000D_
passwordEl.sendKeys('123pwd');_x000D_
_x000D_
btnLoginEl.click().then(function(){_x000D_
browser.wait(5000);_x000D_
});
_x000D_
_x000D_
_x000D_


I typically just add something to the control flow, i.e.:

it('should navigate to the logfile page when attempting ' +
   'to access the user login page, after logging in', function() {
  userLoginPage.login(true);
  userLoginPage.get();
  logfilePage.expectLogfilePage();
});

logfilePage:

function login() {
  element(by.buttonText('Login')).click();

  // Adding this to the control flow will ensure the resulting page is loaded before moving on
  browser.getLocationAbsUrl();
}

I just had a look at the source - Protractor is waiting for Angular only in a few cases (like when element.all is invoked, or setting / getting location).

So Protractor won't wait for Angular to stabilise after every command.

Also, it looks like sometimes in my tests I had a race between Angular digest cycle and click event, so sometimes I have to do:

elm.click();
browser.driver.sleep(1000);
browser.waitForAngular();

using sleep to wait for execution to enter AngularJS context (triggered by click event).


Use this I think it's better

   *isAngularSite(false);*
    browser.get(crmUrl);


    login.username.sendKeys(username);
    login.password.sendKeys(password);
    login.submit.click();

    *isAngularSite(true);*

For you to use this setting of isAngularSite should put this in your protractor.conf.js here:

        global.isAngularSite = function(flag) {
        browser.ignoreSynchronization = !flag;
        };

With Protractor, you can use the following approach

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain newPageName
browser.wait(EC.urlContains('newPageName'), 10000);

So your code will look something like,

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain efg
ptor.wait(EC.urlContains('efg'), 10000);

expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

Note: This may not mean that new page has finished loading and DOM is ready. The subsequent 'expect()' statement will ensure Protractor waits for DOM to be available for test.

Reference: Protractor ExpectedConditions


You don't need to wait. Protractor automatically waits for angular to be ready and then it executes the next step in the control flow.


browser.waitForAngular();

btnLoginEl.click().then(function() { Do Something });

to solve the promise.


In this case, you can used:

Page Object:

    waitForURLContain(urlExpected: string, timeout: number) {
        try {
            const condition = browser.ExpectedConditions;
            browser.wait(condition.urlContains(urlExpected), timeout);
        } catch (e) {
            console.error('URL not contain text.', e);
        };
    }

Page Test:

page.waitForURLContain('abc#/efg', 30000);

Examples related to jasmine

How to execute only one test spec with angular-cli Unit testing click event in Angular Angular 2 Unit Tests: Cannot find name 'describe' How to write unit testing for Angular / TypeScript for private methods with Jasmine toBe(true) vs toBeTruthy() vs toBeTrue() How do I mock a service that returns promise in AngularJS Jasmine unit test? jasmine: Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL Jasmine JavaScript Testing - toBe vs toEqual Protractor : How to wait for page complete after click a button? How to spyOn a value property (rather than a method) with Jasmine

Examples related to protractor

How to import js-modules into TypeScript file? Error 'tunneling socket' while executing npm install toBe(true) vs toBeTruthy() vs toBeTrue() How to use protractor to check if an element is visible? Protractor : How to wait for page complete after click a button? How to getText on an input in protractor How to select option in drop down protractorjs e2e tests

Examples related to wait

How to make the script wait/sleep in a simple way in unity How do I make a delay in Java? Wait some seconds without blocking UI execution Protractor : How to wait for page complete after click a button? How to wait until an element is present in Selenium? Javascript sleep/delay/wait function How to wait till the response comes from the $http request, in angularjs? How to add a "sleep" or "wait" to my Lua Script? Concept behind putting wait(),notify() methods in Object class How can I wait for 10 second without locking application UI in android