Playwright: Novedades y otras utilidades

Playwright: Novedades y otras utilidades

Sergio Alcaraz, Expert Quality Engineer / Technical referent,

Sergio Alcaraz

Expert Quality Engineer / Technical referent,

7 de julio de 2023

¿Qué vamos a ver?

Este artículo sirve como continuación de Playwright: primeros pasos y ejemplos de uso y, vamos a ver funcionalidades de esta herramienta de testing end-to-end, tales como:

  • Nuevo wizard (incluido en la versión 1.32).

  • Cómo generar pruebas con el recorder (plugin).

  • Cómo realizar descargas o subir archivos de forma sencilla.

  • Visual testing.

  • Pruebas de API.

  • Integración con Cucumber.

Ejemplos útiles

Nuevo wizard

Desde la versión 1.32 (y sólo para la opción de Playwright con Node.js) se incluye esta utilidad que nos recuerda mucho al que incluye por defecto Cypress. Para utilizarlo debemos añadir --ui al comando de ejecución de las pruebas, por ejemplo:

npx playwright test userPOM.spec.js --ui

Se abrirá una ventana donde podemos encontrar diferentes utilidades

PlaywrightNovedadesyotrasutilidades.png

Filtro

 Se incluye la opción de filtrar por resultado de la ejecución o navegador utilizado. También se puede filtrar por los proyectos configurados en el fichero playwright.config.js.

Opciones de ejecución

  1. Barra de herramientas rápidas, donde encontramos varias opciones:
  2. Ejecutar todos los tests.
  3. Parar la ejecución.
  4. Vigilancia activa: Marcando esta opción, el wizard se mantiene «alerta» a los cambios en el código y, cuando esto ocurra, re-ejecutará el test.
  5. Colapsar el árbol de tests (disponible en la versión 1.33).

Listado de test disponibles

Desplegable con las pruebas disponibles (en este caso lo ejecutamos a nivel de spec, por lo que muestra los tests disponibles en el fichero). Para cada uno de los tests, tenemos también un submenú con opciones:

  1. Ejecutar el test.
  2. Solicita permiso y abre el código de la prueba (sólo si se utiliza VSCode).
  3. Si se deshabilita la opción de vigilancia en la barra de herramientas rápida, aparece esa opción para cada uno de los tests.

Traza de la ejecución en el tiempo

Vista de la ejecución a lo largo del tiempo. Desplazándonos por esa zona, podemos ver una imagen de la acción en ese momento.

Trazas de la prueba

Solamente aparecen las trazas de los tests que se ejecutan. Se pueden seguir cada una de las acciones realizadas durante la ejecución.

Pestañas de estado

Pulsando sobre cualquier acción del test, tenemos una barra de herramientas con diferentes opciones:

  1. Recuperar localizadores.
  2. Estado actual cuando se realiza la acción.
  3. Estado anterior a realizar la acción.
  4. Estado posterior a realizar la acción.

Inspeccionar el DOM

Pulsando en este botón, se nos abrirá en el navegador una imagen del DOM en ese momento, donde también podemos inspeccionar el documento, los elementos, la consola, etc.

Imágen del navegador en el momento actual

Barra de información

Diferentes pestañas útiles para revisar durante la ejecución

  • Source: Código completo del test seleccionado.
  • Console: Logs de la consola para cada acción.
  • Network: Logs de la red en cada acción.
  • Logs: Trazas de cada acción

Aquí podemos ver un ejemplo de resultado después de ejecutar todos los tests disponibles.

PlaywrightNovedadesyotrasutilidades-3.png

Generar pruebas fácilmente

Gracias al siguiente plugin podemos generar un testing end-to-end directamente «grabando» las acciones manuales que realicemos (aunque también nos ofrece otras opciones interesantes).

PlaywrightNovedadesyotrasutilidades-4.png

Para utilizarlo simplemente entramos en la pestaña de pruebas de la barra lateral y pulsamos en la opción Record new.

PlaywrightNovedadesyotrasutilidades-5-2.jpg

Esto nos abrirá un navegador con el que interactuaremos y una spec donde se irá generando el código con nuestras acciones.

PlaywrightNovedadesyotrasutilidades-6.png

Realizar descargas y adjuntar ficheros

Veamos también un par de utilidades que, aunque sean menos habituales, también son importantes en algunos casos, hablamos de realizar descargas y de seleccionar fichero para adjuntar

Realizar descargas

// Se prepara para esperar una descarga
const downloadPromise = page.waitForEvent('download');
// Pulsamos el botón de descarga
await page.getByText('Download file').click();
const download = await downloadPromise;
// Se espera que la descarga termine
console.log(await download.path());
// Se guarda la descarga en la ruta que queramos
await download.saveAs('/path/to/save/download/at.txt');

Adjuntar ficheros

// Se prepara para seleccionar un fichero
const fileChooserPromise = page.waitForEvent('filechooser');
// Pulsamos el botón de cargar el fichero
await page.getByText('Upload file').click();
const fileChooser = await fileChooserPromise;
// En lugar del explorador de archivos para buscar el fichero, directamente se seleccionará el indicado
await fileChooser.setFiles('myfile.pdf');
Visual testing

Siguiendo la documentación oficial, podemos validar que la página contenga imágenes generadas previamente.

import { test, expect } from "@playwright/test";

