Skip to content

Exercice 2 / Étape 5 — Tests E2E avec Cypress

Tests de bout en bout des écrans du front-end, API mockée via cy.intercept() (aucun appel au vrai back-end), en commençant par les formulaires les plus simples comme demandé par la consigne.

Installation

Cypress n'était pas encore une dépendance du projet :

npm install --save-dev cypress

Config créée :

  • cypress.config.ts — E2E, baseUrl: 'http://localhost:4200'.
  • cypress/support/e2e.ts / cypress/support/commands.ts — commande personnalisée cy.visitAuthenticated(url) : seed un faux JWT dans localStorage avant l'exécution des scripts de la page (option onBeforeLoad), pour atteindre les routes protégées par authGuard sans repasser par tout le flux /login.
  • cypress/tsconfig.json — scope les types Cypress à cypress/**, séparé de tsconfig.spec.json (Jest) pour éviter tout conflit de types entre les deux frameworks de test.

Specs écrites (du plus simple au plus complexe)

Spec Ce qui est mocké Vérifie
register.cy.ts POST /api/register → 201 soumission valide → redirection /login ; formulaire invalide → pas d'appel API
login.cy.ts POST /api/login → 200 (texte brut) / 400 soumission valide → redirection /students ; identifiants refusés → message d'erreur affiché
students-guard.cy.ts accès à /students sans session → redirection /login (authGuard)
students-list.cy.ts GET /api/students → liste / liste vide rendu du tableau / état "No students yet."
students-create.cy.ts POST /api/students → 201 soumission du formulaire → requête envoyée avec le bon corps, retour sur /students
students-delete.cy.ts GET + DELETE /api/students/:id confirmation navigateur stubée (window:confirm), suppression déclenchée

Bug détecté par ces tests (voir détail dans l'étape 4)

Le premier passage de login.cy.ts (cas d'identifiants refusés) a échoué : le message "Invalid credentials" attendu à l'écran n'apparaissait jamais. Root cause et correctif détaillés dans le doc de l'étape 4 — LoginComponent ne parsait pas correctement le corps d'erreur HTTP lorsque la requête est faite avec responseType: 'text'. C'est exactement le genre de régression qu'un test E2E (contrairement à un simple curl) est censé attraper : il exécute le vrai code du composant dans un vrai navigateur, pas seulement la couche HTTP.

Exécution réelle dans cet environnement

Contrairement aux vérifications précédentes de ce projet (étapes 3 et 5 de l'Exercice 1), Cypress a pu s'exécuter en mode headless dans cet environnement WSL (npx cypress verify → OK, Electron headless disponible) :

npx cypress run
Spec                          Tests  Passing  Failing
login.cy.ts                   2      2        -
register.cy.ts                2      2        -
students-create.cy.ts         1      1        -
students-delete.cy.ts         1      1        -
students-guard.cy.ts          1      1        -
students-list.cy.ts           2      2        -
──────────────────────────────────────────────────
All specs passed!             9      9        -

9/9 tests passent, sur les 6 écrans couverts par le plan de tests — tous les écrans listés à l'étape 2 sont couverts, avec succès.

Comment reproduire

cd front-end
npm install                 # installe aussi cypress (devDependency)
npm run start                # terminal 1 — ng serve sur :4200 (nécessaire, Cypress vise cette URL)

# terminal 2
npx cypress run              # exécution headless, résultats dans le terminal
# ou, pour piloter/déboguer visuellement :
npx cypress open

Aucun back-end réel n'est nécessaire : tous les appels /api/** sont interceptés par cy.intercept().

Points de vigilance restants

  • Pas de notion formelle de "taux de couverture E2E" outillée (Cypress n'a pas d'équivalent direct de JaCoCo/Istanbul pour ça) — la couverture est démontrée ici par la correspondance 1:1 entre les écrans du plan de tests (étape 2) et les specs écrites : les 6 écrans/parcours prévus ont chacun au moins un test, tous passent.
  • students-create.cy.ts/students-delete.cy.ts ne couvrent qu'un seul cas nominal chacun — les cas d'erreur (email dupliqué, suppression en échec) ne sont pas testés en E2E, déjà couverts côté Jest (étape 4).