Ir al contenido

Configuración manual

La mayoría debería ejecutar init — escribe por ti todos los archivos de abajo. Esta página es la referencia de lo que init genera, para que puedas cablearlo a mano, omitir el codegen o entender cada pieza.

Para Next.js y frameworks similares, donde tanto el servidor como el navegador hacen llamadas a la API. Usa ambos mecanismos de grabación juntos — mira cómo funciona.

El proxy es un proceso ligero que arrancas junto a tu app para la ejecución de la prueba (vía un script, como abajo, o el webServer de Playwright) — no es infraestructura que despliegas o mantienes. El setup completo es: arráncalo junto a tu app, apunta la URL base de la API de tu app hacia él, propaga la cabecera de sesión desde SSR y escribe un fixture.

{
"scripts": {
"proxy": "test-proxy-recorder http://localhost:8000 --port 8100 --dir ./e2e/recordings",
"dev:proxy": "concurrently \"npm run proxy\" \"TEST_PROXY_RECORDER_ENABLED=1 npm run dev\"",
"serve:proxy": "concurrently \"npm run proxy\" \"TEST_PROXY_RECORDER_ENABLED=1 npm run serve\""
}
}

En el código de tu app, apunta la URL base de la API al proxy cuando el recorder está activado, y al backend real en caso contrario — el proxy nunca se ejecuta en producción:

const API_BASE =
process.env.NODE_ENV === 'production' && !process.env.TEST_PROXY_RECORDER_ENABLED
? 'https://api.example.com'
: 'http://localhost:8100'; // dirección del proxy

TEST_PROXY_RECORDER_ENABLED lo establecen los scripts dev:proxy / serve:proxy de arriba, y los scripts generados por init. Usa la variable de entorno que tu app ya use para la URL base de la API (por ejemplo API_URL, NEXT_PUBLIC_API_URL) — la misma condicional aplica.

2. Etiqueta los fetch del lado del servidor (Next.js)

Sección titulada «2. Etiqueta los fetch del lado del servidor (Next.js)»

Las llamadas fetch del lado del servidor necesitan la cabecera de sesión de grabación para que el proxy sepa a qué prueba pertenecen. Playwright ya la establece en la navegación del navegador, así que el id está en next/headers — solo tienes que adjuntarlo a las peticiones SSR salientes. Añade una línea a tu root layout (init hace esto por ti):

app/layout.tsx
import { registerProxyFetch } from 'test-proxy-recorder/nextjs';
registerProxyFetch(); // no-op en producción salvo TEST_PROXY_RECORDER_ENABLED=true
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}

Esto funciona en los runtimes Node y Edge. Para apps con axios, llama a registerProxyAxios(instance) en cada instancia del lado del servidor; para un único fetch, createHeadersWithRecordingId(await headers()) es una alternativa sin parchear. Un proxy.ts/middleware.ts con setNextProxyHeaders es opcional — solo expone el id, no etiqueta los fetch. Graba contra un build de producción (next build && next start), no next dev. Mira la integración de Next.js para más detalles. Las apps solo de navegador pueden saltarse este paso.

import { test, expect } from '@playwright/test';
import { playwrightProxy } from 'test-proxy-recorder';
// SSR requests (server → proxy) are recorded to .mock.json.
// Browser requests to the proxy URL are also covered.
const CLIENT_SIDE_URL = /localhost:8100/;
// Change to 'record' to update recordings.
const MODE = 'replay' as const;
test.beforeEach(async ({ page }, testInfo) => {
await playwrightProxy.before(page, testInfo, MODE, { url: CLIENT_SIDE_URL });
});
test('homepage loads', async ({ page }) => {
await page.goto('/');
await expect(page.getByText('Welcome')).toBeVisible();
});
Ventana de terminal
# Terminal 1
npm run serve:proxy
# Terminal 2 — .mock.json and .har files are written automatically
npx playwright test
Ventana de terminal
git add e2e/recordings/
git commit -m "add e2e recordings"

Cuando todas las llamadas a la API vienen del navegador (sin SSR), solo necesitas el mecanismo HAR. No hace falta un backend de proxy para la grabación en sí — el proceso del proxy solo proporciona gestión de sesiones.

Ventana de terminal
npm install --save-dev test-proxy-recorder
import { defineConfig } from '@playwright/test';
export default defineConfig({
webServer: {
command: 'test-proxy-recorder https://api.example.com --port 8100 --dir ./e2e/recordings',
url: 'http://localhost:8100/__control',
reuseExistingServer: true,
},
});

El destino del proxy (https://api.example.com) no importa para la grabación solo de navegador — solo se usa si también hay que enrutar peticiones del lado del servidor (SSR). El proceso del proxy debe ejecutarse para que su endpoint /__control esté disponible para la gestión de sesiones.

e2e/fixtures.ts
import { test as base, type Page, type BrowserContext } from '@playwright/test';
import { playwrightProxy } from 'test-proxy-recorder';
// Match the external API domain your browser makes requests to.
// In record mode these requests go to the real API and are saved.
// In replay mode they are served from disk — no network needed.
const CLIENT_SIDE_URL = /api\.example\.com/;
// Change to 'record' to hit the real API and update recordings.
const MODE = 'replay' as const;
export const test = base.extend<{ page: Page }>({
page: async ({ context }, use, testInfo) => {
const page = await context.newPage();
await playwrightProxy.before(page, testInfo, MODE, { url: CLIENT_SIDE_URL });
await use(page);
},
});
e2e/my.test.ts
import { test, expect } from './fixtures';
test('homepage loads', async ({ page }) => {
await page.goto('https://myapp.com/');
await expect(page.getByText('Welcome')).toBeVisible();
});

5. Graba — ejecuta una vez contra la API real

Sección titulada «5. Graba — ejecuta una vez contra la API real»
Ventana de terminal
# In fixtures.ts: const MODE = 'record' as const;
npx playwright test
# .har files are written to e2e/recordings/ automatically
Ventana de terminal
# In fixtures.ts: const MODE = 'replay' as const;
git add e2e/recordings/
git commit -m "add e2e recordings"

CI ahora se ejecuta sin ningún acceso a la red.

Añade esto a .gitattributes para colapsar archivos de grabación grandes en los diffs de PR:

/e2e/recordings/** binary