Email Testing

# Email Testing

In End 2 End testing we need to interact with emails. Email delivery can't be tested locally or mocked while testing. That's why for an end to end test you need real emails to be sent and real email address to receive that emails.

Setting up an email server can be hard. So we recommend to use MailSlurp (opens new window) - a service designed for testing emails. It creates disposable mailboxes and provides you an access to those mailboxes via REST API.

You no longer need to open your gmail account in a browser to check for an email!

# Installation

MailSlurp is a commercial service with a free plan available. To start, create an account at MailSlurp (opens new window) and receive API key to use it. Once received install mailslurp helper from npm:

npm i @codeceptjs/mailslurp-helper --save-dev

Then enable a helper in codecept.conf.js:

helpers: {

  MailSlurp: {
    require: '@codeceptjs/mailslurp-helper',
    apiKey: '<apiKeyFromMailSlurp>'
  }
}

After a helper is added, regenerate TypeScript definitions for auto-completion support:

npx codeceptjs def

# Creating Mailbox

MailSlurp allows you to create disposable mailboxes. It means that an email address is created for one test only and is deleted afterwards. So you can be confident that no other emails are received at that address.

To create a mailbox use I.haveNewMailbox() command:

// inside async/await function
const mailbox = await I.haveNewMailbox();

mailbox object contains:

  • id - which is used in next commands
  • emailAddress - randomly generated address of a created mailbox.

See MailSlurp's guide (opens new window) for details.

Mailbox is opened on creation. If you need more than one mailbox and you want to switch between them use openMailbox method:

const mailbox1 = await I.haveNewMailbox();
const mailbox2 = await I.haveNewMailbox();
// mailbox2 is now default mailbox
// switch back to mailbox1
I.openMailbox(mailbox1);

# Receiving An Email

A last created mailbox will be activated. It means that it will be used by default to check for emails.

After an action that triggers sending an email is performed on a website, you should wait for this email to be received. A timeout for waiting an email can be set globally for a helper or for a one call.

Use waitForLatestEmail function to return the first email from a mailbox:

// to wait for default time (10 secs by default)
I.waitForLatestEmail();

// or specify number of time to wait
I.waitForLatestEmail(30);

To specify the exact email to match use waitForEmailMatching function:

// wait for an email with partial match in subject
I.waitForEmailMatching({ subject: 'Restore password' });

// wait 30 seconds for email with exact subject
I.waitForEmailMatching({ subject: '=Forgot password' }, 30);

// wait a last email from any address @mysite.com
I.waitForEmailMatching({
 from: '@mysite.com', // find anything from mysite
 subject: 'Restore password', // with Restore password in subject
});

# Opening An Email

All wait* functions return a matched email as a result. So you can use it in a test:

const email = await I.waitForLatestEmail();

Please note, that we use await to assign email. This should be declared inside async function

An email object contains the following fields:

  • subject
  • for
  • to
  • body

So you can analyze them inside a test. For instance, you can extract an URL from email body and open it. This is how we can emulate "click on this link" behavior in email:

// clicking a link in email
const email = await I.waitForLatestEmail();
// extract a link by RegExp
const url = email.body.match(/http(s):\/\/(.*?)\s/)[0];
// open URL
I.amOnPage(url);

# Assertions

Assertions are performed on the currently opened email. Email is opened on waitFor email call, however, you can open an exact email by using openEmail function.

const email1 = await I.waitForLatestEmail();
// test proceeds...
const email2 = await I.waitForLatestEmail();
I.openEmail(email1); // open previous email

After opening an email assertion methods are available.

  • seeInEmailSubject
  • seeEmailIsFrom
  • seeInEmailBody
  • dontSeeInEmailBody
  • seeNumberOfEmailAttachments
  • seeEmailAttachment

And here is an example of their usage:

I.waitForLatestEmail()
I.seeEmailIsFrom('@mysite.com');
I.seeInEmailSubject('Awesome Proposal!');
I.seeInEmailBody('To unsubscribe click here');
I.seeNumberOfEmailAttachments(2);
I.seeEmailAttachment('Attachment_1.pdf'); // Regular expression. Escape special characters like '(' or ')' in filename.
I.seeEmailAttachment('Attachment_2.pdf');

More methods are listed in helper's API reference (opens new window)

# Listing All Emails

Use grabAllEmailsFromMailbox to get all emails from a current mailbox:

const emails = await I.grabAllEmailsFromMailbox();

# Sending an Email

You can also send an email from an active mailbox:

I.sendEmail({
  to: ['[email protected]'],
  subject: 'Hello',
  body: 'World'
});
Last Updated: 12/10/2024, 1:51:39 PM