Protractor browser.wait doesn't actually wait

Problem

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 actually 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.

Problem courtesy of: Justin

Solution

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');
    });
});

The following article should help with understanding:

Also see the use cases here:

Solution courtesy of: alecxe

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.