I've recently started exploring unit testing and am currently working on a Nightwatch script that navigates through the body content of a webpage, clicks on each link, and checks if it's broken.
My goal is to create a for loop that goes through every tag in the body content, counts the number of 'a' tags within them, and then clicks on each link. However, I'm facing an issue where the browser.execute command inside the for loop seems to be executing out of order.
Below is my code snippet with some console.log statements added to track what's happening:
'Click Links' : function(browser) {
browser
//Count all non-link tags (p/div) in the content
.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 and check each contained a tag
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);
//Check for on-site broken links
browser.execute(function() {
return document.querySelector("meta[content='Error Document']");
},
//Notify about broken link
function(result){
if (result.value != null) {
browser.url(function(result) {
console.log("BROKEN LINK: " + result.value);
});
}
});
//Navigate 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()
}
The output shows a discrepancy in the execution sequence:
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
It appears that the for loop is processing ahead and skipping the entire browser.execute section. Once the loop completes, the browser.execute part runs with an incorrect value of x. This leads to the question of why the browser.execute command disrupts the order of execution and whether there's a fix to maintain the intended order.