A Practical Guide to Mastering Cypress Email Testing

On February 17, 2024
8min read
Denys Kontorskyy Technical Content Writer @Mailtrap

This guide delves into the practicalities of using Cypress, an advanced web application testing framework that can be integrated with various email testing tools. You’ll gain insights into executing crucial test cases, including ensuring the reliability of email services for functions like password reset and other essential workflows. We’ll cover how to validate email delivery, content accuracy, and cross-platform rendering.

If you’re familiar with Cypress’s functionalities, jump directly to the how-to section.

Why use Cypress for email testing?

If you’re new to Cypress or considering it for your email testing needs, here’s a quick overview of why it stands out:

  • Rapid Test Execution: Cypress’s speed aligns with agile development needs, ensuring quick feedback loops in your test runs.
  • User-Friendly Syntax: Cypress offers straightforward and easy-to-understand syntax.
  • Consistent Performance: It delivers reliable results consistently, a crucial factor for trustworthy testing.
  • Dynamic Content Handling: Cypress is adept at managing dynamic content, vital for testing emails with varying user interactions and personalization.
  • Integration with Plugins and Services: It seamlessly integrates with various email testing services and plugins, creating an efficient ecosystem for email testing in controlled environments.

These features make Cypress a robust choice for email testing, ensuring thorough and efficient verification of email functionalities.

Before Testing: Setting Up Cypress

Before diving into the ins and outs of email testing with Cypress, you’ll need a few prerequisites, including certain dependencies, to ensure a smooth setup.

  • You must install Node.js (version 14 or higher) on your system, as Cypress is a Node.js application.
  • npm (Node Package Manager) should be available to manage the packages Cypress requires.
  • A text editor or Integrated Development Environment (IDE) is necessary to write and manage your test scripts.

Installing Cypress is a straightforward process once you have the prerequisites, including setting up your environment variable and config.

Open your terminal or command prompt, navigate to your project directory, and install Cypress using the npm command:

npm install cypress

After the installation is complete, you can verify it by launching the Cypress Test Runner with the following command:

./node_modules/.bin/cypress open

The next step is to create a new file for your tests. In the cypress/e2e/ directory, create a file named test.cy.js. This file will house your email testing scripts.

How to run different types of email tests with Cypress

Cypress can perform various email tests, each designed to validate different aspects of email functionality. Here’s a categorized list:

  • Checking for Broken Links: Ensures all hyperlinks in an email lead to the intended destinations.
  • Validating Email Content: Verifies the accuracy of text, images, and other content within the email.
  • Testing Email Rendering: Checks how emails are displayed on various devices and screen sizes.

Checking for Broken Links

Correct and secure email links are key to your business’s success. Broken links mean trouble – they frustrate users, hurt conversions, and can even cost you customers and revenue. 
To check for broken links using Cypress, you can place the following code in cypress/e2e/test.cy.js:

describe('Email broken links', () => {
  it('Find all broken links', () => {

    // Visit the email HTML file
    cy.visit('emailcontent.html')


    // Get all the links in the email
    cy.get('a').each((link) => {
      // Check if the link has an href attribute
      if (link.prop('href')) {
        // Make a request to the link
        cy.request({
          // Set the URL of the request to the link's href attribute
          url: link.prop('href'),
          // Do not fail the test if the response status code is not 200
          failOnStatusCode: false
        }).then((response) => {
          // Check if the response status code is not 200
          if (response.status !== 200) {
            // Log the broken link to the Cypress console
            cy.log(`Broken link: ${link.prop('href')}`);
          }
        });
      }
    });

  });
});

This script analyzes the email’s HTML file, iterates over each link, and makes a request to the URL specified in the href attribute. If the response status code is not 200, it logs the broken link.

Validating Email Content

It’s crucial for any email sent from your app to its users to have clear and accurate content.
After all, no one wants to receive emails with confusing “tech junk” text, which can frustrate users and increase your unsubscribe rate.

To validate the content of such emails, you can use the following Cypress script:

