Guías

Probar enlaces mágicos y códigos OTP por correo con Playwright

Captura y prueba enlaces de verificación, enlaces mágicos, restablecimientos y códigos OTP con Playwright.

Para probar un enlace de correo o un código OTP con Playwright, asigna a cada prueba un destinatario único de InboxTap, inicia el flujo real en el navegador, espera el valor coincidente del correo capturado y continúa en el navegador. El mismo patrón cubre la verificación del registro, el acceso con un enlace mágico, el restablecimiento de contraseña, los códigos OTP y las invitaciones sin compartir un buzón entre las pruebas.

Hemos probado este patrón exacto en el ejemplo ejecutable de Better Auth y Next.js de InboxTap, incluidos los enlaces de verificación, los enlaces mágicos, el acceso con códigos OTP, el reenvío y los procesos de trabajo paralelos de Playwright.

Iniciar los servicios

Inicia InboxTap junto a la aplicación en la configuración webServer de Playwright o durante la configuración de servicios de CI. Una opción es ejecutar ambos comandos antes del proceso de pruebas:

npx inboxtap &
npm run dev &
npx playwright test

Configura la aplicación que inicia la prueba para que use SMTP localhost:1025. Mantén InboxTap en la interfaz de bucle local incluso en CI.

Probar un enlace de correo

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();
});

Para un enlace mágico o un restablecimiento de contraseña, conserva la estructura de la prueba y cambia los filtros de asunto y contains para que coincidan con el contrato del correo, por ejemplo /sign in/i con /auth/callback o /reset password/i con /reset-password.

Probar un código OTP por correo

Usa waitForCode() cuando la aplicación pida al usuario copiar un código en lugar de seguir un enlace:

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();
});

Elegir la función auxiliar adecuada

Flujo de correoFunción auxiliar de InboxTapFiltros útiles
Enlace de verificaciónwaitForLink()subject, contains
Acceso con enlace mágicowaitForLink()subject, ruta de devolución
RestablecimientowaitForLink()subject, ruta de restablecimiento
OTP numéricowaitForCode()subject, pattern
Invitación o token propiowaitForMatch()subject, expresión regular

Procesos de trabajo paralelos

Crea el buzón dentro de cada prueba o recurso de prueba, nunca una sola vez en el ámbito del módulo para todo el conjunto. Cada llamada genera una dirección de destinatario nueva, por lo que los procesos de trabajo de Playwright pueden compartir un único servidor InboxTap sin leer los mensajes de otros.

Llama a await inbox.clear() después de una prueba cuando la limpieza inmediata facilite la depuración local. El servidor también desaloja mensajes antiguos cuando su almacén acotado alcanza maxMessages.

Preguntas frecuentes

¿Puede Playwright leer un correo directamente?

La página del navegador de Playwright no necesita credenciales de buzón ni una cuenta de correo alojada. La prueba del lado de Node usa InboxTapClient para esperar el correo capturado y después pasa el enlace o código extraído a las acciones del navegador.

¿Cómo evitan los procesos de trabajo paralelos leer el mismo correo?

Crea un buzón dentro de cada prueba o recurso de prueba. Cada llamada a createInbox() devuelve un destinatario único, por lo que todos los procesos de trabajo pueden compartir un servidor local y filtrar por su dirección.

¿Las pruebas de correo con Playwright necesitan Docker?

No. Inicia InboxTap con npx inboxtap, bunx inboxtap o como servidor dentro del proceso, y apunta la configuración SMTP de la aplicación a localhost:1025.