Q7 of 42 · Playwright
What is the Playwright Test Runner and how is it different from running with Mocha/Jest?
Short answer
Short answer: `@playwright/test` is Playwright's bundled runner. It's purpose-built for browser tests with built-in fixtures, parallel execution, projects (cross-browser), retries, and a rich HTML report. Mocha/Jest run Playwright but lack browser-specific features like parallel projects and the trace viewer wiring.
Detail
Playwright Test (@playwright/test) is more than a thin wrapper — it's a runner designed around browser automation:
Built-in fixtures: page, browser, context, request are injected into every test. You don't manage browser lifecycle; the runner does.
import { test, expect } from '@playwright/test';
test('home page loads', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/qa\.codes/);
});
Parallel execution by file by default. workers: N in config controls concurrency. Each worker has its own browser context, fully isolated.
Projects for cross-browser/cross-config runs: one config can define chromium, firefox, webkit projects, and a single playwright test invocation runs the whole matrix.
Retries with retries: 2 per config or per-test annotation.
Trace, video, screenshot auto-captured per the policy in use. The HTML report (show-report) integrates them.
Test annotations: test.skip, test.only, test.fixme, test.fail for explicit handling.
Vs Mocha/Jest: those runners can drive Playwright (the playwright library is independent). You lose the bundled fixtures, projects, and report integration; you gain flexibility if your codebase already standardises on one. For most teams the bundled runner wins on out-of-the-box ergonomics.
// EXAMPLE
playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
retries: 2,
workers: 4,
reporter: [['html'], ['list']],
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
],
});