Le test d’inscription reste bloqué parce que le code envoyé par e-mail n’arrive pas dans le navigateur Cypress.

Verdict — adapté si le parcours concerne votre propre produit : Cypress pilote la page, tandis qu’une tâche contrôlée côté Node.js ou une interface de réception de test lit le message. Suivez le fil « déclencher l’envoi, attendre le message correspondant, extraire le code, le soumettre, puis vérifier l’état du compte ». Cypress 16 est le contexte de version, pas une raison de faire lire une boîte de réception au navigateur.

Cet article s’adresse aux personnes qui régressent l’inscription ou la vérification d’adresse de leur produit avec Cypress 16.
Les développeurs qui ajoutent un test E2E y trouveront une séparation nette entre les actions dans la page et les opérations sur les e-mails.
Les petites équipes qui entretiennent une intégration continue pourront aussi réduire les erreurs causées par le partage d’adresses personnelles.

Dernière mise à jour : 22 octobre 2026. Vérification du contexte de version à partir du journal officiel des modifications de Cypress ; vérification des exemples d’exécution côté Node.js dans la documentation de cy.task.

Avant le déclenchement : quel résultat le test doit-il prouver ?

Commencez par définir ce qui constitue une réussite. Un test de vérification d’adresse peut couvrir plusieurs faits distincts : l’application a demandé l’envoi, le message contient le code attendu, le formulaire accepte ce code et le compte passe à l’état vérifié. Ces vérifications ne prouvent pas toutes la même chose. En particulier, lire un message dans une boîte de test ne démontre pas que les messages arriveront correctement chez tous les fournisseurs externes.

Pour limiter les ambiguïtés, séparez les responsabilités avant d’écrire les commandes :

  • Dans le navigateur, Cypress remplit le formulaire d’inscription, soumet les informations, saisit le code et contrôle ce que l’interface affiche.
  • Côté réception, une tâche Node.js ou une interface dédiée au test attend le message et renvoie les données nécessaires au test.
  • Dans l’application, une assertion vérifie l’état persistant du compte, par exemple à travers une interface de test réservée à l’environnement concerné.

Le choix du récepteur dépend de la preuve recherchée. Si l’objectif est de valider le flux applicatif et le contenu généré, une boîte de réception de test accessible de façon contrôlée peut convenir. Si l’objectif inclut la livraison vers des services externes, prévoyez en plus une vérification distincte en préproduction. Ne présentez pas ces deux résultats comme équivalents.

Avant de brancher l’automatisation, confirmez que l’environnement est bien celui de test, que les comptes créés sont isolés et que les messages ne contiennent pas de données personnelles réelles. La page consacrée à la protection des données personnelles peut aider l’équipe à définir ce qu’elle accepte dans les adresses et contenus de test. Pour choisir un récepteur ponctuel plutôt qu’une adresse conservée dans la durée, comparez les critères utiles : contrôle de l’accès, capacité à associer un message au scénario et durée de conservation annoncée par le service retenu.

Attention. N’utilisez pas un compte de production ni l’adresse d’une personne de l’équipe comme raccourci. Les messages de test peuvent contenir un code exploitable, un lien de vérification ou des données qui ne devraient pas être dispersées dans les journaux d’exécution.

Déclencher un message traçable depuis Cypress

Une fois l’environnement choisi, le test doit fournir un moyen fiable de rattacher le message reçu à son exécution. Une adresse réservée au scénario est une première option. Lorsque plusieurs cas tournent simultanément, prévoyez également un identifiant propre à l’exécution, transmis dans une donnée que l’application peut inclure dans le message ou que le système de réception peut retrouver.

Le but n’est pas d’ajouter un marqueur arbitraire au sujet après coup. Il faut que le marqueur permette réellement de distinguer le message courant des autres messages disponibles. Selon le produit, cela peut reposer sur l’adresse destinataire, un identifiant d’inscription, une référence de message ou une autre valeur contrôlée par le système testé. Choisissez un mécanisme pris en charge par votre propre application et votre dispositif de réception.

Dans Cypress, le parcours de page reste lisible :

cy.visit('/inscription')

cy.get('[data-cy="email"]').type(testEmail)
cy.get('[data-cy="submit-registration"]').click()

À cet instant, le navigateur a déclenché le flux. Il ne devrait pas essayer d’ouvrir une boîte de réception privée ou de lire directement les messages reçus. La récupération appartient à la couche Node.js ou à l’interface de test qui a accès à cette boîte.

Conservez les éléments utiles au rapprochement dans les données du test : adresse destinataire, identifiant d’exécution et, si votre application en produit un, identifiant de demande. Ne consignez pas le code de vérification dans les journaux généraux par défaut. Si un échec nécessite de le voir, limitez cette information à un rapport de test protégé et adapté à l’environnement.

Pour un test Cypress d’inscription par e-mail, cette séparation évite un problème fréquent : le scénario peut réussir sur l’écran alors qu’il a utilisé un ancien message, ou échouer parce que le navigateur ne dispose pas des droits permettant de lire la boîte. Le résultat du test doit dépendre du message associé au parcours courant, et non de ce qui se trouvait déjà dans la boîte.

