Testing Framework
Organize tests with fixtures, projects, parallelism, and reporters.
Fixtures
Built-in fixtures: page, context, browser, request. Extend with test.extend for custom fixtures—logged-in page, database seed, API client.
Fixtures compose and auto-cleanup in teardown—prefer over beforeEach boilerplate.
export const test = base.extend<{ adminPage: Page }>({
adminPage: async ({ page }, use) => {
await page.goto("/login");
await page.getByLabel("Email").fill("admin@test.com");
await page.getByRole("button", { name: "Sign in" }).click();
await use(page);
},
});
test("admin sees dashboard", async ({ adminPage }) => {
await expect(adminPage.getByText("Admin Dashboard")).toBeVisible();
});Test Organization
Group specs by feature in folders. test.describe groups related cases; test.describe.configure({ mode: "serial" }) when tests share state sequentially.
Tag tests @smoke with grep in CI: --grep @smoke.
test.describe("Checkout", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/cart");
});
test("guest checkout", async ({ page }) => { /* ... */ });
});Parallel Testing
Tests in different files run parallel by default. workers config controls parallelism. fullyParallel: true parallelizes tests within file.
Isolate shared resources—unique user per worker or worker-scoped fixtures.
- Serial mode for tests mutating same global feature flag
- shard: { total, current } splits suite across CI jobs
- Retries: 2 on CI catches transient network flakes—fix root cause still
export default defineConfig({
fullyParallel: true,
workers: process.env.CI ? 4 : undefined,
});Projects and Browsers
projects array defines browser/device matrix—chromium, firefox, webkit, mobile emulation. Each project runs full suite or filtered grep.
Dependency project setup runs auth once, saves storageState, dependent projects reuse logged-in state.
projects: [
{ name: "setup", testMatch: /auth.setup.ts/ },
{
name: "chromium",
use: { ...devices["Desktop Chrome"], storageState: "playwright/.auth/user.json" },
dependencies: ["setup"],
},
]Reporters
list default in terminal; html for interactive report; junit for CI integration; blob for merge-reports across shards.
Custom reporters implement Reporter interface for Slack notifications or metrics push.
reporter: [["html", { open: "never" }], ["junit", { outputFile: "results.xml" }]]