From f86f3270cd301c0d512e9360f348320de8b4db96 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 01:52:09 +0200 Subject: [PATCH] Cover the rail header FAB's collapsed-to-extended morph The reviewer asked this run to look closely at it; no test exercised it. Checks the label span's clipped opacity/max-width and the FAB's square shape while the rail is collapsed, then its read label and wider-than-tall shape once the rail's menu button expands it, waiting past the shared spatial-default spring both morph on (plan step 36, navigation group). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- tests/Browser/NavigationTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/Browser/NavigationTest.php b/tests/Browser/NavigationTest.php index 5b03570d..a0d3bea7 100644 --- a/tests/Browser/NavigationTest.php +++ b/tests/Browser/NavigationTest.php @@ -117,6 +117,28 @@ it('starts the rail collapsed across the expanded class and expands it in the la navigationReady($page->refresh())->assertScript(railWidth(256)); }); +it('morphs the rail header FAB between collapsed (icon only) and extended (with its label)', function () { + $fab = "document.querySelector('[data-md-navigation-rail-fab-row] [data-md-fab]')"; + $label = "document.querySelector('[data-md-navigation-rail-fab-row] [data-md-fab] > span')"; + + $page = shellPage(840) + // Collapsed: the label is clipped to nothing, and the FAB is a plain square icon button — + // navigation-rail.css's [data-md-fab] > span and [data-md-fab][data-md-extended] rules. + ->assertScript("getComputedStyle({$label}).opacity === '0'") + ->assertScript("getComputedStyle({$label}).maxWidth === '0px'") + ->assertScript("Math.round({$fab}.getBoundingClientRect().width) === Math.round({$fab}.getBoundingClientRect().height)"); + + $page->click('[data-md-navigation-rail-menu]') + // The label's width and the FAB's own shape both spring on the rail's spatial-default + // transition; wait past it for the settled, extended end state. + ->wait(0.6) + ->assertScript("getComputedStyle({$label}).opacity === '1'") + ->assertScript("parseFloat(getComputedStyle({$label}).maxWidth) > 0") + ->assertScript("{$fab}.getBoundingClientRect().width > {$fab}.getBoundingClientRect().height") + ->assertSee('Compose') + ->assertNoJavaScriptErrors(); +}); + it('expands the rail from large, and keeps it collapsed across a reload from the first paint', function () { firstPaintProbe();