使用ZombieJS在Cucumber.js场景中回调问题

时间:2014-07-13 16:22:59

标签: javascript zombie.js cucumberjs

我对使用Cucumber和Lettuce等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方案。 documentation for Cucumber.js implies this should work,但第二步失败。

以下是我收到的错误消息:

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();,它就会通过。我不知道发生了什么。为什么这种情况失败了?应用程序本身按预期工作。似乎第二步的回调永远不会解雇。

2 个答案:

答案 0 :(得分:0)

如果将回调添加到第二步,则测试通过,因为刚刚跳过了visitPage。

我的访问功能如下:

 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 for&#39; add&#34;在您的自定义代码中

答案 1 :(得分:0)

为什么要完全使用回调?他们混淆了您的代码。而等效的方法是使用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() ;
}