Ƭrivumo Docs
Ƭrivumo Docs
HomeMCP Server
CypressJest + SeleniumMocha + SeleniumPlaywrightPytest + PlaywrightPytest + SeleniumRobot FrameworkWebdriverIO
Examples

Pytest + Selenium

Learn how to test email workflows in Pytest and Selenium using Trivumo.


Email verification, password resets, magic links, invitations, and OTP-based authentication flows are common parts of modern applications. Trivumo makes it easy to validate these workflows directly from your Selenium tests.

Install

pip install trivumo
pip install pytest selenium

Create a Client

from trivumo import TrivumoClient

trivumo = TrivumoClient(
    apiKey="your_api_key",
    domain="sandbox.trivumo.com",
)

Verify Email Signup Flow

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

from selenium.webdriver.common.by import By
from trivumo import TrivumoClient

trivumo = TrivumoClient(
    apiKey="your_api_key",
    domain="sandbox.trivumo.com",
)

def test_user_can_verify_email(driver):
    email = trivumo.generate_email()

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

    driver.find_element(
        By.NAME,
        "email",
    ).send_keys(email)

    driver.find_element(
        By.NAME,
        "password",
    ).send_keys("Password123!")

    driver.find_element(
        By.CSS_SELECTOR,
        "button[type='submit']",
    ).click()

    message = trivumo.wait_for_message(
        {
            "to": email,
            "subject": "Verify your account",
        }
    )

    verification_link = (
        message.html.links[0].href
        if message.html and message.html.links
        else None
    )

    driver.get(verification_link)

    assert "Email verified" in driver.page_source

Password Reset Flow

Use wait_for_message_after() to ensure only emails received after the reset request are considered.

from selenium.webdriver.common.by import By

def test_user_can_reset_password(driver):
    email = "user@example.com"

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

    driver.find_element(
        By.NAME,
        "email",
    ).send_keys(email)

    message = trivumo.wait_for_message_after(
        lambda: driver.find_element(
            By.CSS_SELECTOR,
            "button[type='submit']",
        ).click(),
        {
            "to": email,
            "subject": "Reset your password",
        },
    )

    reset_link = (
        message.html.links[0].href
        if message.html and message.html.links
        else None
    )

    driver.get(reset_link)

    driver.find_element(
        By.NAME,
        "password",
    ).send_keys("NewPassword123!")

    driver.find_element(
        By.CSS_SELECTOR,
        "button[type='submit']",
    ).click()

    assert "Password updated" in driver.page_source

Magic Link Login

Validate passwordless authentication flows.

def test_user_can_login_with_magic_link(driver):
    email = trivumo.generate_email()

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

    driver.find_element(
        By.NAME,
        "email",
    ).send_keys(email)

    message = trivumo.wait_for_message_after(
        lambda: driver.find_element(
            By.CSS_SELECTOR,
            "button[type='submit']",
        ).click(),
        {
            "to": email,
            "subject": "Sign in to your account",
        },
    )

    magic_link = (
        message.html.links[0].href
        if message.html and message.html.links
        else None
    )

    driver.get(magic_link)

    assert "Welcome back" in driver.page_source

One-Time Password (OTP)

Extract verification codes directly from incoming emails.

from selenium.webdriver.common.by import By

def test_user_can_login_using_otp(driver):
    email = trivumo.generate_email()

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

    driver.find_element(
        By.NAME,
        "email",
    ).send_keys(email)

    message = trivumo.wait_for_message_after(
        lambda: driver.find_element(
            By.CSS_SELECTOR,
            "button[type='submit']",
        ).click(),
        {
            "to": email,
        },
    )

    otp = None

    if message.html and message.html.codes:
        otp = message.html.codes[0]
    elif message.text and message.text.codes:
        otp = message.text.codes[0]

    driver.find_element(
        By.NAME,
        "code",
    ).send_keys(otp)

    driver.find_element(
        By.CSS_SELECTOR,
        "button[type='submit']",
    ).click()

    assert "Successfully logged in" in driver.page_source

Validate Email Content

Assert on email subjects, content, links, and verification codes.

def test_welcome_email_contains_onboarding_link():
    email = trivumo.generate_email()

    message = trivumo.wait_for_message(
        {
            "to": email,
            "subject": "Welcome to Acme",
        }
    )

    assert message.subject == "Welcome to Acme"

    assert "Getting Started" in (
        message.html.body
        if message.html
        else ""
    )

    assert any(
        "/onboarding" in link.href
        for link in (
            message.html.links
            if message.html
            else []
        )
    )

Best Practice

Use wait_for_message_after() whenever a user action triggers an email.

message = trivumo.wait_for_message_after(
    lambda: driver.find_element(
        By.CSS_SELECTOR,
        "button[type='submit']",
    ).click(),
    {
        "to": email,
        "subject": "Verify your account",
    },
)

This ensures Trivumo only considers emails received after the action is executed, making tests more reliable and eliminating false positives from previously received messages.

Pytest + Playwright

Learn how to test email workflows using Trivumo and Pytest with Playwright.

Robot Framework

Learn how to test email workflows using Trivumo and Robot Framework.

On this page

InstallCreate a ClientVerify Email Signup FlowPassword Reset FlowMagic Link LoginOne-Time Password (OTP)Validate Email ContentBest Practice