Requests a reset, waits for the email in the demo's mailbox, follows the link, sets a random new password, signs in with it -- then checks the link no longer works.
demoemailfreightsecurity version: 1.0 DEMO-023__freight_password_reset_email.py group: Freight extrasgroup: Python and TypeScript, side by side
Runs
7
Pass rate
86%
6 passed / 1 failed
Avg duration
10s
p95 11s
Estimate
10s
avg of last 10 judged runs
Flakiness
0.33
0 stable · 1 alternates
Current streak
3
passed
Duration per run point color = outcome; dashed = 7-run average; click a point to open the run
Step timing trends the same step compared across the last 7 runs — slowest steps first, one line each
How long it takes distribution of 7 runs — two humps mean two different behaviours hiding behind one average
fastest 9s · slowest 11s
Why this test failed grouped by message, last 90 days
| times | message | last | |
|---|---|---|---|
| 1 | AssertionError: the reset link worked a SECOND time: any old reset em… | Sep 24 | open |
Outcomes by target version
What this test does plain language, derived from the code
- site = Freight(page, ctx)
- site.open("login/")
- Click #forgot-link
- page.fill("#forgot-login", ACCOUNT)
- Click #forgot-btn
- ref = page.inner_text("#forgot-ref").strip()
- ctx.log(f"reset requested, reference {ref}")
- ⏱ Timed phase: wait for the email
- site.open(f"mailbox/?to={ADDRESS}")
- subject = f"#mail-list a.mail-subject:has-text('ref {ref}')"
- page.wait_for_selector(subject, timeout=60_000)
- page.click(subject)
- page.wait_for_selector(RESET_LINK)
- message = page.url
- Take a screenshot (“the reset email”)
- new_password = "Pw-" + secrets.token_urlsafe(12)
- ⏱ Timed phase: choose a new password
- page.click(RESET_LINK)
- page.fill("#new-password", new_password)
- page.fill("#confirm-password", new_password)
- Click #reset-btn
- Wait until #login-btn appears
- ⏱ Timed phase: sign in with the new password
- page.fill("#username", ACCOUNT)
- page.fill("#password", new_password)
- Click #login-btn
- Wait until #signed-in-user appears
- Note in the log: “signed in with the new password”
- Click #sign-out
- Wait until #login-btn appears
- ⏱ Timed phase: follow the same link again
- page.goto(message)
- page.click(RESET_LINK)
- Wait until #reset-invalid, #reset-form appears
- Take a screenshot (“the same link, a second time”)
- assert page.locator("#reset-form").count() == 0, (
- "the reset link worked a SECOND time: any old reset email is still a key to the "
- "account -- a reset link must stop working once it has been used")
- ctx.log(page.inner_text("#reset-invalid-why"))
Show the code
"""A password reset, end to end -- through the email.
The flow people test by hand because "it goes through email": ask for a
reset, WAIT for the email (a mail queue is not instant), open it, follow the
link, choose a new password, sign in with it -- and then check the link is
dead, because a reset link that works twice turns every old email into a key
to the account.
The demo catches its outgoing mail in a Mailbox page (as MailHog or Mailpit
do in a real test environment), and the test correlates by the request's
reference number: other resets may be in the mailbox too. The reset link
carries a secret token, so the test CLICKS it in the email rather than
navigating to it -- a navigation would write the token into the run's log.
The new password is random per run and never logged.
"""
import secrets
from _lib.freight import Freight
ACCOUNT = "driver" # tester/manager are shared: never reset
ADDRESS = "driver@acme-freight.example"
RESET_LINK = "#mail-body a[href*='/login/reset/']"
def run(page, ctx):
site = Freight(page, ctx)
site.open("login/")
page.click("#forgot-link")
page.fill("#forgot-login", ACCOUNT)
page.click("#forgot-btn")
ref = page.inner_text("#forgot-ref").strip()
ctx.log(f"reset requested, reference {ref}")
with ctx.timed("wait for the email"):
site.open(f"mailbox/?to={ADDRESS}")
# the mailbox checks for new mail every two seconds and reloads itself
subject = f"#mail-list a.mail-subject:has-text('ref {ref}')"
page.wait_for_selector(subject, timeout=60_000)
page.click(subject)
page.wait_for_selector(RESET_LINK)
message = page.url
ctx.screenshot("the reset email")
new_password = "Pw-" + secrets.token_urlsafe(12)
with ctx.timed("choose a new password"):
page.click(RESET_LINK)
page.fill("#new-password", new_password)
page.fill("#confirm-password", new_password)
page.click("#reset-btn")
page.wait_for_selector("#login-btn")
with ctx.timed("sign in with the new password"):
page.fill("#username", ACCOUNT)
page.fill("#password", new_password)
page.click("#login-btn")
page.wait_for_selector("#signed-in-user")
ctx.log("signed in with the new password")
page.click("#sign-out")
page.wait_for_selector("#login-btn")
with ctx.timed("follow the same link again"):
page.goto(message)
page.click(RESET_LINK)
page.wait_for_selector("#reset-invalid, #reset-form")
ctx.screenshot("the same link, a second time")
assert page.locator("#reset-form").count() == 0, (
"the reset link worked a SECOND time: any old reset email is still a key to the "
"account -- a reset link must stop working once it has been used")
ctx.log(page.inner_text("#reset-invalid-why"))
All runs
| Run | Status | Queued | Duration | Version | Trigger | Batch |
|---|---|---|---|---|---|---|
| #473 | passed | 2026-09-25 00:30:11 | 9s | 3.0.0 | group | group: Python and TypeScript,… |
| #363 | passed | 2026-09-24 22:05:07 | 11s | 3.0.0 | group | group: Freight extras |
| #348 | passed | 2026-09-24 20:41:19 | 9s | 3.0.0 | cli-adopted | 3 tests (terminal) |
| #345 | failed | 2026-09-24 20:41:04 | 9s | 2.1.0 | cli-adopted | 3 tests (terminal) |
| #342 | passed | 2026-09-24 20:40:49 | 11s | 2.0.0 | cli-adopted | 3 tests (terminal) |
| #339 | passed | 2026-09-24 20:40:35 | 11s | 1.1.0 | cli-adopted | 3 tests (terminal) |
| #336 | passed | 2026-09-24 20:40:21 | 9s | 1.0.0 | cli-adopted | 3 tests (terminal) |