Nightwatch 在 for 循环中执行命令乱序
Nightwatch execute command within for loop runs out of order
我是单元测试的新手,但我一直在尝试使用 Nightwatch 创建一个脚本,该脚本遍历页面的正文内容,单击每个 link 并报告它是否已损坏。
我正在尝试制作一个循环遍历正文内容中的每个标签,计算其中包含的 'a' 标签的数量,然后点击每个标签,但是每当我使用 browser.execute for循环中的命令,脚本执行乱序。
这是我的代码。我输入了几个 console.log 语句来尝试弄清楚发生了什么:
'Click Links' : function(browser) {
browser
//Count all tags (p/div) in content that aren't links
.useCss()
.execute(function() {
return document.querySelectorAll("div.field-item.even *:not(a)").length;
},
function(tags){
tag_total = tags.value;
//Loop through every tag in content & check every a tag contained within
for (var x = 1; x < tag_total+1; x++) {
console.log("x val before execute: " + x);
browser.execute(function() {
return document.querySelectorAll("div.field-item.even *:not(a):nth-child(" + x + ") a").length;
},
function(links){
console.log("x val at start of execute: " + x);
a_total = links.value;
for (var y = 1; y < a_total+1; y++) {
browser.click("div.field-item.even *:not(a):nth-child(" + x + ") a:nth-child(" + y + ")");
browser.pause(1000);
//Conditionals for on-site 404/403 links
browser.execute(function() {
return document.querySelector("meta[content='Error Document']");
},
//Grabs url if link is broken
function(result){
if (result.value != null) {
browser.url(function(result) {
console.log("BROKEN LINK: " + result.value);
});
}
});
//Go back to previous page
browser.url(process.argv[2]);
browser.pause(1000);
}
console.log("x val at end of execute: " + x);
});
console.log("x val at end of for loop: " + x);
}
})
.end()
}
我得到的输出:
x val before execute: 1
x val at end of for loop: 1
x val before execute: 2
x val at end of for loop: 2
x val at start of execute: 3
x val at end of execute: 3
ERROR: Unable to locate element: "div.field-item.even *:not(a):nth-child(3) a:nth-child(1)" using: css selector
for 循环似乎 运行 遍历并跳过了整个 browser.execute 块。循环完成后,然后输入 browser.execute 块,x 为无效数字 3.
为什么 browser.execute 命令会导致 for 循环乱序执行,是否可以采取任何措施来修复它以使其按预期顺序运行?
这与守夜人无关,但与Javascript有关。
当您有一个循环并在该循环中调用一个函数时,该函数中使用的变量将通过引用保存。换句话说,变量不会因任何函数而改变。
如果我们通过一个简单的例子就更容易了:
var myFuncs = [];
for (var i = 0; i < 3; i += 1) {
myFuncs.push(function () {
console.log('i is', i);
});
}
myFuncs[0](); // i is 3
myFuncs[1](); // i is 3
myFuncs[2](); // i is 3
这是因为i
在函数中保存为引用。因此,当 i
在下一次迭代中递增时,引用不会改变,但值会改变。
这可以通过将函数移出循环来轻松解决:
function log (i) {
return function () {
console.log(i);
}
}
var myFuncs = [];
for (var i = 0; i < 3; i += 1) {
myFuncs.push(log(i));
}
myFuncs[0](); // i is 0
myFuncs[1](); // i is 1
myFuncs[2](); // i is 2
如果您想进一步探索这个概念,可以看看这个 similar SO answer(具有非常相似的示例 - 具有讽刺意味)。
我是单元测试的新手,但我一直在尝试使用 Nightwatch 创建一个脚本,该脚本遍历页面的正文内容,单击每个 link 并报告它是否已损坏。
我正在尝试制作一个循环遍历正文内容中的每个标签,计算其中包含的 'a' 标签的数量,然后点击每个标签,但是每当我使用 browser.execute for循环中的命令,脚本执行乱序。
这是我的代码。我输入了几个 console.log 语句来尝试弄清楚发生了什么:
'Click Links' : function(browser) {
browser
//Count all tags (p/div) in content that aren't links
.useCss()
.execute(function() {
return document.querySelectorAll("div.field-item.even *:not(a)").length;
},
function(tags){
tag_total = tags.value;
//Loop through every tag in content & check every a tag contained within
for (var x = 1; x < tag_total+1; x++) {
console.log("x val before execute: " + x);
browser.execute(function() {
return document.querySelectorAll("div.field-item.even *:not(a):nth-child(" + x + ") a").length;
},
function(links){
console.log("x val at start of execute: " + x);
a_total = links.value;
for (var y = 1; y < a_total+1; y++) {
browser.click("div.field-item.even *:not(a):nth-child(" + x + ") a:nth-child(" + y + ")");
browser.pause(1000);
//Conditionals for on-site 404/403 links
browser.execute(function() {
return document.querySelector("meta[content='Error Document']");
},
//Grabs url if link is broken
function(result){
if (result.value != null) {
browser.url(function(result) {
console.log("BROKEN LINK: " + result.value);
});
}
});
//Go back to previous page
browser.url(process.argv[2]);
browser.pause(1000);
}
console.log("x val at end of execute: " + x);
});
console.log("x val at end of for loop: " + x);
}
})
.end()
}
我得到的输出:
x val before execute: 1
x val at end of for loop: 1
x val before execute: 2
x val at end of for loop: 2
x val at start of execute: 3
x val at end of execute: 3
ERROR: Unable to locate element: "div.field-item.even *:not(a):nth-child(3) a:nth-child(1)" using: css selector
for 循环似乎 运行 遍历并跳过了整个 browser.execute 块。循环完成后,然后输入 browser.execute 块,x 为无效数字 3.
为什么 browser.execute 命令会导致 for 循环乱序执行,是否可以采取任何措施来修复它以使其按预期顺序运行?
这与守夜人无关,但与Javascript有关。
当您有一个循环并在该循环中调用一个函数时,该函数中使用的变量将通过引用保存。换句话说,变量不会因任何函数而改变。
如果我们通过一个简单的例子就更容易了:
var myFuncs = [];
for (var i = 0; i < 3; i += 1) {
myFuncs.push(function () {
console.log('i is', i);
});
}
myFuncs[0](); // i is 3
myFuncs[1](); // i is 3
myFuncs[2](); // i is 3
这是因为i
在函数中保存为引用。因此,当 i
在下一次迭代中递增时,引用不会改变,但值会改变。
这可以通过将函数移出循环来轻松解决:
function log (i) {
return function () {
console.log(i);
}
}
var myFuncs = [];
for (var i = 0; i < 3; i += 1) {
myFuncs.push(log(i));
}
myFuncs[0](); // i is 0
myFuncs[1](); // i is 1
myFuncs[2](); // i is 2
如果您想进一步探索这个概念,可以看看这个 similar SO answer(具有非常相似的示例 - 具有讽刺意味)。