nodejs node javascriptexecutor chrome javascript selenium testng selenium-webdriver

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.


En Ruby puede usar page.execute_script para evaluar una variable de JavaScript (si es accesible desde el alcance del navegador web). Parece que hay un método similar en Java here .

Editar: este podría ser un caso de uso más apropiado para un marco de prueba de unidades de JavaScript como Jasmine .


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")