arcmates

đŸ§Ș Campagne de tests — Ă©tat des lieux

GĂ©nĂ©rĂ© le 2026-08-31 Ă  partir de npm test / node --test --experimental-test-coverage / npm run test:e2e (Node v25.9.0, Playwright/Chromium 1.62). À rĂ©gĂ©nĂ©rer aprĂšs tout changement dans data.js, storage.js, guide-i18n.js, guide.html ou arc-diagram.html — les chiffres ci-dessous sont une photo, pas une valeur qui se met Ă  jour toute seule.

Deux suites, deux vitesses, deux usages :

npm test                                    # unitaire + intégration DOM (jsdom), ~1s
node --test --experimental-test-coverage    # idem + rapport de couverture
npm run test:e2e                            # navigation dans un vrai Chromium, ~10s

1. ✅ DerniĂšre exĂ©cution — npm test (unitaire + intĂ©gration jsdom)

🟱 34 / 34 tests passent, 0 Ă©chec, 0 skip — durĂ©e totale ≈ 0.7 s.

Fichier de test Tests Résultat Portée
tests/data.test.js 6 ✅ 6/6 Modùle statique + calcul des arcs (data.js)
tests/storage.test.js 6 ✅ 6/6 Mapping JS ↔ Supabase (storage.js)
tests/guide-i18n.test.js 7 ✅ 7/7 Dictionnaire FR/EN, pure logique (guide-i18n.js)
tests/guide-integration.test.js 10 ✅ 10/10 DOM rĂ©el (guide.html, arc-diagram.html) via jsdom
Total 29 ✅ 29/29  
📋 DĂ©tail des 29 tests (nom exact, tel qu'exĂ©cutĂ©) **`data.test.js`** - ✅ EVENT_TYPES / TYPE_COLORS / TYPE_EMOJIS restent en phase - ✅ typeColor() renvoie une couleur de secours pour un type inconnu - ✅ pickTitleForType() pioche toujours dans le bon pool - ✅ AVATAR_EMOJIS n'a pas de doublons - ✅ computeArcsForPerson() relie les Ă©vĂšnements d'une personne dans l'ordre chronologique - ✅ computeArcsForPerson() ne crĂ©e aucun arc s'il y a 0 ou 1 Ă©vĂšnement **`storage.test.js`** - ✅ toISODate() / fromISODate() font un aller-retour fidĂšle - ✅ fromISODate() renvoie undefined pour une valeur vide/nulle - ✅ rowToEvent() convertit une ligne Supabase (snake_case) en Ă©vĂšnement JS (camelCase) - ✅ rowToEvent() gĂšre les champs optionnels absents (pas de dateFin/description/personnes) - ✅ eventToRow() convertit un Ă©vĂšnement JS en ligne Supabase, et est l'inverse de rowToEvent() - ✅ eventToRow() met null (pas undefined) pour les champs optionnels absents — important pour Supabase **`guide-i18n.test.js`** - ✅ SUPPORTED_LANGS contient bien FR et EN, DEFAULT_LANG est supportĂ© - ✅ GUIDE_I18N a une entrĂ©e par langue supportĂ©e - ✅ fr et en ont exactement le mĂȘme jeu de clĂ©s — sinon une traduction manque - ✅ aucune valeur de traduction n'est vide - ✅ fr et en diffĂšrent bien sur le contenu (pas un copier-coller oubliĂ©) - ✅ pickLang() renvoie la langue demandĂ©e si supportĂ©e - ✅ pickLang() retombe sur DEFAULT_LANG pour toute valeur non supportĂ©e **`guide-integration.test.js`** - ✅ guide.html : toutes les clĂ©s data-i18n du HTML correspondent exactement au dictionnaire FR - ✅ guide.html : le sĂ©lecteur de langue expose bien un bouton FR et un bouton EN - ✅ guide.html : lien retour vers la frise prĂ©sent - ✅ applyLang('en') traduit rĂ©ellement le texte visible du DOM et persiste le choix - ✅ applyLang('en') traduit aussi les attributs data-i18n-aria (ex. aria-label du sĂ©lecteur de langue) - ✅ applyLang('fr') aprĂšs applyLang('en') repasse bien tout le texte en français - ✅ applyLang() avec une langue non supportĂ©e retombe sur le français plutĂŽt que de planter - ✅ initLang() lit la langue prĂ©cĂ©demment stockĂ©e dans localStorage au chargement - ✅ initLang() branche le sĂ©lecteur : cliquer sur EN traduit la page en direct - ✅ arc-diagram.html : un lien vers guide.html est prĂ©sent dans le drawer #sidebar

2. 🌐 DerniĂšre exĂ©cution — npm run test:e2e (navigation, vrai navigateur)

🟱 6 / 6 tests passent — durĂ©e totale ≈ 3.3 s (4 workers, Chromium headless).

⚠ Contrairement Ă  npm test, cette suite fait de vraies requĂȘtes rĂ©seau vers Supabase (lecture seule — listPeople/listEvents) pour charger arc-diagram.html. Elle Ă©chouera si Supabase est injoignable, et n’écrit jamais rien en base (pas de crĂ©ation/Ă©dition/suppression d’évĂšnement testĂ©e ici — cf. §5).

Test Résultat Durée
guide.html se charge en français par dĂ©faut, sans erreur console ✅ 385ms
Le sĂ©lecteur EN traduit le texte et le choix survit Ă  un reload ✅ 1.3s
Le lien retour ramùne bien vers arc-diagram.html ✅ 1.1s
arc-diagram.html : le bouton ☰ ouvre le drawer, qui contient un lien vers le guide ✅ 1.3s
Cliquer sur le lien Guide dans le drawer navigue vers guide.html ✅ 6.1s
arc-diagram.html charge les donnĂ©es sans passer en Ă©tat d’erreur ✅ 589ms

3. 📊 Couverture par fichier

MesurĂ©e par le reporter de couverture intĂ©grĂ© Ă  Node (--experimental-test-coverage) — concerne uniquement les fichiers require()-ables depuis les tests (donc pas chart.js, cf. §5).

Fichier Lignes Branches Fonctions Lignes non couvertes
data.js 🟡 83.96 % 🟱 100.00 % 🟡 71.43 % 119-145, 174-176
guide-i18n.js 🟱 96.20 % 🟠 57.89 % 🟱 100.00 % 123-126, 141-142
storage.js 🟠 65.55 % 🟱 82.35 % 🔮 44.44 % 68-72, 74-78, 80-88, 90-99, 101-112
Global (3 fichiers) 🟡 83.41 % 🟱 75.00 % 🟡 70.83 %  

4. 🔍 Couverture par fonction

Vue fonction par fonction — plus utile que le %/fichier pour juger si un trou est un problĂšme ou un choix assumĂ©.

data.js

Fonction Testée Test(s) Note
pickTitleForType(type) ✅ pickTitleForType() pioche toujours dans le bon pool  
typeColor(type) ✅ typeColor() renvoie une couleur de secours...  
computeArcsForPerson(person, eventsList) ✅ computeArcsForPerson() relie... / ...0 ou 1 Ă©vĂšnement  
initData() ⬜ — 🌐 Appelle Supabase (listPeople/listEvents) + construit une Ă©chelle D3 — nĂ©cessite un navigateur, hors pĂ©rimĂštre node --test.
recomputeArcs() ⬜ — Wrapper d’une ligne autour de computeArcsForPerson (dĂ©jĂ  testĂ©e) ; pas de logique propre Ă  couvrir.

storage.js

Fonction Testée Test(s) Note
toISODate(date) ✅ toISODate() / fromISODate() font un aller-retour fidùle  
fromISODate(str) ✅ mĂȘme test + fromISODate() renvoie undefined...  
rowToEvent(row) ✅ rowToEvent() convertit... / ...champs optionnels absents  
eventToRow(evt) ✅ eventToRow() convertit... / ...met null (pas undefined)...  
listPeople() ⬜ — 🌐 Appel rĂ©seau Supabase direct, pas de mock DB (choix assumĂ© du projet, cf. CLAUDE.md).
listEvents() ⬜ — 🌐 Idem.
createEvent(evt) ⬜ — 🌐 Idem.
updateEvent(id, evt) ⬜ — 🌐 Idem.
deleteEvent(id) ⬜ — đŸŒâš ïž Idem — contient la logique mĂ©tier “0 ligne supprimĂ©e ⇒ erreur explicite” (cf. commentaire dans le fichier), qui reste donc non vĂ©rifiĂ©e par un test automatisĂ©. Candidat le plus net si vous voulez augmenter la couverture un jour (nĂ©cessiterait un faux client Supabase injectĂ©, pas la vraie base).

guide-i18n.js

Fonction Testée Test(s) Note
pickLang(requested) ✅ pickLang() × 2  
applyLang(lang, root) ✅ 5 tests (applyLang('en')..., applyLang('fr')..., langue non supportĂ©e, data-i18n-aria, indirectement via initLang)  
initLang(root) ✅ initLang() lit la langue... / initLang() branche le sĂ©lecteur...  
bloc catch de applyLang/initLang ⬜ — đŸ›Ąïž ProtĂšge contre un localStorage indisponible (navigation privĂ©e stricte) ; jsdom ne reproduit pas ce cas, donc ces 2 lignes restent hors couverture. Comportement dĂ©fensif, pas un chemin utilisateur normal.

chart.js

đŸš« Aucune fonction n’est exĂ©cutĂ©e par node --test (pas d’export CommonJS, rendu D3/DOM pur) — mais depuis l’ajout de la suite test:e2e, une partie de ses effets est exercĂ©e automatiquement, dans un vrai Chromium :

Comportement Fonctions chart.js concernées Testé par
boot() charge les donnĂ©es sans passer en Ă©tat d’erreur boot(), showStatus(), hideStatus() ✅ test:e2e — “charge les donnĂ©es
 sans passer en Ă©tat d’erreur”
Ouverture du drawer au clic sur ☰ openDrawer() ✅ test:e2e — “le bouton ☰ ouvre le drawer
”
Rendu initial de l’axe temporel (svg#chart .axis-line) render() (partiel — juste sa prĂ©sence) ✅ test:e2e — mĂȘme test
Zoom/drag sur la frise, filtres lĂ©gende, panneau d’ajout/Ă©dition (clic sur une zone vide ou un nƓud), modal mobile render() (reste), setFilter(), setTypeFilter(), openAddPanel(), openEditPanel(), openMobileModal(), etc. đŸš« aucun test automatisĂ© — hors pĂ©rimĂštre test:e2e (cf. §5)

Reste aussi la vĂ©rification manuelle ponctuelle faite via Playwright + Chrome lors de l’implĂ©mentation du guide (captures desktop/mobile FR/EN) — pas rejouable automatiquement, contrairement Ă  test:e2e.

5. ⚠ Ce que la campagne ne couvre toujours pas (assumĂ©)