Files
halobestie-clone/control_center/tests/e2e/README.md
ramadhan sjamsani d09e50af55 Phase 3.7: paid pairing flow + returning chat + extension flip
- 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>
2026-05-03 23:02:49 +08:00

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)
```