How-to

Playwright email testing: wait for the verification email

Playwright email testing means giving the test its own inbox, signing up with that address, and blocking until the verification email lands. Inflovy adds a wait endpoint so the test never sleeps or polls.

Last updated September 18, 2026

Who this is for

1Playwright suites that sign up, reset a password, or confirm a magic link

2CI pipelines where each run needs a fresh address

3Teams that want the email visible in a dashboard when a test fails

In short

To test an email flow in Playwright, create an Inflovy inbox from the test, fill the signup form with its address, then call GET /v1/inboxes/:id/messages/wait?timeout=30. The call returns within about two seconds of the email arriving, with verificationCode already extracted. Delete the inbox in teardown.

Why email steps make tests flaky

An IMAP or Gmail API client adds a polling loop, credentials in CI, and 5–10 seconds per test.

Gmail "+" aliases leak your real address, sites strip the "+", and Gmail silently de-duplicates identical test emails.

Parallel workers that share one mailbox read each other’s codes.

When a test fails, nobody can see what the email actually said.

What changes with a wait endpoint

One inbox per test: created in the test, deleted in teardown, never shared between workers.

wait holds the request open (1–60 s) and returns the first message that arrives after the call started.

verificationCode, candidates[] and links[] come back extracted; the test reads a field, not HTML.

The inbox and its messages stay in the workspace dashboard so a failing run can be inspected.

Step by step

How to do it

  1. 1

    Create an API key

    Settings → API on a Pro or Team workspace. The secret is shown once; store it as INFLOVY_API_KEY in CI.

  2. 2

    Create an inbox in the test

    POST /v1/inboxes with the key. The response has id and emailAddress.

  3. 3

    Sign up with the address

    Fill your form with inbox.emailAddress and submit as usual.

  4. 4

    Wait for the email

    GET /v1/inboxes/:id/messages/wait?timeout=30. Assert status === "received", then use message.verificationCode or message.links[0].

  5. 5

    Clean up

    DELETE /v1/inboxes/:id in afterEach so the inbox count stays low. Messages are removed with it.

Playwright sample
const api = 'https://api.inflovy.com/v1';
const headers = { Authorization: `Bearer ${process.env.INFLOVY_API_KEY}` };
const inbox = await (await fetch(`${api}/inboxes`, { method: 'POST', headers })).json();

await page.goto('https://yourapp.test/signup');
await page.fill('#email', inbox.emailAddress);
await page.click('text=Sign up');

const res = await (await fetch(`${api}/inboxes/${inbox.id}/messages/wait?timeout=30`, { headers })).json();
expect(res.status).toBe('received');
await page.fill('#code', res.message.verificationCode);
await page.click('text=Verify');
await fetch(`${api}/inboxes/${inbox.id}`, { method: 'DELETE', headers });

Needs an API key from Settings → API on a Pro or Team workspace. Full reference at /docs/api.

Comparison

IMAP polling versus an Inflovy wait call.

What the test has to do in each approach.

NeedIMAP / Gmail APIInflovy
Getting an addressA shared mailbox or a "+" alias on a real account.POST /v1/inboxes returns a fresh address in under a second.
Waiting for the emailA retry loop with sleep(); tune the interval, hope the mail is fast.One GET that returns ~2 s after arrival or a clean { status: "timeout" }.
Reading the codeParse MIME, strip HTML, write a regex per template.message.verificationCode and links[] are on the response.
Parallel runsWorkers share one inbox and race for the same message.Each worker owns its inbox; nothing to coordinate.
Credentials in CIA mailbox password or OAuth refresh token.One API key, scoped to the workspace, revocable from Settings.
FAQ

Questions people ask before switching.

Short answers. Inflovy is a receive-only test inbox for developers and QA teams; it does not replace your mailbox or send anything.

How fast does wait return after the email is sent?

Inflovy polls storage every second, so wait returns within about two seconds of the message arriving. Inbound delivery itself usually takes a few seconds from the sender.

What if the email never arrives?

After timeout seconds (1–60) the call returns HTTP 200 with { status: "timeout" } so the test can fail with a clear assertion instead of a network error.

Can I wait for a second email in the same inbox?

Yes. Pass since=<messageId or ISO timestamp> and wait only considers messages that arrived after that marker.

Which plans include the API?

Pro ($12/month) and Team ($39/month). Free workspaces can see the samples and create a key after upgrading; the Chrome extension and dashboard work on every plan.

Related guides

Nearby workflows and comparisons, so you can evaluate the right one without guessing.

Give every Playwright run its own inbox.

Create a workspace, add an API key, and paste the sample. The first inbox on the homepage needs no account at all.