Testing your SaaS onboarding flow manually is time-consuming. Doing it with a simple Selenium script breaks every time the UI changes. Using an AI agent that can reason about the flow and handle variations is far more robust.
What a Full Onboarding Test Looks Like
- Create a unique inbox for this test run
- Navigate to the signup page
- Fill in name, email (inbox address), and password
- Submit the form
- Wait for the verification email to arrive
- Extract the OTP or click the verification link
- Complete verification
- Verify the user lands on the correct onboarding screen
- Assert expected UI elements are present
Code Example
import { test, expect } from "@playwright/test";
const BASE = "https://api.agentmailr.com";
const KEY = process.env.AGENTMAILR_API_KEY;
const h = { "X-API-Key": KEY };
test("new user can complete onboarding", async ({ page }) => {
// Step 1: Create isolated inbox
const inbox = await fetch(`${BASE}/v1/inboxes`, {
method: "POST", headers: { ...h, "Content-Type": "application/json" }, body: "{}"
}).then(r => r.json());
// Steps 2-4: Fill and submit signup
await page.goto("https://yourapp.com/signup");
await page.fill('[name="email"]', inbox.address);
await page.fill('[name="password"]', "TestPassword123!");
await page.click('[type="submit"]');
// Steps 5-6: Get OTP
const otp = await fetch(`${BASE}/v1/inboxes/${inbox.id}/otp?timeout=60`, { headers: h })
.then(r => r.json()).then(d => d.code);
// Step 7: Complete verification
await page.fill('[name="code"]', otp);
await page.click("text=Verify");
// Steps 8-9: Assert correct state
await expect(page).toHaveURL("/onboarding");
await expect(page.locator("h1")).toContainText("Welcome");
});
Running in CI
This test works identically in CI and locally. Add AGENTMAILR_API_KEY as a repository secret. Each CI run gets a fresh isolated inbox. Tests never interfere with each other.
Testing Multiple Scenarios
Run the same test pattern for different user types, countries, or plan tiers. Each scenario gets its own inbox, ensuring complete isolation.