Skip to main content
Playwright Test includes built-in matchers for making assertions about page state, locators, and API responses. All assertions automatically retry until the expected condition is met.

Locator Assertions

toBeAttached

Asserts that an element is attached to the DOM.
await expect(locator).toBeAttached();
await expect(locator).toBeAttached({ attached: false });
options.attached
boolean
default:"true"
Whether to assert that element is attached or detached.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeChecked

Asserts that a checkbox or radio button is checked.
await expect(locator).toBeChecked();
await expect(locator).toBeChecked({ checked: false });
await expect(locator).toBeChecked({ indeterminate: true });
options.checked
boolean
Whether to assert that element is checked or unchecked.
options.indeterminate
boolean
Whether to assert that element is in indeterminate state.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeDisabled

Asserts that an element is disabled.
await expect(locator).toBeDisabled();
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeEditable

Asserts that an element is editable.
await expect(locator).toBeEditable();
await expect(locator).toBeEditable({ editable: false });
options.editable
boolean
default:"true"
Whether to assert that element is editable or readonly.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeEmpty

Asserts that an element contains no text content or child elements.
await expect(locator).toBeEmpty();
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeEnabled

Asserts that an element is enabled.
await expect(locator).toBeEnabled();
await expect(locator).toBeEnabled({ enabled: false });
options.enabled
boolean
default:"true"
Whether to assert that element is enabled or disabled.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeFocused

Asserts that an element has focus.
await expect(locator).toBeFocused();
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeHidden

Asserts that an element is not visible.
await expect(locator).toBeHidden();
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeVisible

Asserts that an element is visible.
await expect(locator).toBeVisible();
await expect(locator).toBeVisible({ visible: false });
options.visible
boolean
default:"true"
Whether to assert that element is visible or hidden.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toBeInViewport

Asserts that an element is within the viewport.
await expect(locator).toBeInViewport();
await expect(locator).toBeInViewport({ ratio: 0.5 });
options.ratio
number
The minimum ratio of the element to be considered in viewport. Defaults to any positive ratio.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toContainText

Asserts that an element contains the specified text.
await expect(locator).toContainText('substring');
await expect(locator).toContainText(/pattern/);
await expect(locator).toContainText(['text1', 'text2']);
expected
string | RegExp | Array<string | RegExp>
required
Expected substring, pattern, or array of expected text values.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.useInnerText
boolean
Whether to use innerText instead of textContent.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveAccessibleDescription

Asserts that an element has the specified accessible description.
await expect(locator).toHaveAccessibleDescription('Button description');
await expect(locator).toHaveAccessibleDescription(/description/);
expected
string | RegExp
required
Expected accessible description.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveAccessibleName

Asserts that an element has the specified accessible name.
await expect(locator).toHaveAccessibleName('Submit button');
await expect(locator).toHaveAccessibleName(/submit/i);
expected
string | RegExp
required
Expected accessible name.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveAccessibleErrorMessage

Asserts that an element has the specified accessible error message.
await expect(locator).toHaveAccessibleErrorMessage('Field is required');
expected
string | RegExp
required
Expected accessible error message.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveAttribute

Asserts that an element has the specified attribute.
// Check attribute exists
await expect(locator).toHaveAttribute('disabled');

// Check attribute value
await expect(locator).toHaveAttribute('href', '/about');
await expect(locator).toHaveAttribute('class', /primary/);
name
string
required
Attribute name.
value
string | RegExp
Expected attribute value.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveClass

Asserts that an element has the specified CSS class.
await expect(locator).toHaveClass('active');
await expect(locator).toHaveClass(/btn-/);
await expect(locator).toHaveClass(['btn', 'btn-primary']);
expected
string | RegExp | Array<string | RegExp>
required
Expected CSS class or array of classes.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toContainClass

Asserts that an element’s class attribute contains the specified class.
await expect(locator).toContainClass('highlight');
await expect(locator).toContainClass(['active', 'selected']);
expected
string | string[]
required
Expected CSS class name or array of class names. RegExp is not supported.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveCount

Asserts that a locator matches the specified number of elements.
await expect(page.locator('.item')).toHaveCount(5);
count
number
required
Expected number of elements.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveCSS

Asserts that an element has the specified CSS property.
// Single property
await expect(locator).toHaveCSS('color', 'rgb(255, 0, 0)');
await expect(locator).toHaveCSS('font-size', /16px/);

// Multiple properties
await expect(locator).toHaveCSS({ color: 'red', display: 'flex' });
name
string
CSS property name.
value
string | RegExp
Expected CSS property value.
styles
Record<string, string>
Object with CSS property names and their expected values.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveId

Asserts that an element has the specified ID.
await expect(locator).toHaveId('submit-button');
await expect(locator).toHaveId(/^btn-/);
id
string | RegExp
required
Expected element ID.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveJSProperty

