# 07 — Plan de tests (recette manuelle)
> Périmètre v1 : **aucun test automatisé** (décision du GOAL.md : « pas de test pour démarrer — à prévoir pour plus tard »). La recette ci-dessous est un **plan de tests manuels** aligné sur les critères d'acceptation du GOAL.md. Elle servira aussi de **cahier de recette** pour le livrable ECF.
## 1. Environnement de test
| Paramètre | Valeur |
| --- | --- |
| Navigateur principal | Chrome / Edge (dernière version) — engine Chromium recommandé |
| Navigateur secondaire | Firefox (contrôle croisé) |
| Résolution principale | ≥ 1024 px (desktop) |
| Commande de lancement | `pnpm dev` (ou `pnpm build && pnpm start` pour la recette finale) |
## 2. Critères d'acceptation globaux (rappel GOAL.md)
- [ ] Application « desktop first » opérationnelle.
- [ ] Interface en deux colonnes respectant le ratio 1/3 – 2/3.
- [ ] Saisie Markdown à gauche, preview temps réel à droite au **format A4**.
- [ ] Sauvegarde localStorage à chaque frappe + restauration au rechargement.
- [ ] Impression du CV en PDF.
- [ ] Pages Documentation et Mentions légales accessibles.
## 3. Tests fonctionnels détaillés
### 3.1 Écran général et layout
| # | Action | Résultat attendu |
| --- | --- | --- |
| G1 | Ouvrir `/` | Deux colonnes : gauche (1/3) avec tab 1 actif, droite (2/3) avec feuille A4 (blanche, ombragée) |
| G2 | Réduire la fenêtre sous 1024 px | Les panneaux s'empilent (gauche au-dessus de la droite) sans casse |
| G3 | Vérifier la barre d'app et le footer | Barre : logo, bouton « Imprimer / PDF », lien Documentation. Footer : lien Mentions légales (masqué à l'impression) |
### 3.2 Onglets 1 à 5 (zones de saisie)
| # | Action | Résultat attendu |
| --- | --- | --- |
| T1 | Cliquer sur les onglets 1→5 | L'onglet actif change ; le textarea affiche le contenu **de cet onglet uniquement** |
| T2 | Saisir du Markdown dans l'onglet 1 (`**Jean Dupont**`) | Rendu temps réel dans le **header** de la feuille A4 (gras) |
| T3 | Idem dans l'onglet 2 (nom, e-mail, site, GitHub en listes) | Rendu dans la section **État civil** (colonne 1/3) |
| T4 | Onglet 3 (formation ex. `### Master` + liste) | Rendu dans la section **Formations** |
| T5 | Onglet 4 | Rendu dans la section **Soft skills** |
| T6 | Onglet 5 | Rendu dans la section **Centres d'intérêt** |
| T7 | Basculer entre onglets après saisie | Chaque contenu est conservé, aucun écrasement croisé |
| T8 | Vider complètement une section | La section correspondante disparaît de la preview |
### 3.3 Expériences professionnelles
| # | Action | Résultat attendu |
| --- | --- | --- |
| X1 | Cliquer sur le bouton **+** | Un formulaire (titre + contenu) apparaît, vide |
| X2 | Saisir titre + contenu puis **Enregistrer** | L'expérience apparaît dans la liste numérotée du panneau gauche (numéro 1) ET en tête de la section « Expériences professionnelles » |
| X3 | Ajouter une 2ᵉ expérience | Elle s'affiche **sous** la 1ʳᵉ ; les listes se renumérotent (1, 2… dans l'ordre de saisie) |
| X4 | Cliquer **Modifier** sur une entrée | Le formulaire se remplit avec titre + contenu de cette expérience (mode modification) |
| X5 | Modifier puis **Enregistrer** | Le rendu preview met à jour la section Expériences |
| X6 | Cliquer **Annuler** en cours de modification | Aucune modification appliquée |
| X7 | Cliquer **×** sur une entrée | Confirmation demandée → confirmer → l'expérience disparaît (panneau gauche + preview) |
| X8 | Supprimer la dernière expérience | La section affiche le message d'incitation « Ajoutez une expérience… » |
| X9 | Contenu Markdown d'une expérience | Rendu temps réel en HTML dans la preview |
### 3.4 Persistance (localStorage)
| # | Action | Résultat attendu |
| --- | --- | --- |
| P1 | Saisir du contenu dans 2-3 zones puis **recharger la page** (F5) | Tous les contenus et la liste des expériences sont restaurés |
| P2 | Vérifier en devtools → Application → localStorage | Une clé `cv-maker:v1` existe, au format JSON avec `version: 1` |
| P3 | Vider localStorage (ou supprimer la clé) puis recharger | L'application démarre avec des zones vides, **sans erreur** |
| P4 | Introduire un JSON corrompu dans la clé (`cv-maker:v1`) puis recharger | Pas de crash ; état par défaut restauré |
| P5 | Cliquer **Exporter JSON** | Un fichier `cv-maker.json` est téléchargé contenant le contenu saisi |
| P6 | Créer/exporter un CV, **Importer JSON** sur ce fichier après modification | Un second clic sur **Importer** (bouton/badge) remplace le contenu par celui du fichier (cas nominal validé) |
### 3.5 Impression / PDF
| # | Action | Résultat attendu |
| --- | --- | --- |
| M1 | Cliquer **Imprimer / PDF** | L'aperçu d'impression ne contient que la feuille A4 (pas de panneau de saisie ni toolbar) |
| M2 | Choisir « Enregistrer en PDF » avec format A4 | Un PDF d'une page (contenu court) ; mise en page 1/3–2/3 respectée |
| M3 | Format A4 par défaut | `@page size: A4` appliqué (aucun choix manuel requis) |
### 3.6 Rendu Markdown et sécurité
| # | Action | Résultat attendu |
| --- | --- | --- |
| S1 | Saisir tous les éléments supportés (titres ###, gras, liste `-`, lien `[t](url)`, code `` ` ``) | Rendu HTML correct dans la preview |
| S2 | Saisir `
` dans une zone | Aucune alerte/exécution ; la balise est neutralisée |
| S3 | Saisir `` | Affiché sans exécution (ou supprimé) — pas d'alerte |
| S4 | Saisir `x` | Lien inoffensif ou supprimé ; aucun dialogue |
### 3.7 Pages Documentation et Mentions légales
| # | Action | Résultat attendu |
| --- | --- | --- |
| D1 | Naviguer vers `/documentation` depuis la toolbar | Page d'aide affichée (prise en main + syntaxe Markdown) |
| D2 | Naviguer vers `/mentions-legales` depuis le footer | Page affichée avec les sections attendues (module `06-` §4), **sans** paragraphe contact |
| D3 | Retour vers l'éditeur | Lien retour fonctionnel ; les données du CV n'ont pas bougé |
### 3.8 PWA (recette avancée — build production requis)
| # | Action | Résultat attendu |
| --- | --- | --- |
| W1 | `pnpm build && pnpm start` | Aucune erreur de build liée à Serwist |
| W2 | DevTools → Application | Service worker enregistré, manifest chargé |
| W3 | Clic « Installer l'application » | Installation proposée (icône et nom corrects) |
| W4 | Passer hors-ligne puis recharger `/` | La page (squelette + app shell) est servie par le cache |
| W5 | Données du CV hors-ligne | Le CV reste intact (localStorage) — pas de régression |
## 4. Hygiène du code (vérifications finales)
- [ ] `pnpm lint` sans erreur ni warning bloquant.
- [ ] `pnpm typecheck` sans erreur.
- [ ] `pnpm audit` sans vulnérabilité critique.
- [ ] Aucun `console.log` résiduel (à l'exception éventuelle du `console.warn` d'échec de sauvegarde documenté).
## 5. Évolutions testables (v2 — hors périmètre v1)
Dès leur mise en place, ajouter à la recette :
- Tests **Vitest** pour `lib/markdown.ts` (rendu + assainissement) et `lib/storage.ts` (parse/corruption) ;
- Mise en place de **drag & drop** des expériences (réordonnancement) avec tests correspondants ;
- Tests composants (React Testing Library) sur `CvTabs`, `ExperienceManager`, `CvPreview` (rendu conditionnel des sections vides).
## 6. Bilan de recette
| Critère global GOAL.md | Tests concernés | Statut final |
| --- | --- | --- |
| Desktop first, 2 colonnes 1/3–2/3 | G1, G2 | ☐ |
| Markdown → HTML temps réel | T2–T6, X9, S1 | ☐ |
| Preview A4 | G1, M1–M3 | ☐ |
| Persistance localStorage | P1–P5 | ☐ |
| Impression PDF | M1–M3 | ☐ |
| Expériences (+, liste, modif, ×) | X1–X9 | ☐ |
| Onglets 1-5 | T1–T8 | ☐ |
| Documentation + Mentions légales | D1–D3 | ☐ |
| PWA | W1–W5 | ☐ |
Tout critère ☐ non coché en livraison = anomalie à corriger avant livraison finale.