Aller au contenu
Facteur
/ Cypress

Attendre un e-mail sans cy.wait

Cypress exécute votre test dans le navigateur, ce qui pose deux problèmes pour lire un e-mail : la clé d'API ne doit pas s'y trouver, et l'appel réseau dépend de l'origine de la page testée. Une tâche Node règle les deux.

La configuration, puis le test

La clé reste dans Node

La tâche vit dans le processus Cypress, là où la clé peut rester. Le test, lui, ne voit qu'une commande.

cypress.config.js JavaScript
// La clé reste ici, hors du navigateur.
import { defineConfig } from 'cypress';

export default defineConfig({
  e2e: {
    setupNodeEvents(on) {
      on('task', {
        async attendreEmail({ sentTo }) {
          const search = new URLSearchParams({ inbox: 'j3k9x2mq', sentTo, wait: '30000' });
          const response = await fetch('https://api.facteur.eu/v1/messages?' + search, {
            headers: { authorization: 'Bearer ' + process.env.FACTEUR_API_KEY },
          });
          if (!response.ok) throw new Error('Facteur a répondu ' + response.status);

          const { messages } = await response.json();
          return messages[0] ?? null;
        },
      });
    },
  },
});
cypress/e2e/inscription.cy.js JavaScript
// Le numéro de tentative sépare une reprise de l'essai précédent.
it('le code arrive par e-mail', () => {
  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 e-mail n'est arrivé").to.not.be.null;
    expect(message.otp).to.have.length(6);
  });
});
La clé reste côté Node
Votre spec est servie à une page : une clé écrite dedans serait une clé dans le JavaScript d'une page. La tâche la garde de l'autre côté.
cy.task rend une valeur, donc la chaîne continue
Le message revient dans le flux de commandes habituel, et .should() se comporte comme sur un cy.get(). Le timeout de cy.task reste au-dessus du wait envoyé à l'API.
Le numéro de tentative est dans l'adresse
Sans lui, un test rejoué relit l'e-mail de sa première tentative et passe pour une mauvaise raison, précisément quand quelque chose est déjà instable.
Pourquoi

Pourquoi il n'y a pas de cy.wait

01

L'attente se fait chez Facteur

La requête reste ouverte jusqu'à l'arrivée du message, avec un délai maximum que vous fixez. Un cy.wait fixe est soit trop court sur une machine chargée, soit du temps perdu à chaque exécution.

02

Le code est déjà extrait

Le message arrive avec son code à usage unique dans le champ otp.

03

Une inbox suffit pour toute la suite

Chaque test reçoit à sa propre adresse dans la même inbox, sans rien créer. Sur une offre qui n'inclut qu'une inbox, c'est la différence entre une suite qui tourne et une suite qui bute sur un plafond.

Le plugin Cypress

Écrit, pas encore publié

cypress-facteur donne une adresse par test et une commande qui attend le message, la clé restant dans Node. Il n'est pas encore publié sur npm. La configuration ci-dessus reste celle qui ne demande rien à installer, en une trentaine de lignes que vous gardez.

Écrivez ce test aujourd'hui

Une inbox et une clé en lecture seule suffisent. L'offre gratuite ne demande pas de carte bancaire.