Nightwatch.js不会在asser函数后结束测试

时间:2019-03-14 08:59:12

标签: javascript automated-tests nightwatch.js gherkin

我有一个带有地址簿部分的帐户页面。 我进行了一些测试,例如创建和更新地址,然后在小黄瓜中,我在末尾有以下命令:

And I delete all the addresses

在common-steps.js中,我有:

Then(/^I delete all the addresses$/,function(){
        return client.addressBookCleaner();
    })

该功能已经存在,我正在尝试弄清楚其工作原理:基本上它可以递归运行并删除所有地址:

var addressBookCleaner = function () {

    function clickMyLink() {
        this
            .click('[data-ctrl="addressbook.removeButton"]')
            .waitForElementVisible('[data-action="confirm"]', 190000)
            .pause(500)
            .click('[data-action="confirm"]')
            .waitForElementVisible('.uiLayer-removeButton .mfp-close', 190000)
            .pause(500)
            .click('.uiLayer-removeButton .mfp-close')
            .pause(500);
    }

    function isDeleteFormVisible(callback) {
        this
            .pause(1000)
            .isVisible('[data-ctrl="addressbook.removeButton"]', function (result) {
                callback(result.status === 0 && result.value.length);
            });
    }

    function verifyDeleteFormIsNotVisible(actual, message) {
        this.verify.ok(!actual, message);
    }

    this
        .waitForElementVisible('body', 190000)
        .pause(1000)
        .clickUntilNotVisible(clickMyLink.bind(this), isDeleteFormVisible.bind(this), verifyDeleteFormIsNotVisible.bind(this), 190000);
};

exports.command = function () {
    debugger;
    addressBookCleaner.call(this);
};

如您所见,调用的函数为clickUntilNotVisible

exports.command = function (clickElementFunction, getVisibilityFunction, assertion, timeout, message) {
    function clickAndGetVisiblity (callback) {
        //debugger;
        clickElementFunction();
        getVisibilityFunction(callback);
    }

    function isTrue (actual) {
        return !!actual;
    }

    return this.waitUntil(clickAndGetVisiblity, isTrue, assertion, timeout, message);
};

调用waitUntil函数:

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

function waitUntil() {
    events.EventEmitter.call(this);
    this.startTimeInMilliseconds = null;
}

util.inherits(waitUntil, events.EventEmitter);

/**
 * The purpose of this command is to serve as a base for waitUntil_ commands. It will run the getActual function until
 * the predicate funciton returns true or the timeout is reached. At that point, the assertion funciton will be called.
 * @param getActual {Function} - should passe the found value to its callback. The callback will be passed as the only
 *      argument.
 * @param predicate {Function} - the wait will end when this returns true. The actual value is passed as the only
 *      argument.
 * @param assertion {Function} - the assertion to make. The assertion should pass when the predicate returns true. This
 *      function will be passed the actual value and the message.
 * @param timeoutInMilliseconds {number} - the number of milliseconds to wait before timing out and failing.
 * @param message {string} - the message to attach to the assertion. The elapsed time will be appended to this.
 * @returns custom command waitUntil, which can be accessed as browser.waitUntil(args);
 */
waitUntil.prototype.command = function (getActual, predicate, assertion, timeoutInMilliseconds, message) {
    message = message || 'waitUntil';
    this.startTimeInMilliseconds = new Date().getTime();
    var self = this;

    this.check(getActual, predicate, function (actual, loadedTimeInMilliseconds) {
        if (predicate(actual)) {
            message += ': true after ' +
                (loadedTimeInMilliseconds - self.startTimeInMilliseconds) + ' ms.';
        } else {
            message += ': timed out after ' + timeoutInMilliseconds + ' ms.';
        }
        assertion(actual, message);
        self.emit('complete');
    }, timeoutInMilliseconds);

    return this;
};

waitUntil.prototype.check = function (getActual, predicate, callback, maxTimeInMilliseconds) {
    var self = this;
    getActual(function (result) {
        // If the argument passed to the callback is an object, it is assumed that the format is of the argument passed
        // to callbacks by the Nightwatch API, in which the object has a "value" attribute with the actual information.
        var resultValue;
        if (typeof result !== 'object') {
            resultValue = result;
        } else if (result.hasOwnProperty('value')) {
            resultValue = result.value;
        } else {
            self.error('Result object does not have a value.');
            return;
        }

        var now = new Date().getTime();
        if (predicate(resultValue)) {
            callback(resultValue, now);
        } else if (now - self.startTimeInMilliseconds < maxTimeInMilliseconds) {
            setTimeout(function () {
                self.check(getActual, predicate, callback, maxTimeInMilliseconds);
            }, TIMEOUT_RETRY_INTERVAL);
        } else {
            callback(resultValue, null);
        }
    });
};

module.exports = waitUntil;

我无法完全理解它的工作原理,基本上它是递归工作,删除所有地址,然后给我一个错误(因为我想,它找不到任何地址):所以我必须修改该函数以停止它。

我以这种方式修改了addressBookCleaner模块的功能之一:

function isDeleteFormVisible(callback) {
    var self = this;
    this
        .pause(1000)
        .element('css selector', '[data-ytos-ctrl="addressbook.removeButton"]', function (result) {
            if(result.status === -1){
                return self.pause(4000)
                            .verify.attributeContains('[data-ctrl="addressbook.addressesCount"]','data-address-count','0')
            } else {
                callback(result.status === 0 && result.value.length);
            }
        });
}

这没有给我任何错误,但是测试根本没有结束,我在控制台中看到以下消息:

√ Testing if attribute data-address-count of <[data-ctrl="addressbook.addressesCount"]> contains "0".

如果我将值从0修改为另一个数字,则会收到错误消息,并且测试失败,但是如果正确无误。

如果我在验证后附加end()函数,浏览器将关闭,但不会收到任何“测试通过”消息

0 个答案:

没有答案