Repository navigation
test(interaction-harness): a busy proof excuses a hold at the block's start only at the position the page set #9467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -618,8 +618,10 @@ function motionStepPx(values: readonly number[]): number { | |
| * at the first presented change inside it: WebKit presents a just-started | ||
| * compositor animation late (a sheet's release held on screen for 130 to | ||
| * 300 ms while its timeline ran, and the screencast reaches Node about 0.7 s | ||
| * late on a loaded runner, too late to wait on before blocking). Every frame | ||
| * after that first change is judged, so a freeze later in the block fails. | ||
| * late on a loaded runner, too late to wait on before blocking). Only a hold | ||
| * at `setBeforeBlock`, the value the page itself last set before the block, | ||
| * is excused. Every frame after that first change is judged, so a freeze | ||
| * later in the block fails. | ||
| * The judged part still ends with the block and the `minJudgedFrames` floor | ||
| * applies to it, so a start the block itself delays fails; any other | ||
| * animation that was already moving is judged from the block's start, and a | ||
|
|
@@ -684,6 +686,7 @@ export function busyWindowProof( | |
| settledWithin, | ||
| settledWithinSteps, | ||
| settledAt, | ||
| setBeforeBlock, | ||
| maxMedianFrameMs = Infinity, | ||
| maxStallFrames = 3, | ||
| minMovedFraction = 0.9, | ||
|
|
@@ -735,6 +738,17 @@ export function busyWindowProof( | |
| * position until the main thread commits the end state. | ||
| */ | ||
| settledAt?: number; | ||
| /** | ||
| * The tracked value the page itself last set before the block, such as a | ||
| * drag's last position at its release. It is in the tracked box's | ||
| * coordinates: where the box sits at rest, plus the offset the page wrote. | ||
| * A hold that starts before the block and ends at its first presented | ||
| * change can be a late hand-off. It is one only when it holds this value, | ||
| * where the animation starts. Without it, or when the hold shows another | ||
| * value, the hold is judged as a stall. An animation can freeze at the | ||
| * block's start. | ||
| */ | ||
| setBeforeBlock?: number; | ||
| /** | ||
| * When the compositor presented each frame, epoch ms on the page clock | ||
| * (`startCompositorTrace`; Chromium). Empty or absent, the screencast is | ||
|
|
@@ -877,11 +891,20 @@ export function busyWindowProof( | |
| v.t < (inWindow[0] ?? -Infinity) && | ||
| Math.abs(v.value - lead[lead.length - 1]) <= 0.25, | ||
| ).length; | ||
| // A late hand-off holds the page's last position. An animation that froze | ||
| // at the block's start holds a position of its own. Within one cast step: | ||
| // WebKit's cast reads positions on a 2 px grid, so a held position can read | ||
| // up to a step off. A cast with no step is read within a pixel. | ||
| const matchPx = tracked.some(f => f.step != null) | ||
| ? castStep(tracked, axis) | ||
| : 1; | ||
| const heldFromBeforeBlock = | ||
| setBeforeBlock != null && | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this gate,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed: that case now passes the last position before the judged part as |
||
| lead.length > 0 && | ||
| holdStart > 0 && | ||
| prior[holdStart].t < window.from && | ||
| heldFrames >= 2; | ||
| heldFrames >= 2 && | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deleting this line alone leaves every harness unit passing.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed: |
||
| Math.abs(lead[lead.length - 1] - setBeforeBlock) <= matchPx; | ||
| const onScreenFrom = | ||
| prior.length > 0 && | ||
| (!movedBefore || heldFromBeforeBlock) && | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking: this case runs on frames with no step, so it takes the 1 px fallback. Every real cast of the default marker carries a step and takes the
castStepbranch inbusy.ts, where no case refuses a hold at another position: replacingcastStep(tracked, axis)withInfinitykeeps every unit passing. A stepped copy of this case pins it: