QA / E2E guide
Open-source QA flows — temporary inbox per test run, OTP and magic links
without a shared test@company.com.
Source on GitHub.
Problems we solve
| Pain | Solution |
|---|---|
| Shared inbox races in CI | label per run / worker |
| Long waits in tests | POST /v1/inboxes/open |
| Wrong email picked | subjectContains + allowlist |
| Parse HTML for OTP | verification.otp, primaryLink |
| Debug failed run | GET /v1/inboxes?label=... |
CI quick start
export MAILAGENT_API_URL=https://api.webmailagent.com
export MAILAGENT_API_KEY=your_key
export RUN_ID="${GITHUB_RUN_ID:-local}"
curl -sS -X POST "$MAILAGENT_API_URL/v1/inboxes/open" \
-H "Authorization: Bearer $MAILAGENT_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"label\": \"ci-$RUN_ID\",
\"service\": \"auth0\",
\"subjectContains\": \"verification\",
\"timeoutSeconds\": 120
}"
Recommended E2E order
POST /v1/inboxeswithlabel→ getaddress- Fill signup form on staging
GET /v1/inboxes/:id/wait?subjectContains=...then/extract
Playwright
Use env MAILAGENT_API_URL and MAILAGENT_API_KEY with the REST API above,
or request the @mailagent/qa helper package during pilot onboarding.
const res = await fetch(`${API}/v1/inboxes`, {
method: "POST",
headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ label: `pw-${workerId}`, service: "auth0" }),
});
const { id, address } = await res.json();
// page.fill email → wait → extract
QA fields
| Field | Where | Purpose |
|---|---|---|
label | create, open | CI run / worker id |
subjectContains | open, wait | Filter by subject |
callbackUrl | create, open | HTTPS webhook on new mail |
deleteAfter | open | false to keep inbox for debug |
Debug after failure
GET /v1/inboxes?label=ci-12345
GET /v1/inboxes/:id/messages