Protractor browser.wait doesn't wait

Justin picture Justin · Jan 6, 2015 · Viewed 52.5k times · Source

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.

Answer

alecxe picture alecxe · Jan 6, 2015

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: