Используйте вспомогательные модули для повторяющихся упорядоченных задач при функциональном тестировании в интернете

Я пытаюсь создать модуль, который будет заполнять входные данные формы при функциональном тестировании, и я хотел бы иметь возможность вызывать его из нескольких наборов тестов.

Псевдокод для вспомогательного файла (helper.js)

module.exports = {
    fillForm: function() {
        this.findByCssSelector('#firstname')
            .click()
            .pressKeys('John')
            .end()
    },
    anotherFunction: function() {
        // more code
    }
}

В спецификации для функционального теста я загружаю этот модуль как helper и я вижу, как это выполняется. Тем не менее, кажется, я не могу использовать этот синтаксис и гарантировать, что цепочечные шаги выполняются в определенном порядке:

'Test filling form data': function() {
    return this.remote
                .get(require(toUrl(url))
                // should happen first
                .then(helper.fillForm)
                // should happen second
                .then(helper.anotherFunction)
                // only after the above should the click happen
                .findByCsSelector('#submit')
                 // click evt should show the #someElement element
                .click()                     
                .findByCssSelector('#someElement')
                .getComputedStyle('display')
                .then(style) {
                     // assertions here
    }

Кажется, что обещание цепочки позволяет click событие произойдет до then обратные вызовы выполнены. Возможен ли такой поток с интерном?

ОБНОВИТЬ:

На данный момент, обойти это с помощью такого кода:

var remote = initTest.call(this, url);
return helpers.fillForm1Data.call(remote)
    .otherChainedMethodsHere()
    .moreChainedMethods()
.then() {
    // assertion code here

где метод initTest выполняет выборку URL, изменение размера окна, очистку данных, а fillForm1Data делает то, что вы ожидаете. Но синтаксис довольно уродлив в этом смысле.

1 ответ

Решение

Ваш помощник не returnс любым значением, поэтому оно обрабатывается как синхронный обратный вызов, и следующая вещь в цепочке выполняется немедленно. Вы также не можете return this от помощника по обещанию, иначе это вызовет тупик (потому что обещание Команды будет ждать своего разрешения, а вместо этого Интерн будет выдавать ошибку, если вы попытаетесь это сделать), поэтому вам нужно создать новую Команду и вернуть ее, если вы вы хотите использовать связанный командный интерфейс внутри вашего помощника:

module.exports = {
    fillForm: function() {
        return new this.constructor(this.session)
            .findByCssSelector('#firstname')
            .click()
            .pressKeys('John');
    },
    anotherFunction: function() {
        // more code
    }
};

Вы также можете просто вернуться из this.session вместо этого, если вы не заботитесь об удобстве Command API и можете работать с обычными цепочками обратного вызова обещания:

module.exports = {
    fillForm: function() {
        var session = this.session;
        return session.findByCssSelector('#firstname')
          .then(function (element) {
            return element.click();
          })
          .then(function () {
            return session.pressKeys('John');
          });
    },
    anotherFunction: function() {
        // more code
    }
};
Другие вопросы по тегам