call('openCreateModal') ->html(); } public function test_escape_calls_the_livewire_close_method(): void { $this->assertStringContainsString( 'x-on:keydown.escape.window="$wire.closeCreateModal()"', $this->openModalHtml() ); } public function test_tab_and_shift_tab_are_trapped(): void { $html = $this->openModalHtml(); $this->assertStringContainsString('x-on:keydown.tab.prevent', $html); $this->assertStringContainsString('x-on:keydown.shift.tab.prevent', $html); } public function test_init_locks_scroll_and_focuses_the_first_element(): void { $html = $this->openModalHtml(); $this->assertStringContainsString("document.body.classList.add('overflow-y-hidden')", $html); $this->assertStringContainsString('firstFocusable()?.focus()', $html); } public function test_destroy_restores_scroll_and_focus(): void { $html = $this->openModalHtml(); $this->assertStringContainsString('destroy()', $html); $this->assertStringContainsString("document.body.classList.remove('overflow-y-hidden')", $html); $this->assertStringContainsString('this.trigger?.focus()', $html); } public function test_teardown_uses_a_data_method_not_a_directive(): void { $this->assertStringNotContainsString('x-destroy', $this->openModalHtml()); } public function test_dialog_keeps_its_aria_attributes(): void { $html = $this->openModalHtml(); $this->assertStringContainsString('role="dialog"', $html); $this->assertStringContainsString('aria-modal="true"', $html); $this->assertStringContainsString('aria-labelledby="modal-title"', $html); } public function test_close_button_is_labelled(): void { $this->assertStringContainsString('aria-label="Close dialog"', $this->openModalHtml()); } public function test_modal_is_absent_until_opened(): void { $html = Livewire::test(Feeds::class)->html(); $this->assertStringNotContainsString('role="dialog"', $html); } }