playwright-receivemail
v0.1.1
Published
Playwright fixture for reading verification emails from a free disposable inbox (receivemail.dev) — no signup, no API key.
Maintainers
Readme
playwright-receivemail
A Playwright fixture for reading verification emails in end-to-end tests, backed by receivemail.dev — a free disposable inbox with no signup and no API key.
Use it to test the parts of a signup flow that usually go untested: the "confirm your email" link, the emailed login code, the password-reset mail.
Install
npm i -D playwright-receivemail@playwright/test is a peer dependency (you already have it).
Use
import { test, expect } from "playwright-receivemail";
test("a new user can verify their email", async ({ page, mailbox }) => {
// `mailbox.address` is a fresh @receivemail.dev address, unique per test
await page.goto("/signup");
await page.getByLabel("Email").fill(mailbox.address);
await page.getByLabel("Password").fill("test-Pa55w0rd");
await page.getByRole("button", { name: "Create account" }).click();
// wait for the verification email and pull the link out of it
const link = await mailbox.waitForMatch(/https:\/\/[^\s"]+\/verify[^\s"]*/, {
subjectContains: "verify",
timeout: 30_000,
});
await page.goto(link);
await expect(page.getByText("Email verified")).toBeVisible();
});Getting a numeric code instead of a link
const code = await mailbox.waitForMatch(/\b\d{6}\b/);
await page.getByLabel("Verification code").fill(code);The whole message
const msg = await mailbox.waitForMessage({ fromContains: "noreply@yourapp" });
console.log(msg.subject, msg.body_text);API
test / expect
Playwright's test extended with one fixture:
mailbox— aMailboxcreated fresh for each test.
If you already extend test yourself, compose instead:
import { test as base } from "@playwright/test";
import { withReceivemail } from "playwright-receivemail";
export const test = withReceivemail(base, { ttlMinutes: 30 });Mailbox
| Member | Description |
| --- | --- |
| address | The @receivemail.dev address to give your app under test. |
| expiresAt | ISO timestamp when the mailbox stops accepting mail. |
| list() | All messages currently in the mailbox, newest first. |
| waitForMessage(opts?) | Poll until a matching message arrives; returns it or throws on timeout. |
| waitForMatch(regex, opts?) | waitForMessage then return the first substring of the body matching regex. |
WaitForMessageOptions: timeout (default 30000), pollInterval (default 2000),
subjectContains, fromContains, onlyNew (default true — ignore mail that
predates this test).
createTestMailbox(config?)
Create a Mailbox outside a fixture (e.g. in globalSetup or a non-Playwright
script).
Config
withReceivemail(base, config) / createTestMailbox(config) accept:
ttlMinutes— mailbox lifetime, 1–60. Default 15.baseURL— override the API host (defaulthttps://receivemail.dev).
Limits
receivemail.dev creates are rate-limited to 20 per minute per IP — fine for a normal suite, worth batching if you fan out hundreds of parallel workers. Mailboxes live at most 60 minutes; this is for test flows, not a real inbox.
Testing an SMS code instead? See sms-florin (rent a real number) or otp-watch (delivery monitoring).
Coming from another tool?
Side-by-side comparisons, with each vendor's current pricing: MailSlurp · Mailosaur · Mailinator · Mailsac
License
MIT
