Descubre cómo integrar Playwright en Angular 17 para crear pruebas E2E efectivas con componentes de Angular Material como tablas, paginadores y buscadores.
En este artículo aprenderás cómo integrar Playwright para realizar pruebas end-to-end (E2E) en una aplicación Angular 17 que utiliza componentes de Angular Material como mat-table, mat-paginator y un campo de búsqueda. Veremos desde la instalación de Playwright hasta la escritura de pruebas que interactúan con el DOM real, verificando que la tabla se filtre correctamente, se pagina y muestre los datos esperados.
Playwright es una herramienta de automatización de pruebas creada por Microsoft. Permite controlar navegadores modernos (Chromium, Firefox, WebKit) y es ideal para realizar pruebas E2E. Se destaca por:
Soporte nativo para múltiples navegadores.
Esperas automáticas para elementos (espera a que estén listos).
Interacción realista con la UI (como un usuario).
Buen soporte para pruebas en CI/CD.
Vamos a utilizar un proyecto existente en angular 17 el cual es una aplicación basica de una pokedex, que tiene tres componentes basicos de angular material:
El repositorio lo encuentras en el siguiente enlace pinchando aquí.
para clonarlo ejecutamos en una consola el siguiente comando
git clone https://github.com/VManuelPM/PokeApp
una vez clonado lo abrimos y verificamos que tengamos la dependencia de playwright en el package.json, en dado caso que no se instala de la siguiente manera:
npm init playwright@latest
Esto generará:
Una carpeta playwright.config.ts
Una carpeta tests/ con un ejemplo básico (example.spec.ts)
Un archivo tests-examples que puedes borrar si no lo necesitas
en los scripts del package.json debemos configurar el script de e2e de la siguiente manera:
"scripts": {
"e2e": "npx playwright test",
"report": "npx playwright show-report"
}
Estos scripts simplifican comandos que usarías en consola, facilitando la ejecución de pruebas con Playwright.
Este script:
Ejecuta las pruebas E2E (end-to-end) usando Playwright.
Busca archivos de prueba (por defecto en tests/ o e2e/) que usen la sintaxis de Playwright.
Lanza los navegadores, abre tu aplicación, y realiza acciones automatizadas (como clics, navegación, validaciones, etc.).
🔧 Este comando se puede correr con:
npm run e2e
Este script:
Abre un reporte interactivo en el navegador con los resultados de las últimas pruebas.
Solo funciona después de haber ejecutado npm run e2e, ya que genera un reporte HTML por defecto.
✅ Útil para:
Ver qué pruebas pasaron o fallaron.
Ver capturas de pantalla o trazas si configuraste trace: ‘on’ o screenshot: ‘on’ en playwright.config.ts.
Lo ejecutas con:
npm run report
Creamos un archivo tests/home.spec.ts con el siguiente contenido:
import { test, expect } from '@playwright/test';
test('La página principal se carga correctamente', async ({ page }) => {
await page.goto('http://localhost:4200');
await expect(page).toHaveTitle(/PokeApp/i);
});
Esta prueba verifica que la página principal de la aplicación se carga y que el título contiene “PokeApp”.
import { test, expect } from '@playwright/test';
Importa el objeto test, que se usa para definir casos de prueba.
Importa expect, que se usa para hacer afirmaciones o validaciones.
test('La página principal se carga correctamente', async ({ page }) => {
Define un caso de prueba con una descripción en español.
La función async recibe un page, que es una instancia de navegador simulada que Playwright controla (como una pestaña en Chrome).
await page.goto('http://localhost:4200');
Define un caso de prueba con una descripción en español.
La función async recibe un page, que es una instancia de navegador simulada que Playwright controla (como una pestaña en Chrome).
await page.goto('http://localhost:4200');
Esta línea indica que el navegador debe navegar a la URL local donde corre tu app Angular (ng serve).
Equivale a que un usuario abre el navegador y escribe la dirección en la barra.
await expect(page).toHaveTitle(/PokeApp/i);
Aquí verificamos que el título de la pestaña (el que se ve en la barra del navegador) contiene el texto “PokeApp”.
El /PokeApp/i es una expresión regular:
✅ Si el título es correcto, la prueba pasa.
❌ Si el título no aparece o no contiene ese texto, la prueba falla.
Creamos un archivo tests/search.spec.ts con el siguiente contenido:
import {expect, test} from '@playwright/test';
test('Buscar un Pokémon por nombre', async ({ page}) => {
await page.goto('http://localhost:4200');
const searchInput = page.locator('input[placeholder="Buscar"]');
await searchInput.fill('pikachu');
await searchInput.press('Enter');
await expect(page.locator('td.cdk-column-name')).toContainText(/pikachu/i);
});
Esta prueba simula la acción de buscar “pikachu” y verifica que la tabla muestra el resultado correspondiente.
Creamos un archivo tests/pagination.spec.ts con el siguiente contenido:
test('Navegar a la siguiente página de resultados', async ({ page }) => {
await page.goto('http://localhost:4200');
const nextPageButton = page.locator('button[aria-label="Next page"]');
await nextPageButton.click();
// Esperar a que el paginador indique la segunda página (rango de 6-10)
await expect(page.locator('mat-paginator')).toContainText(/6\s*[-–]\s*10/, { timeout: 10000 });
});
Esta prueba hace clic en el botón de “Siguiente página” y verifica que el paginador muestra el rango de elementos actualizado.
Creamos un archivo tests/details.spec.ts con el siguiente contenido:
import { test, expect } from '@playwright/test';
test('Ver detalles de un Pokémon', async ({ page }) => {
await page.goto('http://localhost:4200');
const searchInput = page.locator('input[placeholder="Buscar"]');
await searchInput.fill('bulbasaur');
const detailsButton = page.locator('button', { hasText: 'Detalles' });
await detailsButton.click();
await expect(page.locator('mat-card-title')).toContainText('Bulbasaur');
});
Esta prueba busca "bulbasaur", hace clic en el botón de detalles y verifica que la página muestra la información correspondiente.
Para pruebas más avanzadas, podemos interceptar las solicitudes a la PokeAPI y proporcionar respuestas mockeadas. Esto permite probar comportamientos específicos sin depender de la API externa.
import { test, expect } from '@playwright/test';
test('Buscar un Pokémon con datos mockeados', async ({ page }) => {
await page.route('https://pokeapi.co/api/v2/pokemon?limit=10&offset=0', async route => {
const mockResponse = {
results: [
{ name: 'mockmon', url: 'https://pokeapi.co/api/v2/pokemon/999/' }
]
};
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(mockResponse),
});
});
await page.goto('http://localhost:4200');
const searchInput = page.locator('input[placeholder="Buscar"]');
await searchInput.fill('mockmon');
await expect(page.locator('mat-row')).toContainText('Mockmon');
});
Esta prueba intercepta la solicitud a la API y proporciona una respuesta mockeada con un Pokémon ficticio llamado “mockmon”.
Usa locators robustos (getByRole, getByText, etc.).
Agrega esperas solo si Playwright no espera automáticamente (raro).
Usa test.describe para agrupar pruebas por componentes.
Corre las pruebas en múltiples navegadores con:
npx playwright test --project=chromium
El repositorio lo encuentras dando click en el siguiente enlace:
Con Playwright, puedes realizar pruebas E2E modernas y confiables en aplicaciones Angular. Su facilidad de uso y potencia lo convierten en una excelente alternativa a herramientas tradicionales como Protractor o Cypress.