mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-21 01:53:33 +00:00
c8601a2031
* 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.
40 lines
1.4 KiB
JavaScript
40 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
// Cross-platform launcher used by Playwright's `webServer.command`.
|
|
// Wipes the data dir (fresh migrations every run) and then exec's the
|
|
// pad binary. POSIX-only alternatives like `rm -rf && mkdir -p && pad ...`
|
|
// break Windows contributors (cmd.exe / PowerShell don't understand
|
|
// those commands); Node's fs APIs work uniformly on every platform.
|
|
|
|
import { spawn } from 'node:child_process';
|
|
import { mkdirSync, rmSync } from 'node:fs';
|
|
|
|
const dataDir = process.env.PAD_DATA_DIR;
|
|
if (!dataDir) {
|
|
console.error('run-pad: PAD_DATA_DIR is required');
|
|
process.exit(2);
|
|
}
|
|
const binary = process.env.PAD_BINARY;
|
|
if (!binary) {
|
|
console.error('run-pad: PAD_BINARY is required');
|
|
process.exit(2);
|
|
}
|
|
|
|
rmSync(dataDir, { recursive: true, force: true });
|
|
mkdirSync(dataDir, { recursive: true });
|
|
|
|
// Forward stdio so Playwright can wait for the server to bind the port,
|
|
// and so failures surface in the test report. Pass the same env through
|
|
// so PAD_HOST, PAD_PORT, PAD_DATA_DIR, PAD_LOG_LEVEL all reach the binary.
|
|
const child = spawn(binary, ['server', 'start'], { stdio: 'inherit' });
|
|
|
|
const forward = (sig) => () => {
|
|
if (!child.killed) child.kill(sig);
|
|
};
|
|
process.on('SIGINT', forward('SIGINT'));
|
|
process.on('SIGTERM', forward('SIGTERM'));
|
|
|
|
child.on('exit', (code, signal) => {
|
|
if (signal) process.kill(process.pid, signal);
|
|
else process.exit(code ?? 0);
|
|
});
|