for循环中的Nightwatch execute命令运行不正常 [英] Nightwatch execute command within for loop runs out of order

查看:271
本文介绍了for循环中的Nightwatch execute命令运行不正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm pretty new to unit testing, but I've been trying to create a script with Nightwatch that goes through the body content of a page, clicks every link and reports back whether it's broken.

我正在尝试创建一个for循环,该循环遍历正文内容中的每个标记,计算其中包含的"a"标记的数量,然后单击它们中的每个,但是每当我在其中使用browser.execute命令时,在for循环中,脚本会无序执行.

I'm trying to make a for loop that iterates through each tag in the body content, counts the number of 'a' tags contained within and then clicks on each of them, but whenever I use a browser.execute command within a for loop, the script executes out of order.

这是我的代码.我抛出了一些console.log语句,试图弄清楚发生了什么:

Here's my code. I've thrown in a couple of console.log statements to try and figure out what's going on:

'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块.循环结束后,然后使用无效数字3的x输入browser.execute块.

It seems like the for loop is running through and skipping the entire browser.execute block. After the loop finishes, the browser.execute block is then entered with x at an invalid number of 3.

为什么browser.execute命令会导致for循环无序执行,并且可以采取任何措施对其进行修复,以使其按预期顺序运行?

Why does the browser.execute command cause the for loop to execute out of order, and can anything be done to fix it so that it runs in the order intended?

推荐答案

这与Nightwatch无关,但与Javascript无关.

This has nothing to do with Nightwatch, but with Javascript.

当您有一个循环并在该循环内调用一个函数时,该函数中使用的变量将通过引用保存.换句话说,该变量对于任何功能都不会更改.

When you have a loop and you call a function within that loop, the variable used in such function is saved by reference. In other words, the variable doesn't change for any of the functions.

如果我们看一个简单的例子,会更容易:

It's easier if we go through a simple example:

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在下一次迭代中递增时,引用的值不会更改,但值会更改.

This is because i is saved as a reference in the function. So when i increments at the next iteration, the referenced doesn't change but the value does.

可以通过将函数移到循环外部来轻松解决此问题:

This could be easily fixed by moving the function outside of the loop:

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

如果您想进一步探索这个概念,可以看一下

In case you want to explore the concept a little bit more, you can have a look at this similar SO answer (which has a very similar example - ironically).

这篇关于for循环中的Nightwatch execute命令运行不正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