DEMO-023's flow in TypeScript on its own account (courier): request a reset, wait for the email in the mailbox, follow the link, set a random password, sign in -- then check the link no longer works.
demoemailfreightsecuritytypescript DEMO-T16__freight_password_reset_typescript.spec.ts group: Freight in TypeScriptgroup: Python and TypeScript, side by side
Runs
7
Pass rate
86%
6 passed / 1 failed
Avg duration
11s
p95 15s
Estimate
11s
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 17s
Why this test failed grouped by message, last 90 days
| times | message | last | |
|---|---|---|---|
| 1 | 1 of 1 test(s) failed: a password reset works through the email -- ex… | Sep 25 | open |
Outcomes by target version
What this test does plain language, derived from the code
No steps found.
Show the code
import { test, expect } from '@playwright/test';
import { randomBytes } from 'crypto';
import { open } from './_lib/freight';
// A password reset through the email, in TypeScript -- DEMO-023's flow on its
// own account (`courier`, so the two can run side by side). Waiting for the
// email is one web-first assertion with a longer timeout: the mailbox page
// reloads itself when new mail lands, and expect() keeps looking across the
// reloads. The reset link carries a secret token, so it is CLICKED in the
// email -- never navigated to, which would write the token into the log.
const ACCOUNT = 'courier';
const ADDRESS = 'courier@acme-freight.example';
test('a password reset works through the email -- exactly once', async ({ page }) => {
await open(page, 'login/');
await page.click('#forgot-link');
await page.fill('#forgot-login', ACCOUNT);
await page.click('#forgot-btn');
const ref = (await page.locator('#forgot-ref').innerText()).trim();
console.log(`reset requested, reference ${ref}`);
const subject = page.locator(`#mail-list a.mail-subject:has-text('ref ${ref}')`);
const resetLink = page.locator("#mail-body a[href*='/login/reset/']");
await test.step('wait for the email', async () => {
await open(page, `mailbox/?to=${ADDRESS}`);
await expect(subject).toBeVisible({ timeout: 60_000 });
});
await subject.click();
await expect(resetLink).toBeVisible();
const message = page.url();
const password = 'Pw-' + randomBytes(9).toString('base64url'); // fresh every run, never logged
await test.step('choose a new password', async () => {
await resetLink.click();
await page.fill('#new-password', password);
await page.fill('#confirm-password', password);
await page.click('#reset-btn');
await expect(page.locator('#login-btn')).toBeVisible();
});
await test.step('sign in with the new password', async () => {
await page.fill('#username', ACCOUNT);
await page.fill('#password', password);
await page.click('#login-btn');
await expect(page.locator('#signed-in-user')).toBeVisible();
});
await page.click('#sign-out');
await test.step('follow the same link again', async () => {
await page.goto(message);
await resetLink.click();
await expect(page.locator('#reset-invalid, #reset-form')).toBeVisible();
await expect(page.locator('#reset-form'),
'the reset link worked a SECOND time: any old reset email is still a key to the account')
.toHaveCount(0);
});
});
All runs
| Run | Status | Queued | Duration | Version | Trigger | Batch |
|---|---|---|---|---|---|---|
| #480 | passed | 2026-09-25 00:30:11 | 9s | 3.0.0 | group | group: Python and TypeScript,… |
| #468 | passed | 2026-09-25 00:29:44 | 11s | 3.0.0 | group | group: Freight in TypeScript |
| #434 | passed | 2026-09-25 00:23:39 | 10s | 3.0.0 | cli-adopted | 7 tests (terminal) |
| #427 | failed | 2026-09-25 00:23:08 | 17s | 2.1.0 | cli-adopted | 7 tests (terminal) |
| #420 | passed | 2026-09-25 00:22:38 | 12s | 2.0.0 | cli-adopted | 7 tests (terminal) |
| #413 | passed | 2026-09-25 00:22:11 | 10s | 1.1.0 | cli-adopted | 7 tests (terminal) |
| #406 | passed | 2026-09-25 00:21:43 | 12s | 1.0.0 | cli-adopted | 7 tests (terminal) |