كيفية اختبار التحقق من البريد الإلكتروني في Playwright (الدليل الشامل 2026)
End-to-end tests that involve email verification are notoriously fragile. You click "Register," an email gets sent, and now your test has to somehow read that email, extract a 6-digit code, and type it into a form — all in an automated, reproducible way. If you've tried to solve this before, you know the pain.
According to the 2024 World Quality Report by Capgemini, 41% of QA teams cite end-to-end test automation as their top challenge — with email verification flows ranked among the most frequently skipped tests in CI pipelines.
Source: Capgemini / Sogeti, World Quality Report 2024
Teams that skip email verification tests catch authentication regressions in production, where fixes cost 6× more.
مشكلة الأساليب التقليدية
Most teams encounter one of these dead ends when testing email flows:
- Shared test accounts (Gmail): Works locally, breaks in CI because Google detects bot logins. You also get OTP codes mixed across parallel test runs.
- Mailinator free plan: Public inboxes with no API access on the free tier. Any bot can read your test emails. Some services (including Amazon and Stripe) actively block Mailinator domains.
- Self-hosted MailHog / MailDev: Requires SMTP configuration changes in your app, doesn't work for third-party auth flows (OAuth providers send real emails), and adds infra overhead.
- Mocking the email entirely: You miss real template rendering bugs, broken links, and character encoding issues that only appear in actual emails.
- Ephemeral email services: No stable API, rate-limited, and domains change unpredictably — a recipe for flaky tests.
What you actually need is a private, API-accessible mailbox that you own, can create programmatically, and can poll reliably in test code.
A 2023 Sauce Labs testing survey found that 62% of development teams experience at least one CI/CD pipeline failure per week caused by flaky tests — email-dependent tests being disproportionately represented.
Source: Sauce Labs, State of Digital Quality Report 2023
القسم 1: استخدام واجهة برمجة تطبيقات البريد الحقيقية للاختبار
The cleanest solution is to provision dedicated test mailboxes through an API before each test suite runs, use them during the test, and optionally clean them up afterward. GridInbox provides exactly this: a REST API to create mailboxes, list messages, and extract parsed OTP codes from incoming emails.
The key advantages over alternatives:
- Each test gets its own isolated inbox — no cross-contamination between parallel runs
- Inboxes are private (not publicly accessible like Mailinator)
- OTP codes are parsed server-side and returned in a structured JSON field
- Works with any email provider — the receiving infrastructure is real SMTP/SES
- Custom domains are supported — use your own
@test.yourdomain.com
القسم 2: مثال Playwright الكامل
Let's walk through a full end-to-end test: register a new user, receive the verification email, extract the OTP, submit it, and assert the account is verified.
الخطوة 1: إنشاء صندوق بريد اختباري عبر API
// helpers/email.ts
const API_BASE = 'https://api.gridinbox.com/api/v1';
const API_KEY = process.env.GRIDINBOX_API_KEY!;
export async function createTestInbox(label: string) {
const res = await fetch(`${API_BASE}/mailboxes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
},
body: JSON.stringify({ name: label }),
});
const data = await res.json();
// Returns { id, address, name, ... }
return data as { id: string; address: string };
}
الخطوة 2: استطلاع بريد OTP
export async function waitForOtp(
mailboxId: string,
options = { timeoutMs: 30_000, intervalMs: 2_000 }
): Promise<string> {
const deadline = Date.now() + options.timeoutMs;
while (Date.now() < deadline) {
const res = await fetch(`${API_BASE}/mailboxes/${mailboxId}/messages?limit=1`, {
headers: { 'X-API-Key': API_KEY },
});
const { messages } = await res.json();
if (messages?.length > 0) {
const msg = messages[0];
// GridInbox parses OTPs server-side
if (msg.otp) return msg.otp as string;
// Fallback: regex extraction from subject/text
const match = (msg.subject + ' ' + msg.text_body).match(/\b(\d{4,8})\b/);
if (match) return match[1];
}
await new Promise(r => setTimeout(r, options.intervalMs));
}
throw new Error(`OTP not received within ${options.timeoutMs}ms`);
}
الخطوة 3: اختبار Playwright الكامل
// tests/auth/email-verification.spec.ts
import { test, expect } from '@playwright/test';
import { createTestInbox, waitForOtp } from '../helpers/email';
test('user can verify email after registration', async ({ page }) => {
// 1. Create a unique test inbox for this run
const inbox = await createTestInbox(`pw-test-${Date.now()}`);
const testEmail = inbox.address;
// 2. Register with the test email
await page.goto('/register');
await page.fill('[name="email"]', testEmail);
await page.fill('[name="password"]', 'TestPass123!');
await page.click('[type="submit"]');
// 3. Assert we're on the verification step
await expect(page.locator('text=Check your email')).toBeVisible();
// 4. Fetch the OTP from GridInbox API
const otp = await waitForOtp(inbox.id);
// 5. Fill in the OTP form
await page.fill('[name="otp"]', otp);
await page.click('[type="submit"]');
// 6. Assert success
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('text=Welcome')).toBeVisible();
});
القسم 3: التشغيل في CI/CD
Add your API key as a repository secret in GitHub Actions and reference it in your workflow:
# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]
jobs:
playwright:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npx playwright install --with-deps
- name: Run E2E tests
env:
GRIDINBOX_API_KEY: ${{ secrets.GRIDINBOX_API_KEY }}
run: npx playwright test
Because each test creates its own isolated inbox, parallel test execution works perfectly. Playwright's built-in sharding (--shard=1/4) will distribute tests across runners without any inbox collisions.
القسم 4: أفضل الممارسات
"The single most reliable pattern for email-dependent E2E tests is owning the inbox. Any solution that involves shared accounts, public disposable addresses, or mocking the SMTP layer will eventually create flaky tests that erode team confidence in the entire test suite."
- Name inboxes semantically: Use a prefix like
pw-{testName}-{timestamp}so you can identify which test a mailbox belongs to when debugging. - Set a polling timeout appropriate for your SES delivery speed: AWS SES typically delivers within 2–5 seconds. A 30-second timeout gives plenty of buffer. For slower SMTP relays, increase to 60 seconds.
- Clean up after yourself: Add a
test.afterAllhook that deletes test inboxes via the API. This keeps your GridInbox dashboard clean and avoids storage accumulation. - Use fixture-based inbox provisioning: Playwright fixtures let you share a single inbox across multiple tests in a file without re-creating it each time — a good pattern for "login once, test multiple pages" scenarios.
- Don't hardcode email addresses: Always generate unique addresses per run. Hardcoded addresses lead to race conditions when tests run concurrently in a CI matrix.
الخلاصة
Email verification testing doesn't have to be the flaky, manual-intervention-required nightmare that most teams experience. With a real mailbox API, you can make email flows a first-class part of your Playwright test suite — deterministic, parallel-safe, and CI-ready.
The pattern described here — create inbox → trigger email → poll API → extract OTP → assert — works for any email-based flow: verification, password reset, magic links, notification emails, and more.
ابدأ اختبار تدفقات البريد الإلكتروني اليوم
احصل على حساب GridInbox مجاني وابدأ في إنشاء صناديق بريد اختبار معزولة عبر API في دقائق. لا حاجة لبطاقة ائتمان.
إنشاء حساب مجاني →