Test password reset emails
Verify password reset flows in automated tests. Capture reset emails and extract tokens through the API.
The problem
End-to-end tests need to verify password reset flows: request a reset, receive the email, extract the token and complete the process. Without email capture, tests either skip this critical path or rely on fragile mock setups.
How ammo.tools solves it
Your application sends the reset email to ammo.tools via SMTP. Your test fetches the captured message through the API, extracts the reset link and completes the flow against your staging environment.
Setup
- Configure your staging SMTP to use ammo.tools (see Catch staging emails).
- Generate an API key for your test environment.
- In your test, trigger the password reset for a test user.
- Poll the API until the email arrives, then extract the reset link.
Fetching the reset email
curl -H "Authorization: Bearer $AMMO_TOOLS_API_KEY" \ "https://app.ammo.tools/api/v1/inboxes/INB_ID/messages?to=testuser@example.test&subject=reset&wait=30"
The wait parameter holds the connection open until a matching message arrives or the timeout expires.
Extract links from the message
curl -H "Authorization: Bearer $AMMO_TOOLS_API_KEY" \ "https://app.ammo.tools/api/v1/messages/MSG_ID/links?match=reset"
Returns URLs containing the substring. Your test can then follow the link to complete the reset.
Python example
import os, requests, time
api = "https://app.ammo.tools/api/v1"
key = os.environ["AMMO_TOOLS_API_KEY"]
headers = {"Authorization": f"Bearer {key}"}
# Trigger reset in your application first, then:
resp = requests.get(
f"{api}/inboxes/{inbox_id}/messages",
params={"to": "testuser@example.test", "subject": "reset", "wait": 30},
headers=headers,
)
messages = resp.json()["items"]
if messages:
msg_id = messages[0]["id"]
links = requests.get(
f"{api}/messages/{msg_id}/links", params={"match": "reset"}, headers=headers
).json()["items"]
reset_url = links[0]["url"]
# Complete the reset flow with reset_url
Things to know
- Use unique recipient addresses per test run to avoid matching stale messages.
- The
waitparameter accepts values up to 30 seconds. - Filter by
since(ISO timestamp) to ignore older captures. - Links are extracted from both HTML and plain-text bodies.