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>
90 lines
3.7 KiB
PHP
90 lines
3.7 KiB
PHP
<?php
|
|
|
|
use NoNameWeb\LivewireMaterial\Support\Scheme;
|
|
|
|
use function Orchestra\Testbench\workbench_path;
|
|
|
|
/*
|
|
* The Workbench's three profiles (baseline, teal, rose), generated into its stylesheet. Tests other
|
|
* than these run without profiles, so each one here points the package at the scheme file.
|
|
*/
|
|
|
|
beforeEach(function () {
|
|
config(['livewire-material.scheme' => workbench_path('resources/css/material-scheme.json')]);
|
|
|
|
$this->profiles = json_decode(file_get_contents(workbench_path('resources/css/material-scheme.json')), true)['profiles'];
|
|
});
|
|
|
|
afterEach(function () {
|
|
Scheme::resolveProfileUsing(null);
|
|
});
|
|
|
|
/**
|
|
* A #rrggbb hex as the rgb() a computed style reports.
|
|
*/
|
|
function rgb(string $hex): string
|
|
{
|
|
[$red, $green, $blue] = sscanf($hex, '#%02x%02x%02x');
|
|
|
|
return "rgb({$red}, {$green}, {$blue})";
|
|
}
|
|
|
|
/**
|
|
* The page's primary colour role, as <html> resolves it.
|
|
*/
|
|
function pagePrimary(): string
|
|
{
|
|
return "getComputedStyle(document.documentElement).getPropertyValue('--md-sys-color-primary').trim()";
|
|
}
|
|
|
|
function profilesReady(mixed $page): mixed
|
|
{
|
|
return ready($page);
|
|
}
|
|
|
|
it('draws each profile in light and dark, and the default without the attribute', function () {
|
|
$page = profilesReady(visit('/material/colour')->inLightMode())
|
|
->assertScript("document.documentElement.getAttribute('data-scheme') === 'baseline'")
|
|
->assertScript(pagePrimary()." === '{$this->profiles['baseline']['light']['primary']}'");
|
|
|
|
$page->script("document.documentElement.setAttribute('data-scheme', 'teal')");
|
|
$page->assertScript(pagePrimary()." === '{$this->profiles['teal']['light']['primary']}'");
|
|
|
|
$page->script("document.documentElement.setAttribute('data-theme', 'dark')");
|
|
$page->assertScript(pagePrimary()." === '{$this->profiles['teal']['dark']['primary']}'")
|
|
// A panel that sets its own theme keeps the page's profile.
|
|
->assertScript("getComputedStyle(document.querySelector('#colour [data-theme=\"light\"] [data-md-showcase-swatch=\"primary\"]')).backgroundColor === '".rgb($this->profiles['teal']['light']['primary'])."'");
|
|
|
|
$page->script("document.documentElement.removeAttribute('data-scheme')");
|
|
$page->assertScript(pagePrimary()." === '{$this->profiles['baseline']['dark']['primary']}'")
|
|
->assertNoJavaScriptErrors();
|
|
});
|
|
|
|
it('previews a profile from the picker and the showcase menu, and keeps it through wire:navigate', function () {
|
|
$page = profilesReady(visit('/material/colour')->inLightMode());
|
|
|
|
$page->click('#colour [data-md-scheme-picker-option="rose"]')
|
|
->assertScript("document.documentElement.getAttribute('data-scheme') === 'rose'")
|
|
->assertScript(pagePrimary()." === '{$this->profiles['rose']['light']['primary']}'")
|
|
->assertScript("window.eval(\"Alpine.store('theme').scheme\") === 'rose'");
|
|
|
|
// Opens the menu, then an item closes it: pressOnce(), tests/Pest.php.
|
|
pressOnce($page)->click('[data-test="showcase-profiles"] [aria-haspopup="menu"]')
|
|
->click('[data-scheme-preview="teal"]');
|
|
|
|
$page->assertScript("document.documentElement.getAttribute('data-scheme') === 'teal'");
|
|
|
|
$page->click('[data-md-navigation-rail-panel] a[href$="/material/buttons"]')
|
|
->assertScript("location.pathname.endsWith('/material/buttons')")
|
|
->assertScript("document.documentElement.getAttribute('data-scheme') === 'teal'")
|
|
->assertNoJavaScriptErrors();
|
|
});
|
|
|
|
it('paints the profile the application resolves from the first frame', function () {
|
|
Scheme::resolveProfileUsing(fn (): string => 'rose');
|
|
|
|
profilesReady(visit('/material')->inDarkMode())
|
|
->assertScript("document.documentElement.getAttribute('data-scheme') === 'rose'")
|
|
->assertScript(pagePrimary()." === '{$this->profiles['rose']['dark']['primary']}'");
|
|
});
|