# Tests — Rêve de Dragon FoundryVTT

## Architecture

```
tests/
├── rdd_test_plan.md          # Plan de test (227 cas, 33 sections)
└── scripts/
    ├── tc-header.sh           # Fonctions partagées (login, assertions, extraction JSON)
    ├── run-all-tests.sh       # Orchestrateur (sélection, exécution, rapport final)
    ├── tc-01-infrastructure.sh … tc-31-meteo.sh   # 29 scripts TC
    └── …
```

Tous les scripts utilisent `chrome-devtools` (CLI) pour interagir avec Foundry via `evaluate_script`.

## Lancement

### Prérequis

- Foundry VTT démarré sur `https://localhost:31000`
- Chrome-devtools connecté au navigateur (port 9222)
- Le monde « Reve de Dragon » chargé et `game.ready = true`

### Orchestrateur — `run-all-tests.sh`

L'orchestrateur exécute une sélection de tests et affiche un rapport final.

```
# Tous les tests
./tests/scripts/run-all-tests.sh --tests all

# Sous-ensemble (syntaxe: numéros séparés par virgules, ranges avec tiret)
./tests/scripts/run-all-tests.sh --tests 01,08,10,22

# TC-08 à TC-16 (plage)
./tests/scripts/run-all-tests.sh --tests 08-16

# Tests critiques uniquement
./tests/scripts/run-all-tests.sh --tests 01,02,08,10,12,15,16,22,27

# Sans le rapport final
./tests/scripts/run-all-tests.sh --tests all --no-report

# Aide
./tests/scripts/run-all-tests.sh --help
```

**Démarrage du monde** : si `game.ready` n'est pas détecté au lancement, le script affiche les instructions et attend que l'utilisateur démarre le monde manuellement dans le navigateur (sélection du monde, connexion GM), puis appuie sur ENTRÉE. Timeout de 120s.

### Script individuel

```
# Sur une session déjà active (game.ready=true)
./tests/scripts/tc-08-roll-v1.sh

# Avec login auto (nécessite PASS=admin password)
PASS=Slaanesh666 ./tests/scripts/tc-08-roll-v1.sh --navigate
```

## Liste des tests

| TC | Script | Description | Tests |
|---|---|---|---|
| TC-01 | `tc-01-infrastructure.sh` | Infrastructure cœur (settings, classes, sheets) | 15 |
| TC-02 | `tc-02-acteur-personnage.sh` | Acteur personnage (caracs, comp, santé, moral) | 20 |
| TC-03 | `tc-03-acteur-creature.sh` | Acteur créature | 3 |
| TC-04 | `tc-04-acteur-entite.sh` | Acteur entité | 4 |
| TC-05 | `tc-05-acteur-vehicule.sh` | Acteur véhicule | 2 |
| TC-06 | `tc-06-acteur-commerce.sh` | Acteur commerce | 3 |
| TC-07 | `tc-07-feuilles-item.sh` | Feuilles d'item (44 types, scroll) | 44 |
| TC-08 | `tc-08-roll-v1.sh` | Système de jet V1 (RdDRoll) | 8 |
| TC-09 | `tc-09-roll-v2.sh` | Système de jet V2 (RollDialog) | 4 |
| TC-10 | `tc-10-des-custom.sh` | Dés custom (d8 TMR, d8 draconic, d12 heure) | 5 |
| TC-11 | `tc-11-combat.sh` | Combat (RdDCombat, initiative) | 3 |
| TC-12 | `tc-12-calendrier.sh` | Calendrier / temps | 6 |
| TC-13 | `tc-13-sommeil.sh` | Sommeil / repos (château dormant, stress) | 3 |
| TC-14 | `tc-14-voyage.sh` | Voyage (dialog fatigue) | 2 |
| TC-15 | `tc-15-tmr.sh` | TMR (recherche, aléatoire, coordonnées) | 7 |
| TC-16 | `tc-16-commandes-chat.sh` | Commandes chat (/table, /meteo, /ddr, /chrono) | 11 |
| TC-17 | `tc-17-token-hud.sh` | Token HUD | 2 |
| TC-18 | `tc-18-dialogues.sh` | Dialogues V2 (positionnement, boutons) | 3 |
| TC-19 | `tc-19-tirage.sh` | Tirage (FenetreRechercheTirage) | 2 |
| TC-20 | `tc-20-gen-aleatoire.sh` | Génération aléatoire (nom) | 2 |
| TC-22 | `tc-22-compendiums.sh` | Compendiums (packs, drag → acteur) | 6 |
| TC-23 | `tc-23-css-ui.sh` | CSS / UI (police, sélecteurs natifs) | 3 |
| TC-25 | `tc-25-hotbar.sh` | Hotbar (RdDHotbar) | 2 |
| TC-26 | `tc-26-possession.sh` | Possession V2 | 2 |
| TC-27 | `tc-27-active-effects.sh` | Active effects (création, application, suppression) | 6 |
| TC-28 | `tc-28-journal.sh` | Journal sheet | 2 |
| TC-29 | `tc-29-coeur.sh` | Cœur (attachment) | 2 |
| TC-30 | `tc-30-appreciation.sh` | Appréciation | 2 |
| TC-31 | `tc-31-meteo.sh` | Météo | 3 |

**TC-21** (Migrations), **TC-24** (Export), **TC-32** (Sons), **TC-33** (Remote/Socket) sont manuels uniquement (`MAN` dans le plan de test).

## API des scripts

### Variables d'environnement

| Variable | Rôle | Défaut |
|---|---|---|
| `URL` | URL Foundry | `https://localhost:31000` |
| `PASS` | Mot de passe admin (pour `--navigate`) | requis si `--navigate` |
| `PASS_USER` | Mot de passe utilisateur (si différent) | vide |

### Fonctions partagées (`tc-header.sh`)

| Fonction | Description |
|---|---|
| `jse_get "JS_BODY"` | Exécute `() => { JS_BODY }` synchrone, retourne le JSON |
| `jse_get_async "JS_BODY"` | Exécute `async () => { JS_BODY }`, retourne le JSON |
| `jse_wait_ready TIMEOUT POLL` | Poll `game.ready` pendant TIMEOUT secondes |
| `tc_login` | Navigation + login admin (via `--navigate`) |
| `tc_ensure_ready` | Vérifie `game.ready`, login si `--navigate` |
| `eval_ok "$JSON" "key"` | Extrait une clé du JSON résultat |
| `tc_console_errors` | Compte les erreurs console |
| `assert_eq / assert_gt / assert_contains` | Assertions |
| `pass / fail / die` | Affichage des résultats |

### Conventions

- Chaque script est autonome : setup (création d'acteurs/items) → tests → cleanup.
- Le polling `game.ready` est interne à un seul `evaluate_script` asynchrone (pas de boucle bash) pour éviter les races de page.
- Les opérations lourdes (création d'acteurs, ouverture de sheets) sont regroupées dans un seul `evaluate_script` atomique.
- Chaque script affiche `✔/✘` par test et un résumé final `N / M passed`.

## Commandes utiles (console manuelle)

```
CONFIG.debug.hooks = true  # log tous les hooks Foundry
```