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 trivumoCreate 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');
});
});Magic Link Login
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.