# 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/.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) ```