Nightwatch.js не завершает тест после функции подтверждения - PullRequest
0 голосов
/ 14 марта 2019

У меня есть страница учетной записи с разделом адресной книги.Я запускаю тест, например, создаю и обновляю адрес, а затем в 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 до другого числа, я получаю ошибку и тестне удается, но если это сorrect it not.

Если я добавлю функцию end () после проверки, браузер закроется, но я не получу никакого сообщения «тест пройден»

...