Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungFliproom: a room changeover is a content problem(21.09.2026 um 04:10 Uhr)
Sichere ProgrammierungNova Adiutrix: My Second Agent Built My First Project's To-Do List(21.09.2026 um 04:11 Uhr)
IT Security ToolsAntiphishing v35456910988(21.09.2026 um 02:35 Uhr)
IT Security Toolsbrave-browser v1.98.12(21.09.2026 um 03:35 Uhr)
Sichere ProgrammierungFliproom: a room changeover is a content problem(21.09.2026 um 04:10 Uhr)
Sichere ProgrammierungNova Adiutrix: My Second Agent Built My First Project's To-Do List(21.09.2026 um 04:11 Uhr)
IT Security ToolsAntiphishing v35456910988(21.09.2026 um 02:35 Uhr)
IT Security Toolsbrave-browser v1.98.12(21.09.2026 um 03:35 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

How to E2E Test Mailgun Email Workflows in Playwright

Reagiere als Erste:r — dein Feedback zählt!

Mailgun is a popular transactional email API trusted by developers for reliable delivery. But how do you test that your Mailgun emails actually arrive, contain the right content, and work end-to-end in CI?

This guide covers the full testing progression — from local development to automated Playwright tests in GitHub Actions.

The app we're testing

A Next.js API route that sends a verification email via Mailgun:

// app/api/auth/signup/route.ts
import Mailgun from 'mailgun.js';
import FormData from 'form-data';

const mailgun = new Mailgun(FormData);
const mg = mailgun.client({
  username: 'api',
  key: process.env.MAILGUN_API_KEY!,
});

export async function POST(req: Request) {
  const { email } = await req.json();

  const token = crypto.randomUUID();
  const verifyUrl = `${process.env.NEXT_PUBLIC_URL}/verify?token=${token}`;

  await mg.messages.create(process.env.MAILGUN_DOMAIN!, {
    from: '[email protected]',
    to: email,
    subject: 'Verify your email',
    html: `<p>Click <a href="${verifyUrl}">here</a> to verify your email.</p>`,
  });

  return Response.json({ success: true });
}

Stage 1 — Local development: Mailgun sandbox domain

Mailgun provides a sandbox domain for testing. Emails sent to the sandbox domain are captured in your Mailgun dashboard without being delivered to real inboxes.

const mg = mailgun.client({
  username: 'api',
  key: process.env.MAILGUN_API_KEY!,
});

// Use sandbox domain for local development
await mg.messages.create(
  process.env.NODE_ENV === 'development'
    ? process.env.MAILGUN_SANDBOX_DOMAIN!  // sandbox.mailgun.org
    : process.env.MAILGUN_DOMAIN!,
  {
    from: '[email protected]',
    to: email,
    subject: 'Verify your email',
    html: `<p>Click <a href="${verifyUrl}">here</a> to verify.</p>`,
  }
);

Important: Mailgun's sandbox domain only delivers to pre-authorized recipient email addresses. You must add your test email to the authorized list in your Mailgun dashboard.

What it solves: Visual inspection during local development without sending real emails.

What it doesn't solve: Automated testing. You can't programmatically read emails from Mailgun's dashboard in a Playwright test. The authorized recipient limitation also makes it unsuitable for CI where you need random inbox addresses.

Stage 2 — Staging: Mailgun live domain to a real inbox

Switch to your live Mailgun domain for staging:

await mg.messages.create(process.env.MAILGUN_DOMAIN!, {
  from: '[email protected]',
  to: email,
  subject: 'Verify your email',
  html: `<p>Click <a href="${verifyUrl}">here</a> to verify.</p>`,
});

Emails now go through real delivery. You can manually verify they arrive, links work, and nothing lands in spam.

What it solves: Does the email actually reach a real inbox end-to-end?

What it doesn't solve: Automation. You can't run this in CI without access to a real inbox your test can read.

Stage 3 — CI: Mailgun live domain + ZeroDrop

For automated Playwright tests in GitHub Actions:

npm install zerodrop-client
import { test, expect } from '@playwright/test';
import { ZeroDrop } from 'zerodrop-client';

const mail = new ZeroDrop();

test('user can sign up and verify email', async ({ page }) => {
  // 1. Generate a disposable inbox
  const inbox = process.env.TEST_INBOX ?? mail.generateInbox();
  // → "[email protected]"

  // 2. Sign up — Mailgun sends a real verification email to this inbox
  await page.goto('/signup');
  await page.fill('[data-testid="email"]', inbox);
  await page.click('[data-testid="submit"]');

  await expect(page).toHaveURL('/check-email');

  // 3. ZeroDrop catches the email — magic link auto-extracted
  const email = await mail.waitForLatest(inbox, { timeout: 30000 });

  expect(email.subject).toContain('Verify your email');
  expect(email.magicLink).not.toBeNull();

  // 4. Click the verification link
  await page.goto(email.magicLink!);

  // 5. Assert verified
  await expect(page).toHaveURL('/dashboard');
});

No authorized recipient list. No sandbox limitations. ZeroDrop generates a new inbox for every test run — Mailgun delivers to it like any real email address.

OTP flows

await mg.messages.create(process.env.MAILGUN_DOMAIN!, {
  from: '[email protected]',
  to: email,
  subject: 'Your verification code',
  html: `<p>Your code is: <strong>${otp}</strong></p>`,
});
const email = await mail.waitForLatest(inbox, { timeout: 30000 });

// OTP auto-extracted at the edge — no regex needed
expect(email.otp).not.toBeNull();
await page.fill('[data-testid="otp"]', email.otp!);
await page.click('[data-testid="verify"]');

Using Mailgun templates

If you use Mailgun's stored templates:

await mg.messages.create(process.env.MAILGUN_DOMAIN!, {
  from: '[email protected]',
  to: email,
  template: 'verify-email',
  'h:X-Mailgun-Variables': JSON.stringify({
    verify_url: verifyUrl,
    username: 'Test User',
  }),
});
// ZeroDrop catches the fully rendered template
const email = await mail.waitForLatest(inbox, { timeout: 30000 });
expect(email.magicLink).not.toBeNull();

This tests that your Mailgun template renders correctly with real variable substitution.

GitHub Actions workflow

name: E2E Tests

on: [push, pull_request]

jobs:
  test:
    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 chromium

      - name: Generate test inbox
        id: inbox
        uses: zerodrop-dev/create-inbox@8706a59 # v1.0.0

      - name: Run E2E tests
        run: npx playwright test
        env:
          TEST_INBOX: ${{ steps.inbox.outputs.inbox }}
          MAILGUN_API_KEY: ${{ secrets.MAILGUN_API_KEY }}
          MAILGUN_DOMAIN: ${{ secrets.MAILGUN_DOMAIN }}
          NEXT_PUBLIC_URL: ${{ secrets.STAGING_URL }}
// Use CI inbox or generate locally
const inbox = process.env.TEST_INBOX ?? mail.generateInbox();

The full picture

Sandbox domain (local) Live domain (staging) Live domain + ZeroDrop (CI)
Visual inspection ✅ dashboard ✅ real inbox ✅ automated
No real emails sent
Authorized recipients only ✅ (limitation)
Automated in CI
Random test addresses
Parallel test runs
OTP auto-extraction
Tests real delivery

Use the sandbox during development, the live domain for manual staging verification, and the live domain + ZeroDrop for automated CI.

ZeroDrop — disposable email inboxes for CI pipelines. Free, no signup, no Docker.
zerodrop.dev · docs · npm

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How to E2E Test Mailgun Email Workflows in Playwright

Thematisch verwandte Begriffe: Test, Mailgun, Email, Workflows · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-93974 | A flaw has been found in SourceCodester Online Reviewer Management Syste…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick