Когда мы должны использовать.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/

То есть:

  1. Транспортир ставит в очередь все команды драйвера в ControlFlow,
  2. когда вам нужен результат команды драйвера, вы должны использовать.then,
  3. когда вам не нужен результат драйвера, вы можете избежать.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()
})
Другие вопросы по тегам