Let a test pin the clock relativeDate measures from - #6012
Conversation
`relativeDate` renders a file's age against `Date.now()`, so what it produces depends on when it runs: under a month old it changes daily, under a year monthly, and after that annually. A Percy snapshot of a card carrying one of those labels therefore drifts on its own, and the only tool the repository had for that was `data-test-percy-hide`, which stops the element being compared at all. It reads `globalThis.__boxelNow` when that holds a number, so a test can make the label a function of the file's timestamp alone. The label stays visible, so a change in how it is formatted still shows up as a diff. Unset — every non-test path — it is the real clock, so nothing rendered anywhere changes. The read is off a global rather than an argument because it has to reach card code through whichever loader instance rendered it, which the call site does not know about; `__boxelRenderMode` and its neighbours already work this way. This matters more than the thresholds suggest, because the timestamps it measures are already fixed. `scripts/normalize-realm-mtimes.mjs` rewrites every realm file's mtime to a fingerprint of its content so two checkouts agree, and says of the result that the timestamps are "stable but not meaningful as dates". A fingerprint is a fixed point that real time then walks away from, and the fingerprints spread across decades, so one landing inside the thirty-day window renders a label that changes every day until the file's content does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Preview deploymentsHost Test Results 1 files ±0 1 suites ±0 2h 11m 51s ⏱️ + 18m 57s Results for commit 6ac91bf. ± Comparison against earlier commit d3d7eec. For more details on these errors, see this check. Realm Server Test Results 1 files ±0 190 suites ±0 1h 9m 38s ⏱️ + 2m 24s Results for commit 6ac91bf. ± Comparison against earlier commit d3d7eec. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3d7eecd8e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let pinned = (globalThis as { __boxelNow?: unknown }).__boxelNow; | ||
| return typeof pinned === 'number' && Number.isFinite(pinned) | ||
| ? pinned | ||
| : Date.now(); |
There was a problem hiding this comment.
Pin the clock on the Percy rendering path
When a Percy test renders FileFittedShell, this still falls through to Date.now(): a repository-wide search at this commit finds no assignment to __boxelNow outside the new unit-test module, and neither packages/host/tests/helpers/percy-snapshot.ts nor the visual-test setup pins it before rendering. Consequently, the fitted file age that motivated this change continues to drift between Percy builds; set and restore the pin in the relevant visual-test setup before the card renders.
Useful? React with 👍 / 👎.
`relativeDate` was not the only thing rendering an age against the wall clock. `time-ago`, `countdown` and `expiration-warning` each hold a tracked `Date.now()` that a timer refreshes, and `age` computes against a fresh `new Date()` — five renderers, five independent reads, none of them pinnable. They now read `helpers/clock`, which is the seam `file-presentation` carried privately, moved somewhere the rest of them can reach. Unset it is the real clock, so nothing rendered outside a test changes; pinned, every one of these renders from the same instant, which is what makes a visual comparison of them meaningful rather than a race against the schedule each happens to change on. The ticking components keep their timers. A tick still fires and still assigns, it just assigns the same number each time while the clock is pinned, so the component's own behaviour is unchanged and only its output settles. `nowDate()` exists for `age`, which wants a Date rather than a number, so that routing it through the seam did not mean rewriting its arithmetic. What is left reading the clock directly in `packages/base` is defaults and parse references — a quarter field defaulting to the current year, a date parser's reference date — rather than anything whose rendered output is an elapsed time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
relativeDaterenders a file's age againstDate.now(), so what it produces depends on when it runs: under a month old it changes daily, under a year monthly, and after that annually. A Percy snapshot of a card carrying one of those labels therefore drifts on its own, and the only tool the repository had for that wasdata-test-percy-hide, which stops the element being compared at all.It reads
globalThis.__boxelNowwhen that holds a number, so a test can make the label a function of the file's timestamp alone. The label stays visible, so a change in how it is formatted still shows up as a diff. Unset — every non-test path — it is the real clock, so nothing rendered anywhere changes.The read is off a global rather than an argument because it has to reach card code through whichever loader instance rendered it, which the call site does not know about;
__boxelRenderModeand its neighbours already work this way.This matters more than the thresholds suggest, because the timestamps it measures are already fixed.
scripts/normalize-realm-mtimes.mjsrewrites every realm file's mtime to a fingerprint of its content so two checkouts agree, and says of the result that the timestamps are "stable but not meaningful as dates". A fingerprint is a fixed point that real time then walks away from, and the fingerprints spread across decades, so one landing inside the thirty-day window renders a label that changes every day until the file's content does.