Проблема с обратными вызовами в сценарии Cucumber.js с ZombieJS

У меня есть некоторый опыт работы с инструментами BDD, такими как Cucumber и Lettuce. В настоящее время я создаю приложение Phonegap, и я хотел бы начать использовать Cucumber.js для создания приемочных тестов для него. К сожалению, у меня небольшая проблема.

Вот основной файл функций, который я собрал:

Feature: Authentication

    As a user
    I want to be able to log in and out

    Scenario: Logging in
        Given I am not logged in
        And I am on the page "login"
        When I fill in the "username" field with "student"
        And I fill in the "password" field with "password"
        And I click the "LOG IN" button
        Then I should see the text "STUDENT"

Вот мой world.js:

var zombie = require('zombie');
var World = function World(callback) {
    "use strict";

    this.browser = new zombie(); // this.browser will be available in step definitions

    this.visit = function (url, callback) {
        this.browser.visit(url, callback);
    };

    callback(); // tell Cucumber we're finished and to use 'this' as the world instance
};
exports.World = World;

Вот мои определения шагов:

var wrapper = function () {
    "use strict";

    this.World = require("../support/world.js").World; // overwrite default World constructor

    this.Given(/^I am not logged in$/, function (callback) {
        // Clear local storage
        this.browser.localStorage("localhost:9001").clear();
        callback();
    });

    this.Given(/^I am on the page "([^"]*)"$/, function (page, callback) {
        // Visit page
        this.browser.visit('http://localhost:9001/app/index.html#' + page, callback);
    });
};

module.exports = wrapper;

Я настроил задачу Grunt, которая сначала запускает сервер подключения на порту 9001, а затем запускает сценарии Cucumber. документация для Cucumber.js подразумевает, что это должно работать, но на втором этапе это не удается.

Вот сообщение об ошибке, которое я получаю:

Running "connect:cucumber" (connect) task
Started connect web server on http://localhost:9001

Running "cucumberjs:src" (cucumberjs) task
.Cannot call method 'add' of undefined TypeError: Cannot call method 'add' of undefined
    at <anonymous>:10:711
    at <anonymous>:10:874
    at <anonymous>:10:1224
    at Contextify.sandbox.run (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/node_modules/contextify/lib/contextify.js:12:24)
    at DOMWindow.window._evaluate (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/window.js:188:25)
    at Object.HTML.languageProcessors.javascript (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/scripts.js:23:21)
    at define.proto._eval (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:1480:47)
    at loaded (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/scripts.js:74:23)
    at /Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:76:20
    at Object.item.check (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:345:11)
FUUUU

(::) failed steps (::)

TypeError: Cannot call method 'add' of undefined
    at <anonymous>:10:711
    at <anonymous>:10:874
    at <anonymous>:10:1224
    at Contextify.sandbox.run (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/node_modules/contextify/lib/contextify.js:12:24)
    at DOMWindow.window._evaluate (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/window.js:188:25)
    at Object.HTML.languageProcessors.javascript (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/scripts.js:23:21)
    at define.proto._eval (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:1480:47)
    at loaded (/Users/matthewdaly/Projects/myapp/node_modules/zombie/lib/zombie/scripts.js:74:23)
    at /Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:76:20
    at Object.item.check (/Users/matthewdaly/Projects/myapp/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:345:11)

Если я вставлю callback(); после тела второго шага, он пройдет. Я не уверен, что происходит. Почему этот сценарий не работает? Само приложение работает как положено. Кажется, что обратный вызов для второго шага никогда не срабатывает.


person Matthew Daly    schedule 13.07.2014    source источник


Ответы (2)


тест проходит, если вы добавите обратный вызов ко второму шагу, потому что визитная страница просто пропускается.

моя функция посещения выглядит так:

 this.visit = function(url, callback) {
   that.browser.visit(url, function(error) {
     if (error) {
       callback.fail(error);
     } else {
       callback.call(that, that.browser);
     }
   });
 });

но я думаю, что настоящая проблема находится на вашей странице, потому что sandbox.run — это точка, где зомби начинает выполнять пользовательский (js)-код со страницы. Так это анонимный обратный вызов в вашем (уменьшенном) скрипте в столбце 1224? Возможно, вам нужно отследить его с помощью console.log... (что-то с localStorage?, хотя зомби его поддерживает), grep для «добавить» в вашем пользовательском коде

person pscheit    schedule 09.10.2014

Зачем вообще использовать обратные вызовы? Они запутывают ваш код. Принимая во внимание, что эквивалентно использовать пары async/await, которые будут имитировать, так сказать, кодирование Java и правильные инструкции, начинающиеся и заканчивающиеся:

var R = await visit () ;
await do_this_when_visit_is_done () ;
await do_that_when_do_this_is_done() ;

in cucumber :
this.Given(/^I am on the page "(.*)"$/, async function (page) 
{
  await this.page_is_loaded() ;
}
person Bastien Gallienne    schedule 05.12.2018
comment
Спасибо. Мой ответ отвечает не немного большему объему, чем проблема, которую мы здесь рассматриваем, а именно то, что обратные вызовы могут быть трудными для отладки или чтения, поэтому я хотел упомянуть это решение как лучшую, ИМХО, реализацию асинхронного кодирования, которая в свою очередь может облегчить отладку текущей проблемы. - person Bastien Gallienne; 06.12.2018