Contrariamente a lo que sugiere la respuesta actualmente aceptada , no hay nada específico para PhantomJS cuando se trata de la diferencia entre hacer que WebDriver haga un clic y hacerlo en JavaScript.
La diferencia
La diferencia esencial entre los dos métodos es común a todos los navegadores y puede explicarse de manera bastante simple:
WebDriver: cuando WebDriver hace el clic, intenta lo mejor que puede simular lo que sucede cuando un usuario real usa el navegador. Suponga que tiene un elemento A que es un botón que dice "Haga clic en mí" y un elemento B que es un div
elemento que es transparente pero tiene sus dimensiones y está zIndex
configurado para que cubra completamente A. Luego le dice a WebDriver que haga clic en A. WebDriver simule el clic para que B reciba el clic primero . ¿Por qué? Debido a que B cubre a A, y si un usuario intentara hacer clic en A, entonces B obtendría el evento primero. El hecho de que A finalmente obtenga el evento de clic depende de cómo B maneje el evento. En cualquier caso, el comportamiento con WebDriver en este caso es el mismo que cuando un usuario real intenta hacer clic en A.
JavaScript: ahora, supongamos que usa JavaScript para hacerlo A.click()
. Este método de hacer clic no reproduce lo que realmente sucede cuando el usuario intenta hacer clic en A. JavaScript envía el click
evento directamente a A, y B no obtendrá ningún evento.
¿Por qué funciona un clic de JavaScript cuando no funciona un clic de WebDriver?
Como mencioné anteriormente, WebDriver intentará simular lo mejor que pueda lo que sucede cuando un usuario real está usando un navegador. El hecho es que el DOM puede contener elementos con los que un usuario no puede interactuar, y WebDriver no le permitirá hacer clic en estos elementos. Además del caso superpuesto que mencioné, esto también implica que no se puede hacer clic en elementos invisibles. Un caso común que veo en las preguntas de desbordamiento de pila es alguien que está tratando de interactuar con un elemento de la GUI que ya existe en el DOM pero que se vuelve visible solo cuando se ha manipulado algún otro elemento. Esto sucede a veces con los menús desplegables: primero debe hacer clic en el botón que abre el menú desplegable antes de que se pueda seleccionar un elemento del menú. Si alguien intenta hacer clic en el elemento del menú antes de que el menú sea visible,Si la persona intenta hacerlo con JavaScript, funcionará porque el evento se entrega directamente al elemento, independientemente de la visibilidad.
¿Cuándo debe usar JavaScript para hacer clic?
Si está utilizando Selenium para probar una aplicación , mi respuesta a esta pregunta es "casi nunca". En general, su prueba de Selenium debería reproducir lo que un usuario haría con el navegador. Tomando el ejemplo del menú desplegable: una prueba debe hacer clic en el botón que abre primero el menú desplegable y luego hacer clic en el elemento del menú. Si hay un problema con la GUI porque el botón es invisible, o el botón no muestra los elementos del menú, o algo similar, entonces su prueba fallará y habrá detectado el error. Si usa JavaScript para hacer clic, no podrá detectar estos errores a través de pruebas automatizadas.
Digo "casi nunca" porque puede haber excepciones en las que tiene sentido usar JavaScript. Sin embargo, deberían ser muy raros.
Si está utilizando Selenium para eliminar sitios , entonces no es tan importante intentar reproducir el comportamiento del usuario. Por lo tanto, usar JavaScript para omitir la GUI es un problema menor.
click
osendKeys
funcionaron, pero no siempre. No hubo problema de localización u otra excepción, el caso de prueba simplemente no progresó más. El registro mostró que la acción se ejecutó. A veces usandoAction
ayudado. Si hice clic en el elemento manualmente (después de que el caso de prueba se detuvo), todo funcionó bien. Entonces cambiamos a JS sin procesar en esas ocasiones. No he trabajado con AngularJS en los últimos 2 años, por lo que las cosas podrían mejorar ahora.El clic ejecutado por el controlador intenta simular el comportamiento de un usuario real lo más cerca posible mientras el JavaScript
HTMLElement.click()
realiza la acción predeterminada para elclick
evento, incluso si el elemento no es interactivo.Las diferencias son:
El controlador se asegura de que el elemento sea visible desplazándolo hacia la vista y verifica que el elemento sea interactivo .
El controlador generará un error:
disabled
estrue
)pointer-events
esnone
)Un JavaScript
HTMLElement.click()
siempre realizará la acción predeterminada o, en el mejor de los casos, fallará silenciosamente si el elemento está deshabilitado.Se espera que el controlador ponga el elemento en foco si es enfocable.
Un JavaScript
HTMLElement.click()
no lo hará.Se espera que el controlador emita todos los eventos (mousemove, mousedown, mouseup, click, ...) como un usuario real.
Un JavaScript
HTMLElement.click()
emite solo elclick
evento. La página puede confiar en estos eventos adicionales y puede comportarse de manera diferente si no se emiten.Estos son los eventos emitidos por el controlador para un clic con Chrome:
Y este es el evento emitido con una inyección de JavaScript:
El evento emitido por un JavaScript
.click()
no es confiable y la acción predeterminada no se puede invocar:https://developer.mozilla.org/en/docs/Web/API/Event/isTrusted
https://googlechrome.github.io/samples/event-istrusted/index.html
Tenga en cuenta que algunos de los controladores siguen generando eventos no confiables. Este es el caso de PhantomJS a partir de la versión 2.1.
El evento emitido por un JavaScript
.click()
no tiene las coordenadas del clic .Las propiedades
clientX, clientY, screenX, screenY, layerX, layerY
están establecidas en0
. La página puede confiar en ellos y comportarse de manera diferente.Puede estar bien usar un JavaScript
.click()
para eliminar algunos datos, pero no está en un contexto de prueba. Derrota el propósito de la prueba ya que no simula el comportamiento de un usuario. Por lo tanto, si falla el clic del controlador, lo más probable es que un usuario real tampoco realice el mismo clic en las mismas condiciones.El elemento objetivo aún no es visible / interactible debido a un retraso o un efecto de transición.
Algunos ejemplos :
https://developer.mozilla.org/fr/docs/Web (menú desplegable de navegación) http://materializecss.com/side-nav.html (barra lateral desplegable)
Lugares de trabajo:
Agregue un camarero para esperar la visibilidad, un tamaño mínimo o una posición estable:
Vuelva a intentar hacer clic hasta que tenga éxito:
Agregue un retraso que coincida con la duración de la animación / transición:
El elemento objetivo termina cubierto por un elemento flotante una vez que se desplaza hacia la vista:
El controlador desplaza automáticamente el elemento hacia la vista para que sea visible. Si la página contiene un elemento flotante / adhesivo (menú, anuncios, pie de página, notificación, política de cookies ...), el elemento puede terminar cubierto y dejará de ser visible / interactivo.
Ejemplo: https://twitter.com/?lang=en
Soluciones alternativas:
Establezca el tamaño de la ventana en una más grande para evitar el desplazamiento o el elemento flotante.
Mueva sobre el elemento con un
Y
desplazamiento negativo y luego haga clic en él:Desplace el elemento hacia el centro de la ventana antes del clic:
Ocultar el elemento flotante si no se puede evitar:
fuente
NOTA: llamemos 'clic' es clic del usuario final. 'js click' es clic a través de JS
Hay 2 casos para que esto suceda:
I. Si está usando PhamtomJS
Entonces este es el comportamiento conocido más común de
PhantomJS
. Algunos elementos a veces no se pueden hacer clic, por ejemplo<div>
. Esto se debe a quePhantomJS
fue creado originalmente para simular el motor de los navegadores (como HTML + CSS inicial -> computación CSS -> renderizado). Pero no significa interactuar con el usuario final (ver, hacer clic, arrastrar). PorPhamtomJS
lo tanto, solo es parcialmente compatible con la interacción de los usuarios finales.¿POR QUÉ JS HACE CLIC EN EL TRABAJO? En cuanto a cualquiera de los clics, todos son clics medios. Es como una pistola con 1 cañón y 2 disparadores . Uno de la ventana gráfica, uno de JS. Dado que es
PhamtomJS
excelente para simular el motor del navegador, un clic JS debería funcionar perfectamente.II El controlador de eventos de "clic" debe vincularse en el mal período de tiempo.
Por ejemplo, tenemos un
<div>
-> Hacemos algunos cálculos
-> luego vinculamos el evento de clic al
<div>
.-> Además con alguna codificación incorrecta de angular (por ejemplo, no manejando el ciclo de alcance adecuadamente)
Podemos terminar con el mismo resultado. Hacer clic no funcionará porque WebdriverJS intenta hacer clic en el elemento cuando no tiene un controlador de eventos de clic.
¿POR QUÉ JS HACE CLIC EN EL TRABAJO? Js click es como inyectar js directamente en el navegador. Posible de 2 maneras,
El puño es a través de la consola de devtools (sí, WebdriverJS se comunica con la consola de devtools).
El segundo es inyectar una
<script>
etiqueta directamente en HTML.Para cada navegador, el comportamiento será diferente. Pero independientemente, estos métodos son más complicados que hacer clic en el botón. Click está usando lo que ya está allí (clic de los usuarios finales), js click pasa por la puerta trasera.
Y para js click parecerá ser una tarea asincrónica. Esto está relacionado con un tema un poco complejo de ' tarea asincrónica del navegador y programación de tareas de la CPU ' (léelo hace un tiempo no puedo encontrar el artículo nuevamente). Para abreviar, esto resultará principalmente ya que js click tendrá que esperar un ciclo de programación de tareas de la CPU y se ejecutará un poco más lento después del enlace del evento click. (Podría conocer este caso cuando encontró que el elemento a veces se puede hacer clic, a veces no).
=> Como se mencionó anteriormente, ambos significan para un propósito, pero sobre el uso de qué entrada:
=> Para el rendimiento, es difícil de decir porque se basa en los navegadores. Pero en general:
=> Desventajas:
PD: si estás buscando una solución.
browser.wait()
( verifique esto para obtener más información )(Quiero hacerlo breve, pero terminó mal. Cualquier cosa relacionada con la teoría es complicada de explicar ...)
fuente