Транспортир. Подождите, пока вы попробуете асинхронное обещание.

Прежде всего, я уже проверил различные сообщения и блоги, касающиеся этого момента, и я до сих пор не могу понять, как это сделать правильно.

Я пробовал много разных комбинаций:

  • Ожидание браузера
  • protractor.controlFlow(). Выполнить
  • protractor.controlFlow(). Ждать (

... Еще не успел..

Моя проблема

В моей функции beforeEach я хотел бы назвать обещание транспортира и дождаться его разрешения до выполнения остальной части моего кода.

Мой код

Я подготовил этот простой тест для тех, кто хочет помочь мне.

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

});

Текущий выход

[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

Ожидаемый результат

[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

Я думаю, что это даст нужный результат:

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

Два console.log (шаги 1 и 3) в вашем testFunc, которые не завернуты в обещание, немедленно срабатывают при вызове функции. Это подтверждается вашими результатами. Тогда ваше обещание (которое, кажется, работает отлично!), Возвращает log 2-го шага, когда обещание разрешено (но после того, как журналы уже запущены).

И, таким образом, похоже, что это делает то, что вы хотите? То есть ваш beforeEach действительно выглядит так, как будто он запускает функцию асинхронизации, прежде чем нажимать первую спецификацию.