describe('Validating Email', () => {
  it('Validating Email Content', () => {

    cy.visit(emailcontent.html')
    // Get the email body
    cy.get('.email-body').then((emailBody) => {
      // Validate that the specific text is present in the email body
      expect(emailBody.text()).to.contain('specific text');
    });

  });
});

This code checks that the email body contains specific text, ensuring the email’s content is as expected. Additionally, Cypress commands can be used to automate the verification of email contents, such as checking for a specific verification code in a confirmation email. 

Aligning email content and delivery practices with best practices is key to maintaining a strong domain reputation, which is crucial for reliable email deliverability and engagement.

Testing Email Rendering

With just about any mobile device able to read emails today, ensuring emails render correctly across all of them is crucial. 
The following Cypress code snippet helps test email rendering on a mobile viewport:

describe('Email Rendring', () => {
  it('Test email rendering in a mobile viewport', () => {

    // Set the viewport to a mobile size
    cy.viewport(375, 667);

    // Visit the email HTML file
    cy.visit('test.html');

    // Get the email body
    cy.get('.email-body');

    // Take a screenshot of the email body
    cy.screenshot('email-body-mobile.png');

  });
});

This code sets the viewport to a mobile size, visits the email HTML file, and takes a screenshot of the email body. This can help visually verify that the email layout and content scale properly on smaller screens.

Cypress’s ability to interact with email accounts like Gmail for end-to-end testing makes it ideal for email verification processes in automated tests.

Assertions and Commands

Cypress provides a powerful set of assertions and commands tailored for various testing scenarios, and of course, email testing is one of them.

Verifying Email Delivery

Automated tests can make a big difference in the reliability of email delivery, ensuring that emails reach their intended recipients.

Adding the following custom command to cypress/support/commands.js file helps verify that emails are being delivered correctly:

Cypress.Commands.add('checkMessageDelivery', (accountId, inboxId, subject) => {
  return cy.request({
    method: 'GET',
    url: `https://mailtrap.io/api/accounts/${accountId}/inboxes/${inboxId}/messages?search=${subject}`,
    headers: {
      'Accept': 'application/json',
      'Api-Token': 'your api token', // Replace with your Mailtrap API token
    },
  });
});

To use this command in your tests, add the following to cypress/e2e/test.cy.js:

describe('Message Delivery', () => {
  it('should check message delivery', () => {
    const accountId = 'accountId'; // Replace with your Mailtrap account ID
    const inboxId = 'inboxId'; // Replace with your Mailtrap inbox ID
    const subject = 'email subject'; // Replace with the message subject you want to check

    // Call the custom command to check message delivery by subject search
    cy.checkMessageDelivery(accountId, inboxId, subject)
      .then((response) => {
        // Add assertions to verify the response and check message delivery
        expect(response.status).to.equal(200);

        // Add assertions to verify that at least one message exists
        expect(response.body).to.have.length.above(0);

        // You can add more specific assertions based on the response, e.g., verify the message content
        // ...

        // If you want to output the message data for debugging:
        cy.log(JSON.stringify(response.body));
      });
  });
});

Checking for Spam Triggers

If there is one thing that all email marketers aim for, it’s avoiding spam filters

The good news is that the following custom command in cypress/support/commands.js checks for common spam triggers:

Cypress.Commands.add('checkEmailForSpamTriggers', (emailContent, subjectLine) => {
  // Check email content for spam trigger words
  const spamWords = ["free", "buy now", "guarantee", "limited time", "win"];
  const contentHasSpamWords = spamWords.some((word) => emailContent.includes(word));

  // Check subject line for spam trigger words
  const subjectHasSpamWords = spamWords.some((word) => subjectLine.includes(word));

  // Use .should with a custom assertion to wait for the check to complete
  cy.wrap({ contentHasSpamWords, subjectHasSpamWords }).should(({ contentHasSpamWords,         subjectHasSpamWords }) => {
    expect(contentHasSpamWords).to.be.false;
    expect(subjectHasSpamWords).to.be.false;
  });
});

To utilize this command in cypress/e2e/test.cy.js:

describe('Email Marketing', () => {
  it('should send a marketing email and check for spam triggers', () => {
  const emailContent = 'Get a limited-time offer! Buy now and win a prize!';
  const subjectLine = 'Special Limited-Time Offer!!!';

  // Check for spam triggers
  cy.checkEmailForSpamTriggers(emailContent, subjectLine);
});
});

This code checks the email content and the subject line for words that could trigger spam filters, ensuring that marketing emails have a higher chance of reaching the inbox.

Integrating a feedback loop with this approach can further enhance your ability to identify and respond to recipient reactions, ensuring better email deliverability and reducing spam flags.

Testing Email Templates

Notifications like account confirmations and password resets must work perfectly. They’re key for authentication and often the first thing users see. Testing these with Cypress is crucial: it keeps your emails reliable and maintains a good sender reputation, which is vital for success.

The following command in cypress/support/commands.js can help you check for branding elements:

Cypress.Commands.add('checkEmailBranding', (emailContent) => {
  // Define branding elements that should be present in the email
  const expectedLogoUrl = 'https://example.com/logo.png';
  const expectedBackgroundColor = ' #f0f0f0';
  const expectedFontColor = '#333333';
  const expectedFontSize = '16px';

  // Perform assertions to check branding elements in the email content
  cy.get('img').should('have.attr', 'src', expectedLogoUrl);
  cy.get('body').should('have.css', 'background-color', expectedBackgroundColor);
  cy.get('p').should('have.css', 'color', expectedFontColor);
  cy.get('p').should('have.css', 'font-size', expectedFontSize);

  // You can add more branding checks as needed
});

And in your test file cypress/e2e/test.cy.js:

describe('Email Branding', () => {
  it('should check branding elements in the email template', () => {
    // Send or retrieve the email content
    const emailContent = '...'; // Replace with your email content

    // Check branding elements in the email
    cy.checkEmailBranding(emailContent);
  });
});

This script ensures that the email contains the correct branding elements, such as logo, background color, font color, and size, which are crucial for brand recognition and consistency.

How to Test Emails Using Cypress and Mailtrap?

Integrating Mailtrap Email Testing with Cypress offers a secure and effective method for inspecting and debugging emails in staging, development, and QA environments. 

Mailtrap Email Testing acts as an email sandbox, capturing SMTP traffic from your environment and routing emails to a virtual inbox. This setup prevents email delivery to recipients, allowing thorough examination and debugging of your emails.

Mailtrap Email Testing offers a range of features, such as HTML/CSS validation, spam score analysis, and an API for QA automation. It’s designed to work seamlessly with over 20 programming languages, such as Ruby, Python, PHP, .Net, and Node.js (works with Nodemailer). This makes Mailtrap a versatile tool for email preview, multiple inbox management for different projects, user management, and Single Sign-On (SSO) capabilities.

To get started with Mailtrap Email Testing in your Cypress tests:

  1. Sign up and set up your Maitrap account.
  2. Create an inbox in Mailtrap Email Testing to capture your application’s emails.
  3. To send an email to your Mailtrap inbox using Cypress, add this command to cypress/support/commands.js:
Cypress.Commands.add('sendEmailToMailtrap', (sender, recipient, subject, body) => {
  cy.request({
    method: 'POST',
    url: 'https://sandbox.api.mailtrap.io/api/send/inbox_id, // Replace 'inbox_id' with your actual inbox ID
    headers: {
      'Accept': 'application/json',
      'Api-Token': 'api token',
      'Content-Type': 'application/json',
    },
    body: {
      to: [
        {
          email: recipient.email,
          name: recipient.name,
        },
      ],
      from: {
        email: sender.email,
        name: sender.name,
      },
      subject: subject,
      text: body,
    },
  });
});

And to test this functionality, add the following to cypress/e2e/test.cy.js:

describe('Email Testing', () => {
  const sender = { email: 'sales@example.com', name: 'Sales Team' };
  const recipient = { email: 'john_doe@example.com', name: 'John Doe' };
  const subject = 'Your Subject';
  const body = 'Congratulations on your order no. 1234';

  before('checking email contents', () => {
    cy.checkEmailForSpamTriggers(body, subject);
    cy.checkEmailTemplate(body);
    // You can add more content validation here
  });

  it('should send an email and verify the response', () => {
    cy.sendEmailToMailtrap(sender, recipient, subject, body)
      .then((response) => {
        // Add assertions to verify the response
        expect(response.status).to.eq(200);
        expect(response.body).to.exist;
        expect(response.body.success).to.be.true;
        expect(response.body.message_ids).to.exist;
      });
  });
});

This script automates sending emails to Mailtrap and verifies the response, ensuring that Mailtrap’s fake SMTP server has captured the new email successfully. From there, you can start inspecting and debugging your emails!

Also, if you use Mailtrap Email Testing API, you can test your email template, then easily switch to production and send the template. In a nutshell, you need to enable sandbox on API, specify your inbox ID to get the test, then switch to Sending on production.  

Conclusion

With its comprehensive tools for email testing, Cypress is essential for ensuring the reliability of email functions in your applications. Its capability to handle dynamic content and integrate with tools like Mailtrap makes it ideal for testing HTML email templates, especially when setting up a local host for the first test. This approach simulates real-world scenarios, enhancing test effectiveness.

For more insights and practical guidance on using Cypress in your projects, check out the various tutorials and resources on GitHub. These include valuable JavaScript files and API keys, as detailed in the Cypress documentation, to help you refine your testing strategies.

Article by Denys Kontorskyy Technical Content Writer @Mailtrap

I am an experienced Technical Content Writer offering insights on email infrastructure, sending, testing, and optimizing emails. With a strong passion for product marketing, I love creating content that educates audiences and provides practical, applicable knowledge.