MailSlurp integrates with Cypress so you can test real email behavior in browser-driven end-to-end flows. This tutorial covers setup, test structure, and CI hardening.


[![MailSlurp video](https://img.youtube.com/vi/V3kmUe9eeic/hqdefault.jpg)](https://www.youtube.com/watch?v=V3kmUe9eeic)
[Open video on YouTube](https://www.youtube.com/watch?v=V3kmUe9eeic)


## What you can validate

Use Cypress + MailSlurp for flows that break often in production:

- Signup confirmation links
- Password reset links
- OTP passcodes
- Invitation acceptance
- Transactional email content assertions

## How the stack fits together

![browser testing](/assets/cypress-browser-testing.jpg)

- Cypress drives browser actions.
- MailSlurp creates and manages real test inboxes.
- Your tests wait for and assert incoming messages.

This avoids brittle mocks and gives stronger confidence in release pipelines.

## Setup links

- [Cypress plugin docs](/docs/cypress-mailslurp/)
- [Plugin source](https://github.com/mailslurp/cypress-mailslurp)
- [Quick Cypress testing guide](/guides/testing/cypress-js/)

## Configure Cypress and MailSlurp

Start with client configuration:



```javascript
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  defaultCommandTimeout: 30000,
  requestTimeout: 30000,
  viewportHeight: 800,
  viewportWidth: 800,
  videoCompression: false,
  e2e: {
    setupNodeEvents(on, config) {},
  },
})
```



Then implement login or signup helpers in your tests:



```javascript
it('can log in with confirmed account', () => {
  cy.contains('Sign in to your account');
  // fill out username (email) and password
  cy.get('[data-test="username-input"]').type(emailAddress);
  cy.get('[data-test="sign-in-password-input"]').type(password);
  // submit
  cy.get('[data-test="sign-in-sign-in-button"]').click();
});
```



## Add inbox helpers

Create reusable commands for inbox provisioning and retrieval:



```javascript
const { MailSlurp } = require('mailslurp-client');
// set your api key with an environment variable `CYPRESS_API_KEY` or configure using `env` property in config file
// (cypress prefixes environment variables with CYPRESS)
const apiKey = Cypress.env('API_KEY')
const mailslurp = new MailSlurp({ apiKey });

Cypress.Commands.add("createInbox", () => {
  return mailslurp.createInbox();
});

Cypress.Commands.add("waitForLatestEmail", (inboxId) => {
  // how long we should hold connection waiting for an email to arrive
  const timeoutMillis = 30_000;
  return mailslurp.waitForLatestEmail(inboxId, timeoutMillis)
});
```



Use generated inboxes in each test for isolation:



```javascript
const password = "test-password";
let inboxId;
let emailAddress;
it('can generate a new email address and sign up', () => {
  // see commands.js custom commands
  cy.createInbox().then(inbox => {
    // verify a new inbox was created
    assert.isDefined(inbox)

    // save the inboxId for later checking the emails
    inboxId = inbox.id
    emailAddress = inbox.emailAddress;

    // sign up with inbox email address and the password
    cy.get('input[name=email]').type(emailAddress);
    cy.get('input[name=password]').type(password);
    cy.get('[data-test="sign-up-create-account-button"]').click();
  });
});
```



## Practical test blueprint

A robust Cypress email test usually follows this shape:

1. Create a fresh inbox.
2. Trigger the UI flow (signup/reset/login).
3. Wait for matching inbound email.
4. Parse and assert required fields.
5. Continue flow by visiting extracted link or entering OTP.

## CI stability checklist

- One inbox per test worker.
- Explicit timeouts for asynchronous delivery.
- Minimal assertions first; deep assertions second.
- Retry carefully, not as blanket masking.
- Log failing message payloads for triage.

## Related implementation routes

- [Email integration testing](/product/email-integration-testing/)
- [Email Sandbox](/product/email-sandbox/)
- [Webhook reliability testing](/guides/testing-webhooks/)
- [Cypress project example](/examples/cypress-js/)

## Next step

Create a free account and run one signup + confirmation test end-to-end before expanding to OTP and reset scenarios.
