Playwright Assertions

This chapter provides a comprehensive introduction to Playwright's assertion system, including auto-retrying assertions, general assertions, and the usage of soft assertions.


What is an Assertion?

An assertion is used to verify whether the expected result of a test matches the actual result.

Playwright provides two sets of assertions:General assertions(from Jest) andauto-retrying assertions(unique to Playwright).


Auto-retrying Assertions vs General Assertions

Auto-retrying Assertions (Async Matchers)

Playwright's Web-specific assertions automatically retry until the condition is met or a timeout occurs, and must useawait。

Example

// Auto-retrying assertion — waits for the condition to be met
await expect(page.getByText('EXAMPLE')).toBeVisible();

General Assertions

Used for non-Web-specific value comparisons; does not automatically retry.

Example

// General assertion — executes immediately, does not wait
expect(1 + 1).toBe(2);
expect('hello').toContain('ell');
expect(true).toBeTruthy();
TypeAuto-retry?Await required?Applicable scenario
Auto-retrying assertionsYesRequiredawaitWeb-specific content such as page elements, URL, title, etc.
General assertionsnoNot requiredJavaScript values such as ordinary variables, arrays, objects, etc.

Page-level Assertions

Example

// Page title assertion
await expect(page).toHaveTitle('What we learn is not only technology, but also dreams!');
await expect(page).toHaveTitle(/EXAMPLE/);

// Page URL assertion
await expect(page).toHaveURL('https://www.example.com/');
await expect(page).toHaveURL(/example\.com/);

Visibility Assertions

Example

const btn = page.getByRole('button', { name: 'Submit' });

// Element is visible
await expect(btn).toBeVisible();

// Element is not visible
await expect(btn).toBeHidden();

// Element exists in the DOM (but not necessarily visible)
await expect(btn).toBeAttached();

// Element is visible within the viewport
await expect(btn).toBeInViewport();

Text and Value Assertions

Example

const heading = page.getByRole('heading', { name: 'EXAMPLE' });

// Element's text content exactly matches
await expect(heading).toHaveText('Not only technology, but also dreams!');

// Element's text content contains a substring
await expect(heading).toContainText('technology');

// Current value of input
await expect(page.getByLabel('username')).toHaveValue('example_user');

// Element content is empty
await expect(page.getByTestId('error-msg')).toBeEmpty();

State Assertions

Example

const checkbox = page.getByLabel('Agree to the terms');
const input = page.getByLabel('email');

// Element is enabled
await expect(input).toBeEnabled();

// Element is disabled
await expect(input).toBeDisabled();

// Element is editable
await expect(input).toBeEditable();

// Checkbox is checked
await expect(checkbox).toBeChecked();

// Element has focus
await expect(input).toBeFocused();

Attribute Assertions

Example

const element = page.locator('.example-logo');

// DOM attribute assertion
await expect(element).toHaveAttribute('src', '/static/images/logo.png');

// Only check that the attribute exists
await expect(element).toHaveAttribute('alt');

// CSS class name assertion
await expect(element).toHaveClass('logo-primary');

// CSS property value assertion
await expect(element).toHaveCSS('display', 'block');

// Element ID assertion
await expect(element).toHaveId('main-logo');

// Accessible name
await expect(page.getByRole('button')).toHaveAccessibleName('Submit');

Count Assertions

Example

// Number of matched elements
const items = page.getByRole('listitem');
await expect(items).toHaveCount(5);

// Used with filter
const activeItems = page.getByRole('listitem').filter({ hasText: 'Activated' });
await expect(activeItems).toHaveCount(3);

General Assertions Quick Reference

MethodDescriptionExample
toBe(value)Strict equality (===)expect(x).toBe(42)
toEqual(value)Deep equalityexpect(obj).toEqual({ a: 1 })
toContain(item)Array/string containsexpect(arr).toContain('a')
toBeTruthy()Value is truthyexpect(x).toBeTruthy()
toBeFalsy()Value is falsyexpect(x).toBeFalsy()
toBeNull()Value is nullexpect(x).toBeNull()
toBeGreaterThan(n)Greater than nexpect(x).toBeGreaterThan(10)
toBeLessThan(n)Less than nexpect(x).toBeLessThan(100)
toHaveLength(n)Array lengthexpect(arr).toHaveLength(3)

expect.soft() Soft Assertions

Ordinary assertions terminate the test immediately after failure.

Soft assertionsDo not terminate after failure; they continue executing subsequent code and report all failures uniformly at the end of the test.

Example

test('Multiple checks in form validation', async ({ page }) => {
  await page.goto('https://example.com/form');

  // Soft assertion — failure does not stop the test
  await expect.soft(page.getByLabel('username')).toBeVisible();
  await expect.soft(page.getByLabel('password')).toBeVisible();
  await expect.soft(page.getByLabel('email')).toBeVisible();
  await expect.soft(page.getByRole('button', { name: 'Register' })).toBeEnabled();

  // If any of the above assertions fail, checking continues and all failures are reported at the end.
});

Use when testing form pagesexpect.soft()You can discover all missing fields at once without having to fix one by one before seeing the next issue. This greatly improves debugging efficiency.


Assertion Timeout

Auto-retrying assertions have a default timeout of 5 seconds, which can be customized in the configuration file or for a single assertion:

Example

// Set timeout for a single assertion (milliseconds)
await expect(page.getByText('Loading...')).toBeHidden({ timeout: 10000 });

// Globally set in the configuration file
// playwright.config.ts:
// export default defineConfig({
//   expect: { timeout: 10000 },
// });
Other extensions