javascript - tutorial - protractor para que sirve
¿Cómo interactúa la espera implícita de Protractor con la espera explícita? (3)
El malentendido ocurre cuando la espera implícita es menos que explícita:
var timeOut = 5000;
var search = element(by.xpath(`//*[@name=''qwer'']`));
browser.manage().timeouts().implicitlyWait(4000);
browser.ignoreSynchronization = true;
describe(''Protractor Test'', function () {
beforeEach(function () {
browser.get(''https://www.google.com.ua'');
});
it(''EC'', function () {
console.log(''START'');
// browser.sleep(timeOut);
browser.wait(protractor.ExpectedConditions.presenceOf(search), timeOut);
});
});
Tiempo general: 8.613 segundos. Establezca implícitamente Espere un segundo más abajo: 3000 y el resultado es 6.865 segundos. ¿Cómo funciona debajo del capó? ¡Muchas gracias de antemano!
Esa es una gran pregunta y estos tiempos de espera impredecibles cuando se usa una combinación de esperas implícitas y explícitas han sido advertidos y establecidos en la documentación de Selenium . browser.wait()
es una espera explícita y estás usando eso en combinación con un implicit wait - browser.manage().timeouts().implicitlyWait()
Esperar es hacer que la ejecución automática de tareas transcurra una cierta cantidad de tiempo antes de continuar con el siguiente paso. Debe elegir utilizar Esperas explícitas o Esperas implícitas.
ADVERTENCIA: No mezcle esperas implícitas y explícitas. Hacerlo puede causar tiempos de espera impredecibles. Por ejemplo, configurar una espera implícita de 10 segundos y una espera explícita de 15 segundos podría provocar un tiempo de espera después de 20 segundos.
Esa es una buena pregunta. Una gran cantidad de buenos chicos de automatización de QA se rompieron la cabeza con esto.
Espera implícita
Esta es una espera automática oculta especial en cada driver.findElement(...)
. El controlador web original (js, python, java) arroja NoSuchElementException si el elemento no se puede encontrar en la estructura DOM de la página. Este tipo de espera se realizará antes de CADA driver.findElement
, sin importar qué tipo de localizador use. Cuando se agota el tiempo de espera de espera implícita, NoSuchElementException se findElement
fuera de la función findElement
.
Habilitando la espera implícita
Por defecto, el tiempo de espera de espera implícito se establece en 0
. browser.manage().timeouts().implicitlyWait(3000)
hace que webdriver intente / capture esta excepción automáticamente, y vuelva a intentar encontrar este elemento. Si pasaron 3 segundos (tiempo de espera) y el elemento aún no está presente en DOM, solo obtendrá la NoSuchElementException.
Cuando es bueno:
Su página modifica la estructura DOM (99.999% del sitio web) y algunos elementos aún no están en el DOM, pero aparecen en 1-3 segundos. Para no hacer esperas explícitas y reducir la cantidad de código, puede intentar establecer el tiempo de espera de espera implícito.
Cuando es malo: desea probar que ese elemento no está presente en el DOM. Este tipo de espera se agrega antes de cada llamada .findElement
, por lo que cuando intentas afirmar de esta manera:
expect($(''NON-EXIST-ELEMENT'').isPresent()).toBeFalsy()
Su implicitWait
todavía trabajando aquí. Primero esperará 3 segundos para que el elemento esté presente, luego se lanzará la excepción y se capturará mediante la función isPresent (), que devolverá false en este caso (lo que realmente afirmamos). ¡Así que estás esperando 3 segundos extra! Tiene sentido establecer implicitWait(0)
y luego volver a establecerlo después de que el elemento asserting no esté presente (lo que puede ser realmente molesto).
Conclusión Las esperas implícitas son buenas, cuando comprendes cómo funciona. Recomiendo no establecer espera implícita más de 1-5 segundos (debe definir el valor propio para cada sitio web). Además, si planea afirmar la gran cantidad de elementos que no están presentes, restablezca la espera implícita en 0 y luego vuelva a establecerla.
Espera explícita
Este tipo de espera debe llamar usted mismo, pero es mucho más flexible que las esperas implícitas. En protractorjs, cuando necesite esperar algo, debe llamar a browser.wait()
. Acepta la función predicado (función que devolverá solo verdadero / falso, sin excepciones). Webdriver sondeará esta función hasta que se agote el tiempo de espera (usted lo especifica como segundo parámetro). También puede especificar el mensaje de error que desea arrojar como tercer parámetro.
Obviamente, en la automatización de web, usted espera algunas condiciones de elementos la mayor parte del tiempo. Para esto chicos han creado una colección de funciones predicativas. Esta función llama a ExpectedConditions, y devolverá verdadero / falso para el elemento que se les pasó.
browser.wait(ExpectedConditions.visibilityOf($(''NON-EXISTING-ELEMENT'')), 3000, ''error message'')
Cuando es bueno: cuando tienes que esperar algunas condiciones difíciles de tus elementos. Puede definir fácilmente las condiciones propias que desea esperar, especificar el tiempo de espera personalizado, etc. Úselo antes de manipular elementos que quizás aún no estén listos.
Cuando es malo: cuando intenta ayudarlo combinando browser.sleep()
, espera implícita y esperas explícitas juntas. browser.sleep()
es malo por defecto, en el 99% de los casos puedes reemplazarlo por browser.wait()
con las condiciones proporcionadas, o escribir tu propia condición.
Mucho más divertido sucede cuando tienes el conjunto de espera implícito, e intentas llamar a esperar explícitamente. Imagine: browser.manage().timeouts().implicitlyWait(10000)
browser.wait(EC.stalenessOf($(''NON-EXIST-ELEMENT'')), 5000) //waiting for 5 seconds for element to disappear
browser.manage().timeouts().implicitlyWait(10000)
browser.wait(EC.stalenessOf($(''NON-EXIST-ELEMENT'')), 5000) //waiting for 5 seconds for element to disappear
Qué sucede aquí: la función de espera llama a la función stalenessOf()
para su elemento. Dentro de él, se driver.findElement()
. La espera implícita no permite que esta función genere un error de forma inmediata y agrupa la página web durante 10 segundos hasta que se produce un tiempo de espera de espera implícito, y obtenemos la excepción NoSuchElementException. Se produce una excepción y la ejecución vuelve a la función de espera. Ya han pasado 10 segundos. La espera finaliza con TimeOutException, ya que se programó solo durante 5 segundos. Estamos obteniendo un error con un tiempo de espera mucho más largo de lo esperado.
También tenga en cuenta que JS es asíncrono y no puede garantizar el tiempo exacto de espera debido a Event Loop. Por lo general, esto hace que la espera no sea exacta: 5200 ms en lugar de 5000 (como ejemplo). Esta es una historia completamente diferente :)
Qué pasa en tu ejemplo
tiempo de espera implícito: 4000 milisegundos.
expiración explícita - 5000 milisegundos.
- Espere comenzó. Función de predicado de llamada de primera vez -
presenceOf()
- El predicado interno llama a la función webdriverjs original -
driver.findElement(By.xpath(''//*[@name=''qwer'']''))
- Como la espera implícita está establecida, la estamos esperando antes de lanzar el error.
- 4000 milisegundos de elementos implícitos en espera pasados. Solo ahora estamos devolviendo el error a la función de predicado.
- Predicado error de captura de función, y devuelve falso en su lugar
- Ya que todavía tenemos 1000 milisegundos antes del tiempo de espera de la función explícita de predicado de llamada de espera nuevamente.
- La espera implícita comenzó de nuevo. 4000 milisegundos después - devolviendo el error a la función de predicado
- El predicado devuelve falso
- La función de espera es falsa, y nuestra espera explícita está fuera de tiempo; en el caso ideal, sería de unos 8000 milisegundos, pero también debe tener en cuenta las llamadas asíncronas, de modo que el tiempo real sería más
- Error de espera de tiradas - jasminejs detecta error y falla la prueba
¡Espero que esto sea de ayuda!
La respuesta es: ambas esperas esperan en paralelo. Las encuestas de espera implícitas duran 4 segundos y devuelven el error después de lo cual la espera explícita ha esperado solo 4 segundos y le queda 1 más. Esto vuelve a emitir espera implícita nuevamente y sondea otros 4 segundos y vuelve a fallar. Después de 8 segundos (2 intentos de espera implícita), la espera explícita de 5 segundos también se agotó y finalmente tenemos nuestro error después de perder 3 segundos inesperados. Por ejemplo, en el caso de un conjunto implícito a 8 y un conjunto explícito a 17, esperaremos 8 * 3 = 24 segundos. Tenga en cuenta que la ejecución del script tarda algo de tiempo, por lo que si es lenta, la siguiente iteración podría no iniciarse.