Selenium Email Testing Guide

Updated February 14, 2024

Master email testing in your Selenium automation suite using Mail7. This comprehensive guide shows you how to implement robust email testing scenarios in your web application tests across multiple programming languages.

Setting Up Selenium Email Testing

First, add the required dependencies to your project:

Java (Maven)

<dependencies>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.8.1</version>
    </dependency>
    <dependency>
        <groupId>com.mail7</groupId>
        <artifactId>mail7-java-sdk</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.awaitility</groupId>
        <artifactId>awaitility</artifactId>
        <version>4.2.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Python (pip)

pip install selenium mail7-python-sdk pytest-selenium retry

JavaScript (npm)

npm install selenium-webdriver @mail7/node-sdk jest @testing-library/jest-dom

Basic Implementation

Java Example

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import com.mail7.sdk.Mail7Client;
import static org.awaitility.Awaitility.*;
import static java.util.concurrent.TimeUnit.*;

public class EmailTest {
    private WebDriver driver;
    private Mail7Client mail7Client;
    
    @Before
    public void setUp() {
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(10, SECONDS);
        mail7Client = new Mail7Client(System.getenv("MAIL7_API_KEY"));
    }
    
    @Test
    public void testRegistrationEmail() {
        String testEmail = mail7Client.generateEmail();
        
        // Navigate and register
        driver.get("https://example.com/register");
        driver.findElement(By.id("email")).sendKeys(testEmail);
        driver.findElement(By.id("password")).sendKeys("TestPass123");
        driver.findElement(By.id("register")).click();
        
        // Wait for and verify email
        await().atMost(30, SECONDS)
               .pollInterval(2, SECONDS)
               .until(() -> {
                   List emails = mail7Client.getEmails(testEmail);
                   return !emails.isEmpty();
               });
        
        Email email = mail7Client.getEmails(testEmail).get(0);
        Assert.assertTrue(email.getSubject().contains("Welcome"));
        Assert.assertTrue(email.getHtml().contains("verify your account"));
        
        // Extract and visit verification link
        String verifyLink = extractLink(email.getHtml(), "verify");
        driver.get(verifyLink);
        
        // Verify success
        WebElement successMessage = driver.findElement(By.className("verification-success"));
        Assert.assertTrue(successMessage.isDisplayed());
    }
    
    private String extractLink(String html, String pattern) {
        Pattern p = Pattern.compile("href=\"([^\"]*" + pattern + "[^\"]*)\"");
        Matcher m = p.matcher(html);
        if (m.find()) {
            return m.group(1);
        }
        throw new RuntimeException("Link not found in email");
    }
}

Python Example

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from mail7 import Mail7Client
from retry import retry
import re

class TestEmail:
    def setup_method(self):
        self.driver = webdriver.Chrome()
        self.mail7 = Mail7Client(api_key=os.getenv("MAIL7_API_KEY"))
        self.wait = WebDriverWait(self.driver, 10)
    
    @retry(tries=3, delay=2)
    def wait_for_email(self, email_address):
        emails = self.mail7.get_emails(email_address)
        if not emails:
            raise Exception("Email not received")
        return emails[0]
    
    def test_registration_flow(self):
        test_email = self.mail7.generate_email()
        
        # Register
        self.driver.get("https://example.com/register")
        self.wait.until(EC.presence_of_element_located((By.ID, "email"))).send_keys(test_email)
        self.driver.find_element(By.ID, "password").send_keys("TestPass123")
        self.driver.find_element(By.ID, "register").click()
        
        # Verify email
        email = self.wait_for_email(test_email)
        assert "Welcome" in email.subject
        assert "verify your account" in email.html
        
        # Extract verification link
        verify_link = re.search(r'href="([^"]*verify[^"]*)"', email.html).group(1)
        self.driver.get(verify_link)
        
        # Verify success
        success_element = self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, "verification-success"))
        )
        assert success_element.is_displayed()

JavaScript Example

const { Builder, By, until } = require('selenium-webdriver');
const Mail7Client = require('@mail7/node-sdk');
const chrome = require('selenium-webdriver/chrome');

class EmailTest {
    constructor() {
        this.driver = new Builder()
            .forBrowser('chrome')
            .build();
        this.mail7 = new Mail7Client(process.env.MAIL7_API_KEY);
    }
    
    async waitForEmail(emailAddress, timeout = 30000) {
        const startTime = Date.now();
        while (Date.now() - startTime < timeout) {
            const emails = await this.mail7.getEmails(emailAddress);
            if (emails.length > 0) return emails[0];
            await new Promise(resolve => setTimeout(resolve, 2000));
        }
        throw new Error('Email not received within timeout');
    }
    
