Подтвердить что ты не робот

Создание и разрешение promises в транспортире

Я пишу тестовый пример для добавления информации о магазине на странице для приложения Angular с помощью Protractor, где изначально я подсчитываю количество магазинов, которые у меня уже есть, и после завершения тестового блока. Я ожидаю, что счет увеличится на один для этого, я делаю это, следуя этой ссылке создания promises Как создать и управлять promises в Protractor?

describe('myApp', function() {
  var items,startCount;

  var testPromise = function(){
    items = element.all(by.repeater('store in storelist'));
    var deferred = protractor.promise.defer();
    items.count().then(function(orgCount){
       startCount = orgCount;
       console.log('Start Count: '+ startCount); //prints correct value e.g, 6
    }, function(error){
       console.log(error);
    });
    return deferred.promise;
  };

it('should accept valid data for adding new store', function() {
   var cNum = null;
   testPromise().then(function(result){
      cNum = result;
      console.log('cNUm value: '+ cNum); //this value doesn't get printed in console
   });
   /* Code for adding test fields in store page */

   expect(items.count()).toBe(cNum+1);
 });
});

Я ожидаю, что счет магазина будет таким же в конце теста. count() разрешает обещание, и правильное значение счетчика хранилища печатается в testPromise(), но в нем блокируется, когда я вызываю testPromise(), а затем метод никогда не переходит в этот блок "then"

и конечный результат говорит

Message:
 Expected 6 to be 1.
 Stacktrace:
  Error: Failed expectation

Я также изучил немного больше в webdriver.promise.Promise() из этой ссылки http://selenium.googlecode.com/git/docs/api/javascript/class_webdriver_promise_Promise.html и попытался использовать это для создания обещать и разрешать свою ценность, но не уверен, в чем проблема. Либо я получаю сообщение об ошибке: "Ожидается, что 6 - NaN" или "Ожидается, что 6 будет 1". Разве я не разрешаю обещание или не записываю "затем" правильно? Поблагодарили бы за понимание/помощь по этой проблеме.

4b9b3361

Ответ 1

Вот рабочий пример пользовательской функции для использования в Protractor, которая создает и выполняет (или отвергает) обещание:

// Get the text of an element and convert to an integer.
// Returns a promise.
function getTextAsInteger(element, radix) {
  // Specify a default radix for the call to parseInt.
  radix = radix || 10;
  // Create a promise to be fulfilled or rejected later.
  var deferred = protractor.promise.defer();
  // Get the text from the element. The call to getText
  // returns a promise.
  element.getText().then(
    function success(text) {
      var num = parseInt(text, radix);
      if (!isNaN(num)) {
        // Successfully converted text to integer.
        deferred.fulfill(num);
      } else {
        // Error converting text to integer.
        deferred.reject('could not parse "$1" into an integer'
          .replace('$1', text));
      }
    },
    function error(reason) {
      // Reject our promise and pass the reason from the getText rejection.
      deferred.reject(reason);
    });

  // Return the promise. This will be resolved or rejected
  // when the above call to getText is resolved.
  return deferred.promise;
}

Функция принимает element как аргумент и вызывает свой метод getText(), который сам возвращает обещание. При успешном вызове getText() проанализируйте текст как целое число и выполните обещание. Если getText() отклоняется, мы передаем причину нашему собственному отказу.

Чтобы использовать эту функцию, выполните обещание элемента:

var numField = element(by.id('num-field'));
getTextAsInteger(numField).then(
    function success(num) {
        console.log(num);
    }, 
    function error(reason) {
        console.error(reason);
    });

или

var numField = element(by.id('num-field'));
expect(getTextAsInteger(numField)).toEqual(jasmine.any(Number));
expect(getTextAsInteger(numField)).toBeGreaterThan(0);

Ответ 2

Создание

Для создания обещания в транспортирте вам нужно написать:

var deferred = protractor.promise.defer();
var promise = deferred.promise;

Callbacks

Обратные вызовы вызываются асинхронно. Вы можете зарегистрировать один (или более) ответный вызов "на успех":

promise.then(function() {
   ...
});

вы также можете зарегистрировать один (или более) обратный вызов "при ошибке":

promise.then(null, function() {
   ...
});

Эти регистрации могут быть связаны:

promise.then(function() {
   ...
}).then(function() {
   ...
}).then(null, function() {
   ...
}).then(function() {

}, function() {
   ...
}).then(onSuccess, onFailure);

Решение

Успех

Обратные вызовы "на успех" вызываются, когда обещание успешно разрешено:

deferred.fulfill(value);

Отказ

Обратные вызовы "on failure" вызывают, когда обещание успешно разрешено:

deferred.reject(new Error('a problem occurs'));

В коде

вы пропустили шаг разрешения. Вы должны выполнить обещание.

Более полная ссылка доступна в документации Webdriver.js

Ответ 3

Я получил ту же проблему и решил ее, создав обещание для ожидаемого количества элементов:

it('should accept valid data for adding new store', function() {
    // Given
    let expectedCountAfterNewRow = items.count().then((cnt)=>{return cnt+1}); 
    // Note: items.count() is a promise so the expected count should a promise too

    // When
    /* Code for adding test fields in store page */

    // Then
   expect(items.count()).toEqual(expectedCountAfterNewRow);
});