Ƭrivumo Docs
Examples

Cypress

Learn how to test email workflows in Cypress using Trivumo.


Email verification, password resets, magic links, invitations, and OTP-based authentication are common workflows that require email testing. Trivumo allows Cypress tests to generate email addresses, wait for messages, extract links, and verify email content.

Install

npm install trivumo

Create a Client

Create a shared Trivumo client that can be reused across your tests.

import { TrivumoClient } from 'trivumo';

export const trivumo = new TrivumoClient({
  apiKey: Cypress.env('TRIVUMO_API_KEY'),
  domain: Cypress.env('TRIVUMO_DOMAIN'),
});

Verify Email Signup Flow

Generate a unique email address, create an account, wait for the verification email, and visit the verification link.

import { trivumo } from '../support/trivumo';

describe('Signup', () => {
  it('verifies a newly created account', async () => {
    const email = trivumo.generateEmail();

    cy.visit('/signup');

    cy.get('[name=email]').type(email);
    cy.get('[name=password]').type('Password123!');
    cy.contains('button', 'Create Account').click();

    const message = await trivumo.waitForMessage({
      to: email,
      subject: 'Verify your account',
    });

    const verificationLink =
      message.html?.links[0]?.href;

    cy.visit(verificationLink!);

    cy.contains('Email verified')
      .should('be.visible');
  });
});

Password Reset Flow

Wait for the password reset email after triggering the reset action.

import { trivumo } from '../support/trivumo';

describe('Password Reset', () => {
  it('allows users to reset their password', async () => {
    const email = 'user@example.com';

    cy.visit('/forgot-password');

    cy.get('[name=email]').type(email);

    const message =
      await trivumo.waitForMessageAfter(
        () =>
          cy.contains(
            'button',
            'Send Reset Link'
          ).click(),
        {
          to: email,
          subject: 'Reset your password',
        }
      );

    const resetLink =
      message.html?.links[0]?.href;

    cy.visit(resetLink!);

    cy.get('[name=password]')
      .type('NewPassword123!');

    cy.contains('button', 'Update Password')
      .click();

    cy.contains('Password updated')
      .should('be.visible');
  });
});

Validate passwordless authentication workflows.

import { trivumo } from '../support/trivumo';

describe('Magic Link Login', () => {
  it('logs in using a magic link', async () => {
    const email = trivumo.generateEmail();

    cy.visit('/login');

    cy.get('[name=email]').type(email);

    const message =
      await trivumo.waitForMessageAfter(
        () =>
          cy.contains(
            'button',
            'Send Magic Link'
          ).click(),
        {
          to: email,
          subject: 'Sign in to your account',
        }
      );

    const magicLink =
      message.html?.links[0]?.href;

    cy.visit(magicLink!);

    cy.contains('Welcome back')
      .should('be.visible');
  });
});

One-Time Password (OTP)

Extract OTP codes directly from incoming emails.

import { trivumo } from '../support/trivumo';

describe('OTP Login', () => {
  it('logs in using a one-time password', async () => {
    const email = trivumo.generateEmail();

    cy.visit('/login');

    cy.get('[name=email]').type(email);

    const message =
      await trivumo.waitForMessageAfter(
        () =>
          cy.contains(
            'button',
            'Send Code'
          ).click(),
        {
          to: email,
        }
      );

    const otp =
      message.html?.codes[0] ??
      message.text?.codes[0];

    cy.get('[name=code]').type(otp!);

    cy.contains('button', 'Verify')
      .click();

    cy.contains('Successfully logged in')
      .should('be.visible');
  });
});

Validate Email Content

Assert on email subjects, content, links, and extracted metadata.

import { trivumo } from '../support/trivumo';

describe('Welcome Email', () => {
  it('contains an onboarding link', async () => {
    const email = trivumo.generateEmail();

    const message =
      await trivumo.waitForMessage({
        to: email,
        subject: 'Welcome to Acme',
      });

    expect(message.subject)
      .to.equal('Welcome to Acme');

    expect(
      message.html?.body
    ).to.contain('Getting Started');

    expect(
      message.html?.links.some(link =>
        link.href.includes('/onboarding')
      )
    ).to.equal(true);
  });
});

Assert on Email Headers

Validate custom email headers generated by your application.

const message = await trivumo.waitForMessage({
  to: email,
});

const header = message.headers.find(
  header => header.key === 'x-environment'
);

expect(header?.value).to.equal('staging');

Best Practice: Use waitForMessageAfter

Using waitForMessageAfter() ensures that only emails received after a specific action are matched.

const message = await trivumo.waitForMessageAfter(
  () => cy.contains('button', 'Submit').click(),
  {
    to: email,
    subject: 'Verify your account',
  }
);

This prevents tests from accidentally matching emails that were sent before the action under test.

On this page