Playwright Testing
This chapter guides you through writing and running your first Playwright test, helping you understand the basic components and execution flow of a test.
Run the example test
After initializing the project, first run the automatically generated example test to make sure everything is working:
# 运行所有测试 npx playwright test
After running it, you will see output similar to the following:
Running 6 tests using 4 workers ✓ 1 [chromium] › tests/example.spec.ts:3:1 › has title (2.1s) ✓ 2 [chromium] › tests/example.spec.ts:10:1 › get started link (1.8s) ✓ 3 [firefox] › tests/example.spec.ts:3:1 › has title (1.9s) ✓ 4 [firefox] › tests/example.spec.ts:10:1 › get started link (1.7s) ✓ 5 [webkit] › tests/example.spec.ts:3:1 › has title (2.3s) ✓ 6 [webkit] › tests/example.spec.ts:10:1 › get started link (2.0s) 6 passed (12s)
From the output, you can see: the tests ran 2 tests on each of 3 browsers, for a total of 6 tests, all passed.
Create your first test file
Cleartests/example.spec.tsthe contents, and let's write a test from scratch.
Example
import { test, expect } from '@playwright/test';
// test(name, callback) defines a test
// name: the test name, displayed in the test report
// The callback parameter { page } is a fixture provided by Playwright
test('Visit the EXAMPLE homepage and check the title', async ({ page }) => {
// Navigate to the specified URL
await page.goto('https://www.example.com/');
// Assertion: the page title contains "EXAMPLE"
await expect(page).toHaveTitle(/EXAMPLE/);
});
Run this test:
npx playwright test tests/first-test.spec.ts
Expected output:
Running 1 test using 1 worker ✓ 1 [chromium] › tests/first-test.spec.ts:4:1 › 访问 EXAMPLE 首页并检查标题 (2.5s) 1 passed (2.5s)
Detailed explanation of the test() function
test()It is the core function of Playwright Test, used to define a test case.
Basic syntax
Example
// test(test name, test function)
test('Descriptive name of the test', async ({ page }) => {
// Operations in the test
await page.goto('https://example.com');
// Assertions in the test
await expect(page).toHaveTitle(/Example/);
});
Parameter description
| Parameter | Type | Description |
|---|---|---|
| First parameter (test name) | string | The descriptive name of the test, displayed in test reports and logs. |
| Second parameter (test function) | async (fixtures) => {} | An asynchronous function containing the actual test logic. |
What is the page fixture?
{ page }It is the one in the test function parametersdestructuring assignmentit extracts from the fixture object provided by Playwrightpage。
pageis aPage objectrepresenting a browser tab.
Each test has its own independentpageinstance:
| fixture | Type | Description |
|---|---|---|
page | Page object | Independent browser tab, used for navigation, actions, and assertions |
context | BrowserContext object | Browser context, manages cookies, storage, etc. |
browser | Browser object | Browser instance, rarely used directly |
request | APIRequestContext object | Used to send HTTP requests (not through the browser) |
The most commonly used ispage, the vast majority of operations are done through it.
page.goto() navigation
page.goto(url)It is one of the most basic operations in Playwright, used to navigate to a specified URL.
Example
await page.goto('https://www.example.com/');
// Navigation with options
await page.goto('https://www.example.com/', {
// Wait until the 'load' event fires (default value)
waitUntil: 'load',
// Operation timeout (milliseconds)
timeout: 30000,
// Referrer (Referer header)
referer: 'https://www.google.com/',
});
waitUntilThe option has three possible values:
| Value | Meaning | Applicable scenario |
|---|---|---|
'load' | Wait for the load event to fire | Default value, suitable for most pages |
'domcontentloaded' | Wait for the DOMContentLoaded event | You only need the page's basic structure to be loaded |
'networkidle' | Wait for the network to be idle (no new requests within 500ms) | When you need to wait for all asynchronous data to be loaded |
In the vast majority of cases, use the default
'load'and that's it. Playwright's automatic waiting mechanism will handle subsequent element availability issues, so there is no need to use'networkidle'。
expect() assertions
expect()It is Playwright's assertion method, used to verify whether test results meet expectations.
Example
await expect(page).toHaveTitle(/EXAMPLE/);
// Page URL assertion
await expect(page).toHaveURL('https://www.example.com/');
// Element visibility assertion
await expect(page.getByText('EXAMPLE')).toBeVisible();
Playwright's assertions have a key feature:automatic retry。
If the assertion condition is not met temporarily, Playwright will keep retrying until the condition is met or a timeout occurs.
This means you don't need to writewaitFororsleepto wait for the page to be ready.
The async/await pattern in tests
All Playwright operations are asynchronous, so test functions must be declared asasync。
All browser operations (goto、click、filletc.) and assertions (expect) must useawaitkeyword(s).
Example
test('Correct example', async ({ page }) => {
await page.goto('https://www.example.com/');
await expect(page).toHaveTitle(/EXAMPLE/);
});
// Incorrect way (missing await)
test('Incorrect example', async ({ page }) => {
page.goto('https://www.example.com/'); // No await!
expect(page).toHaveTitle(/EXAMPLE/); // No await!
});
If you forget to write
await, the test may assert at the wrong time, causing instability or accidental passes. Be sure to add it every time you call the Playwright APIawait。
Understanding test output
Let's look at another test with a failing assertion to understand test output:
Example
import { test, expect } from '@playwright/test';
test('A deliberately failing test', async ({ page }) => {
await page.goto('https://www.example.com/');
// Assert that the title contains non-existent content; this is expected to fail
await expect(page).toHaveTitle(/non-existent text/);
});
After running, the output looks roughly like this:
Running 1 test using 1 worker
✘ 1 [chromium] › tests/fail-demo.spec.ts:4:1 › 一个故意失败的测试 (5.2s)
1 failed
tests/fail-demo.spec.ts:4:1 › 一个故意失败的测试
At the same time, an HTML report will automatically open, showing detailed failure information and error screenshots.
Other extensions