Customer Portal — Testing Strategy
Status: populated Owner: Product Engineering (Frontend) Last updated: 2026-04-18
1. Test Pyramid
┌─────────────┐
│ E2E (10%) │ Playwright — critical flows
├─────────────┤
│ Integration │ Next.js route handler tests
│ (20%) │ MSW-backed server component tests
├─────────────┤
│ Unit (70%) │ Vitest — components, hooks, utils
└─────────────┘
Target coverage: 80% on unit + integration combined.
2. Unit Tests (Vitest + React Testing Library)
Component Tests
- Test rendered output for each major UI state (loading, empty, populated, error).
- Test user interactions: clicks, form submissions, keyboard navigation.
- Mock API calls with MSW — no real network in unit tests.
Key components to test:
| Component | Test focus |
|---|---|
ApiKeyCreateModal | Create flow, raw key display, copy button, close clears state |
MessageLogTable | Renders all status badges, pagination, filter change emits correct URL |
WebhookCreateModal | Create flow, signing secret displayed once, close clears |
TestSmsForm | Validation errors, character counter, submit flow |
BillingUsageCard | Renders all fields; handles missing data gracefully |
Utility / Hook Tests
| Unit | Test focus |
|---|---|
validateE164(number) | Valid numbers, invalid numbers, edge cases |
useMessageFilters() | URL sync, filter state updates |
formatCurrency(amount, currency) | Formatting, zero values, large amounts |
formatDeliveryRate(rate) | 0%, 100%, decimal rounding |
3. Integration Tests (Next.js Route Handlers)
Using @testing-library/react + MSW for route handler tests.
| Route Handler | Test cases |
|---|---|
POST /api/api-keys | Success → returns ApiKeyCreated; upstream 422 → propagates errors; missing auth → 401 |
DELETE /api/api-keys/[keyId] | Success → 204; not found → 404 |
POST /api/send-test | Success → messageId returned; validation error → 422 |
POST /api/auth/refresh | Valid refresh token → new cookie set; invalid token → 401 |
4. E2E Tests (Playwright)
Critical user journeys:
| Journey | Steps | Assertion |
|---|---|---|
| Login → Dashboard | Navigate to /, sign in with test credentials | Dashboard summary cards visible |
| Create API Key | Navigate to /api-keys, click create, fill form, submit | Raw key displayed in modal |
| Send Test SMS | Navigate to /send-test, fill form, submit | Success message with messageId shown |
| View Message Log | Navigate to /messages, apply status filter | Filtered results shown; URL updated |
| Configure Webhook | Navigate to /webhooks, create webhook | Signing secret shown once in modal |
| Billing overview | Navigate to /billing | Invoice table and usage card render |
Playwright config:
- Browser matrix: Chromium, Firefox, WebKit
- Breakpoints tested: 375px (mobile), 1440px (desktop)
- Test account: seeded via API in
globalSetup
5. Accessibility Testing
axe-corevia@axe-core/playwrightruns on each Playwright test.- Zero violations required for WCAG 2.1 AA before merge.
6. Visual Regression (Optional / Post-MVP)
Playwright screenshots of key pages at 375px and 1440px. Compared with Argos CI or Chromatic.
7. CI Pipeline
pnpm test:unit # Vitest unit
pnpm test:coverage # Coverage check (fail if < 80%)
pnpm test:e2e # Playwright (against mock backend)
pnpm lint
pnpm typecheck