Tengo una aplicación web para probar con Selenium. Hay mucho JavaScript ejecutándose al cargar la página.
Este código JavaScript no está tan bien escrito, pero no puedo cambiar nada. Entonces, esperar a que aparezca un elemento en el DOM con el findElement()
método no es una opción.
Quiero crear una función genérica en Java para esperar a que se cargue una página, una posible solución sería:
- ejecute un script de JavaScript desde WebDriver y almacene el resultado de
document.body.innerHTML
en una variable de cadenabody
. - compare la
body
variable con la versión anterior debody
. si son iguales, configure el incremento de un contador; de lonotChangedCount
contrario, establezca el valornotChangedCount
cero. - espere un poco (50 ms por ejemplo).
- Si la página no ha cambiado durante algún tiempo (500 ms por ejemplo)
notChangedCount >= 10
, salga del bucle; de lo contrario, continúe con el primer paso.
¿Crees que es una solución válida?
findElement
espera a que un elemento esté disponible, pero a veces el elemento está disponible antes de que el código javascript se inicialice por completo, por eso no es una opción.Respuestas:
Si alguien realmente supiera una respuesta general y siempre aplicable, se habría implementado en todas partes hace siglos y nos haría la vida mucho más fácil.
Hay muchas cosas que puede hacer, pero cada una de ellas tiene un problema:
Como dijo Ashwin Prabhu, si conoces bien el guión, se puede observar su comportamiento y realizar un seguimiento de algunas de sus variables en
window
odocument
etc. Esta solución, sin embargo, no es para todos y puede ser utilizado sólo por usted y sólo en un número limitado de páginas.Su solución al observar el código HTML y si se ha cambiado o no durante algún tiempo no está mal (también, hay un método para obtener el HTML original y no editado directamente por
WebDriver
), pero:setTimeout()
) y funcionan una y otra vez y posiblemente podrían cambiar el HTML cada vez que se ejecutan. En serio, todas las páginas de la "Web 2.0" lo hacen. Incluso Stack Overflow. Puede sobrescribir los métodos más comunes utilizados y considerar los scripts que los usan como completados, pero ... no puede estar seguro.innerHTML
divertirse.Hay herramientas para ayudarte en esto. Es decir, Progress Listeners junto con nsIWebProgressListener y algunos otros. El soporte del navegador para esto, sin embargo, es horrible. Firefox comenzó a intentar admitirlo desde FF4 en adelante (aún en evolución), IE tiene soporte básico en IE9.
Y creo que pronto se me ocurrirá otra solución defectuosa. El hecho es que no hay una respuesta definitiva sobre cuándo decir "ahora la página está completa" debido a que los eternos guiones están haciendo su trabajo. Elija el que mejor le sirva, pero tenga cuidado con sus defectos.
fuente
¡Gracias Ashwin!
En mi caso, debería esperar a que se ejecute un complemento jquery en algún elemento ... específicamente "qtip"
según tu sugerencia, funcionó perfectamente para mí:
Nota: estoy usando Webdriver 2
fuente
Debe esperar a que Javascript y jQuery terminen de cargarse. Ejecute Javascript para verificar si
jQuery.active
es0
ydocument.readyState
escomplete
, lo que significa que la carga de JS y jQuery está completa.fuente
document.readyState == 'complete' && jQuery.active == 0
funciona muy bien, pero ¿hay algo así para React? ¿Dado que esas comprobaciones no detectan la carga de datos / componentes de reacción?¿La biblioteca JS define / inicializa alguna variable conocida en la ventana?
Si es así, puede esperar a que aparezca la variable. Puedes usar
((JavascriptExecutor)driver).executeScript(String script, Object... args)
para probar esta condición (algo así como
window.SomeClass && window.SomeClass.variable != null
:) y devolver un booleanotrue
/false
.Envuelva esto en a
WebDriverWait
, y espere hasta que regrese el scripttrue
.fuente
Tuve el mismo problema. Esta solución me funciona desde WebDriverDoku:
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
fuente
Si todo lo que necesita hacer es esperar a que el html en la página se estabilice antes de intentar interactuar con los elementos, puede sondear el DOM periódicamente y comparar los resultados, si los DOM son los mismos dentro del tiempo de encuesta dado, está dorado. Algo como esto en el que pasa el tiempo de espera máximo y el tiempo entre encuestas de página antes de comparar. Simple y eficaz.
fuente
El siguiente código funciona perfectamente en mi caso: mi página contiene scripts complejos de Java
Fuente: cómo esperar a que la página se cargue / esté lista en Selenium WebDriver
fuente
Se pueden usar dos condiciones para verificar si la página está cargada antes de encontrar cualquier elemento en la página:
El uso de readyState a continuación esperará hasta que se cargue la página
A continuación, JQuery esperará hasta que no se hayan cargado los datos
Después de estos JavaScriptCode, intente findOut webElement.
fuente
Les pedí a mis desarrolladores que crearan una variable de JavaScript "isProcessing" a la que pueda acceder (en el objeto "ae") que configuran cuando las cosas comienzan a funcionar y se aclaran cuando las cosas están hechas. Luego lo ejecuto en un acumulador que lo verifica cada 100 ms hasta que obtiene cinco en una fila para un total de 500 ms sin ningún cambio. Si pasan 30 segundos, lanzo una excepción porque algo debería haber sucedido para entonces. Esto está en C #.
fuente
Para hacerlo correctamente, debe manejar las excepciones.
Así es como hago una espera para un iFrame. Esto requiere que su clase de prueba JUnit pase la instancia de RemoteWebDriver al objeto de página:
NOTA: Puede ver mi ejemplo de trabajo completo aquí .
fuente
Para la
nodejs
biblioteca de Selenium, utilicé el siguiente fragmento. En mi caso, estaba buscando dos objetos que se agregan a la ventana, que en este ejemplo son<SOME PROPERTY>
,10000
es el tiempo de espera en milisegundos,<NEXT STEP HERE>
es lo que sucede después de que se encuentran las propiedades en la ventana.fuente
Puedes escribir algo de lógica para manejar esto. Escribí un método que devolverá el
WebElement
y este método se llamará tres veces o puede aumentar el tiempo y agregar una verificación nula paraWebElement
Aquí hay un ejemplofuente
Aquí está mi propio código:
Window.setTimeout se ejecuta solo cuando el navegador está inactivo.
Entonces, llamar a la función de manera recursiva (42 veces) tomará 100 ms si no hay actividad en el navegador y mucho más si el navegador está ocupado haciendo otra cosa.
Como beneficio adicional, el contador se puede restablecer en document.readyState o en llamadas jQuery Ajax o si se están ejecutando animaciones jQuery (solo si su aplicación usa jQuery para llamadas ajax ...)
...
...
EDITAR: Noto que executeAsyncScript no funciona bien si se carga una nueva página y la prueba puede dejar de responder indefinidamente, es mejor usar esto en su lugar.
fuente
No sé cómo hacer eso, pero en mi caso, la carga y el renderizado del final de la página coinciden con FAVICON que se muestra en la pestaña de Firefox.
Entonces, si podemos obtener la imagen del favicon en el navegador web, la página web está completamente cargada.
Pero, ¿cómo realizar esto ...
fuente
El uso de la espera implícita funciona para mí.
Consulte esta respuesta Selenium c # Webdriver: Espere hasta que el elemento esté presente
fuente
Así es como lo hago:
fuente
Me gusta tu idea de sondear el HTML hasta que sea estable. Puedo agregar eso a mi propia solución. El siguiente enfoque está en C # y requiere jQuery.
Soy el desarrollador de un proyecto de prueba de SuccessFactors (SaaS) donde no tenemos ninguna influencia sobre los desarrolladores o las características del DOM detrás de la página web. El producto SaaS puede cambiar potencialmente su diseño DOM subyacente 4 veces al año, por lo que la búsqueda está permanentemente activa de formas sólidas y eficaces de realizar pruebas con Selenium (¡incluyendo NO realizar pruebas con Selenium cuando sea posible!)
Esto es lo que uso para "página lista". Actualmente funciona en todas mis propias pruebas. El mismo enfoque también funcionó para una gran aplicación web interna de Java hace un par de años, y había sido sólido durante más de un año cuando dejé el proyecto.
Driver
es la instancia de WebDriver que se comunica con el navegadorDefaultPageLoadTimeout
es un valor de tiempo de espera en ticks (100ns por tick)A continuación, observe el orden de las esperas en el método
PageReady
(documento de Selenium listo, Ajax, animaciones), lo que tiene sentido si lo piensa:Algo como su enfoque de comparación DOM podría usarse entre 1 y 2 para agregar otra capa de robustez.
fuente