Glosario · Automatización de UI
Web-first assertion (aserción web-first)
En inglés: Web-first assertion
También llamado: web-first assertions, aserción web-first, aserciones web-first, aserción con reintento automático
Definición
Aserción de Playwright que recibe un locator y reintenta hasta que se cumple la condición esperada o vence el timeout, en lugar de comprobar un valor una sola vez.
Una web-first assertion (aserción web-first) es una aserción que entiende que la página todavía puede estar cambiando. Le pasas un locator y una expectativa, y Playwright sigue releyendo el elemento y volviendo a comprobar la expectativa hasta que se cumple o se agota el timeout de expect (5 segundos por defecto). El nombre viene de la documentación de Playwright, que recomienda estas aserciones en lugar de leer un valor y compararlo tú mismo.
Ejemplo
import { test, expect } from '@playwright/test';
test('shows the saved message', async ({ page }) => {
await page.goto('/settings');
await page.getByRole('button', { name: 'Save' }).click();
// Web-first: retries until the text matches
await expect(page.getByRole('status')).toHaveText('Settings saved');
await expect(page.getByRole('progressbar')).toBeHidden();
await expect(page.getByRole('listitem')).toHaveCount(3);
await expect(page).toHaveURL(/\/settings$/);
});
En qué se diferencia de una aserción normal
// Not web-first: reads the text once, then compares
expect(await page.getByRole('status').textContent()).toBe('Settings saved');
// Not web-first: isVisible() returns immediately
expect(await page.getByRole('dialog').isVisible()).toBe(true);
Ambas líneas comprueban la página en un único instante. Si el mensaje de estado se renderiza 200 ms después, el test falla, y ese tipo de fallo es intermitente, así que tienes un test flaky. Las versiones web-first, toHaveText y toBeVisible, esperan a que se cumpla la condición.
Una forma rápida de distinguirlas: las web-first assertions llevan await y reciben un Locator o una Page. Los matchers genéricos como toBe y toEqual reciben un valor simple y nunca reintentan.
Detalles útiles
- La negación también reintenta.
await expect(locator).not.toBeVisible()espera a que el elemento desaparezca. - Timeouts por aserción.
toHaveText('Done', { timeout: 15_000 })para un paso lento concreto, en lugar de subir el timeout global. - Soft assertions.
expect.soft(...)registra el fallo y deja que el test continúe, lo que resulta práctico para comprobar varios campos de una misma pantalla. - Sondeo personalizado.
expect.poll(() => fetchStatus()).toBe('ready')aplica el mismo comportamiento de reintento a valores que no son de UI, como la respuesta de una API.