Stamp0

Selenium

Complete guide to using Stamp0 with Selenium for E2E testing. Test email workflows in Python, Java, and JavaScript.

This guide shows you how to integrate Stamp0 with Selenium for end-to-end testing of email workflows. We cover Python, Java, and JavaScript implementations.

Installation

pip install selenium requests
<!-- pom.xml -->
<dependencies>
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.15.0</version>
  </dependency>
  <dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
  </dependency>
</dependencies>
npm install selenium-webdriver axios

Configuration

Set up your environment variables:

export STAMP0_API_KEY=sk_live_your_api_key_here
export STAMP0_PROJECT_ID=prj_abc123

API Helper

Create a helper to interact with the Stamp0 API:

stamp0_helper.py
import os
import time
import requests

class Stamp0:
    def __init__(self):
        self.api_key = os.environ['STAMP0_API_KEY']
        self.project_id = os.environ['STAMP0_PROJECT_ID']
        self.base_url = 'https://api.stamp0.com/v1'
        self.headers = {
            'Authorization': f'Bearer {self.api_key}',
            'Content-Type': 'application/json'
        }

    def create_inbox(self):
        """Create a new inbox and return it."""
        response = requests.post(
            f'{self.base_url}/inboxes',
            headers=self.headers,
            json={'projectId': self.project_id}
        )
        response.raise_for_status()
        return response.json()

    def get_emails(self, inbox_id):
        """Get all emails for an inbox."""
        response = requests.get(
            f'{self.base_url}/inboxes/{inbox_id}/emails',
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def wait_for_email(self, inbox_id, timeout=30):
        """Wait for an email to arrive in the inbox."""
        start_time = time.time()
        while time.time() - start_time < timeout:
            emails = self.get_emails(inbox_id)
            if emails:
                return emails[0]
            time.sleep(1)
        raise TimeoutError(f'No email received within {timeout} seconds')
Stamp0Helper.java
import okhttp3.*;
import com.google.gson.*;
import java.io.IOException;

public class Stamp0Helper {
    private final String apiKey;
    private final String projectId;
    private final String baseUrl = "https://api.stamp0.com/v1";
    private final OkHttpClient client = new OkHttpClient();
    private final Gson gson = new Gson();

    public Stamp0Helper() {
        this.apiKey = System.getenv("STAMP0_API_KEY");
        this.projectId = System.getenv("STAMP0_PROJECT_ID");
    }

    public JsonObject createInbox() throws IOException {
        RequestBody body = RequestBody.create(
            gson.toJson(Map.of("projectId", projectId)),
            MediaType.parse("application/json")
        );

        Request request = new Request.Builder()
            .url(baseUrl + "/inboxes")
            .addHeader("Authorization", "Bearer " + apiKey)
            .post(body)
            .build();

        try (Response response = client.newCall(request).execute()) {
            return gson.fromJson(response.body().string(), JsonObject.class);
        }
    }

    public JsonArray getEmails(String inboxId) throws IOException {
        Request request = new Request.Builder()
            .url(baseUrl + "/inboxes/" + inboxId + "/emails")
            .addHeader("Authorization", "Bearer " + apiKey)
            .get()
            .build();

        try (Response response = client.newCall(request).execute()) {
            return gson.fromJson(response.body().string(), JsonArray.class);
        }
    }

    public JsonObject waitForEmail(String inboxId, int timeoutSeconds)
            throws IOException, InterruptedException {
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < timeoutSeconds * 1000) {
            JsonArray emails = getEmails(inboxId);
            if (emails.size() > 0) {
                return emails.get(0).getAsJsonObject();
            }
            Thread.sleep(1000);
        }
        throw new RuntimeException("No email received within timeout");
    }
}
stamp0Helper.js
const axios = require('axios');

class Stamp0 {
  constructor() {
    this.apiKey = process.env.STAMP0_API_KEY;
    this.projectId = process.env.STAMP0_PROJECT_ID;
    this.baseUrl = 'https://api.stamp0.com/v1';
    this.client = axios.create({
      baseURL: this.baseUrl,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async createInbox() {
    const response = await this.client.post('/inboxes', {
      projectId: this.projectId
    });
    return response.data;
  }

  async getEmails(inboxId) {
    const response = await this.client.get(`/inboxes/${inboxId}/emails`);
    return response.data;
  }

  async waitForEmail(inboxId, timeout = 30000) {
    const startTime = Date.now();
    while (Date.now() - startTime < timeout) {
      const emails = await this.getEmails(inboxId);
      if (emails.length > 0) {
        return emails[0];
      }
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
    throw new Error(`No email received within ${timeout}ms`);
  }
}

module.exports = { Stamp0 };

Example: User Signup Flow

test_signup.py
import re
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 stamp0_helper import Stamp0

def test_user_signup():
    stamp0 = Stamp0()
    driver = webdriver.Chrome()

    try:
        # 1. Create a fresh inbox
        inbox = stamp0.create_inbox()

        # 2. Fill out signup form
        driver.get('http://localhost:3000/signup')

        driver.find_element(By.NAME, 'name').send_keys('Test User')
        driver.find_element(By.NAME, 'email').send_keys(inbox['address'])
        driver.find_element(By.NAME, 'password').send_keys('SecurePassword123!')
        driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()

        # 3. Wait for success message
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'success-message'))
        )

