test(history): pin the clock so the calendar suite stops betting on the date
From the PR description
Summary
frontend/src/app/(pages)/history/page.test.tsx is time-dependent and goes red on CI by calendar alignment - it took down otherwise-green runs on two open PRs last night (#267 and #294) the moment CI ran past midnight UTC on 2026-08-27. This PR pins the suite's clock so it is deterministic in every timezone, forever. Test-only change; no product code touched.
What changed
One file, +12 lines: the suite's beforeEach now fakes Date and only Date (vi.useFakeTimers({ toFake: ["Date"] }) + vi.setSystemTime(new Date(2026, 5, 15, 12, 0, 0))), and afterEach restores real timers. Faking only Date matters: user-event's internal timers keep running normally, so no test needed rewriting.
Why
The tests derive their calendar expectations from new Date():
- the default range opens the date pickers on the month of today - 30;
- the range-selection test then clicks today - 25 by its
data-dayattribute.
That day is only on the rendered grid when the month's trailing outside-days happen to include it. Example of the failing alignment (the one CI hit): today = Aug 27 UTC → the start picker renders July (Jul 28 = today-30), but today-25 = Aug 2, one row past July's grid → querySelector returns null → expected null not to be null. Whether the suite passes therefore depends on the day of the month and the runner's timezone - a machine in UTC-7 and CI in UTC disagree for seven hours every night.
A pinned mid-month noon keeps every derived day inside the visible grids unconditionally.
Replication
Base case (on main, any machine, no waiting for midnight):
cd frontend
TZ=UTC npx vitest run "src/app/(pages)/history/page.test.tsx" # 1 failed | 4 passed (today: 2026-08-27)
With this PR:
TZ=UTC npx vitest run "src/app/(pages)/history/page.test.tsx" # 5 passed
TZ=Pacific/Kiritimati npx vitest run "src/app/(pages)/history/page.test.tsx" # 5 passed (UTC+14)
npx vitest run "src/app/(pages)/history/page.test.tsx" # 5 passed (local TZ)
Real-world sightings: #267 run 98399913081 and #294 run 98415048314, both failing this exact assertion just after midnight UTC on 2026-08-27, both on branches that do not touch the history page.
Tradeoffs / design decisions
- Pin the clock vs. fix the date arithmetic. Choosing test dates relative to the default picker month (e.g. default-from + 1 day) would also pass, but stays calendar-dependent at month boundaries and has to be re-reasoned every time the picker's default range changes. A pinned clock removes the whole variable class.
toFake: ["Date"]vs. full fake timers. Full fake timers breakuser-eventunless every interaction threadsadvanceTimers; faking onlyDateleaves the interaction machinery untouched.- The pinned date (2026-06-15) is arbitrary mid-month; any mid-month date works.
- No demo GIF: test-only change with no user-visible behavior to film.
Testing performed
- Red-before-green verified: at
main(1b58c7aa) with the fix reverted,TZ=UTCfails the range-calendar test today; with the fix, the suite passes underTZ=UTC,TZ=Pacific/Kiritimati(UTC+14), and local time. - Full file run: 5/5 in all three timezones.
🤖 Generated with Claude Code
Our analysis
Pin history tests to a fixed clock — read the full analysis →
Think the analysis missed something the PR description covers?
Capture this PR into my fork
Download a Markdown prompt that tells Claude how to port every
commit in this PR into your working tree. Run it via
claude -p < capture-pull-390.md from
inside the repo you want the changes in.