Direct answer

How do you test email verification with Playwright?

Use Playwright for the product UI and a separate scoped inbox client for the message.

Maintained by Evidence checked Editorial method

Open the quickstart
Direct answer

Create a unique test inbox before opening the signup flow, enter that address with Playwright, submit the form, wait for the matching inbound message through an email API or CLI, extract the OTP or validate the confirmation URL, then continue in Playwright and assert the verified state. Use a deadline and never automate a personal webmail inbox.

Visual guide

Decision map

Keep browser and inbox responsibilities separate

  1. 01
    Owns the user interface

    Fills the email address, requests verification, enters the code or follows the link, and asserts the final UI.

  2. 02
    Owns email state

    Creates the mailbox, waits for inbound mail, parses the result, and reports delivery diagnostics.

Tool roles

Keep browser and inbox responsibilities separate

Playwright

Owns the user interface

Fills the email address, requests verification, enters the code or follows the link, and asserts the final UI.

Inbox client

Owns email state

Creates the mailbox, waits for inbound mail, parses the result, and reports delivery diagnostics.

Workflow

Run the end-to-end verification

  1. 01

    Allocate the recipient

    Create or reserve an isolated inbox and expose only its address to the browser fixture.

  2. 02

    Trigger the email

    Submit the form and record the time and expected sender or application.

  3. 03

    Wait outside Playwright

    Use the inbox API, SDK, or CLI with a timeout and recipient match.

  4. 04

    Validate the result

    Extract the current code or require the expected HTTPS host for the link.

  5. 05

    Finish the browser assertion

    Enter or navigate, then assert the account is verified and clean up test state.

Wait for the OTP
mails code --to "$TEST_EMAIL" --timeout 60
Reliability

Use conditions instead of sleeps

A fixed sleep waits too long when delivery is fast and still fails when delivery is slow. A bounded wait stops immediately when the expected message arrives and reports a clear timeout otherwise.

Use recipient, trigger time, direction, and sender or subject context. The global latest message is not a safe match when tests run in parallel.

  • Unique inbox or recipient per test.
  • Explicit deadline and poll interval.
  • No reuse of stale code or link.
  • Redacted message and timing evidence on failure.
Link safety

Validate magic links before navigation

CheckReason
Scheme is HTTPSAvoid plaintext or unsupported navigation.
Hostname is expectedPrevent arbitrary links from controlling the browser.
Recipient and token belong to current runPrevent cross-test or stale-message use.
Link is single-use or expires as designedVerify the security behavior, not only the happy path.
Evidence

Sources and product scope

Product behavior is verified against the mails0 source and documentation. External comparisons link to official vendor documentation checked on 2026-08-15.

Questions and answers

Related questions

Does Playwright include an email inbox?

No. Pair Playwright with an email API, CLI, or SDK to retrieve messages outside the browser.

Can I test OTP and magic links with the same pattern?

Yes. The mailbox wait is the same; validate and return either the code or an expected-host URL to the browser step.

Should each parallel test use a different inbox?

Yes, or at least a uniquely addressable recipient and strict message matching so tests cannot consume each other's email.

Start with a bounded inbox

Give the agent an inbox, then prove the workflow.

Start with a receive-only temporary mailbox. Move to a permanent identity or self-hosted deployment only after the workflow reaches a real email value event.

Open the quickstart