Où attendre et lire le message sans bloquer le navigateur ?

La vérification d’arrivée doit avoir lieu au point où le test peut interroger le système de réception. Avec Cypress, une tâche définie dans setupNodeEvents permet de déléguer une opération au processus Node.js. La documentation officielle de cy.task précise que cette commande sert à exécuter du code côté Node.js et qu’une tâche doit renvoyer une valeur, ou une promesse qui se résout avec une valeur ; renvoyer undefined ne constitue pas un résultat valide.

Voici la forme côté test, avec un nom de tâche illustratif :

cy.task('mail:waitForVerification', {
  recipient: testEmail,
  runId
}).then((message) => {
  expect(message).to.have.property('text')
})

La fonction mail:waitForVerification n’est pas une commande Cypress intégrée : c’est une tâche que votre projet doit implémenter avec le moyen d’accès retenu. Elle peut interroger une boîte de réception dédiée ou une interface interne, mais son comportement dépend de votre système. La tâche doit attendre un message qui correspond aux critères définis, puis renvoyer un objet exploitable par la suite du test.

Évitez une attente fixe insérée dans le navigateur pour « laisser le temps au courriel d’arriver ». Elle ne sait pas si le message est arrivé : elle ajoute simplement un délai, puis continue, que l’envoi ait réussi ou non. Concevez plutôt l’attente autour d’un événement observable : message correspondant trouvé, erreur de lecture, ou délai maximal atteint. Le délai maximal est une limite de votre configuration, pas une durée universelle de livraison. Ne présentez pas sa valeur comme un engagement de performance du service testé.

La tâche doit aussi restituer un diagnostic distinct selon le résultat. Par exemple, elle peut signaler qu’aucun message correspondant n’a été trouvé, que plusieurs messages correspondent aux critères, ou que l’interface de réception n’est pas accessible. Ces cas ne doivent pas être silencieusement convertis en objet vide : un résultat vide peut faire échouer plus tard l’extraction du code sans expliquer la cause initiale.

Repère de diagnostic. Si la tâche trouve le message mais que le test ne peut pas l’utiliser, examinez séparément la structure retournée, le contenu disponible et les journaux de l’application. Ne concluez pas à un problème de délivrabilité avant d’avoir vérifié que le message a bien été associé au bon destinataire et à la bonne exécution.

Extraire le code, puis vérifier l’état du compte

Après la réception d’un message correspondant, extrayez le code à partir du champ réellement fourni par votre système de test. La structure peut varier : texte brut, contenu HTML, objet déjà analysé ou réponse propre à l’interface de réception. Évitez de supposer que le code est toujours au même endroit sans avoir vérifié le modèle des messages générés par votre application.

Si l’application utilise un format stable et que le message reçu contient un texte brut, une extraction ciblée peut ressembler à ceci :

const match = message.text.match(/Code de vérification\s*:\s*(\S+)/)

if (!match) {
  throw new Error('Code introuvable dans le message associé au test')
}

const verificationCode = match[1]

Adaptez l’expression au contenu réel produit par votre application. Si le message peut être localisé ou si son texte change souvent, privilégiez une structure de message conçue pour les tests ou une interface interne qui expose la donnée nécessaire. Dans les deux cas, le test doit échouer avec une explication utile si le code est absent, au lieu de saisir une valeur indéfinie dans le formulaire.

La suite du scénario revient dans le navigateur :

cy.get('[data-cy="verification-code"]').type(verificationCode)
cy.get('[data-cy="confirm-verification"]').click()
cy.get('[data-cy="verification-success"]').should('be.visible')

L’assertion d’interface est utile, mais elle ne suffit pas si la réussite attendue porte aussi sur l’état du compte. Ajoutez un contrôle adapté à votre propre produit : par exemple, une requête vers une interface de test protégée ou une vérification par une commande réservée à l’environnement de test. Le résultat doit confirmer que le compte créé par ce scénario est bien marqué comme vérifié, pas seulement que l’écran a affiché un message de succès.

Conservez les catégories de diagnostic séparées :

  • Code introuvable : le message a été reçu, mais son contenu ou son format ne correspond pas à l’attendu.
  • Code refusé : le formulaire a été soumis, mais l’application n’a pas accepté la valeur extraite.
  • État non vérifié : l’interface a peut-être avancé, mais l’état final du compte n’est pas celui que le test doit prouver.

Cette distinction aide à localiser l’échec sans attribuer trop vite la cause au système d’envoi. Elle rend également le rapport de la suite plus utile à la personne qui corrige le test ou l’application.

Écarter les anciens messages et éprouver les erreurs

Une boîte réutilisée peut contenir des messages issus d’une exécution précédente. Si la tâche renvoie simplement le premier message portant le bon sujet, le test risque de saisir un ancien code. Cette erreur peut être intermittente : le scénario semble fonctionner seul, puis échoue quand plusieurs cas partagent le même récepteur ou quand des messages restent accessibles après un passage précédent.

