Playwright is the modern standard for browser automation and end-to-end testing. One of the trickiest parts of writing Playwright tests for real-world applications is handling email verification. This guide shows a reliable approach using AgentMailr.
The Old Way: IMAP Polling
// Fragile — race conditions, rate limits, shared inbox pollution
const imap = require("imap");
let otp = null;
// 50+ lines of IMAP boilerplate...
await new Promise(r => setTimeout(r, 5000)); // hope the email arrived
This breaks in CI because email delivery timing is unpredictable. Sleep timers either waste time or cause flaky tests.
The Better Way: Long-Poll API
import { chromium } from "playwright";
const API_KEY = process.env.AGENTMAILR_API_KEY;
const BASE = "https://api.agentmailr.com";
const headers = { "X-API-Key": API_KEY };
async function createInbox() {
const res = await fetch(`${BASE}/v1/inboxes`, {
method: "POST", headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({})
});
return res.json();
}
async function waitForOtp(inboxId) {
const res = await fetch(`${BASE}/v1/inboxes/${inboxId}/otp?timeout=60`, {
headers,
signal: AbortSignal.timeout(65000)
});
return (await res.json()).code;
}
Full Test Example
test("signup with email verification", async ({ page }) => {
// Create a fresh inbox for this test run
const inbox = await createInbox();
await page.goto("https://myapp.com/signup");
await page.fill('[name="email"]', inbox.address);
await page.fill('[name="password"]', "SecurePass123!");
await page.click('[type="submit"]');
// Block until OTP arrives (no sleep needed)
const otp = await waitForOtp(inbox.id);
await page.fill('[name="otp"]', otp);
await page.click("text=Verify");
await expect(page).toHaveURL("/dashboard");
});
Parallel Tests
Because each test creates its own inbox, parallel test runs never collide. Each test gets its own unique email address and its own OTP. This is impossible with a shared Gmail account.
Running in CI
Set AGENTMAILR_API_KEY as a CI secret and you are done. No IMAP firewall rules, no OAuth setup, no email client configuration.