De una forma u otra, todos enfrentaban situaciones en las que algo inusual suced铆a en un ambiente banal. Un caso similar nos sucedi贸 al probar una nueva aplicaci贸n en un entorno cien veces probado. Una sorpresa para nosotros fue el uso de algunas caracter铆sticas HTML5 en el front-end, o m谩s bien, la incapacidad de automatizar las operaciones de prueba de arrastrar y soltar usando las herramientas est谩ndar de Selenium WebDriver. Queremos hablar sobre esta experiencia.

Imagine un proyecto que es tecnol贸gicamente muy similar al anterior (en nuestra opini贸n, tuvo un peque帽o efecto negativo en t茅rminos de comprender y analizar correctamente el problema que apareci贸), pero la versi贸n de Angular entre proyectos cambi贸 de 1.xa 5.x y se agreg贸 la biblioteca Selenide para pruebas autom谩ticas de UI. .
La aplicaci贸n web desarrollada ten铆a una p谩gina con un cierto conjunto de entidades que pod铆an moverse entre ellas. Imagine nuestra sorpresa cuando un intento de realizar una autocomprobaci贸n de verificar las funciones de arrastrar y soltar utilizando las herramientas de Selenide no tuvo 茅xito. Parece que lo que podr铆a haber salido mal? En el proyecto anterior, en un entorno de prueba similar, todo funcion贸 perfectamente.
Primero, verificamos la funci贸n de arrastrar y soltar de las funciones Selenide y Selenium en el navegador actual usando un ejemplo de otra aplicaci贸n web. Todo funciona Versiones actualizadas, nunca se sabe ...
Decidimos comprobar si arrastramos y all铆. Y hacer la elecci贸n incorrecta de elementos cuando se usa Angular es bastante f谩cil. Nos sentamos con un desarrollador front-end y descubrimos que los elementos de arrastrar y soltar se seleccionaron correctamente.
En general, el entorno de prueba funciona, los m茅todos de prueba est谩n escritos correctamente, arrastrar y soltar "a mano" funciona, pero la prueba autom谩tica no funciona. Y no hay razones para esto a primera vista.
Finalmente, soportamos el hecho del problema y buscamos una soluci贸n en Internet. Cu谩l fue nuestra sorpresa cuando encontramos el problema abierto
Chrome WebDriver # 3604 del 03/04/2016 . Solo piense, desde la primavera de 2016, oficialmente hay un problema con la funci贸n de arrastrar y soltar rota en Chrome WebDriver, sin mencionar otros navegadores. No, ciertamente funciona, pero no cuando se usa HTML5. Y como result贸 en el proceso de an谩lisis del problema, nuestra aplicaci贸n utiliz贸 la implementaci贸n de arrastrar y soltar usando HTML5.
驴Cu谩les son las implementaciones de arrastrar y soltar para probar en HTML5? En Internet, se encontraron dos soluciones:
- Utilice la biblioteca de Java awt.Robot (o alg煤n clicker de terceros);
- Utiliza javascript.
Probablemente ganamos un poco de dinero o nos enterramos en el problema, pero de inmediato har茅 una reserva de que la primera soluci贸n elegida no nos conven铆a :)Lo que se puede decir sobre la implementaci贸n en Robot:
- Interceptamos el mouse, emulando las acciones completas del usuario;
- Usamos selenio para determinar las coordenadas de los elementos;
- Como se utilizan elementos Selenium, no necesita cambiar los localizadores. Estamos intentando en el proyecto usar xpath;
- Est谩 escrito en Java, la sintaxis es intuitiva, buena documentaci贸n.
Pero algo sobre la implementaci贸n de JavaScript vino a la mente:
- Todo sucede en JavaScript dentro del navegador (las acciones est谩n ocultas a los ojos del probador y estas acciones interfieren con el c贸digo);
- De las bibliotecas js para probar arrastrar y soltar en Internet, se encontr贸 una, cuya fuente no era tan f谩cil de encontrar;
- La biblioteca encontrada tendr谩 que estar terminada con un archivo que se ajuste a sus necesidades, ya que implementa solo arrastrar y soltar limpio. Y nosotros, por ejemplo, necesit谩bamos arrastrar -> mover -> mantener -> soltar;
- La biblioteca se implementa como un complemento de jQuery y, por lo tanto, ser谩 necesario comprender la estructura de jQuery;
- Tendremos que convertir los localizadores a css (jquery no funciona con xpath);
- Es imposible utilizar la b煤squeda de elementos de selenio, tendr谩 que pegar los localizadores con "bol铆grafos".
A primera vista, la primera soluci贸n fue mucho m谩s conveniente y fue probada.
En general, la soluci贸n est谩 funcionando ... Sin embargo, en el proceso de su desarrollo, sus 谩reas problem谩ticas quedaron claras.
- El movimiento del mouse o la minimizaci贸n del navegador durante la ejecuci贸n de las pruebas conduce a la interferencia en el curso de las pruebas y su ca铆da;
- No se pueden ejecutar pruebas en paralelo con JUnit / TestNG. A menos que sea paralelo a trav茅s de tareas separadas en CI.
- No se puede controlar el mouse en la m谩quina remota a trav茅s de Selenium Grid / Selenoid;
- En el caso de un bloqueo del navegador, Robot puede hacer clic / arrastrar f谩cilmente algo en el escritorio o en otra aplicaci贸n abierta.
Al final, sin embargo, la implementaci贸n de JavaScript ...Me gustar铆a decir de inmediato que logramos resolver el problema del uso de localizadores xpath utilizando el complemento jquery.xpath.js jQuery.
Y la biblioteca drag_and_drop_helper.js (fuente
aqu铆 ) se convirti贸 en la herramienta principal para js controlar las operaciones de arrastrar y soltar. No tiene sentido ordenar su trabajo, sino sobre c贸mo trabajamos un poco m谩s tarde.
Ahora directamente sobre la implementaci贸n en las pruebas. En Selenide, todo es simple. Antes de usar arrastrar y soltar, debe cargar las bibliotecas JS usadas:
StringBuilder sb = new StringBuilder(); sb.append(readFile("jquery-3.3.1.min.js")); sb.append(readFile("jquery.xpath.min.js")); sb.append(readFile("drag_and_drop_helper.js")); executeJavaScript(sb.toString());
Naturalmente, jQuery debe cargarse si a煤n no est谩 en la aplicaci贸n.
En la versi贸n original de la biblioteca, es suficiente escribir lo siguiente:
executeJavaScript("$('" + source + "') .simulateDragDrop({ dropTarget: '" + target + "'});");
source y target son localizadores css de elementos de arrastrar y soltar.
Como se indic贸 anteriormente, a menudo usamos xpath-locators en el proyecto, por lo que despu茅s de un peque帽o refinamiento, la biblioteca comenz贸 a aceptarlos:
executeJavaScript("$(document).xpath('" + source + "').simulateDragDrop({ dropTarget: '" + target + "'});");
Ahora, en realidad, sobre la biblioteca drag_and_drop_helper.js. Hay piezas en el bloque de c贸digo simulateEvent que son responsables de ciertos eventos del mouse. No tiene sentido enumerar los posibles eventos de operaciones de arrastrar y soltar en HTML5; esta informaci贸n es f谩cil de encontrar.
Para las pruebas, necesit谩bamos implementar una funci贸n que mueva el elemento y mantenga el mouse sobre el elemento de destino. Y esto, como en la biblioteca de origen, no se proporciona.
Por analog铆a, agregamos el evento dragenter a la biblioteca (entre dragstart y drop).
type = 'dragenter'; var dragenterEvent = this.createEvent(type, {}); dragenterEvent.dataTransfer = event.dataTransfer; this.dispatchEvent($(options.dropTarget)[0], type, dragenterEvent);
Sin embargo, esto no es suficiente. Despu茅s de todo, el evento de retenci贸n se completar谩 instant谩neamente. Poner una pausa fija entre los eventos dragEnter y soltar no parec铆a la opci贸n m谩s conveniente. Despu茅s de todo, inicialmente no se sabe cu谩nto tiempo necesita la aplicaci贸n para procesar un evento, se desconoce el n煤mero y el tiempo de las comprobaciones en las pruebas. El retraso entre estos eventos debe ser al menos manejable. En cambio, decidimos dividir las pruebas de arrastrar y soltar en etapas y no emular el conjunto completo de eventos del mouse, es decir, agregar la capacidad de administrar la lista de eventos involucrados a trav茅s del par谩metro.
Y todo parece estar bien, no aparecieron nuevos defectos, y algunos de los antiguos ya no lo son, y lo m谩s importante, las tareas asignadas se est谩n llevando a cabo. Parece que todo es perfecto. Sin embargo, las herramientas de desarrollo modernas establecen el procesamiento de dos eventos y utilizan varios par谩metros del elemento movido. Supongamos que tenemos esta soluci贸n al ejecutar arrastrar y soltar que causa errores dragStartListener. Pero como no rompe nada, nosotros no comenzamos a cambiar nada m谩s. Sin embargo, en alguna otra aplicaci贸n, probablemente tendr谩 que terminar este momento.
Queremos resumir lo anterior. Sorprendentemente, un hecho! HTML5 se lanz贸 en 2013, los navegadores lo han soportado durante varios a帽os, se han desarrollado aplicaciones para 茅l, pero webDriver, por desgracia, todav铆a no sabe c贸mo usar sus capacidades. Y las operaciones de prueba de arrastrar y soltar deben implementarse con herramientas de terceros, complicar la arquitectura y recurrir a todo tipo de trucos. S铆, existen tales herramientas y "bailar con una pandereta" solo nos hace m谩s fuertes, pero a煤n quiero tener una soluci贸n que funcione de inmediato.
En nuestra experiencia, podemos decir que tales problemas no son tan comunes hoy en d铆a, aunque arrastrar y soltar se usa en todas partes. Probablemente el asunto sea la elecci贸n de las tecnolog铆as de desarrollo de aplicaciones web. Sin embargo, el porcentaje de aplicaciones que usan HTML5 est谩 creciendo constantemente, los frameworks se est谩n desarrollando y ser铆a genial si los desarrolladores de navegadores y controladores para ellos tampoco se quedaran atr谩s.
PD Y finalmente, una peque帽a letra. Me gustar铆a aconsejar a todos, si es posible, que no tengan en cuenta la banalidad de la situaci贸n o la proximidad del entorno de prueba a alg煤n tipo de patr贸n al analizar los problemas. Esto puede llevar a conclusiones incorrectas o p茅rdida de tiempo.