From 7abcc7c5f58e9db006d5b53bbd20a8c3eb031f9d Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 05:50:55 +0200 Subject: [PATCH] Pin the carousel showcase's viewport and de-flake one assertScript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found running the full browser suite for plan step 38's last batch, unrelated to its content changes (confirmed by reverting every touched file and reproducing both failures against the pre-batch commit): CarouselTest never pinned a window size, so the multi-browse row's keyline math only lined "scroll by 2 slots" up with the open keyline at some widths — the host's own default (here, wider than the carousel was ever exercised at) left a remainder large enough to fail four assertions. carouselShowcase() now resizes to 1280x900, matching the width other browser tests already treat as "large desktop". One test still failed after that: it put a `.click()` inside the script assertScript asserts, and assertScript retries its whole expression on a false result (this file's own comment says so) — a retry re-fires the click, drifting the carousel one item further each time and never recovering, unlike every other test here, which clicks through a separate call first. Split the click out the same way. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- tests/Browser/CarouselTest.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/Browser/CarouselTest.php b/tests/Browser/CarouselTest.php index 54f548ce..d6e0fe01 100644 --- a/tests/Browser/CarouselTest.php +++ b/tests/Browser/CarouselTest.php @@ -70,7 +70,11 @@ const FIRST_ITEM = '#carousel [data-md-carousel-item] >> nth=0'; function carouselShowcase(array $options = []) { + // Pinned rather than left to the host's own window: at a wide enough viewport the multi-browse + // row's 8 items (220px each) leave a remainder the keyline math does not reduce to zero the way + // it does here, so "scroll by exactly 2 slots" no longer lands item 2 on the open keyline. return visit('/material/carousel', $options) + ->resize(1280, 900) ->waitForEvent('networkidle') ->assertScript("typeof window.Alpine !== 'undefined'"); } @@ -164,14 +168,18 @@ it('brings a partly hidden item into focus when it is pressed, and leaves an ope }); it('scrolls instantly and leaves every item unmasked under reduced motion', function () { - carouselShowcase(['reducedMotion' => 'reduce']) - ->assertScript(onCarousel(0, <<<'JS' - root.querySelector('[aria-label="Next"]').click() - const arrived = at(1) - await pause(50) - return arrived && items.every((_, i) => inset(i) === 0) - && items.every((item) => Math.abs(item.getBoundingClientRect().width - size) < 1.5) - JS)); + // A click, then a separate read-only assertScript: assertScript retries its whole expression + // on a false result (this file's own comment above), and a click inside it would fire again on + // every retry, drifting the carousel one further item each time and never recovering. + $page = carouselShowcase(['reducedMotion' => 'reduce']); + + $page->script(onCarousel(0, 'root.querySelector(\'[aria-label="Next"]\').click()')); + + $page->assertScript(onCarousel(0, <<<'JS' + await pause(50) + return at(1) && items.every((_, i) => inset(i) === 0) + && items.every((item) => Math.abs(item.getBoundingClientRect().width - size) < 1.5) + JS)); }); it('brings an item cut off at the row\'s edge into view when it is pressed under reduced motion', function () {