- Docs
- Delivery
- Testing strategy
#Testing strategy
#Layers
| Layer | Tool | Where | Covers |
|---|
| Backend unit + feature | Pest (V8 rule: a test for every endpoint), Http::fake for OSS/providers/gateways | sa-central-api-2 | Validation, policies (allow and deny), organization isolation, plan limits, payment verification, OSS error mapping |
| Frontend unit | Vitest (to be scaffolded) | frontend-2 | API client (error normalisation, retry rules), formatters, permission map, zod schemas, stores |
| Component | Vitest + Testing Library | frontend-2 | Forms, tables, states (loading/empty/error) |
| End-to-end | Playwright (to be scaffolded) | frontend-2 + a test backend | User flows, mobile/desktop, themes, locales |
| Accessibility | axe (Playwright) | every page | WCAG 2.2 AA, both themes |
| Contract | Recorded OSS responses (fixtures from API_REFERENCE.md / a test panel) | backend | The OSS client keeps working as OSS changes |
| Live smoke | A real OSS test panel (e.g. the .79 test server) | staging | Connect / health / details / disconnect with a real key |
#Per-module checklist
Each module is tested for: happy path · validation · permission (allowed + denied) · API error · loading · empty · network failure · mobile · desktop · dark mode · language · session expiration.
| Module | Key scenarios |
|---|
| Authentication | Register → verify → login. Unverified / banned / wrong password. 2FA (all 3 methods, 5-try limit, resend). IP approval. OAuth new/existing/linked. Reset logs out devices. Refresh rotation. Logout clears everything |
| Organizations | Create first (owner + roles). Rename. Delete refusals (main, only, has servers). Switch reloads every scoped list. Two tabs. Removed while viewing |
| Plans | Catalog only from the API (no hard-coded values: a test fails if a price constant appears in the bundle Assumption). Current plan. Ineligible plans disabled |
| Subscription | Each state's UI (trial, active, pending, cancelled, expired, failed, lifetime). Cancel/resume. Renew. Expired blocks actions except delete |
| Billing | Top-up redirect + return with success/failure/pending (gateway mocked). Never shows success before backend confirmation. Invoices list/download. Auto-recharge form |
| Roles | Create (≥ 1 permission). System roles read-only. Delete rules. Matrix none/view/manage |
| Members | Invite existing/new email. Duplicate. Resend. Cancel. Accept. Change role. Remove (owner only, not self) |
| Dashboard | Each widget's loading/empty/error alone. One server offline doesn't break the page. Charts in both themes. No fake data |
| Servers | Connect: valid, invalid key, offline, duplicate, version, limit. Status changes (revoked key → unauthorized). Disconnect message about revoking on the panel |
| Server details | Each section with a live OSS fixture. Permission per OSS area. Offline state. Polling stops when hidden |
| Providers | OAuth + token connect. Regions/sizes. Create VPS job states. Installer gets --stack + CENTRAL_TOKEN |
| Blueprints | CRUD. Deploy run polling. completed:false with failed steps. Add-on missing/no licence |
| Audit log | Entry written for every mutation (backend). Filters. Deleted actor still readable. Server actions attributed to the person |
#Matrix for E2E
| Dimension | Values |
|---|
| Viewports | 320, 375, 768, 1024, 1280, 1440 (+1920 smoke) |
| Themes | light, dark |
| Locales | en (full), de + ja (layout/overflow), all 8 (smoke on key pages) |
| Roles | owner, admin, custom read-only |
| Browsers | Chromium (all), WebKit + Firefox (smoke) |
#Recommended automated tests (first set)
auth.spec: login states + session expiry redirect with next.
org-switch.spec: switching changes every list. Detail pages go back to the list.
permissions.spec: menu visibility + 403 states for a read-only role.
server-connect.spec: all connect failure codes (backend faked).
billing-return.spec: pending → success polling, failure, tampered query parameters ignored.
i18n.spec: no missing keys, no hard-coded strings (lint rule), locale switch keeps the path.
a11y.spec: axe on every route in both themes.
responsive.spec: no horizontal scroll at 320 px on every route.
Definition of done per feature (project rule): build passes, lint passes, tests green, i18n keys only, no secrets, diff re-read.