Playwright: Primeros pasos y ejemplos de uso
26 de abril de 2023
¿Qué vamos a ver?
En este artículo vamos a descubrir este genial framework basado en javascript con el que se pueden generar y ejecutar pruebas e2e de una forma fácil y rápida.
Hoy conoceremos Playwright desde 0:
- Veremos como se instala.
- Comentaremos las configuraciones básicas.
- Aprenderemos a utilizar algunas de sus funcionalidades para nuestras pruebas con ejemplos útiles.
¿Por qué es interesante
Para qué sirve
Playwright es una herramienta preparada para realizar pruebas end-to-end en webs, dispositivos móviles y de API, entre otras cosas.
Funcionalidades principales
- Setup inicial sencillo, rápido y directo.
- Es compatible con todos los motores de renderizado modernos, incluidos Chromium, WebKit y Firefox.
- Multiplataforma: Permite realizar pruebas en Windows, Linux y macOS, localmente o en CI, sin interfaz o con interfaz.
- Se puede utilizar en diferentes lenguajes de programación: TypeScript, JavaScript, Python, .NET, Java.
- Emulación móvil nativa de Google Chrome para Android y Mobile Safari. El mismo motor de renderizado funciona en su escritorio y en la nube.
- Incluye una espera automática por los elementos antes de interactuar con ellos, eliminando las esperas habituales necesarias en otros entornos.
- Política o gestión de reintentos configurables.
- Permite la generación de vídeos y capturas de pantalla durante la ejecución.
- Permite la generación de múltiples informes diferentes.
- Permite autologin en la web para ahorrar tiempo en logins repetitivos
- Pruebas simples, concisas y fáciles de mantener.
- Debugging sencillo (o algo parecido).
- Incluye una innovadora declaración de localizadores, similar a la utilizada en testinglibrary.
- Visual testing integrado (básico).
- Permite el uso de diferentes estrategias para la definición de pruebas, cómo Page Object Model o cucumber.
- Documentación y ejemplos completos.
- Y, por supuesto, incluye la posibilidad de ejecutar pruebas en paralelo y multinavegador, con lo que, en la ejecución de muchas pruebas, el tiempo se reduce considerablemente y nos permite garantizar que funcionaran en los diferentes navegadores.
¿Dónde lo puedes aplicar?
Casos de uso habituales
Gracias a su versatilidad, Playwright es una gran opción para generar pruebas rápidamente sobre webs, servicios de API y dispositivos móviles, lo que permite mezclar los diferentes tipos de tests/comprobaciones/validaciones en el mismo lugar.
En situaciones donde los planes de pruebas incluyen un número elevado de tests y el tiempo de ejecución es muy elevado, con playwright y su múltiple paralelización lo ejecuta en muchísimo menos tiempo (y, obviamente, el tiempo es dinero).
Dónde no es recomendable
Cuando deseamos validar la configuración del DOM, sus propiedades, atributos, etc. La estrategia de Playwright respecto a los selectores es la de esperar a que el elemento sea visible, activo y esté habilitado, por lo que para estos casos se requieren conocimientos de programación para buscar alternativas.
¿Cómo funciona?
Entorno utilizado, prerrequisitos
Prerrequisitos:
- Node.js version 14 or above
IDE recomendado:
Extensiones recomendadas:
- Playwright Test for VSCode
- Playwright Runner
Todos los ejemplos que vamos a ver, y mucho más, están disponibles en este repositorio.
Setup inicial
Abrimos una carpeta donde guardaremos nuestro proyecto de pruebas o donde hayamos clonado un proyecto vacío de git
Ya que estamos empezando, queda bien decir que confiamos en los autores para fomentar el buen rollo 🙂
Abrimos un terminal nuevo para iniciar el proyecto de node (yo lo tengo configurado para utilizar el terminal de git bash)
Escribimos el comando “npm init playwright@latest”
Durante la instalación, tendremos que definir algunas configuraciones:
- Usaremos JavaScript como lenguaje.
- Seleccionamos la carpeta donde se guardarán los archivos de test (lo dejamos por defecto).
- Indicamos si queremos añadir alguna acción de GitHub (lo dejamos por defecto).
- Nos preguntará si queremos instalar los navegadores de playwright y decimos que si (true).
Automáticamente, playwright creará los siguientes ficheros:
- playwright.config.js => Fichero de configuración.
- tests/ => Carpeta donde se guardaran los ficheros con las pruebas
- example.spec.js => Fichero de pruebas, se debe mantener la nomenclatura {nombre}.spec.js para que Playwright lo pueda identificar correctamente.
- tests-examples/ => Otra carpeta con ejemplos, que borraremos por limpieza
- demo-todo-app.spec.js => Otro fichero de pruebas que se borrará al borrar la carpeta que lo contiene.
Cuando termine la instalación, ya lo tendremos todo preparado.
Automáticamente, se crearán dos carpetas con ejemplos de tests (nos quedamos con la de tests y borramos la otra)
Gracias a las extensiones que habremos instalado previamente, nos aparece sobreimpresionado la opción de ejecutar cada test con diferentes opciones.
Como podemos observar, la nomenclatura para cada fichero de pruebas, debe ser nombreFichero.spec.js para que Playwright lo pueda identificar.
Configuración para las ejecuciones
El instalador nos ha creado un fichero de configuración llamado playwright.config.js donde podemos ver algunas opciones interesantes. Veremos solamente algunas de ellas, pero aquí puedes encontrar información sobre todas ellas.
- testDir: Directorio donde se guardarán los ficheros de pruebas.
-
timeout: Tiempo de ejecución máxima de una prueba (en milisegundos).
- Se puede alterar para algunas pruebas añadiendo test.setTimeout(tiempo en ms) en las pruebas que deseemos.
- expect.timeout: tiempo de espera para ejecutar cada comando.
- fullyParallel: con valor “true” se paraleliza cada prueba en una sesión diferente.
- reporter: generador de informes, por defecto en “html” hará que después de cada ejecución se abra una pestaña local con el informe.
- Aconsejo cambiarlo a “reporter: [['list'],['html', {open: 'never',host: '0.0.0.0',port: 9223,}]]”
- De esta forma, nos mostrará por consola el listado de pruebas y su resultado y el informe en html pero no se abrirá en el navegador
- trace: Parámetro opcional para el seguimiento de la prueba y ver el lugar en el que falla. Podemos revisar aquí cuál nos conviene.
- baseURL: Url base a la que podemos acceder directamente.
- video: Parámetro opcional para guardar un video con la ejecución. Podemos revisar **aquí **el que nos conviene.
- screenshot: Parámetro opcional para generar screenshots de la ejecución. Podemos revisar aquí el que nos conviene.
- headless: Modo de ejecución del navegador. Recomiendo setearlo a “false” para poder ver el navegador durante la ejecución. Más info aquí.
- projects.use.viewport: definimos el tamaño del navegador para cada uno de ellos. (Aquí podemos comprobar el tamaño de nuestra pantalla, tanto el total como el que se ve)
Formato de un fichero de pruebas
// ejemplo.spec.js
Conociendo Playwright
Localizadores
Selectores
Los elementos se pueden localizar siguiendo diferentes estrategias, como por ejemplo:
- await page.locator(‘elemento’)
- await page.locator(‘css=valor’)
- await page.locator(‘xpath=valor’)
- await page.getByText(‘texto’) o await page.getByText(‘texto’, { exact: true}) para evitar conflictos
- await page.getByRole(‘link’, { name: ‘valor’ })
- await page.locator(‘elemento’).first() para el primer elemento que coincida
Más info aquí.
Propiedades
Podemos extraer datos de los elementos tales como su texto, atributos, propiedades,...
- await page.locator('elemento').textContent() => nos sirve para obtener el texto del localizador
- await page.locator('elemento').innerText() => nos sirve para obtener el texto del localizador
- await page.locator('elemento').innerHTML() => nos sirve para recuperar el propio valor del localizador en el DOM.
- await page.locator('elemento').getAttribute(‘atributo’) => recuperamos el valor de un atributo
- await page.locator('elemento').count() => podemos contar el número de elementos que coinciden con la selección.
Más información de todas las propiedades, aquí.
Acciones
Además de conocer sus propiedades, podemos interactuar con los elementos, veamos algunos ejemplos:
- .click() => pulsa sobre el elemento
- .fill(‘texto’) => rellena un campo con el texto indicado
- .click({ button: 'right' }) => pulsa sobre un elemento con el botón derecho del ratón
- .dblclick() => realiza un doble click
Puedes ver el resto de acciones aquí.
**Teclado
En algunos casos puede resultar útil enviar combinaciones de teclas sin necesidad de hacerlo sobre un elemento, Playwright también está preparado para hacerlo, podemos ver todas las opciones aquí.
Aserciones
Como os habréis imaginado, también disponemos de diferentes aserciones tanto para realizar comprobaciones sobre variables como para localizadores, como por ejemplo:
- expect(‘Hello World’).toContain('World')
- expect(20).toBeLessThanOrEqual(42)
- await expect(locator).toBeVisible()
- await expect(locator).toContainText('substring')
Podemos ver todas las aserciones en la documentación sobre variables y sobre localizadores.
Ejecución
Las diferentes opciones de ejecución podemos encontrarlas aquí.
Las más habituales son:
- npx playwright test => Para ejecutar todos los tests
- npx playwright test firstTest.spec.ts => Para ejecutar un solo fichero
- npx playwright test -g "descripción del test" => Para ejecutar los tests por título
Ejemplo básico
Veamos un test simple en el que queremos validar el título de la página
Debug
También se puede ejecutar el test en modo debug añadiendo “--debug”. Por ejemplo, al ejecutar:
npx playwright test firstTest.spec.js -g "Page\s+title\s+should\s+be\s+correct$" –debug
Aparece una ventana con diferentes utilidades e información:
Tiempo de ejecución e informes de resultado
Al finalizar la ejecución nos aparece el resultado de la misma, indicando también el navegador utilizado, el tiempo utilizado y el resultado global:
En este caso aparece el mensaje “3 tests using 1 worker” porque al ser en modo debug, lo ejecuta consecutivamente, por lo que el tiempo de ejecución es de más o menos 60 segundos.
Sin embargo,
En este caso se ha paralelizado y ejecutado al mismo tiempo, por lo que todos los tests se han ejecutado en poco más de 20 segundos, que, cuando el número de tests ejecutados aumenta, el rendimiento mejora considerablemente.
Al terminar la ejecución, se genera automáticamente un informe de resultados en la carpeta:
Además, tenemos el mensaje indicándonos cómo visualizar el último informe generado.
Al acceder a dicha url, se abrirá una pestaña nueva con toda la información de los tests ejecutados por navegador
Ejemplos útiles
Test simple
Veamos por ejemplo un test muy habitual, en el que entramos en una web y realizamos un login, validando que aparece el mensaje de bienvenida.
user.spec.js
Page Object Model (POM)
Realizaremos el mismo test, pero utilizando este patrón para ver la implementación equivalente. Para ello, vamos a crear las diferentes clases de las páginas que intervienen en el flujo de la prueba, de manera que después podamos utilizarlas en nuestro test. Por centrarnos en la prueba anterior, sólo se indicarán los métodos necesarios para realizar la misma comprobación anterior, en el repositorio podemos ver las clases completas. Más información, aquí.
pages/HomePage.js
Creamos la clase de la página inicial que se carga al ir a la web, guardando solamente el elemento correspondiente al botón de login
pages/LoginPage.js
Creamos la clase de la página de login, con los elementos correspondientes al usuario, contraseña, botón de login y un par de botones que aparecerán tras el login para la verificación.
userPom.spec.js
Por último, creamos nuestro test utilizando las clases creadas. En este caso, añadimos también un ejemplo de algo tan habitual como recuperar y utilizar valores de un archivo externo de configuración. En este caso, hacemos uso de la librería ‘fs’ (FileSystem) propia de javascript para leer un fichero json donde tenemos almacenadas las credenciales y los datos de los usuarios.
Qué nos ha parecido
Ventajas
Una de las principales ventajas de esta herramienta es su versatilidad, está preparada para muchos tipos de pruebas diferentes y sobre todo las más habituales, aportando mejoras (en nuestra opinión) a otras alternativas similares como por ejemplo Cypress.
Se aleja de los típicos selectores e incorpora opciones más “familiares” para el usuario.
El sistema de paralelizar las pruebas y hacerlo además en diferentes navegadores nos ahorra mucho tiempo y optimiza las ejecuciones.
Incorpora diferentes tipos de informes por defecto, lo que nos facilita mucho la tarea (suele ser algo que hay que implementar aparte).
Su documentación es muy extensa y con ejemplos de uso, lo que facilita la comprensión e implementación.
Se puede utilizar con diferentes lenguajes de programación, aunque parece que los más habituales son javascript y python.
Inconvenientes
En caso de requerir validaciones o configuraciones más complejas, el lenguaje puede ser un gran hándicap, ya que javascript (que es el lenguaje principal) tiene muchas particularidades que pueden darnos más de un quebradero de cabeza.
Por lo poco que hemos visto, la integración de cucumber no es “limpia”, hacen falta librerías externas y parece más bien un parche que una utilidad más. De hecho, en su documentación oficial no hay rastro de la inclusión de cucumber como una utilidad más. En mi opinión, poder reutilizar los steps entre pruebas sería muy útil para agilizar aún más la creación de pruebas.
Conclusiones
Playwright es una herramienta muy a tener en cuenta desde el punto de vista de un QE, no sólo por su curva de aprendizaje tan corta o por su documentación tan currada, sino por la cobertura de pruebas que se pueden realizar (cubriendo las necesidades de casi cualquier cliente) pudiendo incluso convivir dentro de un mismo repositorio diferentes tipos (web, API,etc).
En este artículo hemos visto bastantes utilidades de la herramienta, pero aún quedan muchas otras opciones como el uso de fixtures, gestión de cookies,etc y parece que está en constante desarrollo de mejoras.
Bibliografía: https://playwright.dev/docs/intro