automated email testing

Testing email OTP flows in Cypress using temporary API inboxes

Eliminate flakiness in Cypress multi-factor authentication tests by fetching real OTP codes via a long-polling inbox API.

By Dennis Farren·September 12, 2026·3 min read
What matters here
  1. InboxRhino's wait endpoint polls for incoming messages up to 180 seconds in a single HTTP request.
  2. Creating dynamic temporary inboxes via API prevents cross-test state leaks during Cypress login runs.
  3. Free tier accounts include 11 active inboxes and 33 inbound emails per month for local development setup.

The Flakiness of 2FA Email Testing

End-to-end testing for multi-factor authentication (MFA) and one-time passwords (OTP) often fails for the wrong reasons. Traditional test suites rely on static shared mailboxes, database hooks, or SMTP mocks. Static mailboxes choke when tests run concurrently. Database hooks skip the mail delivery layer entirely, hiding infrastructure outages and broken email formatting.

To verify a real user signup or login flow, Cypress needs to interact with real MX servers. It must generate a temporary inbox, submit the email address to your app, wait for the incoming message, extract the passkey, and complete the UI form.

Step 1: Provisioning a Test Inbox in Cypress

InboxRhino provides receive-only MX inboxes running on test.inboxrhino.in routed via Cloudflare. You do not need local SMTP sandboxes or external SDKs. Instead, make standard HTTP calls directly inside your Cypress tests.

To generate a single inbox before your login test runs, execute a POST request to the API at https://api.inboxrhino.in/v1/inboxes using your API key in the authorization header. The API returns a payload containing a unique inbox ID and its assigned address.

Creating an inbox dynamically for each test execution guarantees isolation. Parallel test runs will not pick up verification codes meant for other test threads.

Step 2: Submitting the Verification Form

Once you receive the address string from the API response, instruct Cypress to interact with your frontend. Pass the generated email address into your application's signup or password-reset input field and submit the form.

Your backend application handles account creation and queues the verification email through normal outbound SMTP routes. The message travels across public DNS to reach the inbox infrastructure.

Step 3: Waiting for the Email via Long Polling

Email delivery is inherently asynchronous. Network latency and message queuing mean an email might arrive in two seconds or twenty. Adding static sleep delays in Cypress leads to slow, brittle test suites.

InboxRhino handles this delay with a wait parameter on its message listing endpoint. When sending a GET request to https://api.inboxrhino.in/v1/inboxes/{id}/messages, append wait_seconds=180 to the query parameters.

This parameter instructs the API server to hold the connection open for up to 180 seconds. The server returns immediately once a matching email arrives. You can filter the query using subject lines like subject=Verify and include full body payloads with include=content.

Issue a cy.request() command inside Cypress to poll this endpoint. When the server responds, the returned JSON body contains the parsed message text and raw HTML.

Step 4: Extracting the Code and Asserting UI State

With the message body returned in the API response, use standard JavaScript string tools or regular expressions to pull out the security code.

For example, if your service sends a six-digit code, match against a numeric pattern inside the message body string. Pass the extracted code back into standard Cypress commands:

  • Extract: Parse the OTP string from the returned message content.
  • Input: Pass the code into the OTP input field using Cypress.
  • Verify: Submit the form and assert that the authenticated dashboard loads.

If the email fails to arrive within the 180-second window, the API request fails, pinpointing delivery delays in your test reports.

Visual Debugging with the Sandboxed Viewer

When automated tests fail, raw API responses do not always show layout or rendering bugs. InboxRhino includes a browser console with a sandboxed mailbox viewer for visual debugging.

The console renderer isolates incoming emails to prevent security risks and bad script execution during QA reviews:

  • Blocked scripts and popups: JavaScript and popup windows are blocked completely.
  • Form restrictions: Interactive HTML forms inside the message frame cannot submit data.
  • Remote image blocking: External tracker images and assets are blocked by default.

QA team members can log in, select the mailbox, and review the actual email HTML as rendered in a real inbox.

Limits and Lifecycle Management

When structuring your test suite around real MX endpoints, keep account quotas and architectural constraints in mind:

  • Receive-only architecture: Test addresses cannot send, reply to, or forward emails. They function strictly as inbound catch points for automated tests.
  • 30-day retention: Message content, headers, and attachments are retained for 30 days before automatic deletion. Mailboxes persist until deleted manually or via API.
  • Free tier quotas: The live free plan provides 11 active inboxes, 33 inbound emails per UTC calendar month, and 1 organization user. This tier offers enough volume to wire and test a core user flow.
  • Paid plans: Paid Starter, Growth, and Scale plans are marked as coming soon, offering up to 16,500 active inboxes and 55,000 monthly emails under INR billing with GST support.
More from InboxRhino News