Glossário · Automação de UI
Web-first assertion
Também chamado de: web-first assertions, assertion web-first, auto-retrying assertion, assertions com retry automático
Definição
Assertion do Playwright que recebe um locator e tenta de novo até a condição esperada ser atendida ou o timeout expirar, em vez de verificar um valor uma única vez.
Uma web-first assertion é uma assertion que entende que a página ainda pode estar mudando. Você passa um locator e uma expectativa, e o Playwright continua relendo o elemento e reavaliando a expectativa até ela passar ou até o timeout do expect (5 segundos por padrão) se esgotar. O nome vem da documentação do Playwright, que recomenda essas assertions em vez de ler um valor e compará-lo por conta própria.
Exemplo
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$/);
});
Como ela se diferencia de uma assertion comum
// 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);
As duas linhas verificam a página em um único instante. Se a mensagem de status for renderizada 200 ms depois, o teste falha, e esse tipo de falha é intermitente, então você tem um teste flaky. As versões web-first, toHaveText e toBeVisible, esperam pela condição.
Um jeito rápido de diferenciá-las: web-first assertions levam await e recebem um Locator ou uma Page. Matchers genéricos como toBe e toEqual recebem um valor simples e nunca tentam de novo.
Detalhes úteis
- A negação também faz retry.
await expect(locator).not.toBeVisible()espera o elemento desaparecer. - Timeouts por assertion.
toHaveText('Done', { timeout: 15_000 })para um único passo lento, em vez de aumentar o timeout global. - Soft assertions.
expect.soft(...)registra a falha e deixa o teste continuar, o que é prático para verificar vários campos em uma mesma tela. - Polling personalizado.
expect.poll(() => fetchStatus()).toBe('ready')aplica o mesmo comportamento de retry a valores que não são de UI, como uma resposta de API.