Protractor - Wait for async promise before doing next

∥☆過路亽.° 提交于 2019-12-18 12:26:36

问题


First of all, I've already checked various post and blogs concerning that point and I still can't figure out how to make it correctly.

I have tried many different combinaison of :

  • browser wait
  • protractor.controlFlow().execute
  • protractor.controlFlow().await(

...Still no success..

My problem

Within my beforeEach function, I'd like to call a protractor promise and wait for it to resolve before performing the rest of my code.

My Code

I've prepared this simple test for anyone willing to help me

describe('testAsync', function() {

  beforeEach(function() {
    console.log('beforeEach - step 1 ')

    browser.get("https://angularjs.org/");
    console.log('beforeEach - step 2 ')
    testFunc()
    console.log('beforeEach - after testFunc - step 3')

  });

  var testFunc = function(){

    console.log("testFunc - step 1")

    browser.wait(function() {
      var deferred = protractor.promise.defer();
      element(by.id('twitter-widget-1')).isPresent()
        .then(function (isPresent) {
          console.log("testFunc - step 2")
          deferred.fulfill(isPresent);
      });
      return deferred.promise;
    });

    console.log("testFunc - step 3")

  }

  it('test after BeforeEach', function() {
    console.log("Last trace")
  });

});

Current Output

[launcher] Running 1 instances of WebDriver
beforeEach - step 1
beforeEach - step 2
testFunc - step 1
testFunc - step 3
beforeEach - after testFunc - step 3
testFunc - step 2
Last trace

Expected Output

[launcher] Running 1 instances of WebDriver
beforeEach - step 1
beforeEach - step 2
testFunc - step 1
testFunc - step 2 // <------  This is within the promise resolve
testFunc - step 3
beforeEach - after testFunc - step 3
Last trace

回答1:


I think this will get the output you want:

describe('testAsync', function() {

  beforeEach(function() {
    console.log('beforeEach - step 1 ');

    // `get` implicitly registers a promise with the control flow
    browser.get("https://angularjs.org/");

    console.log('beforeEach - step 2 '); // runs "before" get above returns!

    testFunc().then(function() {
       // use a then to explicitly chain a dependency off a promise
       console.log('beforeEach - after testFunc - step 3');
    })

    protractor.promise.controlFlow().execute(function() {
       console.log('beforeEach - after testFunc, via controlFlow - step 4');
    });

    console.log('beforeEach - end of beforeEach - everything registered, nothing done');
  });

  var testFunc = function(){

    console.log("testFunc - step 1")

    // return browser wait promise to caller
    // `wait` also implicitly registers with the control flow
    return browser.wait(function() {
      return element(by.id('twitter-widget-1')).isPresent()
        .then(function (isPresent) {
          console.log("testFunc - step 2")
          return true; // tell wait its done by resolving then promise->element promise->wait
      });
    });
  }

  it('test after BeforeEach', function() {
    console.log("Last trace")
  });

});



回答2:


The two console.logs (steps 1 & 3)in your testFunc, that are not wrapped in the promise, will fire immediately when you call the function. Which is proven by your output. Then your promise (which looks to be working great!), returns the step 2 log when the promise is resolved (but after the logs have already fired).

And thus, it looks like this is doing what you want? I.e. your beforeEach does indeed look like it's firing the async function before hitting your first spec.



来源:https://stackoverflow.com/questions/30949576/protractor-wait-for-async-promise-before-doing-next

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!