# Web-First Assertions — Playwright & Cypress

Source: https://www.skillbyai.com/en/e2e-testing/pw-assert

> Assertions that retry.

## expect(locator) retries until it passes

Assertions such as `await expect(locator).toBeVisible()`, `toHaveText`, `toContainText`, `toHaveValue`, `toHaveCount`, `toBeEnabled` and page-level `toHaveURL` or `toHaveTitle` are **web-first**: they keep re-checking until the condition holds or the expect timeout (5 seconds by default, configurable) runs out. That is why they must be awaited. Avoid reading a value once and asserting on it, as in `expect(await locator.isVisible()).toBe(true)`, because that does not retry. `expect.soft` records a failure without stopping the test, and `expect.poll` retries an arbitrary async function.

## Retrying versus non-retrying

Prefer the first form.

```typescript
import { test, expect } from '@playwright/test';

test('shows saved status', async ({ page }) => {
  await page.goto('/settings');
  await page.getByRole('button', { name: 'Save' }).click();

  // good: retries until the text appears or the timeout expires
  await expect(page.getByRole('status')).toHaveText('Saved');
  await expect(page).toHaveURL(/\/settings$/);

  // fragile: reads once, no retry
  // expect(await page.getByRole('status').textContent()).toBe('Saved');

  // retry an arbitrary async check
  await expect.poll(async () => (await page.request.get('/api/settings')).status()).toBe(200);
});
```

## Raise timeouts in config, not with sleeps

If a step is genuinely slow, set `expect: { timeout: 10_000 }` in the config or pass `{ timeout }` to one assertion, instead of adding `page.waitForTimeout`.

**Quiz:** Why is `await expect(locator).toHaveText('Saved')` better than comparing textContent() once?

- [ ] It ignores letter case automatically
- [ ] It runs faster because it never waits
- [ ] It works without a page
- [x] It retries until the text matches or the timeout expires

*Answer:* It retries until the text matches or the timeout expires. Web-first assertions absorb timing differences.
