Guides

Tester les liens magiques et les OTP par email avec Playwright

Capturez et testez les liens de vérification, les liens magiques, les réinitialisations et les OTP avec Playwright.

Pour tester un lien email ou un OTP avec Playwright, donnez à chaque test un destinataire InboxTap unique, déclenchez le vrai parcours navigateur, attendez la valeur correspondante dans l'email capturé, puis poursuivez dans le navigateur. Le même modèle couvre vérification d'inscription, lien magique, réinitialisation, OTP et invitation sans boîte de test partagée.

Nous avons testé ce modèle exact dans l'exemple exécutable Better Auth et Next.js d'InboxTap, avec liens de vérification, liens magiques, connexion OTP, renvoi et processus Playwright parallèles.

Démarrer les services

Démarrez InboxTap aux côtés de l’application dans la configuration webServer de Playwright ou dans la configuration de vos services CI. Une option consiste à lancer les deux commandes avant le processus de test :

npx inboxtap &
npm run dev &
npx playwright test

Configurez l’application lancée par le test pour utiliser SMTP localhost:1025. Gardez InboxTap sur l’interface de bouclage, même en CI.

Tester un lien email

import { test, expect } from "@playwright/test";
import { InboxTapClient } from "inboxtap/client";

const inboxTap = new InboxTapClient();

test("verifies a new account", async ({ page }) => {
  const inbox = await inboxTap.createInbox({ alias: "signup" });

  await page.goto("/signup");
  await page.getByLabel("Email").fill(inbox.address);
  await page.getByRole("button", { name: "Create account" }).click();

  const verificationUrl = await inbox.waitForLink({
    subject: /verify your email/i,
    contains: "/verify",
    timeoutMs: 20_000,
  });

  await page.goto(verificationUrl);
  await expect(page.getByText("Email verified")).toBeVisible();
});

Pour un lien magique ou une réinitialisation, conservez la structure du test et modifiez les filtres de sujet et contains selon le contrat de l'email, par exemple /sign in/i avec /auth/callback ou /reset password/i avec /reset-password.

Tester un OTP par email

Utilisez waitForCode() quand l'application demande à l'utilisateur de copier un code plutôt que de suivre un lien :

test("signs in with an email OTP", async ({ page }) => {
  const inbox = await inboxTap.createInbox({ alias: "signin" });

  await page.goto("/sign-in");
  await page.getByLabel("Email").fill(inbox.address);
  await page.getByRole("button", { name: "Send code" }).click();

  const otp = await inbox.waitForCode({
    subject: /sign-in code/i,
    timeoutMs: 20_000,
  });

  await page.getByLabel("One-time code").fill(otp);
  await page.getByRole("button", { name: "Verify" }).click();
  await expect(page.getByText("Signed in")).toBeVisible();
});

Choisir la bonne méthode

Parcours emailMéthode InboxTapFiltres utiles
Lien de vérificationwaitForLink()subject, contains
Connexion par lien magiquewaitForLink()subject, chemin de rappel
RéinitialisationwaitForLink()subject, chemin de réinitialisation
OTP numériquewaitForCode()subject, pattern
Invitation ou jeton proprewaitForMatch()subject, expression régulière

Processus parallèles

Créez la boîte dans le test ou sa configuration, jamais une seule fois au niveau du module pour toute la suite. Chaque appel génère une nouvelle adresse destinataire, donc les processus Playwright peuvent partager un seul serveur InboxTap sans lire les messages des autres.

Appelez await inbox.clear() après un test quand un nettoyage immédiat aide au débogage local. Le serveur évince aussi les anciens messages quand son stockage borné atteint maxMessages.

Questions fréquentes

Playwright peut-il lire directement un email ?

La page navigateur Playwright n'a besoin ni d'identifiants de boîte ni d'un compte email hébergé. Le test côté Node utilise InboxTapClient pour attendre l'email capturé, puis transmet le lien ou le code extrait aux actions du navigateur.

Comment les processus parallèles évitent-ils de lire le même email ?

Créez une boîte dans chaque test ou sa configuration. Chaque appel à createInbox() renvoie un destinataire unique : tous les processus partagent ainsi un serveur local tout en filtrant sur leur propre adresse.

Les tests d'email Playwright ont-ils besoin de Docker ?

Non. Démarrez InboxTap avec npx inboxtap, bunx inboxtap ou comme serveur dans le processus, puis pointez la configuration SMTP de l'application vers localhost:1025.