        # 4. Wait for verification email
        email = stamp0.wait_for_email(inbox['id'])

        # 5. Extract verification link
        match = re.search(r'https?://[^\s"]+verify[^\s"]*', email['body'])
        assert match, 'No verification link found'
        verify_link = match.group(0)

        # 6. Click verification link
        driver.get(verify_link)

        # 7. Verify success
        WebDriverWait(driver, 10).until(
            EC.text_to_be_present_in_element((By.TAG_NAME, 'h1'), 'Email Verified')
        )

    finally:
        driver.quit()

if __name__ == '__main__':
    test_user_signup()
SignupTest.java
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.*;
import com.google.gson.JsonObject;
import java.util.regex.*;

public class SignupTest {
    public static void main(String[] args) throws Exception {
        Stamp0Helper stamp0 = new Stamp0Helper();
        WebDriver driver = new ChromeDriver();

        try {
            // 1. Create a fresh inbox
            JsonObject inbox = stamp0.createInbox();
            String inboxId = inbox.get("id").getAsString();
            String address = inbox.get("address").getAsString();

            // 2. Fill out signup form
            driver.get("http://localhost:3000/signup");

            driver.findElement(By.name("name")).sendKeys("Test User");
            driver.findElement(By.name("email")).sendKeys(address);
            driver.findElement(By.name("password")).sendKeys("SecurePassword123!");
            driver.findElement(By.cssSelector("button[type='submit']")).click();

            // 3. Wait for success message
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            wait.until(ExpectedConditions.presenceOfElementLocated(
                By.className("success-message")
            ));

            // 4. Wait for verification email
            JsonObject email = stamp0.waitForEmail(inboxId, 30);

            // 5. Extract verification link
            String body = email.get("body").getAsString();
            Pattern pattern = Pattern.compile("https?://[^\\s\"]+verify[^\\s\"]*");
            Matcher matcher = pattern.matcher(body);
            if (!matcher.find()) {
                throw new RuntimeException("No verification link found");
            }
            String verifyLink = matcher.group();

            // 6. Click verification link
            driver.get(verifyLink);

            // 7. Verify success
            wait.until(ExpectedConditions.textToBePresentInElementLocated(
                By.tagName("h1"), "Email Verified"
            ));

            System.out.println("Test passed!");

        } finally {
            driver.quit();
        }
    }
}
signupTest.js
const { Builder, By, until } = require('selenium-webdriver');
const { Stamp0 } = require('./stamp0Helper');

async function testUserSignup() {
  const stamp0 = new Stamp0();
  const driver = await new Builder().forBrowser('chrome').build();

  try {
    // 1. Create a fresh inbox
    const inbox = await stamp0.createInbox();

    // 2. Fill out signup form
    await driver.get('http://localhost:3000/signup');

    await driver.findElement(By.name('name')).sendKeys('Test User');
    await driver.findElement(By.name('email')).sendKeys(inbox.address);
    await driver.findElement(By.name('password')).sendKeys('SecurePassword123!');
    await driver.findElement(By.css('button[type="submit"]')).click();

    // 3. Wait for success message
    await driver.wait(
      until.elementLocated(By.className('success-message')),
      10000
    );

    // 4. Wait for verification email
    const email = await stamp0.waitForEmail(inbox.id);

    // 5. Extract verification link
    const match = email.body.match(/https?:\/\/[^\s"]+verify[^\s"]*/);
    if (!match) throw new Error('No verification link found');
    const verifyLink = match[0];

    // 6. Click verification link
    await driver.get(verifyLink);

    // 7. Verify success
    await driver.wait(
      until.elementTextContains(driver.findElement(By.tagName('h1')), 'Email Verified'),
      10000
    );

    console.log('Test passed!');

  } finally {
    await driver.quit();
  }
}

testUserSignup().catch(console.error);

Example: Password Reset Flow

test_password_reset.py
import re
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 stamp0_helper import Stamp0

def test_password_reset():
    stamp0 = Stamp0()
    driver = webdriver.Chrome()

