Press once whatever a second press would open over or undo
tests / feature (8.4) (push) Successful in 1m50s
tests / feature (8.5) (push) Successful in 1m54s
tests / browser (chrome, chromium) (push) Successful in 7m52s
tests / browser (firefox, firefox) (push) Successful in 11m56s
tests / browser (safari, webkit) (push) Successful in 12m35s

The browser plugin runs every call on a page again when its first
attempt takes over a second, and on the runner a press can. For most
presses that costs nothing. For two kinds it breaks the test: a press
that opens a dialog, a sheet, a full-screen view or a modal rail over
its own trigger, whose second press can never land, and a press that
changes state a second one would change again — a menu trigger, a
toggle, a chip, a range picker's day, a paging key, a Save. The bottom
sheet with preset heights timed out on WebKit that way after the date
picker had on Firefox.

Every such press in the browser suite now goes through pressOnce(), 253
of them across sixteen files, not only the ones the runner happened to
catch; focus moves inside an open view, Escape, links and plain "set"
actions keep the retry, which is harmless for them.

Two samples that were still racing the machine:

- The standard side sheet's exit is caught half-way with its motion
  stretched, as every other mid-exit sample is, and fullSpeed() takes
  the stretch off again before the test times a reopen against the real
  exit. Under load on Linux WebKit it had failed two runs in five; it
  passes ten in ten.
- The switch-and-checkbox row measures its widths once, so it now waits
  for the resize to land and the brand face to load before it does.