Le filtrage doit donc s’appuyer sur les informations les plus spécifiques que votre application et votre récepteur peuvent fournir. Associez, si possible, le destinataire à un identifiant d’exécution ou à une référence créée pour cette inscription. Utilisez aussi un marqueur temporel uniquement si l’interface de réception fournit une donnée fiable et si la logique d’horloge de l’environnement est maîtrisée. Un sujet identique ou un code de même format ne suffit pas à prouver qu’il s’agit du bon message.

La conception de l’exécution compte autant que le filtre. Si des scénarios parallèles partagent une seule adresse ou une seule boîte, définissez comment la tâche distingue leurs messages. Si ce rapprochement n’est pas possible, isolez les récepteurs ou les scénarios au lieu de rendre le filtre plus permissif. Le choix d’une adresse de test adaptée à la réception dépend notamment de la capacité à la contrôler et à l’associer sans ambiguïté au cas exécuté.

Ajoutez des tests négatifs correspondant aux règles réelles de votre produit : code erroné, absence de message correspondant et tentative de validation sans confirmation préalable. Pour les demandes répétées, vérifiez si l’application envoie un nouveau message et comment elle traite les codes précédents. La durée de validité, la politique de renvoi et l’invalidation d’un ancien code sont des règles propres au produit testé ; elles ne doivent pas être présentées comme un comportement identique pour tous les services.

Liste de décision à cocher avant de lancer les scénarios :

  • [ ] Chaque exécution a une adresse ou une référence de message distincte. Utilisez cette donnée pour retrouver le message, puis contrôlez aussi le destinataire.
  • [ ] Plusieurs exécutions peuvent partager une boîte. Exigez un identifiant propre au parcours et faites échouer le test si plusieurs messages correspondent.
  • [ ] Le récepteur ne permet pas de distinguer les messages. N’exécutez pas les scénarios concernés en parallèle ; isolez les récepteurs ou adaptez le dispositif avant de poursuivre.
  • [ ] Le test doit prouver la livraison vers des services externes. Ajoutez une recette en préproduction : la lecture d’une boîte de test seule ne suffit pas.
  • [ ] Le test vérifie seulement le flux applicatif et le contenu du message. Une réception contrôlée peut convenir, à condition que le message soit associé sans ambiguïté à l’exécution.

Fermer la boucle dans la CI sans confondre test et livraison

Dans l’intégration continue, le test E2E doit rester reproductible et explicable. Centralisez les paramètres du récepteur dans la configuration de l’environnement de test, gardez les secrets hors du dépôt et évitez de publier des codes dans des journaux accessibles sans contrôle. Les informations de diagnostic doivent permettre de retrouver le cas concerné, sans exposer plus de contenu du message que nécessaire.

Vérifiez également que la tâche Node.js et le processus Cypress utilisent le même environnement et les mêmes paramètres de test. Une configuration locale valide n’est pas une preuve que l’agent d’intégration continue peut joindre le récepteur. Quand un test échoue, consignez des éléments utiles comme le destinataire de test, l’identifiant d’exécution, l’étape en échec et le type de résultat retourné. N’enregistrez pas le code complet dans chaque rapport par commodité.

Le journal des modifications officiel confirme que la série Cypress 16 comporte des mises à jour ; il faut donc contrôler les changements de version dans le journal de Cypress, plutôt que supposer que chaque intégration de messagerie reste compatible sans vérification. Le fait que Cypress 16 soit la version utilisée ne démontre pas, à lui seul, qu’un module de réception particulier fonctionne avec elle. Consultez sa documentation actuelle et validez le branchement dans votre projet. La FAQ officielle de Cypress constitue un autre point de repère pour les questions générales sur le fonctionnement de l’outil, mais elle ne remplace pas les instructions de votre intégration de messagerie.

Enfin, distinguez deux résultats dans vos comptes rendus : le test automatisé confirme le flux d’inscription et le traitement de l’e-mail par l’environnement de test ; la recette en préproduction vérifie la réception dans les conditions externes que vous avez choisies. Pour cette dernière, notez l’environnement, le type de destinataire et le résultat observé. Un succès E2E dans une boîte contrôlée ne prouve pas que chaque service externe classera le message de la même manière.

Pour un scénario ponctuel limité à votre propre produit, une boîte temporaire peut être envisagée à condition que les modalités d’accès, de conservation et de lecture affichées par le service retenu conviennent à votre test. Elle évite d’introduire une adresse personnelle dans les données de régression ; pour les comptes importants, les tests qui exigent des réponses ou les vérifications externes durables, conservez plutôt un récepteur maîtrisé par l’équipe. HourInbox est une option à examiner pour ce périmètre précis : consultez les informations disponibles sur HourInbox avant de l’intégrer, sans supposer qu’elle convient à tous les environnements ou à chaque service externe.

Réception à court terme, contact durable : à chaque usage son adresse.

Pour une démarche ponctuelle, utilisez une boîte de réception avec compte à rebours. Si vous devez recevoir d’autres messages par la suite, créez un alias de transfert durable.