Asserts that an element has the specified JavaScript property.
await expect(locator).toHaveJSProperty('loaded', true);
await expect(locator).toHaveJSProperty('value', 42);
name
string
required
Property name.
value
any
required
Expected property value.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveRole

Asserts that an element has the specified ARIA role.
await expect(locator).toHaveRole('button');
role
string
required
Expected ARIA role.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveText

Asserts that an element has the specified text.
await expect(locator).toHaveText('Welcome');
await expect(locator).toHaveText(/welcome/i);
await expect(locator).toHaveText(['Item 1', 'Item 2', 'Item 3']);
text
string | RegExp | Array<string | RegExp>
required
Expected text or array of text values.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.useInnerText
boolean
Whether to use innerText instead of textContent.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

toHaveValue

Asserts that an input element has the specified value.
await expect(locator).toHaveValue('John Doe');
await expect(locator).toHaveValue(/^john/i);
value
string | RegExp
required
Expected input value.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveValues

Asserts that a multi-select element has the specified values.
await expect(locator).toHaveValues(['option1', 'option2']);
await expect(locator).toHaveValues([/opt-1/, /opt-2/]);
values
Array<string | RegExp>
required
Expected array of selected values.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

Page Assertions

toHaveTitle

Asserts that the page has the specified title.
await expect(page).toHaveTitle('Home Page');
await expect(page).toHaveTitle(/dashboard/i);
title
string | RegExp
required
Expected page title.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

toHaveURL

Asserts that the page has the specified URL.
await expect(page).toHaveURL('https://example.com');
await expect(page).toHaveURL(/.*\/dashboard/);
await expect(page).toHaveURL(url => url.searchParams.get('page') === '2');
url
string | RegExp | URLPattern | (url: URL) => boolean
required
Expected URL string, pattern, URLPattern, or predicate function.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.ignoreCase
boolean
Whether to perform case-insensitive match.

API Response Assertions

toBeOK

Asserts that an API response has a successful status code (200-299).
const response = await page.request.get('https://api.example.com/users');
await expect(response).toBeOK();

Snapshot Assertions

toHaveScreenshot

Asserts that a page or locator screenshot matches the stored snapshot.
await expect(page).toHaveScreenshot('homepage.png');
await expect(locator).toHaveScreenshot('button.png');
await expect(page).toHaveScreenshot('modal.png', {
  mask: [page.locator('.dynamic-content')],
  maxDiffPixels: 100
});
name
string | string[]
Snapshot name or path segments.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.
options.animations
'disabled' | 'allow'
How to handle CSS animations.
options.caret
'hide' | 'initial'
Whether to hide the text caret.
options.clip
{ x: number, y: number, width: number, height: number }
Area to capture.
options.fullPage
boolean
Whether to take a full page screenshot.
options.mask
Locator[]
Elements to mask before taking the screenshot.
options.maskColor
string
Color to use for masking.
options.maxDiffPixels
number
Maximum number of differing pixels allowed.
options.maxDiffPixelRatio
number
Maximum ratio of differing pixels (0-1).
options.threshold
number
Color difference threshold (0-1).

toMatchSnapshot

Asserts that a value matches the stored snapshot.
await expect(screenshot).toMatchSnapshot('reference.png');
await expect(data).toMatchSnapshot('data.json');
name
string | string[]
Snapshot name or path segments.
options.maxDiffPixels
number
Maximum number of differing pixels allowed (for images).
options.maxDiffPixelRatio
number
Maximum ratio of differing pixels (0-1, for images).
options.threshold
number
Color difference threshold (0-1, for images).

toMatchAriaSnapshot

Asserts that the accessibility tree matches the expected snapshot.
await expect(page.locator('body')).toMatchAriaSnapshot(`
  - banner:
    - heading "Welcome" [level=1]
  - main:
    - button "Sign up"
`);
snapshot
string
Expected ARIA snapshot in YAML format.
options.timeout
number
Maximum time in milliseconds to wait for the assertion to pass.

Generic Assertions

toPass

Retries a callback until it passes without throwing an error.
await expect(async () => {
  const response = await page.request.get('https://api.example.com/status');
  expect(response.status()).toBe(200);
}).toPass();
callback
() => void | Promise<void>
required
Function to retry until it passes.
options.timeout
number
Maximum time in milliseconds to retry.
options.intervals
number[]
Retry intervals in milliseconds.

Negation

All matchers can be negated using .not:
await expect(locator).not.toBeVisible();
await expect(page).not.toHaveURL('/login');

Soft Assertions

Soft assertions don’t terminate test execution:
await expect.soft(locator).toBeVisible();
await expect.soft(page).toHaveTitle('Expected Title');

Polling

Poll a function and make assertions on its return value:
await expect.poll(async () => {
  const response = await page.request.get('https://api.example.com/data');
  return response.status();
}).toBe(200);
callback
() => any
required
Function to poll.
options.timeout
number
Maximum time in milliseconds to poll.
options.intervals
number[]
Polling intervals in milliseconds.

Build docs developers (and LLMs) love