UXDL Docs

Setup & Installation

Install Playwright, configure projects, and run your first test.

Playwright is our E2E testing framework. It runs tests in real browsers and supports Chromium, Firefox, and WebKit.

Prerequisites

  • Node.js 20 LTS, pnpm
  • Application running locally (pnpm dev) or a deployed Alpha/Beta URL

Install

From the frontend project root:

bash
pnpm add -D @playwright/test
pnpm exec playwright install

The playwright install command downloads browser binaries. Commit playwright.config.ts — do not commit browser binaries.

Project structure

plaintext
e2e/
├── fixtures/
│   └── auth.fixture.ts      # Shared login helper
├── pages/
│   ├── login.page.ts        # Page object models
│   └── dashboard.page.ts
├── specs/
│   ├── auth.spec.ts
│   └── checkout.spec.ts
└── playwright.config.ts

Configuration

typescript
// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
 
export default defineConfig({
  testDir: "./e2e/specs",
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [["html", { open: "never" }], ["list"]],
 
  use: {
    baseURL: process.env.PLAYWRIGHT_BASE_URL ?? "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"] } },
    { name: "webkit", use: { ...devices["Desktop Safari"] } },
  ],
 
  webServer: process.env.CI
    ? undefined
    : {
        command: "pnpm dev",
        url: "http://localhost:3000",
        reuseExistingServer: !process.env.CI,
        timeout: 120_000,
      },
});

Environment variables

dotenv
# Local
PLAYWRIGHT_BASE_URL=http://localhost:3000
 
# Alpha preview (CI sets this from PR deploy URL)
PLAYWRIGHT_BASE_URL=https://alpha-142.preview.company.com
 
# Beta smoke tests
PLAYWRIGHT_BASE_URL=https://beta.company.com
 
# Test user credentials (vault — never commit)
E2E_TEST_EMAIL=test-user@company.com
E2E_TEST_PASSWORD=...

First test

typescript
// e2e/specs/smoke.spec.ts
import { test, expect } from "@playwright/test";
 
test("homepage loads", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/UXDL Docs/);
});
 
test("health endpoint responds", async ({ request }) => {
  const res = await request.get("/api/health");
  expect(res.ok()).toBeTruthy();
  const body = await res.json();
  expect(body.status).toBe("ok");
});

Run tests

bash
# Run all E2E tests (starts dev server automatically)
pnpm exec playwright test
 
# Run with UI mode (interactive debugging)
pnpm exec playwright test --ui
 
# Run a single spec
pnpm exec playwright test e2e/specs/auth.spec.ts
 
# Run headed (see the browser)
pnpm exec playwright test --headed
 
# View last HTML report
pnpm exec playwright show-report

Add scripts to package.json:

json
{
  "scripts": {
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui",
    "test:e2e:report": "playwright show-report"
  }
}

Verify setup

  1. pnpm exec playwright install completes without errors.
  2. pnpm dev is running (or webServer starts it automatically).
  3. pnpm test:e2e passes the smoke spec.
  4. HTML report opens with pnpm test:e2e:report.

Official documentation