Reputation: 557
I've already researched about this problem, but couldn't find a proper solution. Here's what I'm trying to do (I'm using nightwatch v0.9.8 and "selenium-server-standalone-3.0.0-beta3"):
var servico, dataCriado, a, selector;
module.exports = {
'test case': function(client) {
client
*** do login stuff ***
*** go to a page and then execute this: ***
.execute (function (){
// Get all <a/> tags inside 'listaEtapasServicos':
var estados = document.getElementsByClassName('listaEtapasServicos')[0].getElementsByTagName("a");
// Get all divs inside with the class 'grid-cons-medium' inside 'listaEtapasServicos'
var div = document.getElementsByClassName('listaEtapasServicos')[0].getElementsByClassName('grid-cons-medium');
// What I'm trying to do here is to look for an element containing the text "Suspender" inside a table, save the info inside this specific table line ('Serviço' and 'Data criado') and then click on "Suspender":
for (var i = 0; i < estados.length; i++){
if (estados[i].innerHTML == "Suspender") {
a = i+1;
servico = div[i].getElementsByTagName('span')[0].innerHTML;
dataCriado = div[i].getElementsByTagName('span')[1].innerHTML;
selector = "#div-container > div:nth-child(4) > div > div > div > div:nth-child(2) > div.div-group-info-medium > div > div > div.listaEtapasServicos.scroll-pane-pattern.scroll-pane-medium.ps-container.ps-active-y > div:nth-child("+ a +") > div.grid-padroes-geral.grid-col-100.text-left > a";
break;
}
}
}, [])
// Where the error happens:
.perform(function () {
client.click(selector);
})
*** Test failed ***
ERROR: Unable to locate element: "undefined" using: css selector
An image of the table:
The thing is that nightwatch is telling me that the variable 'selector' is undefined, even though if I write another executor before the click function with the command 'alert(selector)', the alert will return exactly the selector that I want. A problem like this was already assigned here: https://groups.google.com/forum/#!topic/nightwatchjs/AzRC-Sbgt4Q
But the given solution didn't work for me. Doing just '.click(selector)' also won't work. Could someone help me find a solution?
UPDATE:
Ok, just found a workaround here: Nightwatch.js cannot set a string variable to an input field?
Then the code will look like this:
for (var i = 0; i < estados.length; i++){
if (estados[i].innerHTML == "Suspender") {
a = i+1;
servico = div[i].getElementsByTagName('span')[0].innerHTML;
dataCriado = div[i].getElementsByTagName('span')[1].innerHTML;
selector = "#div-container > div:nth-child(4) > div > div > div > div:nth-child(2) > div.div-group-info-medium > div > div > div.listaEtapasServicos.scroll-pane-pattern.scroll-pane-medium.ps-container.ps-active-y > div:nth-child("+ a +") > div.grid-padroes-geral.grid-col-100.text-left > a";
client.click(selector);
break;
}
}
}, [])
Worked. But then my problem is that I still need those variables for later use, but nightwatch won't define them. How do I make nightwatch define my variables so that they won't stay undefined? Also, why does this alert shows the selector as it was defined inside the firts executor:
.execute [...] (first executor)
.execute(function (){ alert (selector) })
... but the click inside the '.perform()' function doesn't work?
Upvotes: 0
Views: 3716
Reputation: 557
Found the solution!
My problem was that I didn't know how the .execute()
function actually works. It's scope is limited to the document object, so if I want my variables to keep the values that I want them to have, I must do it through the callback
function.
Also, the client
object and it's steps are all instantiated before the .execute()
function executes, and at this time the selector
value would still be undefined. That's why the perform()
function is needed. The code stays like this:
.execute(function () {
var estados = document.getElementsByClassName('listaEtapasServicos')[0].getElementsByTagName("a");
var div = document.getElementsByClassName('listaEtapasServicos')[0].getElementsByClassName("grid-cons-medium");
for (var i = 0; i < estados.length; i++) {
if (estados[i].innerHTML == "Suspender") {
a = i + 1;
servico = div[i].getElementsByTagName('span')[0].innerHTML;
dataCriado = div[i].getElementsByTagName('span')[1].innerHTML;
selector = "div.grid-cons-medium:nth-child("+a+") > div:nth-child(4) > a:nth-child(1)";
return [a, servico, dataCriado, selector];
}
}
}, [], function (result) {
a = result.value[0];
servico = result.value[1];
dataCriado = result.value[2];
selector = result.value[3];
})
.perform(function(){
client.waitForElementPresent(selector, 10000);
client.click(selector);
})
Now everything is working fine.
Upvotes: 3