- Backend: payment_sessions + pairing_failures tables; payment.service.js and pairing-failure.service.js (new); rewritten pairing.service.js (payment-gated blast + targeted "Curhat lagi" + cancel + fallback); rewritten extension.service.js (data-driven auto-approve with offline safeguard, charge-at-approval); pricing.service.js (extension tiers without free trial); mitra-status.service.js (countAvailableMitras cached path); 60s sweeper for stale payment sessions - Backend routes: client.payment.routes, client.mitra-availability.routes, internal/failed-pairings.routes; client.chat.routes rewritten for payment-gated start + /returning + /cancel + /fallback-to-blast; internal/config.routes adds 4 new keys with Valkey invalidate publish - client_app: mitra-availability poll, payment screen + notifier, pairing notifier rewrite (PairingTargetedWaiting + PairingFailed states), targeted-waiting overlay + bestie-unavailable dialog, "Curhat lagi" CTA, failed-pairing terminal, extension via payment-session - mitra_app: PairingRequestType enum, returning-chat 20s countdown auto-dismiss, extension card "otomatis disetujui" copy - control_center: 4 new config rows in Settings, Failed Pairings page (filter + paginate + action menu), sidebar + route registered - Test infrastructure: Vitest backend (7/7 pass), Playwright CC (4/4 pass), Maestro mobile scaffold (CLI install pending) - Bugs found via Playwright + fixed: LoginPage labels not associated with inputs (a11y); backend internal CORS missing PATCH/PUT/DELETE in allow-methods (silent settings breakage in browsers since Stage 4) - Docs: phase3.7.md PRD, phase3.7-plan.md, phase3.7-questions.md (Q&A), phase3.7-testing.md (E2E checklist), phase3.7-test-run-2026-05-03.md (today's run results) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
161 lines
4.3 KiB
Markdown
161 lines
4.3 KiB
Markdown
# Control Center — Playwright E2E Tests
|
|
|
|
End-to-end tests for the Halo Bestie control center. Tests run a real browser
|
|
against a running CC dev server, which talks to a running internal backend.
|
|
|
|
## Install
|
|
|
|
From `control_center/`:
|
|
|
|
```bash
|
|
npm install
|
|
npx playwright install chromium
|
|
```
|
|
|
|
To add Firefox or WebKit later:
|
|
|
|
```bash
|
|
npx playwright install firefox webkit
|
|
```
|
|
|
|
…then add a project entry in `playwright.config.js`.
|
|
|
|
## Configure
|
|
|
|
Copy the example env file and fill in your local values:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Required env vars (all have sensible defaults for `localhost`):
|
|
|
|
| Var | Default | Purpose |
|
|
| ---------------------- | ------------------------ | -------------------------------------------- |
|
|
| `CC_BASE_URL` | `http://localhost:5173` | Where the CC SPA is reachable |
|
|
| `BACKEND_INTERNAL_URL` | `http://localhost:3001` | Where the internal Fastify listener is |
|
|
| `CC_TEST_EMAIL` | placeholder | Operator account used by the suite |
|
|
| `CC_TEST_PASSWORD` | placeholder | Operator account password |
|
|
|
|
The seeded admin (`admin@halobestie.com` / `ChangeMe123!` from
|
|
`backend/src/db/seed.js`) works as the test operator for local dev. For
|
|
shared/CI environments, provision a dedicated test user.
|
|
|
|
`playwright.config.js` automatically loads `.env` via `dotenv.config()`. CLI
|
|
env vars still take precedence — useful when running one-off:
|
|
|
|
```bash
|
|
CC_BASE_URL=http://192.168.1.10:5173 npm run test:e2e
|
|
```
|
|
|
|
## Run on the same machine
|
|
|
|
1. Start the backend (public + internal listeners):
|
|
|
|
```bash
|
|
cd backend && npm run dev
|
|
```
|
|
|
|
2. Start the CC dev server (separate shell):
|
|
|
|
```bash
|
|
cd control_center && npm run dev
|
|
```
|
|
|
|
3. Run the suite (separate shell):
|
|
|
|
```bash
|
|
cd control_center && npm run test:e2e
|
|
```
|
|
|
|
## Run on a different machine
|
|
|
|
The Playwright config does NOT auto-start the CC dev server — that's deliberate
|
|
so the same suite can target a remote dev server. Point the env vars at it:
|
|
|
|
```bash
|
|
CC_BASE_URL=http://192.168.88.247:5173 \
|
|
BACKEND_INTERNAL_URL=http://192.168.88.247:3001 \
|
|
CC_TEST_EMAIL=test-operator@example.com \
|
|
CC_TEST_PASSWORD=changeme \
|
|
npm run test:e2e
|
|
```
|
|
|
|
The CC dev server must be reachable on the network — by default Vite binds to
|
|
`localhost`. To make it listen on all interfaces, start it with:
|
|
|
|
```bash
|
|
npm run dev -- --host
|
|
```
|
|
|
|
…or set `server.host: true` in `vite.config.js`.
|
|
|
|
## Run a single test
|
|
|
|
```bash
|
|
# One file
|
|
npm run test:e2e -- tests/e2e/settings.spec.js
|
|
|
|
# Tests matching a pattern (across all files)
|
|
npm run test:e2e -- --grep "payment session timeout"
|
|
```
|
|
|
|
## Debug
|
|
|
|
Three options, in order of how heavy they are:
|
|
|
|
```bash
|
|
# 1. UI mode — watches files, lets you re-run individual tests, inspect DOM,
|
|
# and see the timeline. Best for iterating on a flaky test.
|
|
npm run test:e2e:ui
|
|
|
|
# 2. Headed mode — same suite, but with a visible browser window.
|
|
npm run test:e2e:headed
|
|
|
|
# 3. Inspector — pauses execution, opens devtools, lets you step through.
|
|
npm run test:e2e:debug
|
|
```
|
|
|
|
To record video for every test:
|
|
|
|
```bash
|
|
RECORD=1 npm run test:e2e
|
|
```
|
|
|
|
Failure artifacts (screenshots, traces, videos) land in `test-results/`. Open
|
|
the HTML report with:
|
|
|
|
```bash
|
|
npx playwright show-report
|
|
```
|
|
|
|
## Adding a new test
|
|
|
|
1. Create `tests/e2e/<feature>.spec.js`.
|
|
2. Import the helpers:
|
|
|
|
```js
|
|
import { test, expect } from '@playwright/test'
|
|
import { loginAsOperator } from './helpers/auth.js'
|
|
import { backendRequest } from './helpers/backend-api.js'
|
|
```
|
|
|
|
3. Use `loginAsOperator(page)` in `beforeEach` for any test that hits a
|
|
protected route.
|
|
4. Use `backendRequest('/internal/...')` for fixture setup/teardown so the
|
|
test body stays focused on the UI behavior.
|
|
5. Look at `settings.spec.js` and `failed-pairings.spec.js` for the patterns
|
|
already in use (snapshot → mutate → reload → restore).
|
|
|
|
## Files
|
|
|
|
```
|
|
tests/e2e/
|
|
├── README.md (you are here)
|
|
├── helpers/
|
|
│ ├── auth.js loginAsOperator() — UI login flow
|
|
│ └── backend-api.js fetch wrapper + fixture helpers
|
|
├── settings.spec.js Phase 3.7 config rows (2 cases)
|
|
└── failed-pairings.spec.js Failed Pairings page (2 cases)
|
|
```
|