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