From bc6a4d68c6c024a2a45e9a9cd121680ae274ed7d Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 01:48:26 +0200 Subject: [PATCH] Wait past LayoutTest's FAB spring before measuring, fix its safe-area math Three FAB position tests chained ->assertScript() off a bare $page->script(), which returns the script's value, not the page. Fixing that surfaced a real settling issue: layoutPage() opens wider than the 599/600px these tests probe before resize() narrows it, so the FAB's inset-block-end (a spatial spring, scaffold.css) is still animating in from the wider default margin when the page first reports ready. Any baseline captured then is mid-flight, not the resting value, so both tests now wait past the spring before taking one. The safe-area test's inline-end (right) assertion also assumed its margin and the safe area add together; the CSS is max(margin, safe-right), an alternative to the margin, not additive with it, unlike the bottom edge (plan step 36, navigation group). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- tests/Browser/LayoutTest.php | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/Browser/LayoutTest.php b/tests/Browser/LayoutTest.php index 0471fabf..043df15d 100644 --- a/tests/Browser/LayoutTest.php +++ b/tests/Browser/LayoutTest.php @@ -462,11 +462,18 @@ it('drops the bar\'s own height from the FAB\'s offset once hide-bar-on-scroll s BLADE; - $page = layoutPage($body, 599, 800); + // The window opens wider than 599 before resize() narrows it (layoutPage()), so the FAB's own + // spatial-spring transition is still settling from the wider margin when the page first + // reports ready; wait it out before the baseline below or it captures a mid-flight value. + $page = layoutPage($body, 599, 800)->wait(0.6); $shown = (int) $page->script(layoutRect(SCAFFOLD_FAB, 'bottom')); - $page->script('window.scrollTo(0, 400)') - ->assertScript("document.querySelector('[data-md-navigation-bar]').hasAttribute('data-md-hidden')") + $page->script('window.scrollTo(0, 400)'); + + $page->assertScript("document.querySelector('[data-md-navigation-bar]').hasAttribute('data-md-hidden')") + // The FAB's inset-block-end is a spatial spring (scaffold.css), so its move down is not + // done the instant the bar's data-md-hidden attribute flips; wait past it before measuring. + ->wait(0.6) // The bar's own 64px is what --material-bottom-bar drops once the bar has slid off, so the // FAB moves down by exactly that much (navigation-bar.css, layout/scaffold.css). ->assertScript(layoutRect(SCAFFOLD_FAB, 'bottom')." === {$shown} + 64") @@ -487,14 +494,24 @@ it('clears a safe area an application sets on the FAB\'s inline-end and bottom e BLADE; - $page = layoutPage($body, 599, 800); + // The window opens wider than 599 before resize() narrows it (layoutPage()), so the FAB's + // margin (and with it inset-block-end, a spatial spring) is still settling from the wider + // default when the page first reports ready; wait it out before either baseline below. + $page = layoutPage($body, 599, 800)->wait(0.6); $right = (int) $page->script('window.innerWidth - '.layoutRect(SCAFFOLD_FAB, 'right')); $bottom = (int) $page->script('window.innerHeight - '.layoutRect(SCAFFOLD_FAB, 'bottom')); - $page->script("document.documentElement.style.setProperty('--material-safe-right', '20px')") - ->assertScript('window.innerWidth - '.layoutRect(SCAFFOLD_FAB, 'right')." === {$right} + 20"); + // inset-inline-end (right) has no transition of its own, so this one applies at once. It is + // max(margin, safe-right) — an alternative to the margin, not additive with it — unlike the + // bottom edge below, which always adds its margin on top of the greater of the two. + $page->script("document.documentElement.style.setProperty('--material-safe-right', '20px')"); - $page->script("document.documentElement.style.setProperty('--material-safe-bottom', '30px')") + $page->assertScript('window.innerWidth - '.layoutRect(SCAFFOLD_FAB, 'right')." === Math.max({$right}, 20)"); + + // inset-block-end (bottom) is the spatial spring scaffold.css transitions; wait past it. + $page->script("document.documentElement.style.setProperty('--material-safe-bottom', '30px')"); + + $page->wait(0.6) ->assertScript('window.innerHeight - '.layoutRect(SCAFFOLD_FAB, 'bottom')." === {$bottom} + 30") ->assertNoJavaScriptErrors(); });