# WP1a — Playwright scaffold + first LIS scenario (CLI-runnable)

## Goal
Stand up Playwright E2E in the Angular repo so ONE real LIS scenario runs from the CLI, green, against the deployed `/app`. This is the foundation the BE runner (WP1b) will invoke and the FE screen (WP1c) will display. No UI, no backend here — just the `e2e/` harness + one passing spec.

## Repo & branch
FE repo `/home/moonui/public_html/moon-erp`, branch `hazemdev`. Conventional commit `test(e2e): ...`.

## Exact files to CREATE
- `e2e/playwright.config.ts` — config:
  - `use.baseURL = 'https://moonui.elbaset.com/app'` (the deployed app; make it overridable via `process.env.E2E_BASE_URL`).
  - `use.launchOptions.executablePath = '/usr/bin/chromium-browser'` (browsers in /root/.cache are root-owned and unreadable by the runner user `moonui` — MUST use system Chromium 147). Headless.
  - Disable animations for stability (`use.launchOptions.args` as needed; reduce motion).
  - `reporter: [['json', { outputFile: 'e2e/results/last-run.json' }], ['list']]` — the JSON is what WP1b parses.
  - `testDir: './specs'`, sensible timeout (e.g. 60s/test), retries: 1.
  - `outputDir` under `e2e/` (git-ignored).
- `e2e/helpers/auth.ts` — `loginByApi(page, {email, password, apiBase})`: POST to `${apiBase}/auth/login` (apiBase default `https://moonui.elbaset.com/moon-erp-be/api`), read token from `response.token` (NOT `response.data.token`), then set it in the browser: navigate to baseURL, `localStorage.setItem('token', token)` (the app reads the token from `localStorage` key `token` — confirmed `auth.service.ts:30/33`). Also expose a UI-login fallback helper if needed. Header for API calls: `X-Authorization: Bearer <token>` (NOT `Authorization`).
- `e2e/helpers/testData.ts` — small helpers to generate unique test identifiers (e.g. `E2E-<timestamp-ish>` national id / name) so reruns don't collide. NOTE: Date.now() is fine in Playwright (this runs in Node, not the workflow sandbox).
- `e2e/specs/lis-request-flow.spec.ts` — the scenario, steps:
  1. `loginByApi` as the **E2E test user** (see "Test company/user" below).
  2. Navigate the UI to create a patient (go to `/app/lab/patients`, open the add-patient form, fill minimal required fields with a unique test identifier, save). Explore the actual form to find required fields + selectors.
  3. Create a lab request for that patient (go to `/app/lab/requests` → new request wizard, pick the patient, add one common test e.g. CBC, save). Explore the wizard for selectors.
  4. Assert the new request appears in the reception/requests list (search by the unique id, expect it visible).
  Use resilient locators: prefer `getByRole`/`getByLabel`/`getByText`; add `data-testid` ONLY where a selector is genuinely ambiguous (do not retrofit the whole app — WP4 handles that). Keep the scenario self-contained.
- `e2e/.gitignore` — ignore `results/`, `test-results/`, `playwright-report/`, `.auth/`.
- `e2e/README.md` — how to run: `npx playwright test` from repo root (or `npm run test:e2e`), env vars (`E2E_BASE_URL`, `E2E_EMAIL`, `E2E_PASSWORD`, `E2E_API_BASE`).

## Files to MODIFY
- `package.json` — add devDependency `@playwright/test` (do NOT install the browsers via playwright; we use system Chromium). Add scripts: `"test:e2e": "playwright test --config e2e/playwright.config.ts"`.
- Root `.gitignore` (if needed) — ensure `e2e/results`, `e2e/test-results`, `e2e/playwright-report` ignored.

## Test company/user (write-isolated — SAFE DATA)
⛔ Do NOT use a real company (بلاك سيركل=id 4 is real data). Create a dedicated **E2E test company + user ONCE** as a setup step, and document the credentials in `e2e/README.md` + report them back:
- Preferred: a small idempotent setup — insert (via `php artisan tinker` one-liner, NOT a migration) a company `E2E Test Lab` (unique prefix e.g. `e2etest`) + a main branch + a user `e2e@moonerp.test` / a known password, attached to that company, with a role that can create patients/requests. Mirror how `DatabaseSeeder` creates company+branch+user (`/home/moonui/moon-erp-be/database/seeders/DatabaseSeeder.php`).
- Record the created company id + user creds in the ledger/README. The spec logs in as this user, so all created patients/requests are scoped to the test company (company_id filter) and never pollute real companies.
- ⛔ NEVER migrate:fresh / wipe. Only additive inserts.

## Interfaces exposed to later WPs
- CLI entry: `npx playwright test --config e2e/playwright.config.ts` (exit 0 = all pass) run from `/home/moonui/public_html/moon-erp`.
- Results JSON at `e2e/results/last-run.json` (Playwright JSON reporter shape: `suites[].specs[].tests[].results[].status` + titles) — WP1b parses this into per-scenario pass/fail.
- Env knobs: `E2E_BASE_URL`, `E2E_API_BASE`, `E2E_EMAIL`, `E2E_PASSWORD`.

## Acceptance criteria
- [ ] `npx playwright test --config e2e/playwright.config.ts` runs headless using system Chromium and the login+create-patient+create-request+assert scenario **passes green** against the deployed `/app`.
- [ ] It logs in as the E2E test user; the created patient/request are in the **E2E test company**, not any real company.
- [ ] `e2e/results/last-run.json` is produced with a parseable per-test status.
- [ ] Reruns don't collide (unique identifiers).
- [ ] `ng build` still green (the `e2e/` dir must not break the Angular build — keep it OUT of the `src/` tsconfig scope; add a separate tsconfig for e2e if needed).

## Tests
FE has no unit runner. Proof = the Playwright run passes + `ng build` stays green.

## Out of scope
- The BE runner endpoint (WP1b). The FE Tests screen (WP1c). More scenarios (WP2). data-testid retrofit (WP4).

## Flags
No [FIN]. No migration (test company via additive tinker insert, not a schema migration).
