# WP1c — FE "Tests" screen (Run button + results)

## Goal
One owner-only Angular screen at `/core/e2e-tests` with a **Run** button that triggers the E2E suite (WP1b endpoint) and shows each scenario green/red + last-run time, polling until the run finishes. This is the "run tests from the UI" the owner asked for.

## Repo & branch
FE repo `/home/moonui/public_html/moon-erp`, branch `hazemdev`. Conventional commit `feat(e2e-fe):`. Angular 21 standalone + PrimeNG 21, RTL Arabic default, ngx-translate.

## Context from WP1b (already done — the contract you consume)
- `POST /api/e2e/run` (owner + env-gated) → `{ id, status }` (or the existing run if one is already queued/running — single-flight). If `E2E_RUNNER_ENABLED` is off on the server → 403.
- `GET /api/e2e/runs/latest` → `{ id, status ('queued'|'running'|'passed'|'failed'|'error'), started_at, finished_at, duration_ms, total, passed, failed, scenarios: [{title, status, duration_ms}], error }`.
- API header `X-Authorization: Bearer` is added by the existing `auth.interceptor.ts` — just use `HttpClient` against `${environment.apiUrl}/e2e/...`.

## Exact files to CREATE
- `src/app/core/services/e2e-runner.service.ts` — `@Injectable({providedIn:'root'})`, mirror `setting.service.ts` shape:
  - `run(): Observable<{id:number; status:string}>` → POST `${environment.apiUrl}/e2e/run`.
  - `latest(): Observable<E2eRun>` → GET `${environment.apiUrl}/e2e/runs/latest`.
  - Define an `E2eRun` interface (id, status, started_at, finished_at, duration_ms, total, passed, failed, scenarios[], error).
- `src/app/features/e2e-tests/e2e-tests.component.ts` (+ `.html` + `.scss`) — standalone component:
  - A page header ("اختبارات النظام / System Tests") + a big **Run** button (PrimeNG `p-button`, disabled while a run is `queued|running`).
  - On load: call `latest()` to show the last run. On Run click: call `run()`, then **poll** `latest()` every ~3s until status is terminal (`passed|failed|error`), updating the list live. Use `signal`s for state (mirror how other standalone components use `signal`). Stop polling on destroy.
  - Results list: one row per scenario — a colored dot (green=passed, red=failed, blue=running) + the scenario title + its duration. A summary line "X / Y passed" + last-run timestamp. If `status==='error'`, show the `error` text. If a request 403s (runner disabled on this server), show a friendly "runner disabled" note.
  - English-first labels with i18n keys `E2E.*` (both `en.json` and `ar.json`).

## Files to MODIFY
- `src/app/app.routes.ts` — add a route under the `/core` group: `{ path: 'e2e-tests', canActivate: [ownerGuard], loadComponent: () => import('./features/e2e-tests/e2e-tests.component').then(m => m.E2eTestsComponent) }` (mirror the `owner` / `module-activation` owner-only routes at lines 79-80).
- `src/app/core/config/nav-items.config.ts` — add a nav item `{ label: 'NAV.E2E_TESTS', icon: 'pi pi-check-circle', route: '/core/e2e-tests', ownerOnly: true }` near the other `ownerOnly:true` items (module-activation/owner-settings, ~line 42-43).
- `src/assets/i18n/en.json` + `src/assets/i18n/ar.json` — add `NAV.E2E_TESTS` and the `E2E.*` keys used by the screen (Run, Running, Last run, X of Y passed, Runner disabled, Passed, Failed, Error, etc.).

## Interfaces
- Consumes WP1b endpoints only. Exposes nothing to later WPs (WP2 just adds scenarios the runner already picks up; WP3 will extend this screen with selective-run + history).

## Acceptance criteria
- [ ] Route `/core/e2e-tests` exists, guarded by `ownerGuard` (non-owner can't reach it), and a nav item shows only for the owner (`ownerOnly:true`).
- [ ] The screen loads the last run via `GET /e2e/runs/latest`, and the Run button POSTs `/e2e/run` then polls until terminal, rendering per-scenario green/red + duration + summary + last-run time.
- [ ] Button is disabled while a run is in progress (respects single-flight).
- [ ] A 403 (runner disabled) renders a friendly note, not a crash.
- [ ] i18n keys present in BOTH en.json and ar.json (no raw KEY shown).
- [ ] `npx ng build --base-href /app/` is GREEN.

## Tests
FE has no unit runner → proof = `ng build` green + the screen renders and wires to the endpoints (describe how you sanity-checked, e.g. against the deployed API or a local check). The end-to-end proof (button → real run → green/red) is exercised once the owner enables the runner env flag + runs `/fullpush`; note that in the report.

## Out of scope
- More scenarios (WP2). Selective run, run history, screenshots-on-fail (WP3). data-testid retrofit (WP4). Do NOT enable `E2E_RUNNER_ENABLED` anywhere.

## Flags
No [FIN]. No migration. Pure FE.
