Playwright
Create an inbox, let the app send normally, wait, then follow the link.
Playwright consumes @mailwurf/e2e. It is not a dependency of the client.
The app under test keeps its production sender. The test only sets the recipient to inbox.address.
import { expect, test } from "@playwright/test";
import { createClient } from "@mailwurf/e2e";
const mailwurf = createClient(); // MAILWURF_API_KEY, API at https://api.mailwurf.io
test("confirms signup from the inbox", async ({ page }) => {
const inbox = await mailwurf.createInbox();
await page.goto(process.env.APP_URL ?? "http://localhost:3000/signup");
await page.getByLabel("Email").fill(inbox.address);
await page.getByRole("button", { name: "Sign up" }).click();
const mail = await inbox.waitFor({ subject: "Confirm", timeout: 15_000 });
const link = mail.links[0];
expect(link).toBeTruthy();
if (!link) {
throw new Error("confirm mail had no link");
}
await page.goto(link);
await expect(page.getByText("confirmed")).toBeVisible();
});CI needs MAILWURF_API_KEY and the app origin. Set MAILWURF_URL only for a Mailwurf origin other than https://api.mailwurf.io. Optional: await inbox.delete() when the test finishes. Temporary inboxes also expire on their own.