Intégration Playwright

Tester les emails avec Playwright et InboxTap

InboxTap relie les actions du navigateur Playwright à l’email produit par la véritable application. Son adaptateur gère un serveur SMTP/API local par processus d’exécution et injecte un nouveau destinataire dans chaque test : les parcours email parallèles restent ainsi déterministes sans boîte hébergée partagée.

Adapter la ressource au cycle de vie de Playwright

Importez l’adaptateur depuis inboxtap/fixtures/playwright et étendez votre test Playwright existant. La valeur inboxTap injectée a la portée du processus d’exécution, tandis qu’inbox a la portée du test. Playwright démarre donc le service local une fois par processus tout en donnant à chaque test un destinataire d’enveloppe SMTP distinct.

Ce fonctionnement suit le modèle de dépendances natif de Playwright : une ressource n’est préparée que lorsqu’un test ou une autre ressource en a besoin, et une dépendance démarre avant son consommateur puis s’arrête après lui. InboxTap s’appuie sur cet ordre pour fermer son transport Nodemailer vérifié et ses écouteurs, même en cas d’échec du test.

Démarrer l’application après InboxTap

Lorsque l’application a besoin d’un port SMTP sélectionné automatiquement, démarrez-la dans une ressource de processus qui dépend d’inboxTap. Lisez inboxTap.smtp au moment de créer le processus ou le transport d’email : cette valeur contient l’hôte et le port attribués, ainsi que secure: false et ignoreTLS: true.

La configuration webServer de Playwright démarre avant l’existence des ressources de test. Une application lancée de cette façon ne peut pas utiliser un port choisi plus tard par la ressource InboxTap. Employez des ressources dépendantes pour les ports dynamiques, ou choisissez délibérément des ports fixes et démarrez les deux services avec webServer.

tests/fixtures.ts
import { test as base } from "@playwright/test";
import { extendInboxTap } from "inboxtap/fixtures/playwright";

const withInboxTap = extendInboxTap(base);

export const test = withInboxTap.extend<object, { app: TestApp }>({
  app: [
    async ({ inboxTap }, use) => {
      const app = await startTestApp({ smtp: inboxTap.smtp });
      try {
        await use(app);
      } finally {
        await app.close();
      }
    },
    { scope: "worker" },
  ],
});

Piloter le vrai parcours email

Renseignez inbox.address dans le formulaire de l’application, envoyez-le depuis le navigateur, puis attendez dans le test côté Node le lien, le code ou le message complet attendu. Le navigateur n’a besoin ni d’identifiants de boîte ni d’importer le SDK InboxTap.

Utilisez waitForLink() pour les URL de vérification, de lien magique et de réinitialisation ; waitForCode() pour les codes numériques ; et waitForMessage() lorsque l’assertion porte sur les en-têtes, le HTML ou les destinataires de l’enveloppe. Validez l’origine et le chemin attendus d’une URL capturée avant de demander à la page de l’ouvrir.

  • Créez le destinataire dans chaque test ou utilisez la valeur inbox injectée.
  • Fixez le délai d’InboxTap en dessous de celui du test Playwright afin d’obtenir d’abord l’erreur email la plus utile.
  • Filtrez les messages par un sujet stable ou un chemin de lien lorsque le modèle contient plusieurs URL.

Isoler les processus parallèles

L’isolation repose sur le destinataire de l’enveloppe SMTP, et non sur le vidage d’une boîte globale. Chaque valeur inbox injectée possède une adresse générée, et tous ses appels au SDK filtrent sur cette adresse. Des tests simultanés peuvent donc partager le service d’un processus sans récupérer les messages des autres.

Ne créez pas une seule TestInbox au niveau du module pour toute la suite. Évitez aussi le vidage global pendant l’exécution d’autres tests : supprimer l’état partagé du serveur peut retirer un message qu’un autre destinataire attend encore.

Vérifier la livraison sans divulguer les secrets

L’adaptateur d’assertions Playwright renvoie un objet expect étendu. Utilisez-le avec toHaveDeliveredOnce(), toHaveRecipient() et toContainLink() lorsqu’une assertion concise est plus claire qu’une inspection manuelle des champs.

toHaveDeliveredOnce() observe l’instantané actuel de la boîte ; il n’attend pas le premier message. Attendez la livraison de l’application ou appelez d’abord waitForMessage() lorsque l’email part en arrière-plan. Les échecs d’assertion omettent volontairement le corps du message, les valeurs des destinataires et les liens porteurs de jetons.

Laisser le comportement métier au test applicatif

InboxTap prouve ce qui a atteint la frontière SMTP locale et aide à extraire la valeur nécessaire au navigateur. Le test Playwright reste responsable des assertions du produit : usage unique d’un jeton, rejet d’un lien expiré, absence de doublons métier après une nouvelle tentative et droits attendus de la session finale.

Construire le parcours Playwright complet

Consultez le parcours navigateur complet, avec démarrage des services sur des ports fixes, saisie des OTP, processus parallèles et dépannage.

Lire le guide Playwright