# 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.
> https://facteur.eu/aide/tests-playwright

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.

## Avant de commencer

Deux choses, et rien d'autre :

1. **Une clé d'API en lecture seule.** Créez-la dans
   [**Réglages → Clés d'API**](https://app.facteur.eu/settings/api-keys) et mettez-la
   dans les secrets de votre intégration continue, sous `FACTEUR_API_KEY`. Le test
   ci-dessous ne crée rien : il lit. Voir [Clés d'API](cles-api).
2. **L'identifiant de votre inbox**, les huit caractères affichés en haut de la vue
   inbox.

```ts
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 n'écrivez
aucune expression régulière, et vous n'avez rien à corriger le jour où le gabarit
d'email change.

Les liens sont là aussi : `messages[0].links` en porte un objet par lien, dans l'ordre
où ils apparaissent, avec son `href` et son `text`.

## Installer le greffon Playwright

Le greffon écrit à votre place l'adresse de chaque test et l'attente du message. Il
demande Node 20 et Playwright 1.40 au minimum.

1. Installez-le : `npm i -D playwright-facteur`.
2. Créez une clé dans **Réglages → Clés d'API**, et posez-la en `FACTEUR_API_KEY` dans
   l'environnement de votre chaîne d'intégration.
3. Importez `test` et `expect` depuis `playwright-facteur` plutôt que depuis
   `@playwright/test`.

Vous obtenez une fixture `inbox` qui donne une adresse par test, et des assertions comme
`expect(message).toHaveOtp()` que le moteur de Playwright rejoue tout seul. Le test
ci-dessus n'a pas besoin du greffon et continue de fonctionner tel quel.

L'état de chaque intégration est sur la page [Intégrations](https://facteur.eu/integrations).
