Ƭrivumo Docs
Examples

Jest + Selenium

Learn how to test email workflows using Trivumo, Jest, and Selenium WebDriver.

Jest and Selenium WebDriver can be combined with Trivumo to test complete email-driven user journeys, including account verification, password resets, magic links, and one-time passwords.

Install

npm install trivumo selenium-webdriver jest

Create a Client

const { TrivumoClient } = require("trivumo");

const trivumo = new TrivumoClient({
  apiKey: process.env.TRIVUMO_API_KEY,
  domain: "sandbox.trivumo.com",
});

Verify Email Signup Flow

const { Builder, By, until } = require("selenium-webdriver");
const { TrivumoClient } = require("trivumo");

describe("Email verification", () => {
  let driver;

  const trivumo = new TrivumoClient({
    apiKey: process.env.TRIVUMO_API_KEY,
    domain: "sandbox.trivumo.com",
  });

  beforeAll(async () => {
    driver = await new Builder()
      .forBrowser("chrome")
      .build();
  });

  afterAll(async () => {
    await driver.quit();
  });

  test("verifies a newly created account", async () => {
    const email = trivumo.generateEmail();

    await driver.get(
      "http://localhost:3000/signup"
    );

    await driver
      .findElement(By.name("email"))
      .sendKeys(email);

    await driver
      .findElement(By.name("password"))
      .sendKeys("Password123!");

    await driver
      .findElement(
        By.css("button[type='submit']")
      )
      .click();

    const message =
      await trivumo.waitForMessageAfter(
        () => {},
        {
          to: email,
          subject: "Verify your account",
        }
      );

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

    await driver.get(verificationLink);

    const successMessage =
      await driver.wait(
        until.elementLocated(
          By.css("[data-testid='verified']")
        ),
        10000
      );

    expect(
      await successMessage.getText()
    ).toContain("Account verified");
  });
});

Password Reset Flow

const { Builder, By, until } = require("selenium-webdriver");
const { TrivumoClient } = require("trivumo");

describe("Password reset", () => {
  let driver;

  const trivumo = new TrivumoClient({
    apiKey: process.env.TRIVUMO_API_KEY,
    domain: "sandbox.trivumo.com",
  });

  beforeAll(async () => {
    driver = await new Builder()
      .forBrowser("chrome")
      .build();
  });

  afterAll(async () => {
    await driver.quit();
  });

  test("resets a password from email", async () => {
    const email = trivumo.generateEmail();

    await driver.get(
      "http://localhost:3000/forgot-password"
    );

    await driver
      .findElement(By.name("email"))
      .sendKeys(email);

    const message =
      await trivumo.waitForMessageAfter(
        async () => {
          await driver
            .findElement(
              By.css("button[type='submit']")
            )
            .click();
        },
        {
          to: email,
          subject: "Reset your password",
        }
      );

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

    await driver.get(resetLink);

    await driver
      .findElement(By.name("password"))
      .sendKeys("NewPassword123!");

    await driver
      .findElement(By.name("confirmPassword"))
      .sendKeys("NewPassword123!");

    await driver
      .findElement(
        By.css("button[type='submit']")
      )
      .click();

    const successMessage =
      await driver.wait(
        until.elementLocated(
          By.css("[data-testid='password-reset']")
        ),
        10000
      );

    expect(
      await successMessage.getText()
    ).toContain("Password updated");
  });
});
const { Builder, By, until } = require("selenium-webdriver");
const { TrivumoClient } = require("trivumo");

describe("Magic link login", () => {
  let driver;

  const trivumo = new TrivumoClient({
    apiKey: process.env.TRIVUMO_API_KEY,
    domain: "sandbox.trivumo.com",
  });

  beforeAll(async () => {
    driver = await new Builder()
      .forBrowser("chrome")
      .build();
  });

  afterAll(async () => {
    await driver.quit();
  });

  test("logs in using a magic link", async () => {
    const email = trivumo.generateEmail();

    await driver.get(
      "http://localhost:3000/login"
    );

    await driver
      .findElement(By.name("email"))
      .sendKeys(email);

    const message =
      await trivumo.waitForMessageAfter(
        async () => {
          await driver
            .findElement(
              By.css("[data-testid='magic-link']")
            )
            .click();
        },
        {
          to: email,
          subject: "Your magic sign-in link",
        }
      );

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

    await driver.get(magicLink);

    const dashboard =
      await driver.wait(
        until.elementLocated(
          By.css("[data-testid='dashboard']")
        ),
        10000
      );

    expect(
      await dashboard.isDisplayed()
    ).toBe(true);
  });
});

One-Time Password (OTP)

const { Builder, By, until } = require("selenium-webdriver");
const { TrivumoClient } = require("trivumo");

describe("OTP verification", () => {
  let driver;

  const trivumo = new TrivumoClient({
    apiKey: process.env.TRIVUMO_API_KEY,
    domain: "sandbox.trivumo.com",
  });

  beforeAll(async () => {
    driver = await new Builder()
      .forBrowser("chrome")
      .build();
  });

  afterAll(async () => {
    await driver.quit();
  });

  test("verifies an OTP code", async () => {
    const email = trivumo.generateEmail();

    await driver.get(
      "http://localhost:3000/otp"
    );

    await driver
      .findElement(By.name("email"))
      .sendKeys(email);

    const message =
      await trivumo.waitForMessageAfter(
        async () => {
          await driver
            .findElement(
              By.css("button[type='submit']")
            )
            .click();
        },
        {
          to: email,
          subject: "Your verification code",
        }
      );

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

    await driver
      .findElement(By.name("otp"))
      .sendKeys(otp);

    await driver
      .findElement(
        By.css("button[type='submit']")
      )
      .click();

    const successMessage =
      await driver.wait(
        until.elementLocated(
          By.css("[data-testid='otp-success']")
        ),
        10000
      );

    expect(
      await successMessage.getText()
    ).toContain("Verification successful");
  });
});

Validate Email Content

const { TrivumoClient } = require("trivumo");

const trivumo = new TrivumoClient({
  apiKey: process.env.TRIVUMO_API_KEY,
  domain: "sandbox.trivumo.com",
});

test("validates email content", async () => {
  const email = trivumo.generateEmail();

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

  expect(message.subject).toBe(
    "Welcome"
  );

  expect(
    message.html.body
  ).toContain("Getting Started");

  expect(
    message.html.links.some((link) =>
      link.href.includes("/onboarding")
    )
  ).toBe(true);
});

Best Practice

Prefer waitForMessageAfter() when an email is triggered by a user action.

const message =
  await trivumo.waitForMessageAfter(
    async () => {
      await driver
        .findElement(
          By.css("button[type='submit']")
        )
        .click();
    },
    {
      to: email,
      subject: "Verify your account",
    }
  );

waitForMessageAfter() ensures only emails received after the triggering action are considered. This prevents false positives caused by messages that may already exist in the inbox from previous test runs.

On this page