From 1d23f2450068d2ef20a9340d5be778fe15f80afc Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 09:43:17 +0200 Subject: [PATCH] Browser-test the five central cascade claims One probe page per claim: an application's unlayered .app-wide rule beats button.css's layered inline-size and padding; [hidden] beats a component's display on both and ; the layer order holds when Stylesheets::bundle() serves button.css before foundation.css, so the reset's padding: 0 still loses to the button's own; a data-md-variant attribute updates correctly through the same re-render/morph a plain wire:click="$refresh" drives, toggled both ways; mirrors under dir="rtl" and does not under dir="ltr". Chromium: 6 assertions, all green, alongside ShowcaseTest.php (5 tests, 18 assertions). Plan step 42 (Phase F), Part A. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- tests/Browser/CascadeTest.php | 180 ++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 tests/Browser/CascadeTest.php diff --git a/tests/Browser/CascadeTest.php b/tests/Browser/CascadeTest.php new file mode 100644 index 00000000..00c1d9c4 --- /dev/null +++ b/tests/Browser/CascadeTest.php @@ -0,0 +1,180 @@ +waitForEvent('networkidle') + ->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'"); +} + +it('lets an application\'s unlayered rule beat a component default', function () { + // The brief's own example: a caller's plain, unlayered `.app-wide` rule against button.css's + // layered `padding-inline: var(--md-button-padding)` and `inline-size: var(--md-button-width)` + // — unlayered CSS outranks every `@layer`, however specific the layered rule is. + Route::middleware('web')->get('/cascade-unlayered-probe', fn () => Blade::render(<<<'BLADE' + + + + + @vite(config('livewire-material.showcase.vite')) + @livewireStyles + + + + + @livewireScripts + + + BLADE)); + + cascadeReady(visit('/cascade-unlayered-probe')) + ->assertScript("Math.round(document.querySelector('[data-test=\"button\"]').getBoundingClientRect().width) === 320"); +}); + +it('lets [hidden] beat a component\'s display', function () { + // The reset's `[hidden]:where(:not([hidden='until-found'])) { display: none !important }` + // sits outside every layer, so it beats a component's own `display` (button.css's `inline-flex`, + // row.css's `flex`) whatever `@layer` that rule sits in. + Route::middleware('web')->get('/cascade-hidden-probe', fn () => Blade::render(<<<'BLADE' + + + + + @vite(config('livewire-material.showcase.vite')) + @livewireStyles + + + +