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 seleniumCreate 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_sourcePassword 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_sourceMagic 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_sourceOne-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_sourceValidate 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.