What is Mailosaur?
Mailosaur is a service that captures email and SMS messages and lets you test them, both via it’s web dashboard and via the Mailosaur testing API.
If you don’t already have one, create a free account trial now, and send an email into Mailosaur first. Once you have this working, you’re ready to start testing!
Install the Mailosaur API client
Mailosaur provides an official library with everything you need to easily automate email testing in Playwright or any other Node.js tests.
Install the Mailosaur Node.js library via npm
npm install mailosaur
Import Mailosaur into your project
In order to connect to Mailosaur, you need an API key. You access your API key via in the account settings area.
In your tests, simply import the Mailosaur library, using your API key:
const MailosaurClient = require("mailosaur");
const mailosaur = new MailosaurClient("YOUR_API_KEY_HERE");
Basic usage
The messages.get
method automatically waits for the first email to arrive that matches the search criteria you provide.
const MailosaurClient = require("mailosaur");
const mailosaur = new MailosaurClient("YOUR_API_KEY_HERE");
const email = await mailosaur.messages.get("SERVER_ID", {
sentTo: "anything@SERVER_ID.mailosaur.net",
});
console.log(email.subject);
To learn about Server IDs, and what to replace SERVER_ID
with, see sending email to Mailosaur.
This example searches for the email address a message was sent to, but you can also search using any of this criteria too:
PARAMETER | DESCRIPTION |
---|---|
sentTo | The full email address to which the target message was sent. |
sentFrom | The full email address from which the target message was sent. |
subject | Find emails where the subject line contains this text. |
body | Finds messages where the message body contains this text. |
The messages.get
method returns the message object, which contains everything you need to perform in-depth automated testing.
Increasing the wait time
By default, the messages.get
method will wait for 10 seconds for a matching message to arrive. You can increase this wait time by using the timeout
option:
const email = await mailosaur.messages.get(
"SERVER_ID",
{
sentTo: "anything@SERVER_ID.mailosaur.net",
},
{
timeout: 20000, // 20 seconds (in milliseconds)
}
);
console.log(email.subject);
Searching for older messages
By default, the messages.get
method will only find messages received in the last hour. You can change this by setting the receivedAfter
option.
const testStart = new Date();
// TODO Do something here to send an email into your account
// Find any email received after `testStart` was set
const email = await mailosaur.messages.get(
"SERVER_ID",
{
sentTo: "anything@SERVER_ID.mailosaur.net",
},
{
receivedAfter: testStart,
}
);
console.log(email.subject);
Test email addresses
Because Mailosaur email addresses use a wildcard pattern, all plans give you access to unlimited test email addresses. Any address ending @YOUR_SERVER_ID.mailosaur.net
will work.
You can use your own logic to make up an email address, or use the servers.generateEmailAddress
helper method to generate a random string for you:
// Returns a random email address for this server, e.g. "bgwqj@SERVER_ID.mailosaur.net"
const emailAddress = mailosaur.servers.generateEmailAddress("SERVER_ID");
Testing basic properties
Once you have fetched an email (e.g. using messages.get
), you can easily test the properties of that email:
// Test the email subject line
expect(email.subject).toBe("Password reset");
// Test sender information
expect(email.from[0].name).toBe("Support");
expect(email.from[0].email).toBe("noreply@acme.com");
// Test recipient information
expect(email.to[0].name).toBe("John Smith");
expect(email.to[0].email).toBe("john.smith@example.com");
Testing carbon-copy recipients
// Carbon copy (CC) recipients
expect(email.cc[0].name).toBe("Jane Smith");
expect(email.cc[0].email).toBe("jane.smith@example.com");
// Blind carbon copy (BCC) recipients
expect(email.bcc[0].name).toBe("Jill Smith");
expect(email.bcc[0].email).toBe("jill.smith@example.com");
Testing email contents
Most emails will contain separate HTML and plain text content. You can see below how to test either content type:
Plain text content
// Check that the email contains some text
expect(email.text.body).toContain("Expected text");
HTML content
When testing HTML content, you can perform basic contains
or equals
assertions in the same way as with plain text content:
// Check that raw HTML contains some expected content
expect(email.html.body).toContain("<span>Hello world</span>");
In addition, if you want to perform lookups using CSS selectors, etc. you can use jsdom alongside Mailosaur.
You can install jsdom using npm
:
npm install jsdom
Import the library at the start of your test file:
const jsdom = require("jsdom");
Now perform HTML operations like this:
// Use a CSS selector to find the target element
const dom = new JSDOM(email.html.body);
const el = dom.window.document.querySelector(".customer-ref");
// Check the contents of the target element
expect(el.textContent).toBe("XYZ123");
Testing links
Any links that are found in the content of your email are instantly available via the html.links
or text.links
arrays, depending on which content the link was found in:
console.log(`${email.html.links.length} links found in HTML content`);
console.log(`${email.text.links.length} links found in plain text content`);
// Check the first link found in HTML content
expect(email.html.links[0].href).toBe("https://google.com");
expect(email.html.links[0].text).toBe("Google");
Navigating to a link
If you using an automation framework like Playwright or Cypress, you can navigate the browser to links within your tests:
// Playwright Example: Navigating to a link found in an email
await page.goto(email.html.links[0].href);
Clicking a link
If you just need to simulate a link being clicked and do not need to do anything on the target page, you can do this with https
.
Import https
at the top of your test file:
const https = require("https");
Then use this in your test to perform a 'click':
// Make an HTTP call to simulate someone clicking a link
https.get(email.html.links[0].href, (r) => console.log(r.statusCode)); // 200
Testing verification codes
Codes are automatically extracted from the content of your email. Just like links, codes are made available via the html.codes
or text.codes
arrays, depending on which content the code was found in:
console.log(`${email.html.codes.length} codes found in HTML content`);
console.log(`${email.text.codes.length} codes found in plain text content`);
// Check the first code found in HTML content
expect(email.html.codes[0].value).toBe("432123");
Testing attachments
Any email attachments are made available via the attachments
array:
console.log(`${email.attachments.length} attachments found`);
// Get the first attachment
const attachment = email.attachments[0];
// Check attachment attributes
expect(attachment.fileName).toBe("example.pdf");
expect(attachment.contentType).toBe("application/pdf");
// Check the file size (in bytes)
expect(attachment.length).toBe(4028);
Save an attachment to disk
You can download and save attachments using the files.getAttachment
and writeFile
methods:
console.log(`${email.attachments.length} attachments found`);
const file = await mailosaur.files.getAttachment(email.attachments[0].id);
// Save file to disk
fs.writeFile("some-file.pdf", file, () => console.log("File saved."));
Encoding attachments
In some scenarios you may need a base64-encoded copy of an attachment. You can achieve this using toString('base64')
:
console.log(`${email.attachments.length} attachments found`);
const file = await mailosaur.files.getAttachment(email.attachments[0].id);
const base64 = file.toString("base64");
Testing images and web beacons
Any images found within the HTML content of an email are made available via the html.images
array:
console.log(`${email.html.images.length} images found`);
// Get the first attachment
const image = email.html.images[0];
// Check image attributes
expect(image.src).toBe("https://example.com/balloon.png");
expect(image.alt).toBe("A green hot air balloon in the sky");
To test whether an image is accessible online, or that a web beacon is working as expected, you can simply perform an HTTP request, using https
.
Import https
at the top of your test file:
const https = require("https");
Then use this in your test to fetch the image:
console.log(`${email.html.images.length} images found`);
// Get the first attachment
const image = email.html.images[0];
// Fetch the image
https.get(image.src, (r) => console.log(r.statusCode)); // 200
Testing deliverability
The analysis.spam
method runs a SpamAssassin test against an email. This will return an overall SpamAssassin score (see understand your SpamAssassin score).
The lower the score the better and, in most cases, a score higher than 5.0 will result in an email being seen as spam.
const result = await mailosaur.analysis.spam(email.id);
// Overall SpamAssassin score. In most cases a score of
expect(result.score).toBeLessThan(3);
result.spamFilterResults.spamAssassin.forEach((r) => {
console.log(r.rule);
console.log(r.description);
console.log(r.score);
});
List all messages
Recommendation: We strongly recommend using the `messages.get` method for most use cases. This method has been purposely optimised for the most common automated testing scenarios.
If you simply need to list the current emails in an inbox, you can use messages.list
:
const result = await mailosaur.messages.list("SERVER_ID");
console.log(`${result.items.length} messages in inbox`);
const match = result.items[0];
expect(match.subject).toBe("Password reset");
// Note: List results only contain summary information. To get
// the HTML/text content of an email, use `messages.getById`
const email = await mailosaur.messages.getById(match.id);
console.log(email.html.body);
Alternative search for messages
Recommendation: We strongly recommend using the `messages.get` method for most use cases. This method automatically waits for a matching result, and also returns the whole message object in the result, rather than just a summary.
Using the messages.search
method:
const result = await mailosaur.messages.search("SERVER_ID", {
sentTo: "anything@SERVER_ID.mailosaur.net",
});
console.log(`${result.items.length} matching messages found`);
// Get the first result
const match = result.items[0];
expect(match.subject).toBe("Password reset");
// Note: Results only contain summary information. To get
// the HTML/text content of an email, use `messages.getById`
const email = await mailosaur.messages.getById(match.id);
console.log(email.html.body);
Wait for matches to arrive
By default the messages.search
method will only return current matches. By setting the timeout
option, the method will automatically wait for a match:
const result = await mailosaur.messages.search(
"SERVER_ID",
{
sentTo: "anything@SERVER_ID.mailosaur.net",
},
{
timeout: 10000, // Wait 10 seconds (in milliseconds) for a match
}
);
Testing that no matching messages are found
By default, an error will be thrown if no matches are found in time. However, if you are expecting no messages to arrive in a certain period of time, then simply set errorOnTimeout: false
to prevent an exception being thrown:
const result = await mailosaur.messages.search(
"SERVER_ID",
{
sentTo: "anything@SERVER_ID.mailosaur.net",
},
{
timeout: 10000,
errorOnTimeout: false,
}
);
Deleting messages
Delete all messages
To permanently delete all messages held in a specific server/inbox, use the messages.deleteAll
method. This also deletes any attachments related to each message. This operation cannot be undone.
await mailosaur.messages.deleteAll("SERVER_ID");
Deleting an individual message
To permanently delete a single message, use messages.del
. This also deletes any attachments related to the message. This operation cannot be undone.
await mailosaur.messages.del("MESSAGE_ID");
Download an email (.EML)
If you need to download a copy of an email, you can do this using the files.getEmail
method.
This will download a .EML
format file, allowing you to save an email offline and outside of Mailosaur or any other email software.
const file = await mailosaur.files.getEmail(email.id);
// Save file to disk
fs.writeFile("email.eml", file, () => console.log("Email saved."));
Replying to an email
If your product is capable of handling email replies from your customers, you can use Mailosaur’s reply feature to simulate such a scenario.
When you reply, the email is sent back to the email address it was originally sent to Mailosaur from. Before you can reply, you must first add this address as a verified external email address.
await mailosaur.messages.reply("MESSAGE_ID", {
text: "FYI",
});
The options available to use with the messages.reply
method are:
PARAMETER | DESCRIPTION |
---|---|
text | Any additional text content to reply to the email with. |
html | Any additional HTML content to reply to the email with. |
subject | Optionally override the default subject line. |
attachments | Optional attachments (see 'inline attachments' below). |
Include attachments
You can include attachments in emails sent via the API, by including an array of base64-encoded attachment objects:
const attachments = [
{
fileName: "cat.png",
contentType: "image/png",
content: "{BASE64_ENCODED_FILE}",
},
];
await mailosaur.messages.reply("MESSAGE_ID", {
to: "verified-address@example.com",
subject: "Email from Mailosaur",
html: "<p>Hello world.</p>",
attachments: attachments,
});
Forwarding an email
Teams often need to forward emails onto an email address outside of Mailosaur. For example, to send messages to colleagues for further review/analysis, or to test email handling functionality within an product.
You can forward messages from your Mailosaur account to external email addresses either one-by-one, or via the creation of automated forwarding rules.
Before you can forward messages, you must set up a verified external email address, so that you can send email to it.
await mailosaur.messages.forward("MESSAGE_ID", {
to: "verified-address@example.com",
text: "Hello world",
});
The options available to use with the messages.forward
method are:
PARAMETER | DESCRIPTION |
---|---|
to | The email address to which the email will be sent. Must be a verified email address. |
text | Any additional text content to forward the email with. |
html | Any additional HTML content to forward the email with. |
subject | Optionally override the default subject line. |
Sending an email
If your product is capable of handling inbound emails, you can use Mailosaur’s sending feature to trigger this functionality in your product.
The messages.create
method creates and and sends an email to a verified external email address:
await mailosaur.messages.create("SERVER_ID", {
to: "verified-address@example.com",
send: true,
subject: "Request",
text: "Please can you give us a call back?",
});
The options available to use with the messages.create
method are:
PARAMETER | DESCRIPTION |
---|---|
send | This must be set to true if you are sending an outbound email. |
to | The email address to which the email will be sent. Must be a verified email address. |
subject | The email subject line. |
text | Any additional text content to forward the email with. |
html | Any additional HTML content to forward the email with. |
attachments | Optional attachments (see 'inline attachments' below). |
Include attachments
You can include attachments in emails sent via the API, by including an array of base64-encoded attachment objects:
const attachments = [
{
fileName: "cat.png",
contentType: "image/png",
content: "{BASE64_ENCODED_FILE}",
},
];
await mailosaur.messages.create("SERVER_ID", {
to: "verified-address@example.com",
send: true,
subject: "Email from Mailosaur",
html: "<p>Hello world.</p>",
attachments: attachments,
});
Working with servers
List servers
Return a list of your servers/inboxes. Servers are returned sorted in alphabetical order:
const result = await mailosaur.servers.list();
console.log("You have a server called:", result.items[0].name);
Create a new inbox
Create a new server (inbox). Only the name
property is required to create a new server via the API:
const result = await mailosaur.servers.create({
name: "My email tests",
});
Retrieve a server
Retrieve the detail for a single server. Simply supply the unique identifier for the required server:
const server = await mailosaur.servers.get("SERVER_ID");
console.log(server.name);
Retrieve the SMTP/POP3 password for a server
Retrieve the password, for use with SMTP and POP3, for a single server. Simply supply the unique identifier for the required server:
const password = await mailosaur.servers.getPassword("SERVER_ID");
console.log(password);
Update an server
Updates a single server/inbox:
retrievedServer.name = "Updated server name";
await mailosaur.servers.update(retrievedServer.id, retrievedServer);
Delete an inbox
Permanently delete a server. Also deletes all messages and associated attachments within the server. This operation cannot be undone:
await mailosaur.servers.del("SERVER_ID");
Previous
Languages