Repository navigation
test(ProgressBar, CircularProgress): motion traces read screencast frames in the order they were presented - #9378
Conversation
…ames in the order they were presented The ProgressBar storyboard's forward-only check failed once on a loaded runner: one frame's leading edge read 74 px right after one at 121 px. 74 px is where the fill rests before the change, and in a recorded run the frames go 74 (before the change), 74 (the frame that applies it), 122 (the first that moves), 164 and on. The frame that applied the change had arrived after the first one that moved. Chromium encodes each screencast frame off its main thread and can send a slow one after the next, while each frame carries the swap timestamp it was presented at. Both specs judged frames in arrival order. - ProgressBarMotion takes its frames by that timestamp (`inPresentationOrder`, as the interaction harness's own screencast does) and drops a frame repeating a timestamp already kept. Both of its tests that read the screencast, the storyboard and the main-thread block, now judge presentation order. - CircularProgressMotion's main-thread-block test reads its frames the same way. - A frame presented later that shows the fill behind an earlier one keeps its own later timestamp, so it stays and still fails the trace. Delivering the second frame after the third, with its own timestamp, made main's storyboard check fail 5 of 5 with the reported numbers (121, then 74); it passes 5 of 5 here. The same delivery inside the block fails main's CircularProgress check 5 of 5 and passes here, and a later-stamped frame that shows the old position fails both specs here, as it should.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report🔎 Preview ·
|
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| ProgressBar · Storybook | 7.9 kB (0) · 6.9 kB CSS (0) | 413 (0) | ✗ · ✓ · ✓ |
| lab/CircularProgress · Storybook | 8.5 kB (0) · 1.1 kB CSS (0) | 597 (0) | — · ✓ · — |
Visual changes: 2 snapshots in 1 component
A change is a question for the reviewer, not a failure.
| Component · story | Before | After | Diff |
|---|---|---|---|
| ProgressBar · Default (neutral, dark) | ![]() |
![]() |
![]() |
| ProgressBar · Default (neutral, light) | ![]() |
![]() |
![]() |
Package size: no published package changed; no new dependencies.
Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.
Generated by PR Enrichment workflow | View full report
There was a problem hiding this comment.
Ordering the motion specs' screencast frames by their swap timestamp looks right, and a frame that really steps backwards with its own later timestamp still fails. One change is needed first: CircularProgressMotion.a11y.chromium.spec.ts copies the body of the harness's inPresentationOrder, and both specs add the same repeated-timestamp filter beside it, so frame ordering is now defined in three places. Please call inPresentationOrder from both specs (adding @astryxdesign/interaction-harness to Lab's devDependencies, as core already has it), and either drop the filter, which no run has needed, or move it into the shared helper. That also leaves the open ProgressBar and CircularProgress drafts a single call to pick up when they rebase.
[Automated review]
| const presented = [...raw] | ||
| .sort((a, b) => a.t - b.t) | ||
| .filter((frame, i, ordered) => i === 0 || frame.t > ordered[i - 1].t); |
There was a problem hiding this comment.
This sort is the body of inPresentationOrder (internal/interaction-harness/src/frames.ts:193-197), and the filter repeats the one in the ProgressBar spec. Calling the shared helper here, with @astryxdesign/interaction-harness added to Lab's devDependencies as core already has it, keeps one definition of presentation order.
There was a problem hiding this comment.
Done in 1a245be: both specs call inPresentationOrder, and Lab now has @astryxdesign/interaction-harness as a devDependency, which adds three lines to the lockfile.
| return inPresentationOrder(frames).filter( | ||
| (frame, i, ordered) => i === 0 || frame.t > ordered[i - 1].t, | ||
| ); |
There was a problem hiding this comment.
The repeated-timestamp filter lives only in these two specs; the harness's own screencast (frames.ts:124) keeps repeats. No run has repeated a timestamp, and a dropped frame is never judged, so either drop the filter or move it into the shared helper so both specs make one call.
There was a problem hiding this comment.
Dropped in 1a245be: no instrumented run repeated a timestamp, and the harness's own screencast keeps every frame, so both specs now keep every frame too.
…ss's inPresentationOrder Review follow-up. CircularProgressMotion called a copy of the harness's inPresentationOrder, and both specs dropped a frame repeating a timestamp already kept, which no run has needed. Both now call inPresentationOrder from @astryxdesign/interaction-harness, which Lab gains as a devDependency (as core has), and keep every frame.
There was a problem hiding this comment.
Both motion specs now call the interaction harness's inPresentationOrder and keep every frame, which resolves the earlier request, and a frame that really steps backwards still fails because it keeps its own later timestamp. Both specs pass in Chromium at this revision, and the core and Lab typechecks are clean. No further changes are needed.
[Automated review]






Maintainer impact
The ProgressBar storyboard check ("the fill moving from 20% to 80%") failed once in main's CI on a loaded runner, and its re-run passed. Its forward-only check read one frame's leading edge at 74 px right after a frame at 121 px.
Intended invariant
The motion traces judge the frames the page presented, in the order it presented them. A frame that really shows the fill behind an earlier one still fails.
Change
inPresentationOrder, as the harness's own screencast does. Both of its tests that read the screencast, the storyboard and the main-thread block, now judge presentation order.inPresentationOrdertoo.packages/labgains@astryxdesign/interaction-harness(workspace:*) as a devDependency, as core already has. That adds three lines to Lab's importer inpnpm-lock.yaml. Lab is private, so no changeset.package.jsonand the lockfile change. No bound or tolerance changes.Evidence
Scope
Testing
packages/core/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.tsandpackages/lab/src/CircularProgress/__tests__/CircularProgressMotion.a11y.chromium.spec.tsin Chromium. The seams were local copies of the specs with the delivery changed in their screencast handlers.inPresentationOrder, unit-tested inbusy.test.ts). These two specs keep their own screencasts, at their own frame scale and with their acknowledgement checks, and now call the same helper.inPresentationOrdercall when it rebases.Local gates at 1a245be:
pnpm install --frozen-lockfile;pnpm lint,pnpm check:repoandpnpm check:knowledge;