Browser 300 passed on Firefox and WebKitGTK in a Linux container held to
two busy cores, and on Chrome, Firefox and WebKit on macOS. Feature 1159
passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
surtic86
2026-09-18 16:15:25 +02:00
co-authored by Claude Opus 5
parent ad230e0f48
commit ebdc2ef2e1
17 changed files with 1170 additions and 578 deletions
+156 -71
View File
@@ -139,19 +139,25 @@ function containment()
it('writes back what closed means: false for a flag, null for an id', function () {
$page = overlayProbe();
$page->click('button:has-text("Confirm")')
->assertScript("[...document.querySelectorAll('dialog')].some((d) => d.open && d.textContent.includes('Are you sure?'))");
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Confirm")');
$page->click('dialog[open] button:has-text("Re-render")')
->assertSeeIn('#renders', '1')
$page->assertScript("[...document.querySelectorAll('dialog')].some((d) => d.open && d.textContent.includes('Are you sure?'))");
// A counter a retry would double: pressOnce(), tests/Pest.php.
pressOnce($page)->click('dialog[open] button:has-text("Re-render")');
$page->assertSeeIn('#renders', '1')
->assertScript("[...document.querySelectorAll('dialog')].some((d) => d.open && d.textContent.includes('Are you sure?'))");
$page->keys('dialog[open] button:has-text("Re-render")', 'Escape')
->assertScript("! [...document.querySelectorAll('dialog')].some((d) => d.open)")
->assertSeeIn('#confirming', 'false');
$page->click('button:has-text("Delete 7")')
->assertSeeIn('#deleting', '7')
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Delete 7")');
$page->assertSeeIn('#deleting', '7')
->assertScript("[...document.querySelectorAll('dialog')].some((d) => d.open && d.textContent.includes('Delete share?'))");
$page->script("document.querySelector('dialog[open]').dispatchEvent(new Event('cancel', { cancelable: true }))");
@@ -166,8 +172,11 @@ it('closes a showcase dialog on Escape and gives focus back to its trigger', fun
$page->script("[...document.querySelectorAll('#containment button')].find((b) => b.textContent.trim() === 'Basic dialog').focus()");
$page->keys(':focus', 'Enter')
->assertScript("document.querySelector('#containment dialog').open");
// Enter on the focused button is a native click on it, opening the dialog over it: pressOnce(),
// tests/Pest.php.
pressOnce($page)->keys(':focus', 'Enter');
$page->assertScript("document.querySelector('#containment dialog').open");
$page->keys('#containment dialog[open] button:has-text("Cancel")', 'Escape')
->assertScript("! document.querySelector('#containment dialog').open")
@@ -177,9 +186,12 @@ it('closes a showcase dialog on Escape and gives focus back to its trigger', fun
it('slides a side sheet in, traps the page, and closes on the scrim', function () {
$sheet = "document.querySelector('#containment aside[role=\"dialog\"]')";
$page = containment()
->click('#containment button:has-text("Side sheet")')
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
$page = containment();
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Side sheet")');
$page->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("document.querySelector('header').closest('[aria-hidden=\"true\"]') !== null");
// This sheet's own scrim: the standard side sheet above it on the page is a `[data-md-drawer]` too.
@@ -192,9 +204,12 @@ it('slides a side sheet in, traps the page, and closes on the scrim', function (
it('dismisses a bottom sheet dragged down past a quarter of its height', function () {
$sheet = "document.querySelector('#containment section[role=\"dialog\"]')";
$page = containment()
->click('#containment button:has(> span:text-is("Bottom sheet"))')
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
$page = containment();
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has(> span:text-is("Bottom sheet"))');
$page->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->wait(0.5);
$page->script(<<<JS
@@ -272,7 +287,8 @@ it('marks a scrolling dialog\'s divider at the edge with more content, and a nes
// Short and narrow so the probes' paragraphs genuinely overflow their body.
$page = nestedDialogProbe()->resize(320, 300);
$page->click('button:has-text("Open outer")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Open outer")');
// Matched by each dialog's own title element, not its full (recursive) textContent: the
// outer dialog's textContent also contains the nested inner dialog's text, "Inner" included,
@@ -284,7 +300,8 @@ it('marks a scrolling dialog\'s divider at the edge with more content, and a nes
// Scrolled to the top: nothing hidden above, so the head's rule stays off.
$page->assertScript("getComputedStyle({$outerHead}, '::after').opacity === '0'");
$page->click('button:has-text("Open inner")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Open inner")');
$inner = "[...document.querySelectorAll('dialog[open]')].find((d) => d.querySelector('[data-md-modal-title]')?.textContent === 'Inner')";
$innerHead = "{$inner}.querySelector('[data-md-modal-head]')";
@@ -311,7 +328,8 @@ it('shows a full-screen dialog\'s 56px phone bar below 600px, and the basic dial
// CSS on the fullscreen flag, so which comes first makes no difference to what is asserted.
$page = containment();
$page->click('#containment button:has-text("Full screen on a phone")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Full screen on a phone")');
$page->resize(400, 800);
@@ -328,7 +346,8 @@ it('shows a full-screen dialog\'s 56px phone bar below 600px, and the basic dial
it('draws separator dividers whatever the scroll, on a dialog that fits without scrolling', function () {
$page = containment();
$page->click('#containment button:has-text("Always divided (separator)")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Always divided (separator)")');
$dialog = "document.querySelector('#containment dialog[open]')";
$head = "{$dialog}.querySelector('[data-md-modal-head]')";
@@ -348,7 +367,8 @@ it('opens a dialog with no fade under reduced motion, but a real one without it'
$normal = containment()
->assertScript("! window.matchMedia('(prefers-reduced-motion: reduce)').matches");
$normal->click('#containment button:has-text("Basic dialog")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($normal)->click('#containment button:has-text("Basic dialog")');
$normal->assertScript("parseFloat(getComputedStyle({$dialog}).transitionDuration) > 0");
@@ -358,7 +378,8 @@ it('opens a dialog with no fade under reduced motion, but a real one without it'
$reduced = ready(visit('/material/containment', ['reducedMotion' => 'reduce']))
->assertScript("window.matchMedia('(prefers-reduced-motion: reduce)').matches");
$reduced->click('#containment button:has-text("Basic dialog")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($reduced)->click('#containment button:has-text("Basic dialog")');
$reduced->assertScript("parseFloat(getComputedStyle({$dialog}).transitionDuration) === 0")
->assertScript("getComputedStyle({$dialog}).opacity === '1'");
@@ -412,7 +433,9 @@ it('gives the scrolling body an inset focus ring when a text-only dialog opens f
$page->script("document.querySelector('button').focus()");
$page->keys(':focus', 'Enter');
// Enter on the focused button is a native click on it, opening the dialog over it: pressOnce(),
// tests/Pest.php.
pressOnce($page)->keys(':focus', 'Enter');
$body = "document.querySelector('dialog[open] [data-md-modal-body]')";
@@ -432,7 +455,8 @@ it('gives the scrolling body an inset focus ring when a text-only dialog opens f
it('cycles a bottom sheet\'s preset heights from its handle, announcing each, and closes from the last', function () {
$page = containment();
$page->click('#containment button:has-text("Bottom sheet with preset heights")');
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Bottom sheet with preset heights")');
$sheet = "document.querySelector('#containment [data-md-bottom-sheet-panel][data-md-preset]')";
$handle = "{$sheet}.querySelector('[data-md-bottom-sheet-grip]')";
@@ -466,7 +490,8 @@ it('cycles a bottom sheet\'s preset heights from its handle, announcing each, an
it('settles a dragged bottom sheet on the nearest preset height', function () {
$page = containment();
$page->click('#containment button:has-text("Bottom sheet with preset heights")');
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Bottom sheet with preset heights")');
$sheet = "document.querySelector('#containment [data-md-bottom-sheet-panel][data-md-preset]')";
@@ -503,13 +528,15 @@ it('is a standard side sheet from 840px, without a scrim or a focus trap, and th
->assertScript("document.querySelector('header').closest('[aria-hidden=\"true\"]') === null")
->assertScript("! {$sheet}.hasAttribute('inert')");
$page->click($toggle);
// The toggle button opens or closes the sheet on every press: pressOnce(), tests/Pest.php.
pressOnce($page)->click($toggle);
$page->assertScript("getComputedStyle({$sheet}).opacity === '0'");
// Below 840px the same sheet becomes the modal one: fixed, with a scrim, and the page inert.
$page->resize(700, 800)
->click($toggle);
$page->resize(700, 800);
pressOnce($page)->click($toggle);
$page->assertScript("getComputedStyle({$sheet}).position === 'fixed'")
->assertScript("getComputedStyle({$scrim}).display !== 'none'")
@@ -534,7 +561,10 @@ it('gives a closing standard side sheet\'s room back to the content beside it as
// Closed and sampled in one round trip: the sheet's root caught part-way between its width
// and none, still in the layout, while the column beside it has grown part of the way — not
// the whole sheet and its gap handed back in one jump at the end.
// the whole sheet and its gap handed back in one jump at the end. Stretched, as every other
// mid-exit sample is: a loaded engine can paint too few frames in the real exit to see it.
slowMotion($page);
$midExit = $page->script(caughtMidExit(
<<<JS
const root = {$root}
@@ -558,6 +588,9 @@ it('gives a closing standard side sheet\'s room back to the content beside it as
$page->assertScript("{$root}.hasAttribute('data-md-drawer-collapsed') && getComputedStyle({$root}).display === 'none'")
->assertScript("Math.abs({$column}.getBoundingClientRect().width - {$root}.parentElement.getBoundingClientRect().width) < 1");
// What follows times a reopen against the real exit.
fullSpeed($page);
// Reopened part-way through its exit, it ends open, not collapsed. Each script stays well under
// the browser plugin's one-second call timeout, past which it runs the script a second time.
$page->script("{$toggle}.click()");
@@ -655,8 +688,11 @@ function hiddenFromAssistiveTech(string $id): string
it('closes only a dialog opened over a modal sheet on Escape, readable and tabbable while it is open', function () {
$page = layersProbe();
$page->click('#open-sheet')->assertScript(sheetOpen('sheet'));
$page->click('#open-dialog')->assertScript("document.getElementById('dialog').open");
// Opens the sheet, then the dialog over it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-sheet');
$page->assertScript(sheetOpen('sheet'));
pressOnce($page)->click('#open-dialog');
$page->assertScript("document.getElementById('dialog').open");
// Rendered outside the sheet, the dialog is not inside what the sheet hides, and the sheet's
// focus trap does not take the Tab back to the sheet.
@@ -681,14 +717,20 @@ it('closes only a dialog opened over a modal sheet on Escape, readable and tabba
it('closes only the menu, select list or searchable choice open inside a modal sheet on Escape', function () {
$page = layersProbe();
$page->click('#open-sheet')->assertScript(sheetOpen('sheet'));
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-sheet');
$page->assertScript(sheetOpen('sheet'));
$page->click('#open-menu')->assertScript("document.querySelector('#sheet [data-md-menu-popover]').matches(':popover-open')");
// Opens the menu over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-menu');
$page->assertScript("document.querySelector('#sheet [data-md-menu-popover]').matches(':popover-open')");
$page->keys(':focus', 'Escape')
->assertScript("! document.querySelector('#sheet [data-md-menu-popover]').matches(':popover-open')")
->assertScript(sheetOpen('sheet'));
$page->click('#sheet-choices')->assertScript("document.querySelector('#sheet [data-md-field-menu]').matches(':popover-open')");
// Opens the searchable choice's list over the field that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#sheet-choices');
$page->assertScript("document.querySelector('#sheet [data-md-field-menu]').matches(':popover-open')");
$page->keys('#sheet-choices', 'Escape')
->assertScript("! document.querySelector('#sheet [data-md-field-menu]').matches(':popover-open')")
->assertScript(sheetOpen('sheet'));
@@ -696,7 +738,9 @@ it('closes only the menu, select list or searchable choice open inside a modal s
// A customizable select's list, where the browser has one: elsewhere there is no list of the
// page's own open over the sheet.
if ($page->script("CSS.supports('appearance', 'base-select')") === true) {
$page->click('#sheet-select')->assertScript("document.getElementById('sheet-select').matches(':open')");
// Opens the native select's list over the field that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#sheet-select');
$page->assertScript("document.getElementById('sheet-select').matches(':open')");
$page->keys(':focus', 'Escape')
->assertScript("! document.getElementById('sheet-select').matches(':open')")
->assertScript(sheetOpen('sheet'));
@@ -708,15 +752,19 @@ it('closes only the menu, select list or searchable choice open inside a modal s
it('closes only the sheet on top on Escape, inside the first or beside it, and keeps the one beside it readable', function () {
$page = layersProbe();
$page->click('#open-sheet')->assertScript(sheetOpen('sheet'));
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-sheet');
$page->assertScript(sheetOpen('sheet'));
$page->click('#open-inner')->assertScript(sheetOpen('inner-sheet'));
pressOnce($page)->click('#open-inner');
$page->assertScript(sheetOpen('inner-sheet'));
$page->click('#inner-field');
$page->keys('#inner-field', 'Escape')
->assertScript('! '.sheetOpen('inner-sheet'))
->assertScript(sheetOpen('sheet'));
$page->click('#open-beside')->assertScript(sheetOpen('beside-sheet'))
pressOnce($page)->click('#open-beside');
$page->assertScript(sheetOpen('beside-sheet'))
->assertScript('! '.hiddenFromAssistiveTech('beside-sheet'));
$page->click('#beside-field');
$page->keys('#beside-field', 'Escape')
@@ -732,24 +780,32 @@ it('closes only the sheet, searchable choice, menu or select list open inside a
$page->script("window.dispatchEvent(new CustomEvent('open-probe-dialog'))");
$page->assertScript("document.getElementById('dialog').open");
$page->click('#open-dialog-sheet')->assertScript(sheetOpen('dialog-sheet'));
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-dialog-sheet');
$page->assertScript(sheetOpen('dialog-sheet'));
$page->click('#dialog-sheet-field');
$page->keys('#dialog-sheet-field', 'Escape')
->assertScript('! '.sheetOpen('dialog-sheet'))
->assertScript("document.getElementById('dialog').open");
$page->click('#dialog-choices')->assertScript("document.querySelector('#dialog [data-md-field-menu]').matches(':popover-open')");
// Opens the searchable choice's list over the field that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#dialog-choices');
$page->assertScript("document.querySelector('#dialog [data-md-field-menu]').matches(':popover-open')");
$page->keys('#dialog-choices', 'Escape')
->assertScript("! document.querySelector('#dialog [data-md-field-menu]').matches(':popover-open')")
->assertScript("document.getElementById('dialog').open");
$page->click('#open-dialog-menu')->assertScript("document.querySelector('#dialog [data-md-menu-popover]').matches(':popover-open')");
// Opens the menu over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#open-dialog-menu');
$page->assertScript("document.querySelector('#dialog [data-md-menu-popover]').matches(':popover-open')");
$page->keys(':focus', 'Escape')
->assertScript("! document.querySelector('#dialog [data-md-menu-popover]').matches(':popover-open')")
->assertScript("document.getElementById('dialog').open");
if ($page->script("CSS.supports('appearance', 'base-select')") === true) {
$page->click('#dialog-select')->assertScript("document.getElementById('dialog-select').matches(':open')");
// Opens the native select's list over the field that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#dialog-select');
$page->assertScript("document.getElementById('dialog-select').matches(':open')");
$page->keys(':focus', 'Escape')
->assertScript("! document.getElementById('dialog-select').matches(':open')")
->assertScript("document.getElementById('dialog').open");
@@ -911,8 +967,10 @@ it('opens a row\'s opener from a press anywhere on the row, but not from its own
$page->script("window.__opened = 0; document.querySelector('{$row} [data-md-list-open]').addEventListener('click', (event) => { event.preventDefault(); window.__opened++ })");
$page->click("{$row} p")
->assertScript('window.__opened === 1');
// A counter a retry would double: pressOnce(), tests/Pest.php.
pressOnce($page)->click("{$row} p");
$page->assertScript('window.__opened === 1');
$page->click("{$row} button:has-text(\"Copy link\")")
->assertScript('window.__opened === 1');
@@ -929,8 +987,10 @@ it('makes a directly actionable card the one tab stop, answering Enter', functio
$page->assertScript("document.activeElement.matches('{$card}')");
$page->keys($card, 'Enter')
->assertScript('window.__opened === 1');
// A counter a retry would double: pressOnce(), tests/Pest.php.
pressOnce($page)->keys($card, 'Enter');
$page->assertScript('window.__opened === 1');
});
it('binds a collapse to a Livewire property both ways', function () {
@@ -939,10 +999,15 @@ it('binds a collapse to a Livewire property both ways', function () {
$page = collapseProbe()
->assertScript("{$collapse}.open === false");
$page->click('#fine-tuning-collapse summary')
->assertScript("{$collapse}.open === true")
->click('button:has-text("Re-render")')
->assertSeeIn('#renders', '1')
// A native <summary> click toggles the collapse: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#fine-tuning-collapse summary');
$page->assertScript("{$collapse}.open === true");
// A counter a retry would double: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Re-render")');
$page->assertSeeIn('#renders', '1')
->assertSeeIn('#fine-tuning', 'true')
->assertScript("{$collapse}.open === true");
@@ -961,8 +1026,10 @@ it('binds a collapse to an Alpine property both ways', function () {
$page = collapseProbe()
->assertScript("{$collapse}.open === false");
$page->click('#advanced-collapse summary')
->assertScript("{$collapse}.open === true")
// A native <summary> click toggles the collapse: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#advanced-collapse summary');
$page->assertScript("{$collapse}.open === true")
->assertSeeIn('#advanced', 'true');
$page->click('button:has-text("Close from Alpine")')
@@ -1001,9 +1068,12 @@ dataset('containment sheets', [
it('fades the sheet\'s scrim out on close, rather than making it vanish', function (string $sheet, string $trigger, string $scrimAttr) {
$scrim = "{$sheet}.parentElement.querySelector(':scope > [{$scrimAttr}]')";
$page = containment()
->click($trigger)
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
$page = containment();
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click($trigger);
$page->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("getComputedStyle({$scrim}).opacity === '1'")
// Settled, not still fading in: an engine reads a transition's end value until its next
// refresh tick, so an opacity of 1 alone does not say the entry has run — and a close
@@ -1033,9 +1103,12 @@ it('slides the sheet out on close, rather than making it vanish', function (stri
$offset = "(parseFloat(getComputedStyle({$sheet}).translate{$axis}) || 0)";
$sample = $absolute ? "Math.abs(parseFloat(style.translate{$axis}) || 0)" : "(parseFloat(style.translate{$axis}) || 0)";
$page = containment()
->click($trigger)
->assertScript("getComputedStyle({$sheet}).display !== 'none'")
$page = containment();
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click($trigger);
$page->assertScript("getComputedStyle({$sheet}).display !== 'none'")
->assertScript("Math.abs({$offset}) < 0.5")
// Settled, not still sliding in: see the scrim's fade above.
->assertScript(settled($sheet));
@@ -1092,7 +1165,8 @@ it('slides the side sheet in from its own edge in a right-to-left page', functio
$sheet = "document.querySelector('aside[data-md-side]')";
$page->click('button:has-text("Open")');
// Opens the sheet over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Open")');
// `side="end"` (the default) is the trailing edge — the *left* of a right-to-left page — so it
// slides in from off the left, not the right (the CSS mirror reads `[dir='rtl']` rather than
@@ -1156,7 +1230,8 @@ it('keeps a basic dialog\'s own title and padding when it is nested inside a ful
$page = ready(visit('/nested-fullscreen-dialog-probe')->resize(400, 800));
$page->click('button:has-text("Open settings")');
// Opens the dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Open settings")');
$outerBar = "document.querySelector('dialog[data-md-fullscreen][open] [data-md-modal-bar]')";
@@ -1165,7 +1240,8 @@ it('keeps a basic dialog\'s own title and padding when it is nested inside a ful
// must keep its own head regardless.
$page->assertScript("getComputedStyle({$outerBar}).display !== 'none'");
$page->click('button:has-text("Delete the share")');
// Opens the nested dialog over the button that triggers it: pressOnce(), tests/Pest.php.
pressOnce($page)->click('button:has-text("Delete the share")');
$inner = "[...document.querySelectorAll('dialog[open]')].find((d) => d.querySelector('[data-md-modal-title]')?.textContent === 'Delete this share?')";
$innerHead = "{$inner}.querySelector('[data-md-modal-head]')";
@@ -1184,12 +1260,13 @@ it('shows the 16% dragged state layer on the showcase card being dragged', funct
$page->assertScript("getComputedStyle({$card}, '::before').opacity === '0'");
$page->click('#containment button:has-text("Pick it up or put it down")');
// Toggles the drag state on every press: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#containment button:has-text("Pick it up or put it down")');
$page->assertScript("{$card}.hasAttribute('data-md-dragged')")
->assertScript("getComputedStyle({$card}, '::before').opacity === '0.16'");
$page->click('#containment button:has-text("Pick it up or put it down")');
pressOnce($page)->click('#containment button:has-text("Pick it up or put it down")');
$page->assertScript("! {$card}.hasAttribute('data-md-dragged')")
->assertScript("getComputedStyle({$card}, '::before').opacity === '0'");
@@ -1464,10 +1541,12 @@ it('eases a collapse open and shut in every engine, moving what is under it', fu
expect($clipped)->toBe('clip');
// From the keyboard: Enter on the summary is the same press, taken over the same way.
// From the keyboard: Enter on the summary is the same press, taken over the same way, and it
// toggles: pressOnce(), tests/Pest.php.
$page->script("document.querySelector('#plain summary').focus()");
$page->keys('#plain summary', 'Enter')
->assertScript("document.querySelector('#plain').open === false && document.querySelector('#plain').getAnimations().length === 0");
pressOnce($page)->keys('#plain summary', 'Enter');
$page->assertScript("document.querySelector('#plain').open === false && document.querySelector('#plain').getAnimations().length === 0");
});
it('eases a collapse bound to Alpine open and shut, keeping the binding in step', function () {
@@ -1489,9 +1568,11 @@ it('eases a collapse bound to Alpine open and shut, keeping the binding in step'
$page->assertSeeIn('#advanced', 'false');
// A press on the summary tells the binding when the section has closed, and never loops.
$page->click('#bound summary')
->assertSeeIn('#advanced', 'true')
// A press on the summary tells the binding when the section has closed, and never loops; a
// native <summary> click toggles the collapse: pressOnce(), tests/Pest.php.
pressOnce($page)->click('#bound summary');
$page->assertSeeIn('#advanced', 'true')
->assertScript("document.querySelector('#bound').open === true");
});
@@ -1655,8 +1736,10 @@ it('shows no tooltip on the control a sheet or a dialog focuses as it opens, but
// A full-screen dialog opened from the keyboard moves the focus to its bar's ✕ in showModal().
$page = ready(visit('/opened-layers-probe', ['viewport' => ['width' => 393, 'height' => 800]]), alpine: false);
$page->keys('#open-setback', 'Enter')
->assertScript("document.querySelector('{$dialog}').open && document.activeElement.matches('{$dialog} button[aria-label=\"Close\"]')")
// Enter on the focused button opens the dialog over it: pressOnce(), tests/Pest.php.
pressOnce($page)->keys('#open-setback', 'Enter');
$page->assertScript("document.querySelector('{$dialog}').open && document.activeElement.matches('{$dialog} button[aria-label=\"Close\"]')")
->wait(0.3)
->assertScript('! '.closeTooltipOpen($dialog));
@@ -1667,8 +1750,10 @@ it('shows no tooltip on the control a sheet or a dialog focuses as it opens, but
// A rich tooltip's trigger as the first control of a dialog opened from the keyboard.
$page = ready(visit('/opened-layers-probe', ['viewport' => ['width' => 393, 'height' => 800]]), alpine: false);
$page->keys('#open-about', 'Enter')
->assertScript("document.activeElement.id === 'about-help'")
// Enter on the focused button opens the dialog over it: pressOnce(), tests/Pest.php.
pressOnce($page)->keys('#open-about', 'Enter');
$page->assertScript("document.activeElement.id === 'about-help'")
->wait(0.3)
->assertScript("! document.querySelector('[data-md-rich-tooltip-bubble]').matches(':popover-open')");
});