with javascriptexecutor how executescript ejecutar con javascript testing selenium webdriver qa

javascriptexecutor - selenium execute javascript python



WebDriver executeAsyncScript vs executeScript (5)

¿Cuál es la diferencia entre executeAsyncScript y executeScript? ¿Cómo puedo usar eventos como window.onload? Intenté algo como esto

((JavascriptExecutor) driver).executeAsyncScript("window.onload = function() {alert(''Hello'')}");

Pero, por supuesto, no funcionó ... Entonces, si alguien sabe cómo funciona, escriba un ejemplo


(Mantenlo simple y correcto )

La diferencia relevante entre execteScript y executeAsyncScript es la siguiente:

La función invocada con executeAsyncScript toma una ''devolución de llamada hecha'' como el último argumento, que debe invocarse para indicar que el script se ha ejecutado.

Esto permite que se use con un código que solo ''finaliza'' cuando se utiliza una devolución de llamada, por ej. setTimeout o XHR asincrónico. Si no se llama a la ''devolución de llamada hecha'' dentro de los límites de tiempo de espera, se rechazará la promesa devuelta.

A diferencia de la ejecución de JavaScript sincrónico con #executeScript, las secuencias de comandos ejecutadas con [#executeAsyncScript] deben indicar explícitamente que terminan invocando la devolución de llamada proporcionada . Esta devolución de llamada siempre se inyectará en la función ejecutada como último argumento.

Es decir, ambas funciones bloquean el flujo de control de WebDriver hasta que finalizan, ya sea ejecutando el final del código para executeScript o llamando a la ''devolución de llamada hecha'' con executeAsyncScript : "async" en el nombre significa el mecanismo de señal utilizado y no significa / implica que el código JavaScript se ejecuta de manera asíncrona con respecto a WebDriver.


La principal diferencia entre ellos es que los scripts ejecutados con async deben indicar explícitamente que terminan invocando la devolución de llamada proporcionada. Esta devolución de llamada siempre se inyecta en la función ejecutada como último argumento.


Usé mucho tiempo para entender esta función y finalmente lo conseguí. El código de Follwing ayudará mucho:

/** * executeAsyncScript document mentioned callback is a browser intrinsic function for returning deferred value (e.g 123 in example) from * js environment to Java environment * */ @Test public void testAsyncScript() { webDriver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS); Integer a = 23; TestUtil.elapse("first", () -> { Object value = getJsExecutor().executeAsyncScript("window.setTimeout(arguments[arguments.length - 1](123), 500);", a); // following code should be executed after 500ms timeout System.out.println("a is " + a); // a has nothing to do with the documented "callback" assertEquals(123, value); }); }


Yo uso executeScript . Ejemplo proporcionado:

String cssSelector="...blablabla..."; JavascriptExecutor js = (JavascriptExecutor) driver; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("document.getElementById(/'"+cssSelector +"/').click();"); js.executeScript(stringBuilder.toString());

En cuanto a los detalles sobre las alertas, existe un problema conocido. puedes obtener detalles here

De acuerdo con la diferencia de documentación es:

executeScript

public java.lang.Object executeScript(java.lang.String script, java.lang.Object... args)

Descripción copiada de la interfaz: JavascriptExecutor Ejecuta JavaScript en el contexto del marco o ventana seleccionado actualmente. El fragmento de script proporcionado se ejecutará como el cuerpo de una función anónima. Dentro de la secuencia de comandos, use el documento para hacer referencia al documento actual. Tenga en cuenta que las variables locales no estarán disponibles una vez que el script haya terminado de ejecutarse, aunque las variables globales persistirán. Si la secuencia de comandos tiene un valor de retorno (es decir, si la secuencia de comandos contiene una declaración de devolución), se tomarán los siguientes pasos:

  • Para un elemento HTML, este método devuelve un WebElement
  • Para un decimal, se devuelve un doble
  • Para un número no decimal, se devuelve un Long
  • Para un booleano, se devuelve un booleano
  • Para todos los demás casos, se devuelve una cadena.
  • Para una matriz, devuelva una lista con cada objeto siguiendo las reglas anteriores. Apoyamos listas anidadas.
  • A menos que el valor sea nulo o no haya un valor de retorno, en el que se devuelve nulo

Los argumentos deben ser un número, un booleano, un String, WebElement o una Lista de cualquier combinación de los anteriores. Se lanzará una excepción si los argumentos no cumplen estos criterios. Los argumentos estarán disponibles para JavaScript a través de la variable mágica "arguments", como si la función se llamara a través de "Function.apply"

Especificado por: executeScript en la interfaz JavascriptExecutor Parámetros: script - El JavaScript para ejecutar args - Los argumentos para el script. Puede estar vacío Devuelve: uno de Boolean, Long, String, List o WebElement. O nulo.

executeAsyncScript

public java.lang.Object executeAsyncScript(java.lang.String script, java.lang.Object... args)

Descripción copiada de la interfaz: JavascriptExecutor Ejecuta un fragmento de JavaScript asincrónico en el contexto del marco o ventana seleccionado actualmente. A diferencia de la ejecución de JavaScript sincrónico, las secuencias de comandos ejecutadas con este método deben indicar explícitamente que terminaron al invocar la devolución de llamada proporcionada. Esta devolución de llamada siempre se inyecta en la función ejecutada como último argumento. El primer argumento pasado a la función de devolución de llamada se usará como resultado del script. Este valor se manejará de la misma manera que el caso sincrónico.

Ejemplo # 1: realizar una suspensión en el navegador bajo prueba.

long start = System.currentTimeMillis(); ((JavascriptExecutor) driver).executeAsyncScript( "window.setTimeout(arguments[arguments.length - 1], 500);"); System.out.println( "Elapsed time: " + (System.currentTimeMillis() - start));

Ejemplo # 2: Sincronización de una prueba con una aplicación AJAX:

WebElement composeButton = driver.findElement(By.id("compose-button")); composeButton.click(); ((JavascriptExecutor) driver).executeAsyncScript( "var callback = arguments[arguments.length - 1];" + "mailClient.getComposeWindowWidget().onload(callback);"); driver.switchTo().frame("composeWidget"); driver.findElement(By.id("to")).sendKeys("[email protected]");

Ejemplo n. ° 3: Inyectar XMLHttpRequest y esperar el resultado:

Object response = ((JavascriptExecutor) driver).executeAsyncScript( "var callback = arguments[arguments.length - 1];" + "var xhr = new XMLHttpRequest();" + "xhr.open(''GET'', ''/resource/data.json'', true);" + "xhr.onreadystatechange = function() {" + " if (xhr.readyState == 4) {" + " callback(xhr.responseText);" + " }" + "}" + "xhr.send();"); JSONObject json = new JSONObject((String) response); assertEquals("cheese", json.getString("food"));

Los argumentos del script deben ser un número, un booleano, un String, WebElement o una lista de cualquier combinación de los anteriores. Se lanzará una excepción si los argumentos no cumplen estos criterios. Los argumentos estarán disponibles para JavaScript a través de la variable "arguments".

Especificado por: executeAsyncScript en la interfaz JavascriptExecutor Parámetros: script: el JavaScript que se ejecutará. args - Los argumentos para el script. Puede estar vacío. Devoluciones: una de Boolean, Long, String, List, WebElement o null.

La documentación detallada está here


((JavascriptExecutor) driver).executeScript("alert(''Hello'');");

mostrará la alerta:

El controlador ((JavascriptExecutor)) .executeAsyncScript () se usa cuando el JS toma tiempo para ejecutar una llamada al Servicio Web.

window.onload se asegura de que JS se ejecute cuando la página se carga por completo.