Catch an exit half-way on a slow machine, not only on a fast one
tests / feature (8.4) (push) Successful in 1m45s
tests / feature (8.5) (push) Successful in 2m0s
tests / browser (chrome, chromium) (push) Successful in 8m6s
tests / browser (firefox, firefox) (push) Failing after 12m52s
tests / browser (safari, webkit) (push) Failing after 13m1s

The browser suite passes on every engine here and fails on the runner,
which takes three times as long: each failing test triggers a close and
then samples for an in-between state — a rail part-way out, a scrim
part-way faded, a menu's exit copy part-way sunk — and a starved runner
takes its one sample after the 150-650ms exit has already finished.

So the tests that assert *that* something animates now stretch every
motion duration token to three seconds first (`slowMotion()`, beside
`ready()` in tests/Pest.php; ActionsTest's own copy of it goes). The two
polling helpers grew their budget to match: the rail panel and the sheet
slide on emphasized-accelerate, which is under 1% of its travel at a
quarter of the way through, so a 300ms window no longer reached the
threshold once the exit itself was three seconds long.

The two full-screen date picker tests waited for a resize through
click()'s own retry, which ate the whole 15s budget on Firefox; they now
wait for the new width and a settled document first. The bottom sheet's
preset test waits for its entry to finish before pressing the grip.

`hold()` in search.js reads the view's animations a frame after the
closed state, as the rail's settle() does, but one frame is not always
enough: an engine that starts them on its next tick shows none, and the
full-screen layout would end at once, mid-exit. An empty list is now
asked again on the following frame.

Feature 1159 passed. Browser 299 passed on Chrome, Firefox and WebKit,
and again on WebKit under ten spinning cores.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andreas Reinhold / reini
2026-09-17 23:57:43 +02:00
co-authored by Claude Opus 5
parent 145f60aa11
commit 94d6e31432
7 changed files with 82 additions and 21 deletions
+13 -3
View File
@@ -435,7 +435,10 @@ it('cycles a bottom sheet\'s preset heights from its handle, announcing each, an
$announce = "{$sheet}.querySelector('[data-md-bottom-sheet-announce]')";
$page->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("{$sheet}.style.getPropertyValue('--sheet-stop').trim() === '50dvh'");
->assertScript("{$sheet}.style.getPropertyValue('--sheet-stop').trim() === '50dvh'")
// Settled, not still sliding in: a grip pressed while the entry is still under way would
// read as unstable on a loaded runner, the way opening it does elsewhere in this file.
->assertScript("{$sheet}.getAnimations({ subtree: true }).length === 0");
$gripSelector = '#containment [data-md-bottom-sheet-panel][data-md-preset] [data-md-bottom-sheet-grip]';
@@ -992,6 +995,8 @@ it('fades the sheet\'s scrim out on close, rather than making it vanish', functi
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("getComputedStyle({$scrim}).opacity === '1'");
slowMotion($page);
// Triggering the close and sampling for a mid-fade opacity in the same round trip: a round
// trip apiece for a separate `script` and `assertScript` already costs real time, easily as
// much as the 200ms fade itself, so a click, then a later separate read, can just as easily
@@ -1026,16 +1031,21 @@ it('slides the sheet out on close, rather than making it vanish', function (stri
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("Math.abs({$offset}) < 0.5");
slowMotion($page);
// Sampled in the page, in the same round trip as the close, as the scrim's fade is above: the
// sheet must be caught still displayed and part of the way to its closed offset (one sheet's
// own size past its edge), not gone at once — which is what Firefox showed while the exit
// leaned on `allow-discrete` holding `display`.
// leaned on `allow-discrete` holding `display`. 400 iterations (2000ms): the sheet closes on
// the emphasized-accelerate easing, which stays close to its start for a good part of its run,
// so slowMotion()'s stretched exit needs longer than a scrim's fade (a spring, front-loaded)
// before the offset has moved past a pixel.
$midSlide = $page->script(<<<JS
(async () => {
const size = {$sheet}.getBoundingClientRect().{$dimension}
{$scrim}.click()
for (let i = 0; i < 60; i++) {
for (let i = 0; i < 400; i++) {
const style = getComputedStyle({$sheet})
const offset = {$sample}
if (style.display !== 'none' && offset > 1 && offset < size - 1) return true