blade(''); expect($html) ->toContain('data-search') ->toContain('role="search"') ->toContain('type="search"') ->toContain('placeholder="Search shares"') ->toContain('aria-label="Search shares"') ->toContain('role="combobox"') ->toContain('aria-haspopup="dialog"') ->toContain('aria-controls="find-view"') ->toContain('aria-expanded="false"') ->toContain('wire:model.live.debounce.300ms="query"') ->toContain('id="find-view"') ->toContain('data-search-clear') ->toContain('data-search-scrim') ->toContain('aria-label="Back"') ->toContain('materialSearch(false,') ->not->toContain('data-search-results'); // The state belongs to the combobox, never to the bare textbox ARIA gives it to. expect($html)->toMatch('/]*aria-expanded/s'); expect($html)->not->toMatch('/]*aria-expanded/s'); }); it('announces how many results there are, politely', function () { $html = (string) $this->blade(''); expect($html) ->toContain('data-search-status') ->toContain('aria-live="polite"') ->toContain('aria-atomic="true"') ->toContain('No results') ->toContain('1 result') ->toContain(':count results'); }); it('shows the results as a list, or what to say when there are none', function () { expect((string) $this->blade('holiday.zip')) ->toContain('data-search-results role="list"') ->toContain('holiday.zip') ->and((string) $this->blade('No shares match.')) ->toContain('No shares match.') ->not->toContain('data-search-results role="list"'); }); it('names the input, trails the bar, and stays docked on request', function () { $html = (string) $this->blade(''); expect($html) ->toContain('placeholder="Search"') ->toContain('aria-label="Search your shares"') ->toContain('data-search-trailing') ->toContain('') ->toContain('materialSearch(true,'); });