    try:
        inbox = stamp0.create_inbox()

        # Request password reset
        driver.get('http://localhost:3000/forgot-password')
        driver.find_element(By.NAME, 'email').send_keys(inbox['address'])
        driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()

        # Wait for reset email
        email = stamp0.wait_for_email(inbox['id'])

        # Extract reset link
        match = re.search(r'https?://[^\s"]+reset[^\s"]*', email['body'])
        reset_link = match.group(0)

        # Complete password reset
        driver.get(reset_link)
        driver.find_element(By.NAME, 'password').send_keys('NewPassword456!')
        driver.find_element(By.NAME, 'confirmPassword').send_keys('NewPassword456!')
        driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()

        # Verify success
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'success-message'))
        )

    finally:
        driver.quit()
passwordResetTest.js
const { Builder, By, until } = require('selenium-webdriver');
const { Stamp0 } = require('./stamp0Helper');

async function testPasswordReset() {
  const stamp0 = new Stamp0();
  const driver = await new Builder().forBrowser('chrome').build();

  try {
    const inbox = await stamp0.createInbox();

    // Request password reset
    await driver.get('http://localhost:3000/forgot-password');
    await driver.findElement(By.name('email')).sendKeys(inbox.address);
    await driver.findElement(By.css('button[type="submit"]')).click();

    // Wait for reset email
    const email = await stamp0.waitForEmail(inbox.id);

    // Extract reset link
    const match = email.body.match(/https?:\/\/[^\s"]+reset[^\s"]*/);
    const resetLink = match[0];

    // Complete password reset
    await driver.get(resetLink);
    await driver.findElement(By.name('password')).sendKeys('NewPassword456!');
    await driver.findElement(By.name('confirmPassword')).sendKeys('NewPassword456!');
    await driver.findElement(By.css('button[type="submit"]')).click();

    // Verify success
    await driver.wait(
      until.elementLocated(By.className('success-message')),
      10000
    );

  } finally {
    await driver.quit();
  }
}

testPasswordReset().catch(console.error);

Example: OTP Verification

test_otp.py
import re
from stamp0_helper import Stamp0

def extract_otp(email_body):
    """Extract 6-digit OTP from email body."""
    match = re.search(r'\b(\d{6})\b', email_body)
    return match.group(1) if match else None

def test_otp_verification():
    stamp0 = Stamp0()
    driver = webdriver.Chrome()

    try:
        inbox = stamp0.create_inbox()

        # Trigger OTP email
        driver.get('http://localhost:3000/verify-phone')
        driver.find_element(By.NAME, 'email').send_keys(inbox['address'])
        driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()

        # Wait for OTP email
        email = stamp0.wait_for_email(inbox['id'])

        # Extract OTP
        otp = extract_otp(email['body'])
        assert otp, 'No OTP found in email'

        # Enter OTP
        driver.find_element(By.NAME, 'otp').send_keys(otp)
        driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()

        # Verify success
        WebDriverWait(driver, 10).until(
            EC.url_contains('/dashboard')
        )

    finally:
        driver.quit()
otpTest.js
async function testOtpVerification() {
  const stamp0 = new Stamp0();
  const driver = await new Builder().forBrowser('chrome').build();

  try {
    const inbox = await stamp0.createInbox();

    // Trigger OTP email
    await driver.get('http://localhost:3000/verify-phone');
    await driver.findElement(By.name('email')).sendKeys(inbox.address);
    await driver.findElement(By.css('button[type="submit"]')).click();

    // Wait for OTP email
    const email = await stamp0.waitForEmail(inbox.id);

    // Extract 6-digit OTP
    const otpMatch = email.body.match(/\b(\d{6})\b/);
    const otp = otpMatch[1];

    // Enter OTP
    await driver.findElement(By.name('otp')).sendKeys(otp);
    await driver.findElement(By.css('button[type="submit"]')).click();

    // Verify success
    await driver.wait(until.urlContains('/dashboard'), 10000);

  } finally {
    await driver.quit();
  }
}

Best Practices

Tips for Selenium + Stamp0:

  1. Create a fresh inbox for each test to avoid interference
  2. Use explicit waits instead of sleep statements
  3. Handle email polling with reasonable timeouts (30 seconds is usually enough)
  4. Extract links and OTPs with robust regex patterns
  5. Clean up test data when possible

Next Steps