Testing
This page is primarily a how-to for running the frontend test suites. The first section maps the layers; the rest focuses on prerequisites, commands, pass signals, and the failure modes that show up most often in the current setup.
The frontend repo uses two test layers:
- Vitest for unit and small component-oriented tests under
src/ - Playwright for API, flow, UI, and SSR regression coverage under
e2e/
Source Paths
| Path | Role |
|---|---|
lumie-frontend/package.json | Test entrypoint scripts |
lumie-frontend/vitest.config.ts | Vitest environment, setup file, include and exclude globs |
lumie-frontend/vitest.setup.ts | Loads @testing-library/jest-dom/vitest |
lumie-frontend/playwright.config.ts | Playwright projects, retries, reporter, and the UI-only webServer |
lumie-frontend/e2e/config/environments.ts | TEST_ENV resolution and monolith base URL mapping |
lumie-frontend/e2e/config/global-setup.ts | Optional backend health probe via CHECK_SERVICES=true |
lumie-frontend/e2e/ssr/auth.setup.ts | SSR login bootstrap and required credential env vars |
Unit Tests With Vitest
vitest.config.ts is configured for:
jsdomas the test environmentvitest.setup.tsto load@testing-library/jest-dom/vitestsrc/**/*.{test,spec}.{ts,tsx}as the include patterne2e/**excluded from unit runs
The current unit suite is focused on shared utilities and parsing boundaries, including tests around:
- custom-domain resolution helpers
- API proxy route logic
- search-param and list-param helpers
- session cache behavior
Testing Library packages are installed, so component tests can use the same setup when added under src/.
End-To-End Tests With Playwright
playwright.config.ts defines multiple projects with different responsibilities.
| Project | Scope |
|---|---|
api | API-level specs under e2e/api |
flows | End-to-end business flows under e2e/flows |
chromium | Browser UI checks under e2e/ui |
ssr-setup | One-time authenticated storage setup for SSR checks |
ssr | SSR regression specs under e2e/ssr |
Notable behavior from the current config:
- only the browser UI project boots
npm run dev, and only whenPW_UI=1 - API and flow projects do not start the Next.js dev server automatically
- traces are collected on first retry
- CI runs with retries enabled and a single worker
Test Directories
| Path | Purpose |
|---|---|
e2e/api/ | Request-level auth and exam API checks |
e2e/flows/ | Cross-feature product flows |
e2e/ui/ | Browser rendering and route-level interaction checks |
e2e/ssr/ | SSR and hydration regression coverage |
e2e/utils/ | Reusable API clients and helpers |
e2e/config/ | Environment selection and global setup or teardown |
Before You Run Tests
Start from the frontend repo root:
cd lumie-frontend
npm install
Prerequisites differ slightly by suite:
| Suite | What must already be running |
|---|---|
test:unit | Nothing beyond local dependencies |
test:e2e:api and test:e2e:flows | Reachable backend at the selected monolith base URL |
test:e2e:ui | Nothing else; playwright.config.ts boots npm run dev automatically because the script sets PW_UI=1 |
test:e2e:ssr | A running frontend at BASE_URL plus a reachable backend and valid login credentials |
Environment Variables
Playwright chooses backend targets through TEST_ENV and e2e/config/environments.ts.
localis the defaultk3sandmirrordsupport cluster-backed runs- the monolith base URL is resolved separately from the older per-service URLs
For new backend-facing E2E flows, e2e/utils/monolith-client.ts reflects the current cookie-based monolith backend. e2e/utils/api-client.ts still exists for older legacy auth specs that target the previous split-service assumptions.
Use these env vars when a suite needs more than the defaults:
| Variable | Used by | Meaning |
|---|---|---|
TEST_ENV | Playwright | Chooses local, docker, k3s, mirrord, or ci; defaults to local |
LUMIE_API_URL | Playwright API and flow suites | Overrides the monolith base URL from e2e/config/environments.ts |
CHECK_SERVICES=true | Playwright global setup | Adds a best-effort GET {baseUrl}/actuator/health probe before tests |
BASE_URL | ssr and ssr-setup projects | Frontend URL for SSR login and route checks; defaults to http://localhost:3000 |
TEST_TENANT_SLUG | e2e/ssr/auth.setup.ts | Tenant slug sent on SSR login requests; defaults to demo |
TEST_CREDS_LOGIN_ID and TEST_CREDS_PASSWORD | ssr-setup | Owner login used to generate e2e/ssr/.auth/owner.json |
TEST_STUDENT_LOGIN_ID and TEST_STUDENT_PASSWORD | ssr-setup | Optional student login for dashboard SSR checks |
Run The Unit Suite
cd lumie-frontend
npm run test:unit
Expected pass signal:
vitest runexits0- the summary reports all selected
src/**/*.{test,spec}.{ts,tsx}files passed e2e/**is not part of the run
Useful quick loop:
cd lumie-frontend
npm run test:unit:watch
Run API And Flow E2E Suites
Use the monolith base URL selected by TEST_ENV or LUMIE_API_URL.
cd lumie-frontend
TEST_ENV=local npm run test:e2e:api
TEST_ENV=local npm run test:e2e:flows
Expected pass signal:
- Playwright exits
0 - the list reporter ends with all selected specs passed
- if
CHECK_SERVICES=true, global setup logs the resolved monolith URL before the tests start
Run Browser UI E2E Checks
test:e2e:ui is the only frontend test script that starts next dev automatically. playwright.config.ts injects dummy NEXT_PUBLIC_API_URL and NEXT_PUBLIC_API_BASE values because the current UI project is render-only.
cd lumie-frontend
npm run test:e2e:ui
Expected pass signal:
- Playwright starts
npm run devautomatically because the script exportsPW_UI=1 - the
chromiumproject exits0 - the HTML report is available afterward through
npm run test:e2e:report
Run SSR Regression Checks
The ssr project does not start the frontend for you. It depends on the ssr-setup project, which logs in through /api/v1/login and writes storage state files under e2e/ssr/.auth/.
cd lumie-frontend
npm run dev
In a second shell:
cd lumie-frontend
BASE_URL=http://localhost:3000 \
TEST_TENANT_SLUG=demo \
TEST_CREDS_LOGIN_ID=<owner-login-id> \
TEST_CREDS_PASSWORD=<owner-password> \
TEST_STUDENT_LOGIN_ID=<student-login-id> \
TEST_STUDENT_PASSWORD=<student-password> \
npm run test:e2e:ssr
Expected pass signal:
ssr-setupcreatese2e/ssr/.auth/owner.json- student storage is created too unless the configured tenant intentionally skips the student suite with the built-in
401skip path - the Playwright summary ends with the
ssrproject passing and exit code0
Common Failures
| Symptom | Likely cause | What to check |
|---|---|---|
| API or flow suite hangs or immediately fails on connection errors | The backend monolith is not reachable at the resolved base URL | Confirm TEST_ENV, LUMIE_API_URL, and optionally rerun with CHECK_SERVICES=true |
test:e2e:ui waits on port 3000 | Another frontend dev server already owns the port, or next dev failed to boot | Stop the other process or inspect the webServer startup logs from Playwright |
ssr-setup fails with 401 for the owner | TEST_CREDS_LOGIN_ID or TEST_CREDS_PASSWORD is wrong for TEST_TENANT_SLUG | Re-run with the correct tenant-specific staff account |
| Student SSR tests are skipped | The configured tenant does not contain the default student seed account | Set TEST_STUDENT_LOGIN_ID and TEST_STUDENT_PASSWORD explicitly |
| Unit tests unexpectedly miss a file | The spec is outside src/**/*.{test,spec}.{ts,tsx} | Move the test under src/ or adjust the repo config in code first |