Keep the full-screen range picker's months where they were as it grows
tests / feature (8.4) (push) Successful in 1m46s
tests / feature (8.5) (push) Successful in 1m53s
tests / browser (chrome, chromium) (push) Successful in 7m46s
tests / browser (firefox, firefox) (push) Successful in 11m56s
tests / browser (safari, webkit) (push) Failing after 13m58s

When the full-screen range picker adds months above the ones on screen,
extendMonths() puts the scroll back by however much the list grew. An
engine with scroll anchoring moved it back as well, so a reader paging up
landed half a year on, and a press meant for one day chose another. The
calendar now opts out of scroll anchoring (`overflow-anchor: none`) and
the picker's own correction is the only one, in every engine alike. A
test holds what sits under a fixed point of the list while it grows.

The browser plugin retries an action the way it retries an assertion:
when the page takes longer than a second to handle a press, it presses
again. On a loaded runner the full-screen picker, which re-renders every
day of every month it holds, took that long — so its toggle was pressed
a second time under the picker it had just opened, and never landed, and
a day pressed twice became the range's end as well as its start.
`pressOnce()` sends a press that must not be repeated exactly once, with
Playwright's own wait for the element; the picker's toggle, its paging
keys, its days and its Save go through it, and so do the menu triggers
that toggle.

Browser 300 passed on Chrome, Firefox and WebKit on macOS, and the date
picker and menu tests 61 passed on Linux Firefox and WebKitGTK held to
two busy cores. Feature 1159 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
surtic86
2026-09-18 13:45:51 +02:00
co-authored by Claude Opus 5
parent e7885ce1eb
commit ad230e0f48
8 changed files with 127 additions and 40 deletions
+21
View File
@@ -2,6 +2,7 @@
use Illuminate\Support\Facades\File;
use NoNameWeb\LivewireMaterial\Tests\TestCase;
use Pest\Browser\Api\Webpage;
pest()->extend(TestCase::class)->in('Feature', 'Browser');
@@ -117,6 +118,26 @@ function onceInPage(string $expression): string
return "(() => (window.{$memo} ??= {$expression}))()";
}
/**
* `$page` for an action that must happen exactly once: the plugin's own page object, without the
* retry every call on `$page` goes through (see onceInPage()). That retry does the whole call
* again after 1000ms, which costs an assertion nothing but repeats a press: a key or a click the
* page took longer than that to handle arrived twice — one PageDown paging two months, a day
* pressed twice making the range's start its end as well — or the second press found what the
* first one opened lying over its button, and never landed. Here the action runs once, with
* Playwright's own wait for the element and the whole timeout.
*
* For a press a second one would undo or overturn — a menu's trigger toggles it, a day pressed
* twice ends the range it began — into something that can take a loaded runner that long: opening
* a menu, or the full-screen range picker, which re-renders every day of every month it holds on
* each press. Assert on `$page` again. The plugin retrying every action is the cause, and every
* press in the suite is exposed to it; these are the ones slow and undoable enough to have shown it.
*/
function pressOnce(mixed $page): Webpage
{
return new Webpage($page->page(), $page->url());
}
/**
* A JS expression that runs `$trigger` in the page and then samples `$condition` there once per
* animation frame, answering whether it ever held: the whole exit and its sample in one round trip,