# cypress-mailslurp

> Cypress email and SMS plugin for MailSlurp. Create test email accounts to send and receive emails in Cypress tests. Read SMS and TXT messages too and test against fake mailservers.

Latest version **2.0.0** (published 2026-09-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install cypress-mailslurp
pnpm add cypress-mailslurp
yarn add cypress-mailslurp
bun add cypress-mailslurp
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.0.0 |
| Published | 2026-09-24 |
| First published | 2021-04-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 22.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | mailslurp |
| Maintainers | caseartifact, office-mailslurp |

## Links

- npm: https://www.npmjs.com/package/cypress-mailslurp
- npm.io page: https://npm.io/package/cypress-mailslurp

## Dependencies (1)

- [mailslurp-client](https://npm.io/package/mailslurp-client.md) ^17.6.0

## Recent versions

- 2.0.0 (latest) — 2026-09-24
- 1.11.1 — 2025-08-19
- 1.11.0 — 2025-08-19
- 1.10.0 — 2024-05-03
- 1.9.0 — 2024-01-12
- 1.7.0 — 2023-03-24
- 1.6.0 — 2023-01-31
- 1.5.0 — 2022-08-16
- 1.4.0 — 2022-05-29
- 1.3.0 — 2021-10-13
- 1.1.0 — 2021-05-22
- 1.0.1 — 2021-04-12
- 1.0.0 — 2021-04-11
- 0.1.0 — 2021-04-11

## README

# MailSlurp Cypress Plugin
Official MailSlurp email plugin for Cypress JS. Create real test email accounts. Send and receive emails, SMS, and attachments in Cypress tests. For examples and usage see the standard [MailSlurp library](https://www.npmjs.com/package/mailslurp-client).

## Tutorial
[![Cypress email test tutorial](https://www.mailslurp.com/video-thumbnails/cypress-test-still.jpg)](https://www.youtube.com/watch?v=Ud274da6NIE)

## Test email and SMS/TXT messages in Cypress
With MailSlurp and Cypress you can:
- create unlimited, disposable email addresses for testing
- send and receive emails in tests
- send and receive SMS messages in tests
- capture outbound emails with fake mailservers
- extract email verification codes and OTP magic links

### Example

```typescript
it('can sign up using throwaway mailbox', function () {
    // create a mailslurp instance
    cy.mailslurp().then(function (mailslurp) {
        cy.clearAllLocalStorage();
        cy.clearAllCookies();
        // visit the demo application
        cy.visit('/');
        // create an email address and store it on this
        cy.then(() => mailslurp.createInbox())
            .then((inbox) => {
                // save inbox id and email address to this
                cy.wrap(inbox.id).as('inboxId');
                cy.wrap(inbox.emailAddress).as('emailAddress');
            })
        // fill user details on app
        cy.get('[data-test=sign-in-create-account-link]').click()
        cy.then(function () {
            // access stored email on this, make sure you use Function and not () => {} syntax for correct scope
            cy.get('[name=email]').type(this.emailAddress)
            cy.get('[name=password]').type('test-password')
            return cy.get('[data-test=sign-up-create-account-button]').click();
        })
        // now wait for confirmation mail
        cy.then({
            // add timeout to the step to allow email to arrive
            timeout: 60_000
        }, function () {
            return mailslurp
                // wait for the email to arrive in the inbox
                .waitForLatestEmail(this.inboxId, 60_000, true)
                // extract the code with a pattern
                .then(email => mailslurp.emailController.getEmailContentMatch({
                    emailId: email.id,
                    contentMatchOptions: {
                        // regex pattern to extract verification code
                        pattern: 'Your Demo verification code is ([0-9]{6})'
                    }
                }))
                // save the verification code to this
                .then(({matches}) => cy.wrap(matches[1]).as('verificationCode'))
        });
        // confirm the user with the verification code
        cy.then(function () {
            cy.get('[name=code]').type(this.verificationCode)
            cy.get('[data-test=confirm-sign-up-confirm-button]').click()
            // use the email address and a test password
            cy.get('[data-test=username-input]').type(this.emailAddress)
            cy.get('[data-test=sign-in-password-input]').type('test-password')
            // click the submit button
            return cy.get('[data-test=sign-in-sign-in-button]').click();
        })
        cy.get('h1').should('contain', 'Welcome');
    });
});
```

### Quick links
- [API documentation](https://docs.mailslurp.com/js/)
- [JSDocs](https://js.mailslurp.com/)
- [Example project](https://github.com/mailslurp/examples/tree/master/javascript-cypress-mailslurp-plugin)
- [Use without plugin](https://github.com/mailslurp/examples/tree/master/javascript-cypress-js)
- [SMS testing](https://github.com/mailslurp/examples/tree/master/javascript-cypress-sms-testing)
- [Test email verification](https://www.mailslurp.com/examples/cypress-js/)

## Install
Version 2 of this plugin requires Cypress 15.10 or newer and supports Cypress 16. Ensure you have Cypress installed first, then run:

```sh
npm install --save-dev cypress-mailslurp
```

Then include the plugin in your `cypress/support/e2e.{js,ts}` file.

```typescript
import 'cypress-mailslurp'
```

For a CommonJS support file, use `require('cypress-mailslurp')` instead. The package tests both entry points.

> [!IMPORTANT]  
> Load `cypress-mailslurp` from your support file, such as `cypress/support/e2e.ts`, so the command is registered before specs run.

### Configuration
See the [example project](https://github.com/mailslurp/examples/tree/master/javascript-cypress-mailslurp-plugin) for example code.

### API Key
MailSlurp is free but requires an API Key. Get yours by [creating a free account](https://www.mailslurp.com/sign-up/).

API keys are secrets. The plugin reads `MAILSLURP_API_KEY` with Cypress's secure, asynchronous `cy.env()` command. It does not use the removed `Cypress.env()` API and does not expose your key to the application under test.

#### Environment variable
The simplest option for local runs and CI is an operating-system environment variable. Cypress removes the `CYPRESS_` prefix before making the key available to `cy.env()`.

For macOS/Linux:

```bash
CYPRESS_MAILSLURP_API_KEY=your-api-key npx cypress run
```

For Windows PowerShell:

```powershell
$env:CYPRESS_MAILSLURP_API_KEY=your-api-key;
npx cypress run;
```

#### Load the API key from `.env`

Cypress does not load generic `.env` files itself. Install `dotenv`, ignore `.env` in git, and map one value into the Cypress `env` configuration from the Node.js config process:

```bash
npm install --save-dev dotenv
```

```dotenv
# .env
MAILSLURP_API_KEY=your-api-key
```

```typescript
// cypress.config.ts
import { defineConfig } from 'cypress'
import 'dotenv/config'

export default defineConfig({
  env: {
    MAILSLURP_API_KEY: process.env.MAILSLURP_API_KEY,
  }
})
```

Do not commit `.env` or hard-code the key in `cypress.config.ts`. Cypress also supports `cypress.env.json`, `--env`, and values returned from `setupNodeEvents`; see the [Cypress environment variables and secrets guide](https://docs.cypress.io/app/guides/environment-variables).

#### Configure dynamically
You can also pass `cy.mailslurp()` a config containing an `apiKey`. Prefer environment configuration for real secrets so they do not become part of your test bundle. Other MailSlurp client options, such as `basePath` and `headers`, can be combined with an API key loaded from the environment.

```typescript
cy.mailslurp({ apiKey: 'YOUR_KEY' }).then(mailslurp => {
    expect(mailslurp.inboxController).to.exist
})
```

### Timeouts
MailSlurp requires timeouts to wait for inbound emails. You can set global timeouts in `cypress.config.ts`:

```typescript
import { defineConfig } from 'cypress'

export default defineConfig({
  defaultCommandTimeout: 30_000,
  responseTimeout: 30_000,
  requestTimeout: 30_000,
})
```

Or you can set timeouts on a per-method basis using the first argument as a timeout config: 

```typescript
cy.then({ timeout: 60_000 }, () => { /* use mailslurp */ })
```

#### TypeScript support
MailSlurp adds the `mailslurp` command to the Cypress `cy` object. Importing the package from the support file normally loads its type augmentation automatically. If your Cypress TypeScript configuration uses an explicit `types` list, include this reference in your spec or support file:

```typescript
/// <reference types="cypress-mailslurp" />
```

Or define the type yourself like so:

```typescript
import type { MailSlurpConfig } from 'cypress-mailslurp'
import type { MailSlurp } from 'mailslurp-client'

declare global {
  namespace Cypress {
    interface Chainable {
      mailslurp(config?: MailSlurpConfig): Chainable<MailSlurp>
    }
  }
}
```

## Usage
The Cypress MailSlurp plugin provides one simple command attached to the Cypress object: `cy.mailslurp()`. This method returns a MailSlurp client instance that has all the same methods and properties as the [official MailSlurp client](https://www.npmjs.com/package/mailslurp-client). Use the command with the `then()` method to access the instance:

```typescript
cy.mailslurp().then(mailslurp => mailslurp.createInbox() /* etc */)
```

You can test that you have set up MailSlurp correctly like this:

```typescript
describe('basic usage', function () {
  it('can load the plugin', function () {
    // test we can connect to mailslurp
    cy.mailslurp()
      .then(mailslurp => mailslurp.userController.getUserInfo())
      .then(userInfo => {
        expect(userInfo.id).to.exist
      })
  })
});
```

### Common methods
The client chained by the `cy.mailslurp()` has all the same methods and properties as the official MailSlurp client. See the [Javascript documentation](https://www.mailslurp.com/docs/js/) for a full [API reference](https://www.mailslurp.com/docs/js/docs/) or see the examples below.

The MailSlurp client has a number of convenience methods and also exposes the full MailSlurp API as controllers. See the [class reference for full method documentation](https://www.mailslurp.com/docs/js/docs/classes/MailSlurp/).

#### Create email address
You can create test email accounts with MailSlurp by creating inboxes. Inboxes have an `id` and an `emailAddress`. Save the `id` for later use when fetching or sending emails.

```typescript
cy.mailslurp()
    .then((mailslurp: MailSlurp) => mailslurp.createInboxWithOptions({}))
    .then(inbox => {
      expect(inbox.emailAddress).to.match(/^[^@]+@[^@]+$/)
      // save the inbox values for access in other tests
      cy.wrap(inbox.id).as('inboxId')
      cy.wrap(inbox.emailAddress).as('emailAddress')
    })
```

#### Send emails
To send emails in Cypress tests first create an inbox then use the `sendEmail` method.

```typescript
cy.mailslurp()
    .then((mailslurp: MailSlurp) => mailslurp.sendEmail(this.inboxId, {
      to: [this.emailAddress],
      subject: 'Email confirmation',
      body: 'Your code is: ABC-123',
    }))
```

#### Receive emails in tests
Use the `waitFor` methods to wait for emails for an inbox. See the [email object docs](https://www.mailslurp.com/docs/js/docs/interfaces/email/) for full properties.

```typescript
cy.log("Waiting for email")
cy.mailslurp().then({
    // set a long timeout when waiting for an email to arrive
    timeout: 60_000,
}, (mailslurp: MailSlurp) => mailslurp.waitForLatestEmail(this.inboxId, 60_000, true))
    .then(email => {
        expect(email.subject).to.contain('Email confirmation')
        const code = /Your code is: (\w+-\d+)/.exec(email.body ?? '')?.[1]
        expect(code).to.equal('ABC-123')
    })
```


#### Accessing more methods
To access all the MailSlurp methods available in the [REST API](https://api.mailslurp.com/swagger-ui.html) and [Javascript Client](https://www.mailslurp.com/docs/js/) use the controllers on the mailslurp instance.

```typescript
cy.mailslurp().then(mailslurp => mailslurp.attachmentController.uploadAttachment({
    base64Contents: fileBase64Encoded,
    contentType: 'text/plain',
    filename: basename(pathToAttachment)
}))
```

### Sharing values with tests
Cypress commands are asynchronous. Chain MailSlurp work with [`then()`](https://docs.cypress.io/api/commands/then), or store results in aliases using [`wrap()`](https://docs.cypress.io/api/commands/wrap) and [`as()`](https://docs.cypress.io/api/commands/as). Cypress resets aliases before every test, so create aliases in `beforeEach()` when multiple tests need them:

```typescript
beforeEach(function() {
  return cy
      .mailslurp()
      .then(mailslurp => mailslurp.createInbox())
      .then(inbox => {
        // save inbox id and email address to this (make sure you use function and not arrow syntax)
        cy.wrap(inbox.id).as('inboxId');
        cy.wrap(inbox.emailAddress).as('emailAddress');
      });
});
it('can access values on this', function() {
  // get wrapped email address and assert it is valid
  expect(this.emailAddress).to.match(/^[^@]+@[^@]+$/);
});
```

> [!NOTE]
> Accessing aliases with `this` requires `function` syntax instead of an arrow function. You can avoid `this` by retrieving an alias with `cy.get('@emailAddress')` in the same test.

## Example test
Here is an example of testing user sign up on a demo application hosted at [playground.mailslurp.com](https://playground.mailslurp.com). 
The test creates a MailSlurp inbox and saves its `id` and `emailAddress` as aliases within the same test. It then fills out the sign-up form, waits for the verification email with `waitForLatestEmail`, extracts the confirmation code, and signs in.

```typescript
describe('user sign up test with mailslurp plugin', function() {
  it('can verify a new user by email', function() {
    cy.mailslurp().then(function(mailslurp) {
      cy.then(() => mailslurp.createInbox()).then(inbox => {
        cy.wrap(inbox.id).as('inboxId')
        cy.wrap(inbox.emailAddress).as('emailAddress')
      })

      cy.visit('/')
      cy.get('[data-test=sign-in-create-account-link]').click()
      cy.then(function() {
        cy.get('[name=email]').type(this.emailAddress)
        cy.get('[name=password]').type('test-password')
        cy.get('[data-test=sign-up-create-account-button]').click()
      })

      cy.then({ timeout: 60_000 }, function() {
        return mailslurp.waitForLatestEmail(this.inboxId, 60_000, true)
      })
        .then(email => {
          const code = /verification code is (\d{6})/.exec(
            email.body ?? ''
          )?.[1]
          if (!code) {
            throw new Error('Verification email did not contain a code')
          }
          return code
        })
        .then(code => {
          cy.get('[name=code]').type(code)
          cy.get('[data-test=confirm-sign-up-confirm-button]').click()
        })

      cy.then(function() {
        cy.get('[data-test=username-input]').type(this.emailAddress)
        cy.get('[data-test=sign-in-password-input]').type('test-password')
        cy.get('[data-test=sign-in-sign-in-button]').click()
      })
      cy.get('h1').should('contain', 'Welcome')
    })
  })
});
```

### More examples
See the [Cypress example test suite](https://github.com/mailslurp/cypress-mailslurp/tree/master/cypress) for real tests that use this plugin.

## Development

Cypress 16 requires Node.js 22.x, 24.x, or 26.x and newer. The live end-to-end suite runs in Chrome because Cypress 16 deprecates Electron and uses its native browser network in Chrome. Copy `.env.example` to `.env`, replace the placeholder `API_KEY`, then run:

```bash
npm install
npm test
npm run cypress
```

The repository's `cypress.config.ts` loads `API_KEY` from `.env` in its Node.js process and maps it to `MAILSLURP_API_KEY` for the plugin's `cy.env()` call. The `.env` file is ignored by git.

README examples are generated from the tested `<gen>` blocks in the Cypress specs. After changing one of those blocks or this template, run `npm run readme`; `npm test` verifies that `README.md` is current.

---
_Source: https://npm.io/package/cypress-mailslurp · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
