Reference · Cheat Sheet

Automating Playwright — webServer + CI

Make tests start the app themselves and re-run on every push. Testing that just happens.

1 · webServer — let Playwright start your app

Add to playwright.config.ts so you never hand-start a server before tests:

export default defineConfig({
  use: {
    baseURL: 'http://localhost:8000',   // tests can use page.goto('/')
  },
  webServer: {
    command: 'python3 -m http.server 8000',
    cwd: 'practice-app',                  // run the command from here
    url: 'http://localhost:8000',        // wait until this responds
    reuseExistingServer: !process.env.CI, // reuse locally, fresh in CI
    timeout: 60 * 1000,
  },
});

For a real app, command is just your dev command — npm run dev, vite, rails s, etc. — and url is wherever it serves.

With baseURL set, simplify tests: page.goto('/') instead of the full URL. One place to change when the port moves.

2 · GitHub Actions — re-run on every push

Playwright scaffolds this for you, or create .github/workflows/playwright.yml:

name: Playwright Tests
on:
  push:
    branches: [ main ]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v5
        with:
          node-version: lts/*
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

In CI there's no display, so tests run headless automatically. The uploaded playwright-report/ artifact lets you download the HTML report (with screenshots) from any failed run.

3 · The mental model

Push code → GitHub spins up a fresh Linux box → installs deps + browsers → webServer starts your app → tests run headless → red/green on the commit, report attached. You did nothing but push.