Glossario · Automazione della UI
Web-first assertion
Detto anche: web-first assertions, asserzione web-first, asserzioni web-first, asserzioni con retry automatico
Definizione
Asserzione di Playwright che riceve un locator e ritenta finché la condizione attesa non è soddisfatta o scade il timeout, invece di controllare un valore una sola volta.
Una web-first assertion (asserzione web-first) è un’asserzione che sa che la pagina potrebbe ancora cambiare. Le passi un locator e un’aspettativa, e Playwright continua a rileggere l’elemento e a ricontrollare l’aspettativa finché non passa o finché non scade il timeout di expect (5 secondi per impostazione predefinita). Il nome viene dalla documentazione di Playwright, che raccomanda queste asserzioni invece di leggere un valore e confrontarlo da sé.
Esempio
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$/);
});
In cosa differisce da un’asserzione normale
// 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);
Entrambe le righe controllano la pagina in un singolo istante. Se il messaggio di stato viene renderizzato 200 ms dopo, il test fallisce, e quel tipo di fallimento è intermittente: hai un test flaky. Le versioni web-first, toHaveText e toBeVisible, attendono la condizione.
Un modo rapido per distinguerle: le web-first assertion vengono precedute da await e ricevono un Locator o una Page. I matcher generici come toBe e toEqual ricevono un valore semplice e non ritentano mai.
Dettagli utili
- Anche la negazione ritenta.
await expect(locator).not.toBeVisible()attende che l’elemento scompaia. - Timeout per singola asserzione.
toHaveText('Done', { timeout: 15_000 })per un passo lento, invece di alzare il timeout globale. - Soft assertion.
expect.soft(...)registra il fallimento e lascia proseguire il test, comodo per verificare più campi in una stessa schermata. - Polling personalizzato.
expect.poll(() => fetchStatus()).toBe('ready')applica lo stesso meccanismo di retry a valori non legati alla UI, come la risposta di un’API.