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 jestCreate 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");
});
});Magic Link Login
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.