Recevoir un email dans un test Cypress
Une tâche Node qui garde la clé hors du navigateur, et un test qui attend l'email au lieu de patienter un nombre de secondes fixe.
Cypress exécute votre test dans le navigateur, ce qui pose deux problèmes pour lire un email : votre clé d’API n’a rien à faire dans une page, et l’appel réseau répond à l’origine du site testé. Une tâche Node règle les deux d’un coup.
La configuration, où la clé peut rester
// cypress.config.js
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
setupNodeEvents(on) {
on('task', {
async attendreEmail({ sentTo }) {
const response = await fetch('https://api.facteur.eu/v1/messages/search', {
method: 'POST',
headers: {
authorization: 'Bearer ' + process.env.FACTEUR_API_KEY,
'content-type': 'application/json',
},
body: JSON.stringify({ inbox: 'j3k9x2mq', sentTo, wait: 30000 }),
});
const { messages } = await response.json();
return messages[0] ?? null;
},
});
},
},
});
Ce fichier tourne dans le processus Cypress, pas dans la page. La clé y est lue depuis l’environnement et n’atteint jamais le navigateur.
Le test
it('le code arrive par email', () => {
const tag = 'inscription-a' + (Cypress.currentRetry ?? 0) + '-' + Date.now();
cy.visit('/inscription');
cy.get('[name=email]').type(tag + '@j3k9x2mq.inbox.facteur.eu');
cy.contains('button', 'Créer mon compte').click();
cy.task('attendreEmail', { sentTo: tag }, { timeout: 40000 }).should((message) => {
expect(message, "aucun email n'est arrivé").to.not.be.null;
expect(message.otp).to.match(/^[0-9]{6}$/);
});
});
Pourquoi il n’y a pas de cy.wait
L’attente se fait chez nous : la requête reste ouverte jusqu’à l’arrivée du message, avec un délai maximum que vous fixez. Une pause fixe est soit trop courte sur une machine chargée, soit du temps perdu à chaque exécution.
Le timeout passé à cy.task doit rester au-dessus du wait envoyé à l’API :
quarante secondes pour une attente de trente, faute de quoi Cypress abandonne la tâche
avant que la réponse n’arrive, et l’échec accuse le mauvais coupable.
Le numéro de tentative dans l’adresse
Cypress.currentRetry vaut 0 au premier essai. Sans lui, un test rejoué relit l’email
de sa première tentative et passe pour une mauvaise raison, précisément quand quelque
chose est déjà instable.
Une inbox suffit pour toute la suite
Toute adresse finissant par le domaine de l’inbox y arrive, sans rien créer. Chaque test reçoit donc à son adresse dans la même inbox. Sur un plan qui inclut une seule inbox, c’est la différence entre une suite qui tourne et une suite qui bute sur un plafond.
Et un greffon Cypress ?
Il est prévu et il n’est pas encore publié. La version ci-dessus est celle qui fonctionne aujourd’hui, en une trentaine de lignes que vous gardez. L’état de chaque intégration est sur la page Intégrations.
Vérifié le Cet article est faux ou incomplet ?