Создание и разрешение 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". Разве я не разрешаю обещание или не записываю "затем" правильно? Поблагодарили бы за понимание/помощь по этой проблеме.
Ответы
Ответ 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);
});