Protractor browser.wait doesn't wait
Asked Answered
J

3

33

I am assuming that browser.wait should be a blocking call, but it is not working as I expected. Here is my sample:

describe("browser.wait", function() {
    beforeEach(function() {
        browser.wait(function() {
            console.log('1 - BeforeEach WAIT');
            return true;
        });
    console.log('2 - BeforeEach after wait');
});

afterEach(function() {
    browser.wait(function() {
        console.log('4 - afterEach WAIT');
        return true;
    });
    console.log('5 - afterEach after wait');
});

it('should probably actually wait.', function() {
    console.log('3 - IT statement');
    expect(1).toBe(1);      
});

Now, because I assumed browser.wait was actually blocking, I thought that my console.log calls would be run in order; 1,2,3,4,5;

The actual output I get is:

2 - BeforeEach after wait  
1 - BeforeEach WAIT  
3 - IT statement  
5 - afterEach after wait  
4 - afterEach WAIT  

How can I get browser.wait to wait? Or am I using the wrong function completely? I need things to block until my browser gets to where it needs to be for the next call.

Jaws answered 6/1, 2015 at 16:50 Comment(0)
C
43

It is all about promises (actually every protractor question is about promises).

browser.wait() is not a blocking call, it schedules a command to wait for a condition:

Schedules a command to wait for a condition to hold, as defined by some user supplied function. If any errors occur while evaluating the wait, they will be allowed to propagate. In the event a condition returns a webdriver.promise.Promise, the polling loop will wait for it to be resolved and use the resolved value for evaluating whether the condition has been satisfied. The resolution time for a promise is factored into whether a wait has timed out.

It would not call the function you are passing in immediately, it would schedule a command and wait for promise to be resolved (if the function inside returns a promise).

You can use then() to have a correct order in this case:

beforeEach(function() {
    browser.wait(function() {
        console.log('1 - BeforeEach WAIT');
        return true;
    }).then(function () {
        console.log('2 - BeforeEach after wait');
    });
});

See the use cases here:

Cochrane answered 6/1, 2015 at 19:1 Comment(2)
The lovely thing about this that the code example in the doc shows this as blocking wait, while the Returns section warns you that this is a Promise. See: angular.github.io/protractor/#/… Example from the doc: var started = startTestServer(); driver.wait(started, 5 * 1000, 'Server should start within 5 seconds'); driver.get(getServerUrl());Reinsure
@Reinsure - agree with your statement. The sample code you've pointed out is misleading, as is shows as blocking. i.e. the driver.get() function should actually wrapped inside the fulfilled promise.Dentil
C
1

Wait function will hold execution for that particular function, But JavaScript work in async way. So sometime there might be chance your function gets executed before wait function. To understand it better you need to read Promises in angular/protractor.

To get your code working you need to .then(function(){}); (asking function 2 to wait until 1st complete.

browser.wait(function() {
    console.log('1 - BeforeEach WAIT');
    return true;
}).then(function () {
    console.log('2 - BeforeEach after wait');
});
Concupiscent answered 2/11, 2017 at 7:53 Comment(0)
C
1

You need to instruct protractor to pause until browser.wait is completed by using await

it('test case', async () => {
  await browser.wait(function() {
    console.log('1 - BeforeEach WAIT');
    return true;
  });
  console.log('2 - BeforeEach after wait');
});
Coset answered 9/2, 2021 at 23:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.