mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-11 21:39:01 +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.
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { expect, test } from './fixtures';
|
|
import { WORKSPACE_NAME } from './global-setup';
|
|
|
|
/**
|
|
* Dashboard smoke test.
|
|
*
|
|
* Confirms that:
|
|
* - A logged-in user lands on a workspace route without redirecting
|
|
* to login (session from the auth fixture is honored).
|
|
* - The seeded workspace's name shows up on the page.
|
|
*
|
|
* If this test goes red, something fundamental in the auth → route →
|
|
* render path is broken; any deeper flow tests would be meaningless
|
|
* until it's green again.
|
|
*
|
|
* Runs in both project viewports; the dashboard should render in both.
|
|
*/
|
|
|
|
test('authed user sees the seeded workspace dashboard', async ({ page, fixture }) => {
|
|
await page.goto(`/${fixture.adminUsername}/${fixture.workspaceSlug}`);
|
|
|
|
// We shouldn't have been bounced to an inline "Sign in" form.
|
|
await expect(page.getByRole('button', { name: /^sign in$/i })).toHaveCount(0);
|
|
|
|
// Workspace name should be visible somewhere — top bar, title, or
|
|
// dashboard header all render it.
|
|
await expect(page.getByText(WORKSPACE_NAME, { exact: false }).first()).toBeVisible();
|
|
});
|