This page documents the expect assertion API in @playwright/test: how it dispatches to assertion classes, what each assertion class provides, how snapshot-based matchers work, and how the system is configured. For details about how test fixtures (page, context, etc.) are set up before assertions run, see Fixtures and Lifecycle. For how assertion failures are surfaced in the runner pipeline, see Test Execution Architecture.
The expect function exported from @playwright/test is the central entry point for all assertions. It inspects the type of its argument at the TypeScript level and dispatches to one of four specialized assertion interfaces: LocatorAssertions, PageAssertions, APIResponseAssertions, or GenericAssertions.
Playwright-specific assertions (LocatorAssertions, PageAssertions) are web-first: they automatically retry until the condition is met or a timeout expires. Generic assertions are synchronous and fail immediately.
The public surface is defined in packages/playwright/types/test.d.ts and utils/generate_types/overrides-test.d.ts
expect Entry PointThe Expect<ExtendedMatchers> type is defined in utils/generate_types/overrides-test.d.ts505-517
export const expect: Expect<{}>
Expect is callable and has several static methods:
| Call form | Description |
|---|---|
expect(value) | Standard assertion; throws on first failure |
expect.soft(value) | Soft assertion; records failure but continues test |
expect.poll(fn) | Retries a callback until its inner assertions pass |
expect.extend(matchers) | Registers custom matchers; returns a new Expect |
expect.configure(config) | Returns a new Expect with overridden timeout, soft, or message |
expect.not | Asymmetric matchers namespace (negated) |
Assertion Dispatch Flow
Sources: utils/generate_types/overrides-test.d.ts413-496
AllowedGenericMatchers is a restricted subset of GenericAssertions — only toBe, toBeDefined, toBeFalsy, toBeNull, toBeTruthy, and toBeUndefined — so that web-first assertion targets do not accidentally expose synchronous generic matchers in an unexpected context.
Class and Type Relationships
Sources: utils/generate_types/overrides-test.d.ts413-517
LocatorAssertions is the most frequently used assertion interface. All methods are asynchronous and retry until the condition holds or the timeout expires. The default timeout is 5000 ms (configurable via TestConfig.expect.timeout).
Defined via interface in utils/generate_types/overrides-test.d.ts408-411 with full documentation in docs/src/api/class-locatorassertions.md
| Method | Description |
|---|---|
toBeVisible(options?) | Element is attached to DOM and visible |
toBeHidden(options?) | Element is not visible or not attached |
toBeAttached(options?) | Element is connected to Document or ShadowRoot |
toBeInViewport(options?) | Element intersects viewport per IntersectionObserver |
| Method | Description |
|---|---|
toBeChecked(options?) | Checkbox/radio is in checked state; indeterminate flag available |
toBeDisabled(options?) | Element is disabled via attribute or aria-disabled |
toBeEnabled(options?) | Element is not disabled |
toBeEditable(options?) | Element is editable (not readonly, not disabled) |
toBeFocused(options?) | Element has focus |
toBeEmpty(options?) | Input has no value, or element has no text |
| Method | Description |
|---|---|
toHaveText(expected, options?) | Full text matches string, RegExp, or array thereof |
toContainText(expected, options?) | Text contains the expected substring or pattern |
toHaveAttribute(name, value?, options?) | Attribute exists and optionally matches value |
toHaveClass(expected, options?) | className matches string, RegExp, or list |
toContainClass(expected, options?) | classList contains the specified class(es) |
toHaveId(id, options?) | id attribute matches |
toHaveCSS(name, value, options?) | Computed CSS property matches |
toHaveCSS(values, options?) | Multiple computed CSS properties match |
toHaveJSProperty(name, value, options?) | JS property on element matches via deep equality |
toHaveValue(value, options?) | input/textarea/select value matches |
toHaveValues(values, options?) | <select multiple> selected options match |
toHaveCount(count, options?) | Locator resolves to exactly N elements |
toHaveRole(role, options?) | Computed ARIA role matches |
| Method | Description |
|---|---|
toHaveAccessibleName(name, options?) | Computed accessible name matches |
toHaveAccessibleDescription(desc, options?) | Computed accessible description matches |
toHaveAccessibleErrorMessage(msg, options?) | aria-errormessage value matches |
| Method | Description |
|---|---|
toMatchAriaSnapshot(expected?, options?) | ARIA snapshot comparison (text-based) |
toHaveScreenshot(name?, options?) | Pixel-level screenshot comparison |
Sources: docs/src/api/class-locatorassertions.md500-2000
PageAssertions applies to Page objects. Defined in docs/src/api/class-pageassertions.md
| Method | Description |
|---|---|
toHaveURL(url, options?) | Page URL matches string, RegExp, URLPattern, or predicate |
toHaveTitle(title, options?) | Page <title> matches string or RegExp |
toHaveScreenshot(name?, options?) | Full-page pixel comparison; waits for stability |
toHaveURL also accepts a predicate (url: URL) => boolean for complex query string verification.
Sources: docs/src/api/class-pageassertions.md130-360
APIResponseAssertions applies to APIResponse objects from page.request or apiRequestContext. Defined in docs/src/api/class-apiresponseassertions.md
| Method | Description |
|---|---|
toBeOK() | Status code is in range 200–299 |
The .not modifier inverts: expect(response).not.toBeOK() checks for a non-2xx status.
Sources: docs/src/api/class-apiresponseassertions.md74-105
GenericAssertions<R> provides synchronous value-based assertions, similar to Jest's expect. These do not retry. Defined in utils/generate_types/overrides-test.d.ts354-380 and docs/src/api/class-genericassertions.md
| Method | Description |
|---|---|
toBe(expected) | Strict identity via Object.is |
toEqual(expected) | Deep equality; ignores undefined properties |
toStrictEqual(expected) | Deep equality including type checking |
toBeCloseTo(expected, numDigits?) | Approximate float equality |
| Method | Description |
|---|---|
toBeDefined() | Value is not undefined |
toBeUndefined() | Value is undefined |
toBeNull() | Value is null |
toBeTruthy() | Value is truthy |
toBeFalsy() | Value is falsy |
toBeNaN() | Value is NaN |
toBeInstanceOf(expected) | Value is instanceof given class |
| Method | Description |
|---|---|
toBeGreaterThan(expected) | value > expected |
toBeGreaterThanOrEqual(expected) | value >= expected |
toBeLessThan(expected) | value < expected |
toBeLessThanOrEqual(expected) | value <= expected |
| Method | Description |
|---|---|
toContain(expected) | String contains substring, or Array/Set contains item |
toContainEqual(expected) | Array/Set contains item with matching deep content |
toHaveLength(expected) | .length property equals expected |
toHaveProperty(keyPath, value?) | Object has property at dotted path |
toMatch(expected) | String matches RegExp or string |
toMatchObject(expected) | Object contains expected fields (subset check) |
| Method | Description |
|---|---|
toThrow(error?) | Function throws; optionally matches message/type |
toThrowError(error?) | Alias for toThrow |
expect exposes asymmetric matchers as properties for use inside toEqual and toMatchObject:
| Matcher | Description |
|---|---|
expect.any(constructor) | Matches any instance of the given class |
expect.anything() | Matches anything except null/undefined |
expect.arrayContaining(arr) | Array contains the given items |
expect.arrayOf(sample) | Array where all items match the sample |
expect.objectContaining(obj) | Object has at least the given keys |
expect.stringContaining(str) | String contains substring |
expect.stringMatching(pattern) | String matches RegExp or string |
expect.closeTo(number, precision?) | Approximate float match |
Sources: utils/generate_types/overrides-test.d.ts343-380 docs/src/api/class-genericassertions.md
Snapshot matchers compare the current state against a stored reference. If no reference exists on first run, it is created. Subsequent runs compare against the stored file.
Snapshot Assertion Lifecycle
The --update-snapshots CLI flag causes the actual value to overwrite the stored reference rather than failing.
Sources: tests/playwright-test/golden.spec.ts35-92 tests/playwright-test/to-have-screenshot.spec.ts62-125
toMatchSnapshot(name?, options?)Applies to any value: strings, Buffers, and PNG image buffers. Part of SnapshotAssertions. Text content is diffed as strings; image buffers use pixelmatch for pixel-level comparison.
Snapshot files are stored under <testFile>-snapshots/ by default. The path is controlled by snapshotPathTemplate in TestProject/TestConfig.
Configuration options (per-call or global):
| Option | Description |
|---|---|
threshold | YIQ color-space difference tolerance (0–1, default 0.2) |
maxDiffPixels | Maximum number of differing pixels |
maxDiffPixelRatio | Maximum ratio of differing pixels (0–1) |
toHaveScreenshot(name?, options?)Available on both Page and Locator. Waits for two consecutive screenshots to be identical (stable), then compares against the stored reference. CSS animations are disabled by default.
Configuration options (in addition to snapshot options):
| Option | Description |
|---|---|
animations | "disabled" (default) or "allow" |
caret | "hide" (default) or "initial" |
scale | "css" (default) or "device" |
fullPage | Capture the full scrollable page (page only) |
clip | Clip rectangle |
mask | Locators to mask with maskColor |
stylePath | CSS file(s) to inject before screenshotting |
omitBackground | Transparent background (locator only) |
On failure, the runner writes three artifact files to test-results/:
<name>-actual.png — captured screenshot<name>-expected.png — stored reference<name>-diff.png — visual diff imageWhen no reference yet exists, <name>-previous.png and <name>-diff.png are written instead.
Sources: docs/src/api/class-pageassertions.md130-243 tests/playwright-test/to-have-screenshot.spec.ts33-320
toMatchAriaSnapshot(expected?, options?)Available on Locator. Captures the ARIA accessibility tree as a YAML-like text snapshot and compares it. Reference files use .aria.yml or similar extensions, stored via the snapshotPathTemplate path.
Can be called with an inline string for in-code snapshots, or without arguments to compare against a stored file.
Sources: docs/src/api/class-locatorassertions.md482-497
Snapshot file locations are controlled by TestProject.snapshotPathTemplate (or TestConfig.snapshotPathTemplate). Assertion-specific overrides exist at:
TestConfig.expect.toHaveScreenshot.pathTemplateTestConfig.expect.toMatchAriaSnapshot.pathTemplateAvailable tokens:
| Token | Meaning |
|---|---|
{testDir} | Resolved test directory |
{testFilePath} | Relative path from testDir to the test file |
{testFileDir} | Directory portion of testFilePath |
{testFileName} | Test file name with extension |
{testName} | Sanitized test title (including describe blocks) |
{projectName} | Sanitized project name |
{arg} | Name argument passed to the assertion, minus extension |
{ext} | File extension including leading dot |
{platform} | process.platform value |
{snapshotDir} | Resolved TestProject.snapshotDir |
Sources: packages/playwright/types/test.d.ts506-557 tests/playwright-test/to-have-screenshot.spec.ts191-213
.notInverts the assertion condition. Available on all assertion types.
await expect(locator).not.toBeVisible();
await expect(response).not.toBeOK();
.soft(value)Records the failure but does not stop test execution. All soft failures collected during the test are reported at the end.
expect.soft(value).toBe(expected);
Soft mode can also be enabled globally for a configured Expect instance using expect.configure({ soft: true }).
.poll(fn, options?)Takes a function (sync or async) and retries it, running inner assertions until they pass or timeout expires. Returns PollMatchers which provides only GenericAssertions and SnapshotAssertions (not web-first assertions).
await expect.poll(async () => {
const response = await page.request.get('/api/status');
return response.status();
}).toBe(200);
Options: timeout and intervals (retry interval schedule in ms).
.resolves / .rejectsUnwrap a Promise before applying the matcher. .resolves expects the promise to fulfill; .rejects expects it to reject.
Sources: utils/generate_types/overrides-test.d.ts481-517
toPass — Retrying Arbitrary Assertion BlocksFunctionAssertions exposes toPass, which wraps a callback and retries the entire block until all assertions inside it pass or the timeout expires.
await expect(async () => {
const response = await page.request.get('https://api.example.com');
expect(response.status()).toBe(200);
}).toPass({
intervals: [1_000, 2_000, 10_000],
timeout: 60_000,
});
By default toPass does not inherit the global assertion timeout; it must be set explicitly. Configurable globally via TestConfig.expect.toPass.timeout and TestConfig.expect.toPass.intervals.
Sources: utils/generate_types/overrides-test.d.ts382-404 docs/src/test-api/class-testconfig.md71-93
expect.extend(matchers) registers additional matcher functions. Each matcher receives this: ExpectMatcherState and the receiver value, plus any additional arguments.
The ExpectMatcherState type (utils/generate_types/overrides-test.d.ts453-469) provides:
isNot: boolean — whether .not was appliedpromise: 'rejects' | 'resolves' | '' — promise modifier appliedtimeout: number — current timeout settingutils: ExpectMatcherUtils — formatting helpersThe matcher must return MatcherReturnType (utils/generate_types/overrides-test.d.ts471-479):
| Field | Description |
|---|---|
pass: boolean | Whether the assertion passed (before .not inversion) |
message: () => string | Failure message generator |
name? | Matcher name for display |
expected? | Expected value for diff display |
actual? | Actual value for diff display |
log? | Additional log lines |
timeout? | Timeout to report |
ExpectMatcherUtils (lines 443-451) provides helpers: matcherHint, printDiffOrStringify, printExpected, printReceived, diff, stringify.
Multiple Expect instances with different custom matchers can be merged using mergeExpects(e1, e2, ...).
Sources: utils/generate_types/overrides-test.d.ts443-517
The expect block under TestConfig (or TestProject) controls assertion behavior globally or per-project. Defined in packages/playwright/types/test.d.ts179-294
Sources: packages/playwright/types/test.d.ts179-294 docs/src/test-api/class-testconfig.md71-93
TestConfig.expect.timeout.timeout option.expect.configure({ timeout: n }) creates a scoped Expect with a different default.toPass has its own independent timeout that does not inherit from expect.timeout unless explicitly set.timeout (default 30 s) acts as an outer bound; an assertion timeout that outlasts the test timeout will be cut short.Setting TestProject.ignoreSnapshots: true skips all snapshot assertions (toMatchSnapshot, toHaveScreenshot, toMatchAriaSnapshot) for that project. Useful for running cross-browser tests where visual output differs.
Sources: packages/playwright/types/test.d.ts357-358 docs/src/test-api/class-testproject.md141-172
Sources: utils/generate_types/overrides-test.d.ts packages/playwright/types/test.d.ts docs/src/api/class-locatorassertions.md docs/src/api/class-pageassertions.md docs/src/api/class-apiresponseassertions.md docs/src/api/class-genericassertions.md docs/src/api/class-playwrightassertions.md
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.