*/ public array $files = []; public string $audience = 'anyone'; public bool $public = false; public string $message = ''; public function save(): void { $this->validate(['name' => 'required']); } public function render(): string { return <<<'BLADE'

name: {{ $name }}

hours: {{ $hours }}

files: {{ implode(',', $files) }}

audience: {{ $audience }}

public: {{ var_export($public, true) }}

@foreach (['a', 'b', 'c'] as $file) @endforeach
BLADE; } } function fieldProbe() { Livewire::component('field-probe', FieldProbe::class); Route::middleware('web')->get('/field-probe', fn () => Blade::render(<<<'BLADE' @vite(config('livewire-material.showcase.vite')) @livewireStyles @livewireScripts BLADE)); return visit('/field-probe')->waitForEvent('networkidle') ->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'"); } it('floats the label while the field has focus or holds a value', function () { $label = "getComputedStyle(document.querySelector('label[for=\"name-field\"]')).fontSize"; $page = fieldProbe()->assertScript("{$label} === '16px'"); $page->click('#name-field')->assertScript("{$label} === '12px'"); $page->type('#name-field', 'Holiday') ->assertSeeIn('#name', 'Holiday'); $page->click('#password-field')->assertScript("{$label} === '12px'"); }); it('clears a field and tells Livewire', function () { fieldProbe() ->type('#name-field', 'Holiday') ->assertSeeIn('#name', 'Holiday') ->click('[data-field-clear]') ->assertScript("document.querySelector('#name-field').value === ''") ->assertScript("document.querySelector('#name').textContent === ''") ->assertScript("document.activeElement.id === 'name-field'"); }); it('copies a field\'s value and says so', function () { $page = fieldProbe()->type('#name-field', 'Holiday'); $page->script("window.eval(\"Object.defineProperty(navigator, 'clipboard', { configurable: true, value: { writeText: async (text) => { window.copied = text } } })\")"); $page->click('[data-field-copy]') ->assertScript("window.copied === 'Holiday'") ->assertSee('Copied to the clipboard'); }); it('shows and hides a password', function () { fieldProbe() ->type('#password-field', 'secret') ->click('[data-field-reveal]') ->assertScript("document.querySelector('#password-field').type === 'text'") ->assertAttribute('[data-field-reveal]', 'aria-pressed', 'true') ->click('[data-field-reveal]') ->assertScript("document.querySelector('#password-field').type === 'password'"); }); it('shows the server\'s error in place of the hint', function () { fieldProbe() ->click('button:has-text("Save")') ->assertSee('The name field is required.') ->assertAttribute('#name-field', 'aria-invalid', 'true') ->assertScript("document.querySelector('#name-field').closest('.field').hasAttribute('data-invalid')"); }); it('binds a select to Livewire', function () { fieldProbe() ->select('#hours-field', '1') ->assertSeeIn('#hours', '1'); }); it('keeps a partly ticked checkbox in step with the server', function () { $all = "document.querySelector('#all')"; $page = fieldProbe()->assertScript("! {$all}.indeterminate"); $page->click('label[for="file-a"]') ->assertSeeIn('#files', 'a') ->assertScript("{$all}.hasAttribute('data-indeterminate') && {$all}.indeterminate"); $page->click('label[for="file-b"]') ->click('label[for="file-c"]') ->assertSeeIn('#files', 'a,b,c') ->assertScript("! {$all}.hasAttribute('data-indeterminate') && ! {$all}.indeterminate"); }); it('moves between radio buttons with the arrow keys', function () { fieldProbe() ->keys('input[type="radio"][value="anyone"]', 'ArrowDown') ->assertSeeIn('#audience', 'team') ->assertScript("document.querySelector('input[type=\"radio\"][value=\"team\"]').checked"); }); it('turns a switch on from the keyboard and from its label', function () { $page = fieldProbe() ->keys('#public', 'Space') ->assertSeeIn('#public-state', 'true'); $page->click('label[for="public"]') ->assertSeeIn('#public-state', 'false') ->assertAttribute('#public', 'role', 'switch'); }); it('grows a textarea with its text up to its maximum', function () { $height = "document.querySelector('#message').getBoundingClientRect().height"; $page = fieldProbe(); $rows = $page->script("({$height})"); $page->type('#message', "one\ntwo\nthree") ->assertScript("({$height}) > {$rows}"); $three = $page->script("({$height})"); $page->type('#message', "one\ntwo\nthree\nfour\nfive\nsix\nseven") ->assertScript("Math.abs(({$height}) - ({$three} + 24)) < 2") ->assertScript("document.querySelector('#message').scrollHeight > document.querySelector('#message').clientHeight"); });