Skip to content

Playwright Assertions

Playwright extends generic expect with web-first assertions that retry until a condition is met or timeout expires — the mirror of auto-waiting on actions.

Web-First Assertions

Import expect from @playwright/test, not @jest/globals or chai. Web assertions like toBeVisible() poll the DOM until pass or timeout.

Separate generic assertions (toEqual, toBeTruthy) for plain values from web assertions (toHaveText, toBeVisible) for locators and pages.

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

test('assertions demo', async ({ page }) => {
  await page.goto('/dashboard');
  await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
  await expect(page).toHaveURL(/dashboard/);
});

Always await web assertions — they are async.

Assertion Categories

// Locator
await expect(locator).toBeVisible();
await expect(locator).toHaveText('x');
await expect(locator).toHaveCount(3);

// Page
await expect(page).toHaveTitle(/App/);
await expect(page).toHaveURL('/home');

// API (with APIResponse)
expect(response.ok()).toBeTruthy();
  • Locator assertions auto-retry — default timeout from config.
  • Negation: await expect(locator).not.toBeVisible().
  • Soft assertions (optional): expect.soft() collects failures.
  • Generic expect for non-DOM values inside test.step or callbacks.

Common Assertions

Assertions you will use daily.

Assertion Checks
toBeVisible() Element is visible
toBeHidden() Element is not visible
toHaveText() Exact text content
toContainText() Substring in text
toHaveValue() Input value
toBeChecked() Checkbox/radio state
toHaveURL() Page URL
toHaveScreenshot() Visual regression

Soft Assertions

await expect.soft(page.getByText('A')).toBeVisible();
await expect.soft(page.getByText('B')).toBeVisible();
// test continues; all soft failures reported at end

Soft Assertions with expect.soft

expect.soft() continues the test after failure, collecting multiple assertion errors — useful for checking several fields on a form in one pass.

Common Mistakes

  • Using plain expect(await locator.textContent()).toBe('x') without retry.
  • Importing wrong expect library without web matchers.
  • Forgetting await on expect(locator)....
  • Assertion timeout too low on slow CI.

Key Takeaways

  • Use expect from @playwright/test for web matchers.
  • Web assertions retry automatically until timeout.
  • Match assertion type to subject: locator, page, or API.
  • Soft assertions help audit pages with many checks.

Pro Tip

Configure expect: { timeout: 10_000 } in config if CI is slower than local — one place instead of per-assertion overrides.