test.beforeEach(async ({ page }) => {
  await page.goto('/');
});
test('Check image appears in page', async ({ page }) => {
  await expect(page).toHaveScreenshot('home.png');
});

La primera vez que ejecutamos el test, fallará porque no existe la imagen con la que comparar. Playwright nos muestra el error y automáticamente nos genera una imagen actual.

PlaywrightNovedadesyotrasutilidades-10.png

Si re-ejecutamos de nuevo el test, esta vez irá todo bien.

PlaywrightNovedadesyotrasutilidades-11.png

PlaywrightNovedadesyotrasutilidades-12.png

Como te podrás imaginar, dentro de el testing end-to-end, Playwright no solo se limita a comparar la página completa, también podemos hacer la comparación de objetos de manera similar de esta forma. Al igual que en el caso anterior, si la imagen no existe, Playwright la genera automáticamente.

import { test, expect } from "@playwright/test";

test.beforeEach(async ({ page }) => {
  await page.goto('/');
});

test('Compare image by locator', async ({ page }) => {
  expect(await page.getByRole('link', { name: 'women\'s perfume' }).screenshot()).toMatchSnapshot('women.png');
});
Pruebas de API

Veremos un ejemplo simple de una llamada API haciendo uso de la herramienta y siguiendo la documentación oficial.

import { test, expect } from "@playwright/test";

test('Requests basic', async ({ request }) => {
  const people = await request.get(`https://swapi.dev/api/people/1`, {
    headers: {
      'Content-Type': 'application/json;',
    },
  });
  expect(people.ok()).toBeTruthy();
  const response = await people.json();
  console.log('response: ' + JSON.stringify(response, null, 2))
  expect(people.status()).toBe(200)
  expect(response.name).toMatch(/Luke Skywalker/);
});
Cucumber

Por si no era suficiente todo lo anterior, también podemos utilizar Cucumber.

Requisitos previos

Para ello, primero debemos instalar un par de paquetes:

  • npm i @cucumber/cucumber

  • npm i playwright

Feature

Creamos el fichero features/login.feature.

features/login.feature
Feature: Login in perfumes website

  @login
  Scenario: Check correct login
    Given I go to Perfumes WebStore
    When I do login
    Then I check correct welcome message appears

World (Hooks)

La palabra World describe los pasos donde podemos declarar e invocar objetos y variables que se podrán utilizar globalmente. Es el equivalente a lo que conocemos como Hooks en Java o C#.

// features/support/world.js
const { setWorldConstructor } = require("@cucumber/cucumber");
const playwright = require('playwright');

class CustomWorld {
    async openUrl(url) {
        const browser = await playwright.chromium.launch({
            headless: false,
        });
        const context = await browser.newContext();
        this.page = await context.newPage();
        await this.page.goto(url);
    }
}
setWorldConstructor(CustomWorld);

Steps

Implementamos el código de cada uno de los pasos.

// features/support/steps.js
const { Given, When, Then } = require("@cucumber/cucumber");
const { expect } = require('@playwright/test');

Given("I go to Perfumes WebStore", { timeout: 60 * 1000 }, async function () {
    await this.openUrl('http://localhost:3000');
});

When("I do login", async function () {
    await this.page.getByRole('link', { name: 'SIGN IN' }).click();
    await this.page.locator('input[name="email"]').fill('test123@test.com');
    await this.page.locator('input[name="password"]').fill("admin");
    await this.page.getByRole('button', { name: 'Sign in' }).click();
});

Then("I check correct welcome message appears", async function () {
    await expect(this.page.getByRole('link', { name: 'EXIT' })).toBeVisible();
    await expect(this.page.getByRole('link', { name: 'MY ACCOUNT' })).toBeVisible();
    expect((await this.page.content()).includes('Hello John Doe!'));
});

Ejecución

Utilizamos el comando siguiente para filtrar por etiqueta

  • npx cucumber-js --tags @login --exit

PlaywrightNovedadesyotrasutilidades-13.png

Qué nos ha parecido

Ventajas

Nos encontramos ante una herramienta en auge y en continua mejora que amplía sus funcionalidades (incluyendo su completa documentación).

Como ya comentamos en el artículo anterior, es una herramienta con una amplia versatilidad que busca simplificar las implementaciones y facilitar la generación de pruebas.

Inconvenientes

Se observa una descompensación entre los diferentes lenguajes. Por citar algunos casos, las aserciones sobre variables, el wizard de ejecución, visual testing, ..., solamente están disponibles para Node.js y no existen para el resto de lenguajes. Ese desajuste es algo que deberían solucionar, ya que puede ser una limitación a la hora de migrar desde otra herramienta.

Conclusiones

Playwright está haciendo un gran trabajo para convertirse en una herramienta de referencia para diferentes tipos de testing end-to-end. Es muy positivo descubrir que está en constante crecimiento y mejora, aunque deberían balancear el esfuerzo para equiparar todos los lenguajes en lugar de limitarse a sólo uno de ellos.

Bibliografía:

https://playwright.dev/docs/intro

Sergio Alcaraz, Expert Quality Engineer / Technical referent,

Sergio Alcaraz

Expert Quality Engineer / Technical referent,

Llevo 9 años automatizando pruebas, especializándome sobre todo en Cucumber para pruebas web, de API y en dispositivos móviles, aunque me encanta investigar y aprender cosas nuevas.