El blog de software y ciberseguridad de Redsauce

Drag and drop entre pestañas con Playwright

Artículo de Alejandro Rey

Drag and drop entre pestañas con Playwright

Hace unos días me he tenido que enfrentar a un caso de uso en el que se requiere una funcionalidad relativamente sencilla: hacer drag desde un elemento que se encuentra en una pestaña a un drop en un lugar de otra pestaña. Es la primera vez, en mis cinco años de experiencia como QA, que he tenido que atacar un caso de uso así.


Personalmente no creo que sea la mejor experiencia de usuario, pero la aplicación ya está desarrollada ¡y tenemos que solucionar el problema!

El desafío

Automatizar pruebas E2E ya es una tarea compleja por sí sola, pero cuando se trata de interactuar entre pestañas del navegador mediante Drag and Drop, el reto se amplifica. Los principales frameworks de automatización como Playwright, Cypress y WebdriverIO no permiten hacer esto de manera nativa. Es por ello, que para enfrentar este tipo de interacción, tuvimos que buscar soluciones “alternativas”.

Comprendiendo el funcionamiento con DevTools

Para abordar el problema, en primer lugar recurrimos a las DevTools del navegador para tener todo el detalle posible de qué está pasando. Utilizamos Event Listener Breakpoints para interceptar y manejar los eventos clave del Drag and Drop: dragstart, dragover, drop, entre otros.

Durante este proceso, descubrimos que al dispararse el evento dragstart, el programa añadía al event.DataTransfer una serie de ítems cuya información estaba contenida en el propio elemento que soporta el drag, en forma de atributos personalizados. Además, esta información se guardaba en el localStorage, una técnica muy utilizada antes para mantener el estado de los elementos arrastrados entre sesiones.

Implementando la solución con JavaScript inyectado

No podíamos realizar el Drag and Drop entre pestañas directamente con las herramientas de automatización. Decidimos entonces realizar un Drag and Drop dentro de la misma pestaña que contiene el elemento a arrastrar, garantizando así la ejecución real de esa parte del código por la aplicación web.


Para ello, copiamos el elemento con todos sus hijos y, mediante JavaScript, lo añadimos a la pestaña que tiene el elemento que soporta el drop. En esta pestaña, añadimos un Event Listener al elemento recién creado para que, al hacer el arrastre del elemento, lea del localStorage la información creada con anterioridad y se la añada al event.DataTransfer, tal como lo hace la aplicación durante su uso real.

Con todo esto ya configurado, realizamos un Drag and Drop utilizando los métodos nativos del framework de automatización, que en este caso es Playwright.


Tuvimos que implementar un doble locator.hover() para asegurar que el evento dragover se disparara correctamente en todos los navegadores, siguiendo la secuencia: hover sobre el elemento de arrastre, mouse down, hover sobre el elemento de soltado dos veces, y luego mouse up, tal como indica la documentación oficial en su versión 1.46.


Compartimos una versión generalizada de nuestra solución:

export async function customDragAndDrop(page: Page, page2: Page) { 
const dragHtml = await page.waitForSelector("[draggable="true"]", { timeout: 5000 }).then(async element => await element.evaluate(node => node.outerHTML)) .catch(() => { throw new Error("No draggable element found on the page."); });
await page.locator("span[draggable="true"]").dragTo(page.getByText("Refresh").);


await page2.bringToFront();


await page2.evaluate((dragHtml) => {
const targetContainer = document.querySelector("#wrapper");
const newDiv = document.createElement("div");
newDiv.innerHTML = dragHtml;
targetContainer.appendChild(newDiv);
newDiv.addEventListener("dragstart", (event) => {
const local = localStorage.getItem("ngStorage-clipboard"); event.dataTransfer.setData("element-items", local);
});
}, dragHtml);

await page2.locator("span[draggable="true"]").hover();
await page2.mouse.down();
await page2.locator("#droppable").hover();
await page2.locator("#droppable").hover();
await page2.mouse.up();


await expect(page2.getByText("Action completed successfully.")).toBeVisible({timeout: 30000});

}

Importancia de dominar las web APIs

Este logro subraya la importancia de que el equipo de automatización comprenda y domine las Web APIs. No solo se trata de conocer las herramientas de automatización, sino también de entender cómo funcionan las aplicaciones web a un nivel más profundo. En este caso, aunque no pudimos interactuar exactamente como lo haría un usuario real debido a las limitaciones de las herramientas de automatización, ejecutamos el mínimo código JavaScript necesario para respetar al máximo la implementación y el comportamiento original de la aplicación.

Habilidades y colaboración en QA

Una vez que comprendimos claramente el comportamiento de la aplicación y disponíamos de una solución, comunicamos la propuesta al equipo de desarrolladores. La colaboración con ellos fue crucial en esta etapa, para asegurarnos de que nuestro enfoque fuera correcto y estaba alineado con la implementación original de la aplicación. nos permitió avanzar con confianza hacia la solución.


En Redsauce, entendemos que un buen QA debe saber desarrollar o, al menos, entender los conceptos detrás del desarrollo web. Esta comprensión es crucial para enfrentar problemas complejos y encontrar soluciones innovadoras. Además, la integración del perfil de QA como parte del equipo de desarrollo es fundamental facilitando la colaboración, el soporte y la comprensión de la aplicación. Y todo esto es vital cuando se enfrentan problemáticas complejas.

Conclusión

Automatizar un escenario de Drag and Drop entre pestañas del navegador no fue una tarea sencilla, pero a base de creatividad y conocimiento técnico pudimos lidiar con ella. Esto destaca la importancia de un enfoque integral en el desarrollo y la automatización de pruebas.


Esta experiencia nos hace creer (más si cabe) en la importancia de comprender profundamente las tecnologías web y trabajar estrechamente con los desarrolladores para superar desafíos.

Sobre nosotros

Has llegado al blog de Redsauce, un equipo de expertos en QA y desarrollo de software. Aquí hablaremos sobre testing ágil, automatización, programación, ciberseguridad… ¡Bienvenido!