Написание Asyn c пользовательской команды с Nightwatch - PullRequest
0 голосов
/ 03 августа 2020

Последние 3 дня я безуспешно пытался получить функцию, которую использую для получения CSS путей селектора списка элементов, соответствующих определенному селектору, для работы в качестве настраиваемой команды в Nightwatch JS.

То, что вы даете команде:

browser.getUniqueCssSelector('.note');

Каким должен быть результат:

['HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(1) > DIV.note:nth-child(1)',
'HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(1) > DIV.note:nth-child(2)',
'HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(2) > DIV.note:nth-child(1)',
'HTML> BODY> SECTION.bottom-container > DIV.inner > DIV.notes:nth-child(1) > DIV.note'
'HTML> BODY> SECTION.bottom-container > DIV.inner > DIV.notes:nth-child(2) > DIV.note']

И так и так.

Я пробовал много разных способов реализовать это, но безуспешно, я новичок в Async / Await, поэтому мне не повезло, и я не смог связать примеры в Nightwatch. (https://nightwatchjs.org/guide/extending-nightwatch/#writing -custom-commands ) к моей проблеме.

Я написал следующее, используя сегмент кода, найденный в Как сгенерировать уникальный css селектор для элемента DOM ? :

// getUniqueCssSelector.js file
exports.command = async function(selector) {
        var browser = this;
     let result = browser.execute(function (selector) {

            const nodes = Array.from(document.querySelectorAll(selector))
            var nodesSelectors = [];

            nodes.forEach(node => {
                nodesSelectors.push(getCssSelectorShort(node));
            });
            return nodesSelectors;

            
            function getCssSelectorShort(el) {
                let path = [], parent;
                while (parent = el.parentNode) {
                let tag = el.tagName, siblings;
                path.unshift(
                    el.id ? `#${el.id}` : (
                    siblings = parent.children,
                    [].filter.call(siblings, sibling => sibling.tagName === tag).length === 1 ? tag :
                    `${tag}:nth-child(${1+[].indexOf.call(siblings, el)})`
                    )
                );
                el = parent;
                };
                return `${path.join(' > ')}`;
            };
            
            

        }, [selector], function(res) {
            console.log('************INSIDE COMMAND RETURN CALLBACK ');
            return res;

        })

        return result;

    }


Оттуда я хочу, чтобы в моем тестовом коде, который вызывает эту настраиваемую команду, можно было await ее. Эту команду нужно будет вызывать для нескольких элементов, чтобы сделать ее функцией обратного вызова, хотя она работала, также поместила бы мой код в вечный стек обратного вызова, что сделало бы его очень уродливым, очень быстрым.

в идеале, Я хочу, чтобы код стал примерно таким:

// nwtest.js file
 let nodeSelectorsList= await browser.getUniqueCssSelectors('.note');
            console.log(nodeSelectorsList); // Would bring me back the entire set I posted above.

nodeSelectorsList.forEach(async (noteElement)=> {
                 let resultSingle = await browser.element('css selector', noteElement);
                 console.log(resultSingle); // Should print the elements returned individually
             })

К сожалению, я всегда получаю undefined как результат моих усилий. : /

Я ломал себе голову над этим от нескольких дней до почти недели и пробовал реализации как Promise, так и Event, но этот был немного выше меня, поэтому я обращаюсь за помощью к SO. Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 04 августа 2020

Я думаю, вы можете обернуть его как Promise, а затем ждать извне,

// getUniqueCssSelector. js file

exports.command = function (selector) {
    var browser = this;
    return new Promise(function (resolve, reject) {

        browser.execute(function (selector) {

            const nodes = Array.from(document.querySelectorAll(selector))
            var nodesSelectors = [];

            nodes.forEach(node => {
                nodesSelectors.push(getCssSelectorShort(node));
            });
            return nodesSelectors;


            function getCssSelectorShort(el) {
                let path = [],
                    parent;
                while (parent = el.parentNode) {
                    let tag = el.tagName,
                        siblings;
                    path.unshift(
                        el.id ? `#${el.id}` : (
                            siblings = parent.children,
                            [].filter.call(siblings, sibling => sibling.tagName === tag).length === 1 ? tag :
                            `${tag}:nth-child(${1+[].indexOf.call(siblings, el)})`
                        )
                    );
                    el = parent;
                };
                return `${path.join(' > ')}`;
            };



        }, [selector], function (res) {
            resolve(res);
        });
    });
}

// nwtest. js файл

let nodeSelectorsList = await browser.getUniqueCssSelectors('.note');
console.log(nodeSelectorsList); // Would bring me back the entire set I posted above.

nodeSelectorsList.forEach(async (noteElement) => {
    let resultSingle = await browser.element('css selector', noteElement);
    console.log(resultSingle); // Should print the elements returned individually
})
...