javascript - for 循环中的 Nightwatch 执行命令出现乱序

标签 javascript selenium for-loop iteration nightwatch.js

我对单元测试还很陌生,但我一直在尝试使用 Nightwatch 创建一个脚本,该脚本会遍历页面的正文内容,单击每个链接并报告它是否已损坏。

我正在尝试创建一个 for 循环,迭代正文内容中的每个标签,计算其中包含的“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 block 。循环完成后,将使用无效数字 3 的 x 输入 browser.execute block 。

为什么 browser.execute 命令会导致 for 循环无序执行,可以采取什么措施来修复它,使其按预期顺序运行吗?

最佳答案

这与 Nightwatch 无关,而是与 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 (其中有一个非常相似的例子 - 讽刺的是)。

关于javascript - for 循环中的 Nightwatch 执行命令出现乱序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33549514/

相关文章:

javascript - jQuery 将删除按钮附加到列表中会不断添加额外的按钮

javascript - 收集适当的 onScroll 数据来触发 AJAX 功能

java - Robot Framework和Selenium调用java方法

javascript - 无法更改文本字段变体的边框半径 = 在 Material-ui-core 中填充

javascript - 理解nodeJS中的这个日期吗?

selenium - 如何在selenium webdriver中上传具有相对路径的文件

selenium - 点击带有soapui和 Selenium 的按钮

javascript - 如何用变量定义一个数组,然后用一个数字填充每个数组?

c - 简单的 for 循环在 C 中不起作用

c - 如何使用bool、if语句、while语句,用来检查用户输入的有效性