2015-11-05 134 views
0

我對單元測試很新,但我一直在嘗試使用Nightwatch創建一個腳本,該腳本通過頁面的主體內容,單擊每個鏈接並報告返回它是否壞了。Night循環執行命令for循環內循環順序不正確

我試圖做一個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塊。循環結束後,browser.execute塊隨後以x輸入,其數字爲3。

爲什麼browser.execute命令會導致for循環亂序執行,並且可以執行任何操作來修復它是否按照預期的順序運行?

回答

2

這與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(其中有一個非常相似的例子 - 諷刺)。

+0

非常感謝。完美回答問題並澄清問題。只是想知道;在Nightwatch腳本中以句法方式格式化此解決方案的最佳方式是什麼?你會爲每個單獨的函數創建一個自定義命令嗎? – JoPinsy