Когда мы должны использовать.then с Protractor Promise?
У меня много нестабильности с Protractor, и я уверен, что есть кое-что, чего я не понимаю. Иногда мне нужно использовать.then () при нажатии на кнопку перед продолжением, иногда это не оказывает никакого влияния, и я не должен использовать.then (), или тест не пройден.
Интересно, когда мне следует использовать обратный вызов.then () при тестировании в Protractor? Пример:
createAccountForm = $('#form-create-account');
submitButton = createAccountForm.$('button[type=submit]');
browser.wait(EC.elementToBeClickable(submitButton), 5000);
submitButton.click(); // .then(function(){ <-- uncomment in the .then form
// find the confirmation message
var message = $('.alert-success');
browser.wait(EC.visibilityOf(message), 5000);
log.debug('After visibilityOf');
expect(message.isPresent()).to.be.eventually.true;
// }); --> uncomment when in .then form
Когда я использую эту форму теста (без.then ()), я вижу в браузере, что нажатие кнопки не выполнено, тест продолжается со следующим ожиданием и затем останавливается.
Если я использую форму.then (), щелчок по кнопке завершается, и тест продолжается без ошибок.
В другом тесте мне не нужно использовать обратный вызов then () при нажатии на кнопку.
Итак, когда я должен использовать.then (), а когда нет?
Жан-Марк
2 ответа
Ответ на этот вопрос можно найти в этом посте: http://spin.atomicobject.com/2014/12/17/asynchronous-testing-protractor-angular/
То есть:
- Транспортир ставит в очередь все команды драйвера в ControlFlow,
- когда вам нужен результат команды драйвера, вы должны использовать.then,
- когда вам не нужен результат драйвера, вы можете избежать.then, но все последующие инструкции должны быть поставлены в очередь в ControlFlow, иначе они будут выполняться перед командами в очереди, приводящими к непредсказуемому результату. Поэтому, если вы хотите выполнить команду, не относящуюся к тестам драйверов, вы должны добавить ее в обратный вызов.then или поместить тест в Promise и поставить тест в очередь в ControlFlow. Смотрите пример ниже.
Вот пример моего теста, работающего без.then:
log.debug('test0');
// enqueue the click
submitButton.click();
var message = $('.alert-success');
// enqueue the wait for message to be visible
browser.wait(EC.visibilityOf(message), 5000);
log.debug('test1');
// enqueue a test
expect(message.isPresent()).to.be.eventually.true;
log.debug('test2');
// a function returning a promise that does an async test (check in MongoDB Collection)
var testAccount = function () {
var deferred = protractor.promise.defer();
// Verify that an account has been created
accountColl.find({}).toArray(function (err, accs) {
log.debug('test5');
expect(err).to.not.exist;
log.debug('test6');
expect(accs.length).to.equal(1);
return deferred.fulfill();
});
return deferred.promise;
};
log.debug('test3');
// Enqueue the testAccount function
browser.controlFlow().execute(testAccount);
log.debug('test4');
Выход теперь то, что мы ожидаем:
test0
test1
test2
test3
test4
test5
test6
Сделайте себе одолжение и избегайте.
Сегодня,
async/await
гораздо больше подходит для обещаний
Но в двух словах откройте страницу API транспортира https://www.protractortest.org/#/api, найдите метод, который вы собираетесь использовать, и посмотрите, что он вернет. Если написано обещание, просто добавьте
await
перед тем как позвонить. Убедитесь, что ваша функция обертывания
async
it('test case 1', async () => {
await elem.click()
})