Проблема с обратными вызовами в сценарии Cucumber.js с ZombieJS
У меня есть некоторый опыт работы с инструментами BDD, такими как огурец и салат. В настоящее время я создаю приложение 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();
после тела второго шага оно проходит. Я не уверен, что происходит. Почему этот сценарий терпит неудачу? Само приложение работает как положено. Кажется, что обратный вызов для второго шага никогда не срабатывает.
1 ответ
Тест пройден, если вы добавите обратный вызов ко второму шагу, потому что посещение только что пропущено.
моя функция посещения выглядит следующим образом:
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 для "add" в вашем пользовательском коде
Зачем вообще использовать обратные вызовы? Они запутывают ваш код. Принимая во внимание, что эквивалентно использовать пары асинхронный / ожидающий, которые будут имитировать, так сказать, кодирование 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() ;
}