javascript - 使用 Nightwatch 编写异步自定义命令
问题描述
在过去的 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.js 指南中的示例联系起来(https ://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands)到我的问题。
我使用如何为 DOM 元素生成唯一 css 选择器中的代码段编写了以下内容? :
// 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。任何帮助将不胜感激!
解决方案
我认为您可以将其包装为 Promise 然后从外部等待,
// 获取UniqueCssSelector.js 文件
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
})
推荐阅读
- python - Rename object internal repr, name // tkinter 问题
- apexcharts - ApexChart - 数字非常小的轴
- java - 将 CSV 文件读入 java 对象
- c# - 使用 iPhone/Android 遥控器构建 Windows 应用程序
- java - java中的加密(jasypt)和nodejs中的解密
- google-app-engine - 错误:(gcloud.app.deploy)错误响应:[9] Cloud build XXXXXXXXXXXX 状态:FAILURE
- task - 从不同的测试平台调用任务 systemverilog
- php - Laravel 路由模型绑定:销毁方法没有获取必要的信息
- sql - 如何从两个不同的列中选择我的搜索功能?
- bluebird - 如何在发生错误后停止调用承诺链中的所有方法