Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling done() in a step ends the whole test #444

Closed
wheelsandcogs opened this issue May 12, 2015 · 5 comments
Closed

Calling done() in a step ends the whole test #444

wheelsandcogs opened this issue May 12, 2015 · 5 comments

Comments

@wheelsandcogs
Copy link

I'm trying to use the done() callback as my tests are using async code to make requests to a REST API. However, when I have more than one step, the test completes after the first call to done() and exits the suite. It also seems to display ✔ Passed as soon as the test is started...

$ bin/nightwatch -v
nightwatch v0.6.7

$ bin/nightwatch --env api 

[Widget] Test Suite
===================

Running:  Create a single widget (POST)
 ✔ Passed
 ✔ Passed [equal]: 201 Created

$

nightwatch.json:

"test_settings" : {
    "default" : {
        "launch_url" : "http://example.dev",
        "selenium_port"  : 4444,
        "selenium_host"  : "localhost",
        "silent": true,
        "screenshots" : {
            "enabled" : true,
            "path" : "./tests/output/screenshots"
        },
        "desiredCapabilities": {
            "browserName": "chrome",
            "javascriptEnabled": true,
            "acceptSslCerts": true
        },
        "exclude": [
            "./tests/functional/_assertions",
            "./tests/functional/_commands",
            "./tests/functional/Api"
        ]
    },

    "api" : {
        "selenium": {
            "start_process": false,
            "start_session": false
        },
        "filter": "./tests/functional/Api/*",
        "exclude": ""
    }
}

widget-test.js

module.exports = {

    widget: { id: "widget::1", html: "<p>widget 1</p>" },

    "Create a single widget (POST)": function (client, done) {
        client.post("/api/widget", this.widget, function (response) {
            client.assert.equal(response.statusCode, 201, "201 Created");
            done();
        });
    },

    "Retrieve created widget (GET)": function (client, done) {
        client.get("/api/widget/"+this.widget.id, function (response) {
            var widget = JSON.parse(response.body);

            client.assert.equal(response.statusCode, 200, "200 OK");
            client.assert.deepEqual(widget, this.widget, "widget matches");

            done();
        });
    }
}

_commands/post.js:

/**
 * POST data to the specified path.
 *
 * @method post
 * @param {string}   path    The relative path to post to
 * @param {object}   json    The object to post
 * @param {function} success A callback on success
 */
exports.command = function(path, json, success) {
    var request = require("request");

    var options = {
        uri: this.launchUrl + path,
        method: "POST",
        json: true,
        body: json
    };

    request(options, function (error, response) {
        if (error) {
            console.log(error);
            return;
        }

        success(response);
    });
};

_commands/get.js:

/**
 * GET data from the specified path.
 *
 * @method get
 * @param {string}   path    The relative path to fetch
 * @param {function} success A callback on success
 */
exports.command = function(path, success) {
    var request = require("request");

    request.get(this.launchUrl + path, function (error, response) {
        if (error) {
            console.log(error);
            return;
        }

        success(response);
    });
};
@beatfactor
Copy link
Member

I fixed the extra "Passed".

The other problem is with your custom command. You must explicitly emit the "complete" event, like this:

var util = require('util');
var events = require('events');

function Get () {}
util.inherits(Get, events.EventEmitter);

Get.prototype.command = function(path, success) {
    var request = require("request");

    request.get(this.launchUrl + path, function (error, response) {
        if (error) {
            console.log(error);
            return;
        }

        success(response);
        this.emit('complete');
    }.bind(this));
};

module.exports = Get;

@wheelsandcogs
Copy link
Author

Thanks.

When I change my command to mirror the above, this.launchUrl is undefined? How do I access the launchUrl setting inside my custom command please?

@beatfactor
Copy link
Member

Try this.api.launchUrl.

@wheelsandcogs
Copy link
Author

Yep that works thanks.

@drptbl
Copy link

drptbl commented Oct 2, 2015

@wheelsandcogs Have you managed to do this? What was the result? Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants