← Back to Playwright Mastery
Intermediate20 min read

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" }]]

Get In Touch


Ready to discuss your next project? Drop me a message.