Lección 6 de 7 · 3 min
Mock de red y control del tiempo
page.route: el backend bajo tu control
// Stub: la UI recibe exactamente lo que el test necesita
await page.route('**/api/servicios', (route) =>
route.fulfill({ json: [{ id: 1, nombre: 'Corte', precio: 12000 }] }),
);
// Error 500: ¿la app tiene mensaje amable o pantalla blanca?
await page.route('**/api/bookings', (route) =>
route.fulfill({ status: 500, json: { error: 'internal' } }),
);
// Red lenta: ¿aparece el skeleton? ¿se puede hacer doble submit mientras tanto?
await page.route('**/api/servicios', async (route) => {
await new Promise((r) => setTimeout(r, 3000));
await route.fallback(); // después del delay, deja pasar la request real
});
Los estados difíciles de reproducir con datos reales — vacío, error, lentitud, respuesta malformada — se vuelven tests de cinco líneas. Ahí viven los bugs vergonzosos.
HAR: grabar la realidad, reproducirla determinista
¿Mock realista sin escribirlo a mano? Graba una sesión real y reprodúcela:
// Grabar (una vez, contra el backend real)
await page.routeFromHAR('fixtures/booking.har', { update: true });
// Reproducir (siempre, determinista, sin backend)
await page.routeFromHAR('fixtures/booking.har');
Perfecto para aislar la suite de UI de un backend inestable de staging — con la disciplina de re-grabar cuando el contrato de la API cambie de verdad.
page.clock: el tiempo congelado
Desde Playwright 1.45, el reloj del navegador es tuyo:
await page.clock.setFixedTime(new Date('2026-08-15T10:00:00'));
await page.goto('/reservas');
// "Hoy" es SIEMPRE 15 de agosto: los slots del calendario no dependen de cuándo corre el test
// O avanza el tiempo a voluntad:
await page.clock.install();
await page.clock.fastForward('05:00'); // el toast de "sesión por expirar" en 5 min, ya
Todo lo que dependa de Date.now(), setTimeout o contadores regresivos pasa de "imposible de probar" a determinista.
¿Cuánto mockear? La regla de las dos capas
- Suite de UI (la mayoría): stub de red completo. Rápida, determinista, corre sin backend.
- Smoke de integración (5–10 tests): cero mocks, contra entorno real. Detecta que el contrato API↔UI sigue vivo.
El error es el extremo: todo mockeado no detecta que el backend cambió el shape de la respuesta; todo real hace la suite lenta y esclava de staging. Las dos capas juntas cubren ambos riesgos con presupuesto mínimo.
Ejercicio
Para un formulario con envío a API: escribe los 4 tests de estados con route.fulfill (éxito, 500, lento con skeleton, respuesta malformada) y uno con page.clock si hay algo dependiente del tiempo. Cronometra la suite: los 5 deberían correr en segundos.