Playwright e2e: foundation + smoke suite #150
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol#150
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Carol has no browser-level e2e today — coverage stops at the vitest API/DB/unit layer. Nothing exercises the assembled product (the Expo RN-Web SPA served by the Next.js API against a real DB) the way a user does, so regressions in routing, auth redirects, or the SPA↔API contract can slip through CI green.
This umbrella issue covers standing up a real Playwright harness that boots the whole app and drives Chromium, plus a thin smoke path that proves the stack end to end. Broader coverage is split into child tickets.
What this slice delivers (closed by the foundation PR)
apps/e2e/workspace (@carol/e2e, private) holding the Playwright harness — kept out of@carol/api/@carol/clientso browser deps don't leak into the shipped packages.webServer: a build-awarescripts/serve.shbuilds the client web bundle (pnpm -F @carol/client export:web) and the API (pnpm -F @carol/api build) if missing, then runspnpm -F @carol/api startagainst a throwaway file-backed SQLite underapps/e2e/.tmp/(wiped each boot), withSPA_BUNDLE_PATHpointed atapps/client/dist. Readiness gate isGET /api/health. A fresh DB per boot means the firstregisterbecomes admin and lands authenticated — a clean entry with no invite/approval. (A file, not:memory::next startmigrates from the instrumentation hook, whose module graph is separate from the API routes in a production build, so a:memory:DB isn't shared across the two.)tests/smoke.spec.ts), ordered: register auniqueEmail()user → land authenticated at/notes→ assert the sidebar renders and navigate ≥2 nav items, asserting the route changes → create a note and assert it appears → log out → assert redirect to/login→ log back in and assert authenticated.e2ejob in.forgejo/workflows/pr.yml(SQLite + Chromium) that builds the bundle, installs Chromium, boots the app, and runs the smoke spec on every PR.Conventions chosen
getByPlaceholder/getByLabel; buttons viagetByRole('button', { name }); nav by visible label text. Button/nav names are imported from the i18n catalog (packages/i18n/messages/en.json) throughfixtures/strings.ts, never hardcoded — robust to copy changes and aligned with the no-hardcoded-strings rule.testIDs. RN-Web mapstestID→data-testid. Added only where a role/name is genuinely ambiguous (the note list row). Primary action buttons that lacked anaccessibilityRolegotaccessibilityRole="button"so they expose a button role to assistive tech and Playwright alike — an accessibility win, not test-only scaffolding.actions/checkout+actions/setup-node,corepack enable,pnpm install --frozen-lockfile --ignore-scripts,pnpm rebuild). SQLite + Chromium only.Acceptance criteria
apps/e2e/workspace with a Playwright config that boots the assembled app and gates readiness on/api/health.testIDs are minimal and justified.e2eCI job on PRs (SQLite + Chromium) that builds the bundle and runs the spec.Follow-ups (child tickets)
storageStatefixture.This issue stays the umbrella; the foundation PR closes it.
(STUB) Playwrite teststo Playwright e2e: foundation + smoke suite