Cypress JS Email Plugin —how to test with real email addresses! 🚀

How to send and receive emails in Cypress integration tests using Javascript and the free MailSlurp library.

What is Cypress Js?

Cypress is an amazing end-to-end testing framework. It’s popular, bundles its own chrome browser and is easily extended. Here is a screenshot:

An example login form being tested with Cypress.

Cypress lets you test many parts of a website or web application with a browser in an automated way. It’s like Selenium but a lot more user-friendly.

Testing with real email addresses

Many application use emails for account login and creation. Testing logins with Cypress is easy if you have a designated test user — but what about sign ups?

Email sign up has to be the most important aspect of any application and without access to unique, private email addresses end-to-end testing is difficult.

Luckily there’s MailSlurp, a free API that lets you create real, randomized email addresses on demand. It also lets you send and receive email programmatically — perfect for end-to-end testing user sign-up flows!

An example

To demonstrate Cypress testing we’ll use the MailSlurp Authentication Playground app. It’s a dummy React application that has a user sign-up process. To test this process end-to-end we will:

  • Load the playground in Cypress
  • Create a test email address with MailSlurp
  • Sign up for using the email address
  • Receiving a confirmation email
  • Extract the confirmation code and confirm the user

Setup Cypress

To setup make sure you have NodeJS installed then run:

npm install --save cypress mailslurp

Your package.json should look something like this:

{
"dependencies": {
"cypress": "^4.4.1",
"mailslurp-client": "^8.7.8"
}
}

Next we need to create a cypress.json file. We will set defaultCommandTimeout and requestTimeout to 30 seconds so that our tests have time to wait for emails to be sent or received. We'll also add some viewport dimensions to the Cypress browser.

Note for this example we also include our MailSlurp API Key in an env section of the cypress.json file. We can read that later in tests using Cypress.env("API_KEY").

{
"defaultCommandTimeout": 30000,
"requestTimeout": 30000,
"viewportHeight": 800,
"viewportWidth": 800,
"env": {
"API_KEY": "put-your-mailslurp-key-here"
}
}

Setup MailSlurp

In order to use MailSlurp with Cypress we will define some custom commands.

To do that create a cypress/support directory and add index.js and commands.js.

cypress 
└── support
└── commands.js
└── index.js

Inside index.js import the commands file.

// cypress/support/index.js
import "./commands";

Now inside commands let’s import and configure a MailSlurp client — this will let us send and receive emails. Make sure you have a free API Key.

// cypress/support/commands.js
const { MailSlurp } = require("mailslurp-client");

const apiKey = "YOUR_MAILSLURP_API_KEY";// or Cypress.env("API_KEY")
const mailslurp = new MailSlurp({ apiKey });

Next we will add commands to create email addresses and receive emails:

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

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

Now in Cypress tests we can do the following:

cy.createInbox().then(inbox => {
console.log(inbox);
// { id: '...', emailAddress: '...' }
});

Or:

cy.waitForLatestEmail(inbox.id).then(email => {
console.log(email);
// { subject: '...', body: '...' }
});

Create test structure

So in order to test a sign-up flow end-to-end we need an integration test. Create a test spec in the cypress/integration folder structure:

touch cypress/integration/example.spec.js

The test should be located as follows:

cypress 
└── integration
└── example.spec.js

Inside integration/example.spec.js let's write our first test.

Writing a test

Let’s start simple and write a test to load the MailSlurp playground app in Cypress.

That would look a little like this:

describe("Sign up", () => {
it("can load oauth demo site", () => {
cy.visit("https://playground.mailslurp.com");
cy.contains("Sign in to your account");
});
});

Next we want to click a sign up button to begin the sign up process.

it("can click sign up link", () => {
cy.get('[data-test="sign-in-create-account-link"]').click();
cy.contains("Testable Sign Up Form");
});

The end result for our test looks like this:

describe("Sign up", () => {
it("can load oauth demo site", () => {
cy.visit("https://playground.mailslurp.com");
cy.contains("Sign in to your account");
});

it("can click sign up link", () => {
cy.get('[data-test="sign-in-create-account-link"]').click();
cy.contains("Testable Sign Up Form");
});
});

Running tests

To run the test run npx cypress run. Cypress will open:

Click the spec runs our test. Our clicked Cypress loads the Playground app and asserts that a sign-in message is displayed on the page, it then clicks the sign-up link.

The output looks like this:

Testing with emails in Cypress

Now let’s integrate email address into our test using . MailSlurp requires an api key but it’s free for personal use so sign up to get one.

Once you’ve sign up we can extend Cypress with a command to creates new email address when we need them.

Generate test email accounts in Cypress

To extend Cypress first create a support folder in the cypress directory and place an index.js and a command.js inside it. Like so:

cypress 
├── integration
│ └── example.spec.js
└── support
├── commands.js
└── index.js

Inside index.js import the commands.

import './commands'

Now let’s set up a command called createInbox inside commands.js that calls MailSlurp and creates an email address on demand.

const { MailSlurp } = require("mailslurp-client");

Cypress.Commands.add("createInbox", () => {
// instantiate MailSlurp
const mailslurp = new MailSlurp({ apiKey: Cypress.env("API_KEY") });
// return { id, emailAddress } or a new randomly generated inbox
return mailslurp.createInbox();
});

Using our createInbox command

Now that we have a Cypress command that returns a new email address we can put it all together in our sign up test. Inside the same describe method add the following:

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();
});
});

Notice that we destructure the returned value from our helper command.

cy.newEmailAddress().then(({ emailAddress }) => {
/* do stuff */
});

Now we can run our tests again

npx cypress run

Cypress loads our login screen and enters a real address that was generated with MailSlurp. We then see a confirm screen:

Receive confirmation email

Once we have submitted our new user sign-up the Playground will send a confirmation email with a code that we need to enter. We can receive this email using MailSlurp:

let code;
it("can receive the confirmation email and extract the code", () => {
// wait for an email in the inbox
cy.waitForLatestEmail(inboxId).then(email => {
// verify we received an email
assert.isDefined(email);

// verify that email contains the code
assert.strictEqual(/verification code is/.test(email.body), true);

// extract the confirmation code (so we can confirm the user)
code = /([0-9]{6})$/.exec(email.body)[1];
});
});

Running the tests shows that Cypress waits for and extracts the email content:

Confirm the user

Finally we can use the extracted email code to confirm the user:

let code;
it("can receive the confirmation email and extract the code", () => {
// wait for an email in the inbox
cy.waitForLatestEmail(inboxId).then(email => {
// verify we received an email
assert.isDefined(email);

// verify that email contains the code
assert.strictEqual(/verification code is/.test(email.body), true);

// extract the confirmation code (so we can confirm the user)
code = /([0-9]{6})$/.exec(email.body)[1];
});
});

Now we can use Cypress to login with our confirmed email address and password:

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();
});

If successful the Playground will show a picture of a happy dog. Let’s test for that:

it("shows the successful greeting", () => {
cy.contains("Welcome");
});

Next Steps

Testing with real emails means truly testing your app’s most important processes like user sign up and email verification.

For more information on receiving emails in tests see the developers sections.

Code Samples

As always you can find this and other examples at https://github.com/mailslurp/examples. Use MailSlurp free and take your end-to-end test coverage to 💯 !

Originally published at https://www.mailslurp.com.

--

--

MailSlurp | Email APIs for developers

Test Email API for end-to-end with real email addresses. Support for NodeJS, PHP, Python, Ruby, Java, C# and more. See https://www.mailslurp.com for details.