# 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 commandsemailAddress
- 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'
});