Aller au contenu
Facteur

Tapez au moins deux caractères.

Recevoir un email dans un test Playwright

Le test complet qui attend un email, lit le code qu'il contient et poursuit le parcours, sans sleep et sans paquet à installer.

Un parcours d’inscription se termine dans une boîte mail, et votre test doit lire ce qui y arrive. Voici le fichier entier, sans rien à installer de notre part.

import { expect, test } from '@playwright/test';

const KEY = process.env.FACTEUR_API_KEY!;
const INBOX = 'j3k9x2mq';

/** Reste ouvert jusqu'à l'arrivée du message, trente secondes au plus. */
const attendre = (sentTo: string) =>
  fetch('https://api.facteur.eu/v1/messages/search', {
    method: 'POST',
    headers: {
      authorization: `Bearer ${KEY}`,
      'content-type': 'application/json',
    },
    body: JSON.stringify({ inbox: INBOX, sentTo, wait: 30_000 }),
  }).then((response) => response.json());

test('le lien de vérification active le compte', async ({ page }) => {
  const tag = `run-${Date.now()}`;

  // Lancée avant le clic : elle répond dès que l'email arrive.
  const arrive = attendre(`inscription+${tag}`);

  await page.goto('/inscription');
  await page.getByLabel('Email').fill(`inscription+${tag}@${INBOX}.inbox.facteur.eu`);
  await page.getByRole('button', { name: 'Créer mon compte' }).click();

  const { messages } = await arrive;
  expect(messages[0].status).toBe('parsed');
  await page.goto(messages[0].links[0].href);

  await expect(page.getByText('Compte vérifié')).toBeVisible();
});

Lancez l’attente avant l’action

C’est la seule ligne dont l’ordre compte. La requête part avant le clic, reste ouverte, et répond à l’instant où l’email arrive. Lancée après, elle courrait après un message peut-être déjà traité, et vous verriez ce défaut le jour où votre intégration continue devient lente.

Une adresse par test, sans rien créer

Toute adresse qui finit par le domaine de votre inbox y arrive. Vous n’avez donc pas d’appel à faire pour créer inscription+run-1734@j3k9x2mq.inbox.facteur.eu : il suffit de l’écrire. C’est ce qui permet à seize tests parallèles de partager une inbox sans se voler leurs emails.

Mettez le nom du test et le numéro de tentative dans l’étiquette. Sans le numéro, 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.

Lisez status avant tout le reste

Un email accepté existe avant d’être analysé. Pendant quelques millisecondes il n’a ni sujet, ni code, ni liens. Le champ status sépare « il n’y a pas de code dans ce message » de « le code n’est pas encore extrait ». La recherche ne rend que des messages analysés par défaut, donc le cas ne se présente que si vous demandez status: any.

Le code est déjà sorti du message

messages[0].otp porte le code à usage unique, extrait à la réception. Vous ne réécrivez pas l’expression régulière qui traîne dans toutes les suites de tests, et vous ne la corrigez pas le jour où le gabarit d’email change.

Même chose pour les liens : messages[0].links porte ceux du message, dans l’ordre où ils apparaissent.

Une clé en lecture seule suffit

Le test ci-dessus ne crée rien : il lit. Créez une clé en lecture dans Réglages → Clés d’API, mettez-la dans les secrets de votre intégration continue, et n’en donnez pas plus à une suite de tests.

Et un greffon Playwright ?

Il est prévu et il n’est pas encore publié. Le test ci-dessus n’en a pas besoin : il appelle l’API directement, et continuera de fonctionner quand le greffon sortira. L’état de chaque intégration est sur la page Intégrations.

Vérifié le Cet article est faux ou incomplet ?