Configuración E2E con Playwright
Instala y configura Playwright para pruebas de extremo a extremo de tu aplicación Next.js.
Receta
Tarjeta de referencia rápida — lista para copiar y pegar.
# Instalar Playwright
npm init playwright@latest
# O instalar manualmente
npm install -D @playwright/test
npx playwright install// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./e2e",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? "github" : "html",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
screenshot: "only-on-failure",
},
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
{ name: "firefox", use: { ...devices["Desktop Firefox"] } },
{ name: "webkit", use: { ...devices["Desktop Safari"] } },
],
webServer: {
command: "npm run dev",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
});# Ejecutar todos los tests
npx playwright test
# Ejecutar en modo headed (ver el navegador)
npx playwright test --headed
# Ejecutar con la UI de Playwright
npx playwright test --ui
# Ejecutar un archivo específico
npx playwright test e2e/home.spec.ts
# Modo depuración (paso a paso)
npx playwright test --debug
# Mostrar informe HTML
npx playwright show-reportCuándo usarlo: Cuando necesitas probar flujos completos de usuario en un navegador real — navegación, envíos de formularios, autenticación e interacciones entre páginas.
Ejemplo funcional
// e2e/home.spec.ts
import { test, expect } from "@playwright/test";
test.describe("Home Page", () => {
test("has correct title", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/My App/);
});
test("navigates to about page", async ({ page }) => {
await page.goto("/");
await page.getByRole("link", { name: /about/i }).click();
await expect(page).toHaveURL("/about");
await expect(page.getByRole("heading", { level: 1 })).toHaveText("About Us");
});
test("search works", async ({ page }) => {
await page.goto("/");
await page.getByRole("searchbox").fill("react testing");
await page.getByRole("button", { name: /search/i }).click();
await expect(page).toHaveURL(/q=react\+testing/);
await expect(page.getByRole("heading")).toContainText("Search Results");
});
test("responsive navigation", async ({ page }) => {
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await page.goto("/");
// Mobile menu should be hidden initially
await expect(page.getByRole("navigation")).not.toBeVisible();
// Open mobile menu
await page.getByRole("button", { name: /menu/i }).click();
await expect(page.getByRole("navigation")).toBeVisible();
});
});Lo que demuestra:
- Config básica de Playwright con el servidor de desarrollo de Next.js
- Configuración de proyectos multibrowser
- Tests E2E con navegación, interacción de formularios y pruebas responsive
- Estrategias de locators alineadas con patrones de Testing Library
- Configuración compatible con CI (reintentos, un solo worker, reporter de GitHub)
Profundización
Cómo funciona
- Playwright lanza instancias reales de navegador (Chromium, Firefox, WebKit) y las controla mediante el DevTools Protocol
- La config
webServerinicia tu servidor de desarrollo de Next.js antes de ejecutar los tests y espera a que esté listo - Cada test obtiene un
BrowserContextnuevo (cookies y almacenamiento aislados) — sin fugas de state entre tests fullyParallel: trueejecuta tests en distintos archivos de forma concurrente para mayor velocidad- Los traces capturan una línea de tiempo de peticiones de red, instantáneas del DOM y logs de consola — invaluables para depurar fallos
Variaciones
Usar un build de producción para las pruebas:
// playwright.config.ts
webServer: {
command: "npm run build && npm run start",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},Configuración de CI con GitHub Actions:
# .github/workflows/e2e.yml
name: E2E Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx playwright test --project=chromium
env:
CI: true
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 7Ejecutar solo chromium en CI por velocidad:
// playwright.config.ts
projects: process.env.CI
? [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }]
: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
{ name: "firefox", use: { ...devices["Desktop Firefox"] } },
{ name: "webkit", use: { ...devices["Desktop Safari"] } },
],Notas de TypeScript
// Playwright tests use TypeScript natively -- no extra config needed
// The @playwright/test package includes all types
import { test, expect, Page } from "@playwright/test";
// Typed page fixture
test("example", async ({ page }: { page: Page }) => {
// page is fully typed with all Playwright methods
});Errores comunes
-
Conflictos de puerto — Si el puerto 3000 ya está en uso,
webServerde Playwright no puede iniciarse. Solución: UsareuseExistingServer: trueen local, o configura un puerto distinto. -
Arranque lento en CI — Compilar Next.js antes de cada ejecución E2E es lento. Solución: Cachea el directorio de build
.nexten CI, o ejecuta los tests E2E solo al fusionar en main. -
Instalación de navegadores faltante —
npx playwright installdescarga los navegadores. En CI, usa--with-depspara instalar también las dependencias del sistema. Solución: Añadenpx playwright install --with-depsa tu script de CI. -
Tests inestables por timing — Los tests E2E que dependen de tiempos exactos fallan. Solución: Usa la auto-espera integrada de Playwright y las aserciones
expect, que reintentan automáticamente. -
Contaminación de datos de prueba — Los tests que crean datos reales en una base de datos compartida pueden entrar en conflicto. Solución: Usa una base de datos de prueba, siembra datos antes de los tests y limpia después.
Alternativas
| Alternativa | Cuándo usarla | Cuándo no usarla |
|---|---|---|
| Cypress | Prefieres la API de Cypress o necesitas su component testing | Quieres soporte multibrowser o ejecución más rápida |
| Testing Library (unit) | Quieres tests de componentes rápidos sin navegador | Necesitas probar comportamiento real del navegador (navegación, cookies) |
| Selenium | Tienes infraestructura existente de Selenium | Empiezas desde cero (Playwright es más moderno) |
FAQs
¿Qué hace la config webServer en playwright.config.ts?
Inicia automáticamente tu servidor de desarrollo (o de producción) de Next.js antes de ejecutar los tests y espera a que esté listo. También lo apaga cuando los tests terminan.
¿Cuál es la diferencia entre el modo --headed y --ui?
--headedmuestra la ventana del navegador mientras se ejecutan los tests.--uiabre la UI interactiva de Playwright para seleccionar, ejecutar y depurar tests individuales con una vista de línea de tiempo.
¿Cómo ejecuto tests en un solo navegador por velocidad?
npx playwright test --project=chromiumO configura projects en playwright.config.ts para incluir solo chromium en CI.
Trampa común: ¿Qué ocurre si el puerto 3000 ya está en uso?
webServer de Playwright no puede iniciarse. Usa reuseExistingServer: true en local para reutilizar un servidor de desarrollo en ejecución, o configura un puerto distinto.
¿Cómo instalo los navegadores de Playwright en CI?
npx playwright install --with-deps chromiumLa bandera --with-deps instala dependencias del sistema (fuentes, bibliotecas) necesarias para el renderizado del navegador.
¿Qué hace fullyParallel: true?
Ejecuta tests en distintos archivos de forma concurrente. Cada test obtiene un contexto de navegador nuevo, por lo que no hay fugas de state entre tests en paralelo.
¿Cómo depuro un test de Playwright que falla?
npx playwright test --debugEsto abre el navegador con un depurador paso a paso. También puedes usar --trace on para capturar traces y depurar post-mortem.
Trampa común: ¿Por qué mis tests E2E son inestables en CI?
Causas habituales: problemas de timing, variables de entorno faltantes o máquinas de CI lentas. Usa la auto-espera integrada de Playwright y las aserciones expect, que reintentan automáticamente. Evita page.waitForTimeout().
¿Cómo pruebo layouts responsive con distintos tamaños de viewport?
await page.setViewportSize({ width: 375, height: 667 });
await page.goto("/");
await expect(page.getByRole("button", { name: /menu/i })).toBeVisible();¿Cómo escribo tests de Playwright en TypeScript?
No se necesita configuración adicional. El paquete @playwright/test incluye todos los tipos:
import { test, expect, Page } from "@playwright/test";¿Cómo uso un build de producción para tests E2E en lugar del modo dev?
Cambia el comando de webServer:
webServer: {
command: "npm run build && npm run start",
url: "http://localhost:3000",
},¿Cómo subo el informe de Playwright como artefacto de CI?
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 7Relacionado
- Patrones E2E con Playwright — Page Object Model y patrones comunes
- Playwright avanzado — auth, pruebas de API y mocking
- Estrategia de pruebas y mejores prácticas — cuándo usar E2E frente a tests unitarios
- Configuración de Vitest — tests unitarios junto a E2E