Snapshot testing fragility with accessibility violations
Do not snapshot the entire accessibilityScanResults.violations array because it contains implementation details like rendered HTML snippets that change unrelated to the actual violation. Instead, create a fingerprint containing only essential information (rule id and target selectors) and snapshot the fingerprint.
test.beforeAll and test.afterAll for setup and teardown
Use test.beforeAll to create resources before running tests and test.afterAll to clean up resources after all tests have run. Both hooks receive the request fixture for API testing.
Global assertion timeout in C# with NUnit
In C# with NUnit, set a global assertion timeout by calling SetDefaultExpectTimeout(10_000) in a [OneTimeSetUp] method of a PageTest class.
Global assertion timeout in C# with MSTest
In C# with MSTest, set a global assertion timeout by calling SetDefaultExpectTimeout(10_000) in a [ClassInitialize] static method of a PageTest class.
Global assertion timeout in C# with xUnit
In C# with xUnit, set a global assertion timeout by calling SetDefaultExpectTimeout(10_000) in the constructor of a PageTest class.
Per-assertion timeout in Python
In Python, set a timeout for a specific assertion by passing timeout parameter: expect(page.get_by_text("Name")).to_be_visible(timeout=10_000)
Global assertion timeout in Python
In Python, set a global assertion timeout using expect.set_options(timeout=10_000) in conftest.py. This applies to all assertions in the test suite.
Soft assertions in Python
Soft assertions do not terminate test execution when they fail; instead, they mark the test as failed and allow execution to continue. In Python, use expect.soft() to create a soft assertion. Soft assertions require pytest-playwright (or pytest-playwright-asyncio) plugin version 0.8.0 or newer.
Soft assertions example
expect.soft(page.get_by_test_id("status")).to_have_text("Success")
expect.soft(page.get_by_test_id("eta")).to_have_text("1 day")
page.get_by_role("link", name="next page").click()
expect.soft(page.get_by_role("heading", name="Make another order")).to_be_visible()
Custom expect message in Python
In Python, you can specify a custom expect message as a second argument to the expect function: expect(page.get_by_text("Name"), "should be logged in").to_be_visible()
Custom expect message in C#
In C#, you can specify a custom expect message as a second argument to the Expect function: await Expect(Page.GetByText("Name"), "should be logged in").ToBeVisibleAsync();
Default assertion timeout
The default timeout for assertions is 5 seconds (5000 milliseconds).
Per-assertion timeout in C#
In C#, set a timeout for a specific assertion by passing a Timeout property in the options: await Expect(Page.GetByText("Name")).ToBeVisibleAsync(new() { Timeout = 10_000 });
expect() basic assertion structure
To make an assertion in Playwright, call expect(value) and choose a matcher that reflects the expectation. Example: expect(success).toBeTruthy();
GenericAssertions non-retrying methods
GenericAssertions provides the following non-retrying assertion methods: toBe(), toBeCloseTo(), toBeDefined(), toBeFalsy(), toBeGreaterThan(), toBeGreaterThanOrEqual(), toBeInstanceOf(), toBeLessThan(), toBeLessThanOrEqual(), toBeNaN(), toBeNull(), toBeTruthy(), toBeUndefined(), toContain() (for strings and arrays/sets), toContainEqual(), toEqual(), toHaveLength(), toHaveProperty(), toMatch(), toMatchObject(), toStrictEqual(), toThrow().
Asymmetric matchers in expect
Asymmetric matchers that can be nested in other assertions include: expect.any(), expect.anything(), expect.arrayContaining(), expect.arrayOf(), expect.closeTo(), expect.objectContaining(), expect.stringContaining(), expect.stringMatching().
Negating matchers with .not
Add .not before matchers to expect the opposite to be true. Examples: expect(value).not.toEqual(0); await expect(locator).not.toContainText('some text');
Soft assertions do not terminate test
Soft assertions are created using expect.soft() and do not terminate test execution when they fail. Instead, they mark the test as failed and allow execution to continue. Soft assertions only work with the Playwright test runner.
Soft assertions with test.info().errors
Check for soft assertion failures at any point during test execution using expect(test.info().errors).toHaveLength(0) to verify no soft assertion failures occurred.
Custom expect message as second argument
Pass a custom message as the second argument to expect() to provide context about the assertion. Example: await expect(page.getByText('Name'), 'should be logged in').toBeVisible(); The message is shown in reporters for both passing and failing expects.
expect.configure() creates pre-configured instance
Use expect.configure({ timeout: <milliseconds>, soft: <boolean> }) to create a pre-configured expect instance with custom defaults. Example: const slowExpect = expect.configure({ timeout: 10000 }); const softExpect = expect.configure({ soft: true });
expect.poll() for polling synchronous expects
Convert any synchronous expect to an asynchronous polling one using expect.poll(asyncFunctionReturningValue, options). Options include: message (custom expect message, optional), timeout (poll duration in ms, defaults to 5000, pass 0 to disable), intervals (array of wait intervals in ms between polls, defaults to [100, 250, 500, 1000]).
expect.poll() with custom intervals example
Example polling with custom intervals: await expect.poll(async () => { const response = await page.request.get('https://api.example.com'); return response.status(); }, { intervals: [1_000, 2_000, 10_000], timeout: 60_000 }).toBe(200);
expect.soft.poll() for soft polling assertions
Combine expect.soft with expect.poll to perform soft assertions in polling logic, allowing the test to continue even if the assertion inside poll fails: await expect.soft.poll(async () => { ... }).toBe(200);
expect.configure({ soft: true }) chains with expect.poll()
A configured expect instance with soft: true can chain with poll(): const softExpect = expect.configure({ soft: true }); await softExpect.poll(async () => { ... }).toBe(200);
expect.toPass() retries code blocks until passing
Use await expect(async () => { /* code with assertions */ }).toPass() to retry blocks of code until they pass successfully. Supports options: intervals (array of wait intervals in ms, defaults to [100, 250, 500, 1000]), timeout (in ms, defaults to 0). Note that by default toPass has timeout 0 and does not respect custom expect timeout.
expect.toPass() example with timeout and intervals
Example of toPass with custom timeout and intervals: 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 });
expect.extend() for custom matchers
Extend Playwright assertions by providing custom matchers using baseExpect.extend({ matcherName(args, options) { ... } }). Custom matchers must return an object with: pass (boolean flag), message (callback function used when assertion fails), name (matcher name string), expected (expected value), actual (actual value).
Custom matcher implementation structure
A custom matcher function receives the Playwright assertion context (this) with access to this.isNot, this.utils.matcherHint(), this.utils.printExpected(), this.utils.printReceived(). The function should return an object with message (function), pass (boolean), name (string), expected, and actual properties.
mergeExpects() to combine custom matchers from modules
Use mergeExpects() to combine custom expect instances from multiple modules: export const expect = mergeExpects(dbExpect, a11yExpect);
Distinguish Playwright expect from Jest expect library
Do not confuse Playwright's expect with the Jest expect library. The Jest expect library is not fully integrated with Playwright test runner, so use Playwright's own expect instead.