Playwrightbeginner
TypeScript SDK + Playwright E2E Test
Test OTP verification with Plop TypeScript SDK and Playwright
TypeScript SDK + Playwright E2E Test (typescript)typescript
import { test, expect } from '@playwright/test';
import { Plop } from '@plop-email/sdk';
const plop = new Plop({ apiKey: process.env.PLOP_API_KEY });
test.describe('OTP Verification', () => {
test('login with OTP code', async ({ page }) => {
const tag = `otp-${Date.now()}`;
const testEmail = `qa+${tag}@in.plop.email`;
// Start login flow
await page.goto('/login');
await page.fill('[name="email"]', testEmail);
await page.click('button[type="submit"]');
// Wait for OTP email — replaces manual polling
const message = await plop.waitFor({
mailbox: 'qa',
tag,
timeout: 15_000,
});
// Extract 6-digit OTP code
const otp = message.textContent?.match(/\b\d{6}\b/)?.[0];
expect(otp).toBeTruthy();
// Enter OTP and verify login
await page.fill('[data-testid="otp-input"]', otp!);
await page.click('button[type="submit"]');
await expect(page.locator('text=Dashboard')).toBeVisible();
});
test('magic link authentication', async ({ page }) => {
const tag = `magic-${Date.now()}`;
const testEmail = `qa+${tag}@in.plop.email`;
// Request magic link
await page.goto('/login');
await page.fill('[name="email"]', testEmail);
await page.click('text=Send Magic Link');
// Wait for magic link email
const message = await plop.waitFor({
mailbox: 'qa',
tag,
timeout: 15_000,
});
// Extract and navigate to magic link
const linkMatch = message.htmlContent?.match(/href="([^"]*magic[^"]*)"/);
expect(linkMatch).toBeTruthy();
await page.goto(linkMatch![1]);
await expect(page.locator('text=Dashboard')).toBeVisible();
});
});How It Works
1
SDK vs Raw API
The Plop SDK replaces manual fetch + polling loops with a single waitFor() call. No need to write retry logic or handle HTTP headers.
2
Tag-based Isolation
Each test uses a unique tag with Date.now() so tests can run in parallel without interfering with each other.
3
Typed Responses
The SDK returns typed Message objects with autocomplete for subject, textContent, htmlContent, and other fields.
4
Timeout Handling
waitFor() throws a clear error if the email does not arrive within the timeout, making test failures easy to diagnose.