Complete Playwright examples for email testing with Mailoverse. Learn to test signup flows, email verification, password reset, and MFA with custom fixtures and helper functions.
Playwright
Complete examples for testing email flows with Playwright, including signup verification, password reset, and custom fixtures.
Helper Functions
Create a helper file to generate test emails and wait for them to arrive:
// tests/helpers/mailoverse.ts
import { Page } from '@playwright/test';
const MAILOVERSE_API_KEY = process.env.MAILOVERSE_API_KEY!;
const MAILOVERSE_DOMAIN = process.env.MAILOVERSE_DOMAIN!;
export function generateTestEmail(prefix = 'test') {
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2)}@${MAILOVERSE_DOMAIN}`;
}
export async function waitForEmail(
page: Page,
address: string,
options: { timeout?: number; interval?: number } = {}
) {
const { timeout = 30000, interval = 1000 } = options;
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const response = await page.request.get(
`https://api.mailoverse.com/email?address=${encodeURIComponent(address)}`,
{
headers: { 'Authorization': `Bearer ${MAILOVERSE_API_KEY}` },
}
);
const data = await response.json();
if (data.email) {
return data.email;
}
await page.waitForTimeout(interval);
}
throw new Error(`Timeout waiting for email to ${address}`);
}Signup Test
Using the helper in a signup flow test:
// tests/signup.spec.ts
import { test, expect } from '@playwright/test';
import { generateTestEmail, waitForEmail } from './helpers/mailoverse';
test('user can sign up and verify email', async ({ page }) => {
const testEmail = generateTestEmail('signup');
// Complete signup flow
await page.goto('/signup');
await page.fill('[name="email"]', testEmail);
await page.fill('[name="password"]', 'SecurePass123!');
await page.click('button[type="submit"]');
// Wait for verification email
const email = await waitForEmail(page, testEmail);
expect(email.subject).toContain('Verify');
expect(email.parsedHtml.links).toHaveLength(1);
// Click the verification link
const verifyLink = email.parsedHtml.links.find(
(link: { href: string }) => link.href.includes('/verify')
);
expect(verifyLink).toBeDefined();
await page.goto(verifyLink.href);
await expect(page.locator('h1')).toContainText('Email Verified');
});Password Reset Test
Testing a complete password reset flow:
test('user can reset password', async ({ page }) => {
const testEmail = generateTestEmail('reset');
// Create account first
await page.goto('/signup');
await page.fill('[name="email"]', testEmail);
await page.fill('[name="password"]', 'OldPassword123!');
await page.click('button[type="submit"]');
// Wait for signup email and verify
const signupEmail = await waitForEmail(page, testEmail);
const verifyLink = signupEmail.parsedHtml.links[0];
await page.goto(verifyLink.href);
// Now request password reset
await page.goto('/forgot-password');
await page.fill('[name="email"]', testEmail);
await page.click('button[type="submit"]');
// Wait for reset email
const resetEmail = await waitForEmail(page, testEmail);
expect(resetEmail.subject).toContain('Reset');
const resetLink = resetEmail.parsedHtml.links.find(
(link: { href: string }) => link.href.includes('/reset-password')
);
// Complete password reset
await page.goto(resetLink.href);
await page.fill('[name="password"]', 'NewPassword456!');
await page.fill('[name="confirmPassword"]', 'NewPassword456!');
await page.click('button[type="submit"]');
await expect(page.locator('h1')).toContainText('Password Updated');
});Custom Fixtures
For cleaner tests, create custom Playwright fixtures:
// tests/fixtures.ts
import { test as base } from '@playwright/test';
import { generateTestEmail, waitForEmail } from './helpers/mailoverse';
type MailoverseFixtures = {
testEmail: string;
getEmail: () => Promise<any>;
};
export const test = base.extend<MailoverseFixtures>({
testEmail: async ({}, use) => {
const email = generateTestEmail();
await use(email);
},
getEmail: async ({ page, testEmail }, use) => {
await use(async () => {
return await waitForEmail(page, testEmail);
});
},
});
export { expect } from '@playwright/test';
// Usage in tests:
// tests/signup.spec.ts
import { test, expect } from './fixtures';
test('signup flow', async ({ page, testEmail, getEmail }) => {
await page.goto('/signup');
await page.fill('[name="email"]', testEmail);
await page.fill('[name="password"]', 'Test123!');
await page.click('button[type="submit"]');
const email = await getEmail();
expect(email.subject).toContain('Verify');
});