node - Lectura de variables JavaScript usando Selenium WebDriver
selenium webdriver github nodejs (4)
Estoy usando Selenium WebDriver (Java) y TestNG para hacer algunas pruebas en un sitio web que creé. En este sitio web, también tengo JavaScript y en algunas de las funciones, devuelve valores y también genera valores en la consola del navegador a través de console.log()
.
Me preguntaba si hay una manera fácil para que Selenium WebDriver acceda a parte de esta información de JavaScript para que pueda realizar afirmaciones usando TestNG.
Soy bastante nuevo en Selenium, pero entiendo que puedes hacer algo como:
WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
Entonces, ¿hay algo similar que pueda hacer con WebDriver
para leer el JavaScript en el sitio?
Aclaración
Parece que la gente está asumiendo que estoy tratando de "ejecutar" el código JavaScript a través de Selenium.
Ese no es el caso. En cambio, estoy intentando almacenar variables de JavaScript ya definidas usando Selenium.
Básicamente, quiero que Selenium pueda tomar el valor de la variable de JavaScript, almacenarlo localmente y luego hacer una prueba de aserción en él.
Intento 1
Supongamos que tengo el siguiente código JS para mi sitio web:
$(document).ready(function() {
var foo = $(#"input-field-val").val();
function returnFoo() {
return foo;
}
});
Por lo que he leído y entendido, en mi archivo de prueba de Selenio (Selenium.java), ¿podría hacer algo como esto ?:
public class Selenium {
WebDriver driver = new FirefoxDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
@Test
public void testSample() {
driver.get("www.mywebsite.com");
js.executeScript("alert(returnFoo());");
}
}
Hago algo similar a lo que está arriba, pero no aparece ningún cuadro de alerta. En cambio, recibo un mensaje de error:
Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined
Estoy bastante seguro de que no entiendo lo que significa cuando dijo que la variable JS
no debe ser parte de un cierre o variable local
También he intentado definir una variable global por encima de $(document).ready(function()...
y la configuración está dentro de la function returnFoo()
pero aún no funciona.
Intento 2
He movido tanto foo
como returnFoo()
fuera de $(document).ready(function()...
Eso ha solucionado el mensaje ReferenceError
que obtenía en el intento 1 anterior.
También le he dado un valor a foo
así que mi código JS se ve así:
var foo = "Selenium test run";
$(document).ready(function() {
...
});
function returnFoo() {
return foo;
}
Ahora, estoy teniendo dificultades para asignar el retorno de returnFoo()
a una variable local dentro de mi prueba de Selenium. Esto es lo que intenté:
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
driver.get("http://localhost:8080/HTML5TestApp/prod.html");
Object val = js.executeScript("window.returnFoo();");
System.out.println(val);
}
Pero la consola muestra null
lugar del valor real de "Selenium test run" .
Intento 2 - SOLUCIÓN
Parece que sí lo hago Object val = js.executeScript("alert(returnFoo());");
Obtengo el valor de foo
.
SOLUCIÓN
Así que aquí está la solución que he encontrado con mi problema gracias a la solución de Martin Foot a continuación.
En mi archivo JavaScript, creé una var
y una función setter / getter así:
index.js
var seleniumGlobal;
$(document).ready(function() {
...
)};
function setSG(toSet) {
seleniumGlobal = toSet;
}
function getSG() {
return seleniumGlobal;
}
SampleTest.java
// Do all the necessary imports
public class SampleTest {
WebDriver driver = new FirefoxDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
@Test
public void testPrintVal() {
String sgVal = (String) js.executeScript("alert(getSG());");
Assert.assertEquals("new value for seleniumGlobal", sgVal);
}
}
Así que cada vez que algún código en mi JavaScript establece mi variable seleniumGlobal
través del método setter, puedo llamarlo a través de mi prueba Selenium y hacer aserciones en él.
Probablemente esta no sea la forma más eficiente de hacerlo, pero si alguien más tiene una mejor solución, hágamelo saber.
Prueba esto:
page.evaluate_script("script code")
page.execute_script("script code")
page.find("#id").click
Todo lo que tienes que hacer es:
Object val = js.executeScript("return returnFoo();");
Eso te dará lo que estás buscando.
No es necesario definir funciones de JavaScript. Tampoco se necesita alert()
.
Object result = js.executeScript("return globalVar");
Para Python:
result = driver.execute_script("return globalVar")