Understanding protractor's use of promises

2019-02-20 03:30发布

问题:

Essentially I am playing around with getting a library for preconditions set up (think user creation). As protractor is promise-based and magically does all the wrapping to keep things in order, I thought of using promises for that purpose. I wrote a little sample code but I cannot explain the observed behaviour so maybe someone can help me understand what's going on.

function timeout(ms) {
    var promise = protractor.promise.defer();
    setTimeout(function() {
        console.log('qwer');
        promise.fulfill(true);
    }, ms);
    return promise.promise;
}

So now the function returns a promise, which I would assume to be usable inline just like so (as all the code supposedly gets wrapped in a control flow)

describe('test', function() {
  it('bla', function() {
    browser.get('/');
    timeout(5000);
    $('some-element').click();
  });
});

however this does not work as expected (i.e. the console.log never happens). Even when expecting the result from that promise, it does not change the results. If actually explicitly waiting for done by doing timeout(5000).then(done), the timeout completes, but the next action is not queued to after that action (i.e. site gets opened, element clicked, then after 5 seconds the log from timeout happens).

So I am really confused how the claims of using a control flow to make sure everything gets executed in order and the observed behaviour fit together.

回答1:

It's not enough just to create a protractor.promise deferred object - you need to tell the control flow about it. This is usually done with protractor.promise.controlFlow().execute().

function timeout(ms) {
  protractor.promise.controlFlow().execute(function() {
    var deferred = protractor.promise.defer();
    setTimeout(function() {
      console.log('qwer');
      deferred.fulfill(true);
    }, ms);
    return deferred.promise;
  });
}

Read through https://code.google.com/p/selenium/source/browse/javascript/webdriver/promise.js for all the magic behind the scenes here.