Automating Tests with Node.js

Getting Started

In this guide we’ll be using Mocha, Chai and Mailosaur together to perform automated email testing in Node.js.

Remember that Mailosaur is language and framework agnostic though, so if you’re using another set up then take a look at our other guides or just get in touch - we’re coders too!

Let’s get going by installing our three dependencies:

npm install mailosaur --save-dev
npm install mocha --save-dev
npm install chai --save-dev

Send & Fetch an Email

Create a new folder called test and within it place a blank file called example.js, we’ll place our sample code inside this file.

.
├── package.json
├── node_modules
└── test
    └── example.js

Initial code

You can send an email to Mailosaur for testing either via a test email address or by changing your product’s SMTP configuration. Read our guide on sending email for testing for more information.

We’re making the assumption that, because you’re reading an guide on how to perform email testing, you probably know how to send an email. But if you don’t, just check out our guide on sending email via SMTP.

In the code below we skip over how you choose to send an email, because each product is going to be different. But if you need help with this step just get in touch.

const assert = require('chai').assert;

const MailosaurClient = require('mailosaur');
const client = new MailosaurClient('YOUR_API_KEY');

/*
 * At this point you need your code to send an email. You most likely
 * want to do this by triggering an event in your product that causes
 * an email to be sent - for example `myProduct.requestPasswordReset();`
 *
 * If you just want to play around for now, you could try Nodemailer.
 */

// Look for email that was just sent...
client.messages.waitFor('SERVER_ID', {
  sentTo: 'someone.SERVER_ID@mailosaur.io'
}).then((email) => {
  // Test all the things...
  assert.equal(email.subject, 'Password reset request');
});

What email tests can I perform?

Assuming the code above is working for you, it’s time to get stuck in with some more useful tests.

You will have received an email object, which is documented in our API reference. Using this structure you can perform a wide array of tests, here are some examples to get you started.

Email properties

You can easily test common email properties, such as:

// Who sent the email
assert.equal(email.from[0].email, 'noreply@company.com');
assert.equal(email.from[0].name, 'ACME Company');

// To whom was the email addressed
assert.equal(email.to[0].email, 'john.smith@example.com');
assert.equal(email.to[0].name, 'John Smith');

// Any carbon-copies
assert.equal(email.cc[0].email, 'jane.smith@example.com');
assert.equal(email.cc[0].name, 'Jane Smith');

// Any blind carbon-copies
assert.equal(email.bcc[0].email, 'aperson@company.com');
assert.equal(email.bcc[0].name, 'Another Person');

// Email subject line
assert.equal(email.subject, 'Password reset request');

// Was the email was received today?
assert.equal(email.received.toISOString().slice(0, 10), new Date().toISOString().slice(0, 10));

You can also test email headers via the email.metadata.headers property.

Email content

HTML

If your email contains HTML content, then the email.html.body property will include the full, raw HTML of your email.

You can use this to perform simple checks, such as:

assert.match(email.html.body, /<div id="something">/);

However by using a library like Cheerio you can perform far more detailed HTML testing:

const cheerio = require('cheerio');
const $email = cheerio.load(email.html.body);

var $el = $email('#some-element');

assert.isTrue($el.hasClass('col-6'));

One of the most common end-to-end testing scenarios involving email is the password reset request. This usually involves a product sending a one-time use link via email, which the user must then click.

Mailosaur extracts all links it finds within the HTML body of an email and makes them available via email.html.links:

assert.equal(email.html.links.length, 1);
assert.equal(email.html.links[0].text, 'Set a new password now');

// Get unique password reset link
var resetLink = email.html.links[0].href;

To complete an end-to-end testing scenario for a password reset you would usually navigate your browser to this link, and complete the remaining UI steps with something like Selenium.

However, if your scenario simply requires a user to click the link (for example in an account verification workflow), you can easily do this using the standard Node.js library:

const https = require('https');

// Verify our account, by 'clicking' the link within the email
https.get(email.html.links[0].href);

Working with images

Just like hyperlinks, Mailosaur extracts any images that it finds within your HTML content:

assert.equal(email.html.images.length, 5);
assert.equal(email.html.images[0].src, 'amazing.png');'ID'
assert.equal(email.html.images[0].alt, 'A wizard flying a unicorn over a rainbow'); // Just imagine!

Plain Text

The tests above will also work with any plain text content your email contains. Just like HTML content is available via email.html, plain text content is available via email.text.

Working with attachments

The metadata related to any attachments found on the email is available via email.attachments:

assert.equal(email.attachments.length, 2);

var attachment = email.attachments[0];

// A unique identifier for this attachment
assert.isOk(attachment.id);

// The URL from which this attachment can be downloaded
assert.isOk(attachment.url);

// Size (in bytes) of the email
assert.equal(attachment.length, 82138);

// The filename specified when the attachment was sent
assert.equal(attachment.fileName, 'cat.png');

// The file MIME type
assert.equal(attachment.contentType, 'image/png');

You can download attachments either by using the attachment’s url property, or in code via the files API:

client.files.getAttachment(attachment.id)
  .then((file) => {
    // ...
  });

Conclusion

This guide shows you some of the most common approaches to email testing, but we know that every product and project is different. If you can’t find the answer to any question you might have here and would like some help from our team just get in touch!