Smoke tests (default on PRs):
npx playwright test --project=chromium --reporter=lineFull suite (manual / on-demand):
FULL_E2E=1 npx playwright test --project=chromium --reporter=lineThe full suite includes a11y, visual, offline, and large-flow tests. Set FULL_E2E=1 to include these in a local run or trigger the E2E Full (manual) workflow in GitHub Actions.
Quarantine
Add globs to .ci/quarantine.txt (one per line) to skip unstable specs from all runs.
For Playwright smoke/flow tests we expose a small E2E-only button on /island/:biomeId:
- Append
?e2e=1to the URL or setlocalStorage.E2E_CONTROLS = "1"to reveal a Complete lesson button. - This control triggers
completeLesson(biome)and causes the store to persist and dispatchisland-progress-updated. - It is not visible in production UX unless explicitly enabled for tests.
Example (Playwright):
await page.goto(`${BASE_URL}/island/forest?e2e=1`);
await page.getByTestId("complete-lesson").click();/lesson loads a mocked "today's lesson" and links to /activity/:id?e2e=1.
On the activity page, enabling E2E (via ?e2e=1 or localStorage.E2E_CONTROLS="1") reveals Complete lesson used by tests.
Build once and serve mock APIs + static app on the same origin (127.0.0.1:4173):
npm run dev:mock:full
# then open http://127.0.0.1:4173/__seed (sets E2E_CONTROLS=1) -> redirects to /islandManual Step Required: Add these scripts to package.json:
"preview": "vite preview --port 4173 --host 127.0.0.1 --strictPort",
"dev:mock": "node server/dev-mock-server.cjs",
"dev:mock:full": "npm-run-all -s build dev:mock"Endpoints served locally:
GET /api/progress/island(reads e2e/fixtures/island-progress.json if present, else fallback)GET /api/lessons/today→{ id: "les-001", displayTitle: "Patterns", firstActivityId: "act-001", firstActivityTitle: "Patterns Intro" }
Tip: Use /__seed once per fresh session to enable biome E2E controls.