Espera automática y tiempo de espera en Playwright

Este capítulo profundiza en el mecanismo de espera automática de Playwright, así como en el conocimiento completo sobre la espera manual y la configuración del tiempo de espera.


Por qué se necesita la espera automática

Las aplicaciones web modernas utilizan ampliamente la renderización asíncrona; el contenido de la página no se carga por completo de inmediato.

En los marcos de prueba tradicionales, los desarrolladores tienen que escribirsleepowaitForpara esperar, pero estas operaciones no son lo suficientemente flexibles: o esperan demasiado y ralentizan las pruebas, o no esperan lo suficiente y causan pruebas inestables (flaky).

Playwright incorpora la lógica de espera en cada Locator y Action, resolviendo este problema de raíz.


Sistema de espera automática de tres niveles

Primer nivel: espera automática del Locator

Cuando creas un Locator, Playwright no busca el elemento de inmediato; comienza a buscarlo y espera automáticamente cuando ejecutas una acción o una aserción.

Ejemplo

// Crear el Locator (no se busca el elemento en este momento)
const btn = page.getByRole('button', { name: 'Botón que aparece con retraso' });

// Al hacer clic, espera automáticamente a que el botón aparezca (espera como máximo el tiempo de espera de acción)
await btn.click();

Segundo nivel: verificación de operabilidad de la acción

Antes de ejecutar una acción (click, fill, etc.), Playwright se asegura de que el elemento: Attached → Visible → Stable → Receives Events → Enabled.

Tercer nivel: reintento automático de aserciones

Cuando una aserción falla, no se reporta el error de inmediato; en su lugar, se reintenta continuamente hasta que se cumpla la condición o se agote el tiempo de espera.

Ejemplo

// Esta aserción reintentará durante 5 segundos hasta que aparezca el texto o se agote el tiempo de espera
await expect(page.getByText('Carga de datos completada')).toBeVisible();

Métodos de espera manual

En escenarios especiales donde la espera automática no es suficiente, Playwright también proporciona métodos de espera manual.

page.waitForTimeout(ms) — espera fija

Ejemplo

// Espera fija de 2 segundos (generalmente no recomendado)
await page.waitForTimeout(2000);

Evita usarlo en la medida de lo posiblewaitForTimeout, ya que la espera fija es muy inestable ante diferencias de rendimiento entre dispositivos. Prioriza el uso dewaitForURL、waitForResponseesperas basadas en eventos que se mencionan más adelante.

page.waitForURL() — esperar el cambio de URL

Ejemplo

// Esperar coincidencia exacta de URL
await page.waitForURL('https://www.example.com/dashboard');

// Esperar que la URL contenga un patrón específico
await page.waitForURL(/dashboard/);

page.waitForLoadState() — esperar el estado de carga

Ejemplo

// Esperar el evento load
await page.waitForLoadState('load');

// Esperar DOMContentLoaded
await page.waitForLoadState('domcontentloaded');

// Esperar a que la red esté inactiva
await page.waitForLoadState('networkidle');

page.waitForResponse() — esperar la respuesta de red

Ejemplo

// Esperar una respuesta específica de API
const response = await page.waitForResponse(
  resp => resp.url().includes('/api/data') && resp.status() === 200
);

// Obtener los datos de la respuesta
const data = await response.json();

page.waitForEvent() — esperar un evento

Ejemplo

// Esperar a que aparezca una ventana emergente
const dialogPromise = page.waitForEvent('dialog');
await page.getByRole('button', { name: 'Eliminar' }).click();
const dialog = await dialogPromise;
await dialog.accept();

// Esperar a que se abra una nueva página
const pagePromise = page.context().waitForEvent('page');
await page.getByRole('link', { name: 'Abrir en ventana nueva' }).click();
const newPage = await pagePromise;

Explicación detallada de la configuración del tiempo de espera

Playwright tiene 4 tipos de tiempo de espera, que actúan en diferentes niveles:

Tipo de tiempo de esperaUbicación en el archivo de configuraciónValor predeterminadoObjeto sobre el que actúa
Test timeouttimeout30000msTodo el caso de prueba
Expect timeoutexpect.timeout5000msReintento de aserciones
Action timeoutuse.actionTimeoutNinguno (sin límite)Operaciones sobre elementos (click, fill, etc.)
Navigation timeoutuse.navigationTimeoutNinguno (sin límite)Navegación de página (goto, goBack, etc.)

Configuración global

Ejemplo

// Ruta del archivo: playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Tiempo de espera total para cada prueba (en milisegundos)
  timeout: 60000,

  // Tiempo de espera para el reintento automático de aserciones
  expect: {
    timeout: 10000,
  },

  use: {
    // Tiempo de espera para cada operación (click, fill, etc.)
    actionTimeout: 15000,

    // Tiempo de espera para cada navegación
    navigationTimeout: 30000,
  },
});

Configuración individual (prioridad mayor que la configuración global)

Ejemplo

// Establecer el tiempo de espera total para una sola prueba
test.setTimeout(120000);

// Establecer el tiempo de espera para una sola operación
await page.getByRole('button').click({ timeout: 30000 });

// Establecer el tiempo de espera para una sola navegación
await page.goto('https://www.example.com/', { timeout: 60000 });

Prioridad del tiempo de espera

Configuración individual > Configuración global del archivo > Valor predeterminado.


Recomendaciones para establecer tiempos de espera razonables

EscenarioTiempo de espera recomendadoDescripción
Desarrollo localValor predeterminadoEl servicio local responde rápido, el valor predeterminado es suficiente
Entorno de CI2 a 3 veces el valor predeterminadoEl rendimiento de las máquinas de CI fluctúa considerablemente
Páginas lentasactionTimeout: 15000Formularios grandes, páginas complejas
Llamadas a servicios de tercerostest.setTimeout(120000)Las API externas responden lentamente
Otras extensiones