    async testRegistration() {
        const testEmail = await this.mail7.generateEmail();
        
        // Register
        await this.driver.get('https://example.com/register');
        await this.driver.findElement(By.id('email')).sendKeys(testEmail);
        await this.driver.findElement(By.id('password')).sendKeys('TestPass123');
        await this.driver.findElement(By.id('register')).click();
        
        // Wait for and verify email
        const email = await this.waitForEmail(testEmail);
        expect(email.subject).toContain('Welcome');
        expect(email.html).toContain('verify your account');
        
        // Extract and visit verification link
        const verifyLink = email.html.match(/href="([^"]*verify[^"]*)"/)[1];
        await this.driver.get(verifyLink);
        
        // Verify success
        const successElement = await this.driver.wait(
            until.elementLocated(By.className('verification-success')),
            10000
        );
        expect(await successElement.isDisplayed()).toBe(true);
    }
}

Advanced Testing Scenarios

1. Password Reset Flow

@Test
public void testPasswordReset() {
    String testEmail = mail7Client.generateEmail();
    String newPassword = "NewPass123!";
    
    // Register user first
    registerUser(testEmail);
    
    // Initiate password reset
    driver.get("/forgot-password");
    driver.findElement(By.id("email")).sendKeys(testEmail);
    driver.findElement(By.id("reset-button")).click();
    
    // Wait for reset email
    await().atMost(30, SECONDS)
           .pollInterval(2, SECONDS)
           .until(() -> !mail7Client.getEmails(testEmail).isEmpty());
    
    Email resetEmail = mail7Client.getEmails(testEmail).get(0);
    String resetLink = extractLink(resetEmail.getHtml(), "reset");
    
    // Complete reset
    driver.get(resetLink);
    driver.findElement(By.id("new-password")).sendKeys(newPassword);
    driver.findElement(By.id("confirm-password")).sendKeys(newPassword);
    driver.findElement(By.id("submit")).click();
    
    // Verify login with new password
    driver.get("/login");
    driver.findElement(By.id("email")).sendKeys(testEmail);
    driver.findElement(By.id("password")).sendKeys(newPassword);
    driver.findElement(By.id("login")).click();
    
    Assert.assertTrue(driver.findElement(By.className("dashboard")).isDisplayed());
}

2. Multi-Step Verification

@Test
public void testMultiStepVerification() {
    String testEmail = mail7Client.generateEmail();
    
    // Start verification process
    driver.get("/verify-account");
    driver.findElement(By.id("email")).sendKeys(testEmail);
    driver.findElement(By.id("send-code")).click();
    
    // Wait for first verification email
    await().atMost(30, SECONDS)
           .pollInterval(2, SECONDS)
           .until(() -> !mail7Client.getEmails(testEmail).isEmpty());
    
    Email firstEmail = mail7Client.getEmails(testEmail).get(0);
    String verificationCode = extractVerificationCode(firstEmail.getText());
    
    // Enter verification code
    driver.findElement(By.id("verification-code")).sendKeys(verificationCode);
    driver.findElement(By.id("verify-code")).click();
    
    // Complete 2FA setup
    driver.findElement(By.id("setup-2fa")).click();
    
    // Wait for 2FA setup email
    await().atMost(30, SECONDS)
           .pollInterval(2, SECONDS)
           .until(() -> mail7Client.getEmails(testEmail).size() > 1);
    
    Email secondEmail = mail7Client.getEmails(testEmail).get(1);
    String setupCode = extractVerificationCode(secondEmail.getText());
    
    driver.findElement(By.id("2fa-code")).sendKeys(setupCode);
    driver.findElement(By.id("complete-2fa")).click();
    
    Assert.assertTrue(driver.findElement(By.className("setup-complete")).isDisplayed());
}

Best Practices

1. Test Organization

  • Use Page Object Model for better maintainability
  • Implement proper wait strategies
  • Handle timeouts and retries properly
  • Clean up test data after each test

2. Error Handling

  • Implement proper exception handling
  • Add retry mechanisms for flaky operations
  • Log detailed error information
  • Handle browser-specific issues

3. Performance

  • Use explicit waits instead of thread sleep
  • Implement efficient email polling
  • Reuse browser sessions when possible
  • Clean up resources properly

Common Pitfalls

  • Timing Issues: Not waiting properly for emails or page loads
  • Resource Management: Not closing browser sessions
  • Test Isolation: Not cleaning up test data
  • Error Handling: Not implementing proper retries

Debugging Tips

  • Enable Selenium's detailed logging
  • Use browser developer tools
  • Implement screenshot capture on failure
  • Log all API responses
  • Use Mail7's web interface for manual verification

Start Email Testing with Selenium

Implement comprehensive email testing in your Selenium automation suite with Mail7's testing infrastructure.