> ⚠️ **MODE DEV STRICT (pas PROD)**  
> - **Aucune transition**, **aucun fallback**, **aucune rétro-compat**.  
> - Soit on règle un point proprement soit on n'y touche pas. pas de zone de : "transition ou entre deux".  
> - Toute contribution qui introduit une zone grise, un compromis ou un retour au legacy est **refusée**.

# Tests & E2E — Guide d’exécution

## Portée
- CI exécute: guards (anti‑legacy) → PHPUnit (incl. Eris) → Playwright (E2E).
- Les réponses HTTP/JSON DOIVENT respecter l’enveloppe canonique.

## E2E Playwright
- `npm run e2e` (local) ou via CI.
- Web server: `php -S 127.0.0.1:8080 -t public` (configuré dans `playwright.config.ts`).
- Storage: `tests/e2e/.auth/dev.json` (créé en `global-setup`).

### Test "wiring UI → /api/commands"
- Actuellement marqué `skip` tant que la session UI n’est pas disponible en local (cookies **Secure** conservés).
- Pour l’activer plus tard, choisir l’une des options:
  1) Servir le site en **HTTPS local** (reverse‑proxy dev avec certificat),
  2) Simuler une **session** dans `global-setup` (login UI réel ou injection d’un storageState déjà authentifié),
  3) Introduire un **flux Bearer** DEV (si validé en architecture).
- Tant que ces prérequis ne sont pas en place, le test reste `skip`; le "crawler" E2E tourne et remonte les erreurs console.

## PHP / Property‑based
- `composer test:php` exécute PHPUnit + Eris (séquences aléatoires de commandes) et vérifie l’enveloppe.
- Tests unitaires scheduler: `tests/SchedulerSlotTest.php` valide `nextSlot()` (EVERY_N_DAYS/WEEKLY/MONTHLY) avec logique Europe/Paris et bascules DST.
- Tests contrat Admin purge: `tests/AdminCategoryDeleteControllerTest.php` vérifie l’enveloppe HTTP/JSON et les statuts (200/404/500) sans DB.

## Scheduler (CLI) — Dry‑run
- L’outil `tools/scheduler/notifications-digest.php` accepte `--dry-run` pour une exécution sans effets (logs d’intention uniquement).
- Verrous: lock global + locks par catégorie (advisory MySQL) pour éviter les exécutions concurrentes.

## CI (résumé)
- `.github/workflows/ci.yml`: guards → serveur PHP → PHPUnit → Playwright.
- Les E2E échouent si la page ne charge pas ou si des erreurs console apparaissent.
