The README had two TODO placeholders for screenshots that have been
sitting commented-out since the project started. With the launch
imminent, fill them in.
Captures:
- docs/screenshots/dashboard.png — workspace dashboard with Active
Work cards, Active Plans (v0.2 — Collaboration with progress),
collection summaries, recent activity.
- docs/screenshots/board.png — tasks board view, four columns
(Open / In-Progress / Done / Cancelled) with realistic task cards.
- docs/screenshots/list.png — list view (not currently referenced
from the README, but kept as part of the reproducible asset set).
Reproducibility:
web/e2e/screenshots.spec.ts is a gated Playwright spec (skipped
unless PAD_SCREENSHOTS=1) that uses the existing e2e fixture
infrastructure to:
1. Spin up a fresh pad binary against a clean data dir.
2. Bootstrap an admin + workspace seeded with the startup template.
3. Add a realistic demo dataset (1 active plan, 7 tasks across
open/in-progress/done with mixed priorities, 2 ideas).
4. Navigate + capture three views at 1440x900.
To regenerate:
make build
cd web && PAD_SCREENSHOTS=1 PAD_E2E_PORT=17801 \\
npx playwright test screenshots --project=desktop-chromium
Notes:
- Table view (?view=table) was originally in scope but the URL
parser only accepts list/board today; setting via toggle would
require localStorage manipulation. Three screenshots already
cover the README's needs; revisit if/when table view becomes
URL-reachable.
- Dark/light variants were also in scope but the web UI is dark-
mode-only at present, so the captures are dark-only.
Refs: TASK-673
* test(e2e): Playwright smoke test infrastructure + 2 dashboard tests (TASK-689)
Option A of TASK-689: land the test infrastructure and a minimal smoke
test on both mobile and desktop viewports. Broader flow coverage (board
view drag, item detail, comments, mobile hamburger, BottomSheet
regression guard) is tracked as TASK-733.
Infrastructure
--------------
- web/playwright.config.ts: two projects (desktop-chromium, mobile-
chromium via Pixel 7), reporter list+html, trace/video/screenshot
retained on failure, webServer that wipes + recreates the data dir
then runs the pad binary. Paths anchored to the config file's
directory so runs are cwd-invariant.
- web/e2e/global-setup.ts: bootstraps admin via POST /auth/bootstrap,
logs in, creates the e2e workspace, mints a user-scoped API token,
and persists the token + resolved admin username to fixture.json.
- web/e2e/fixtures.ts: extends base test so every BrowserContext
automatically gets Authorization: Bearer <token>. Uses a token
rather than a session cookie because sessions are User-Agent bound
in middleware_auth.go and a node-minted session would be rejected
by a Chromium UA.
Tests
-----
- web/e2e/dashboard.spec.ts: a logged-in user lands on the seeded
workspace, no login form is rendered, and the workspace name
appears on the page. Runs in both project viewports.
CI
--
- New `e2e` job in .github/workflows/ci.yml: builds web UI + binary,
installs Playwright chromium with OS deps, runs the suite, and
uploads the HTML report as an artifact on failure. Timeout capped
at 10 minutes (suite itself runs in ~4s today).
Local run (in mcr.microsoft.com/playwright:v1.59.1-noble): 2 passed
in 4.1s.
Parent: PLAN-644.
Follow-up: TASK-733 for broader flow coverage (Option B in the
original ship plan).
* fix(e2e): persist server-returned workspace slug instead of the constant (TASK-689)
Addresses Codex P2 on PR #225. When Playwright's `reuseExistingServer:
true` (local dev), a re-run of globalSetup hits `POST /api/v1/workspaces`
against a DB that already has `e2e`. The server uniquifies the slug
(`e2e` → `e2e-2` → …) and returns the uniquified value, but the old
code wrote `WORKSPACE_SLUG` (the constant) to fixture.json. Tests
then navigated to /e2e-admin/e2e — which might still exist from a
previous run with stale state — instead of /e2e-admin/e2e-2, missing
regressions in freshly-seeded content.
Fix: read `slug` back from the workspace-create response and use that
when writing fixture.json. Local re-runs now always point at the
workspace this run actually created.
Parent: PLAN-644.
* fix(e2e): cross-platform webServer bootstrap via Node wrapper (TASK-689)
Addresses Codex P2 on PR #225: `rm -rf && mkdir -p && pad server start`
in webServer.command is POSIX-only. Windows contributors on cmd.exe or
PowerShell can't run `npm run test:e2e` at all — the e2e suite becomes
Linux/macOS-only, defeating the "CI parity" goal.
Fix: extract the wipe-and-exec logic into web/e2e/run-pad.mjs. Node's
fs.rmSync / mkdirSync / child_process.spawn are uniform across
platforms, and the wrapper forwards SIGTERM/SIGINT so Playwright's
teardown still cleanly kills the child on suite exit.
Local re-run in mcr.microsoft.com/playwright:v1.59.1-noble: 2 passed.
Parent: PLAN-644.