diff --git a/tests/Feature/CopyButtonComponentTest.php b/tests/Feature/CopyButtonComponentTest.php index a9996a062e..7177da08e8 100644 --- a/tests/Feature/CopyButtonComponentTest.php +++ b/tests/Feature/CopyButtonComponentTest.php @@ -1,16 +1,42 @@ blade(''); $html->assertSee('Copy backup path') ->assertSee('backup\/path.sql', false) - ->assertSee('window.copyToClipboard', false) - ->assertSee('size-6', false); + ->assertSee('x-data="copyButton"', false) + ->assertDontSee('window.copyToClipboard', false); }); -it('uses the reusable copy button for database backup paths', function () { - $view = file_get_contents(resource_path('views/livewire/project/database/backup-executions.blade.php')); +it('disables the button when no backend value is available', function () { + $html = $this->blade(''); - expect($view)->toContain(''); + $html->assertSee('disabled', false); +}); + +it('evaluates a resolve expression at click time instead of a static value', function () { + $html = $this->blade(''); + + $html->assertSee('await ($wire.copyValue())', false) + ->assertDontSee('disabled', false); +}); + +it('is the single clipboard implementation shared by its call sites', function () { + expect(file_get_contents(resource_path('js/copy-button.js'))) + ->toContain("window.Alpine.data('copyButton'"); + + expect(file_get_contents(resource_path('js/app.js'))) + ->toContain('initializeCopyButtonComponent'); + + $modalConfirmation = file_get_contents(resource_path('views/components/modal-confirmation.blade.php')); + $backupExecutions = file_get_contents(resource_path('views/livewire/project/database/backup-executions.blade.php')); + + expect($modalConfirmation) + ->toContain('not->toContain('navigator.clipboard'); + + expect($backupExecutions) + ->toContain('not->toContain('navigator.clipboard'); }); diff --git a/tests/Feature/ResourceDetailsVisibilityTest.php b/tests/Feature/ResourceDetailsVisibilityTest.php index 29f611cbaa..4cac570f7e 100644 --- a/tests/Feature/ResourceDetailsVisibilityTest.php +++ b/tests/Feature/ResourceDetailsVisibilityTest.php @@ -27,7 +27,7 @@ it('keeps the resource details helper text visible below the modal header', func ])->render(); expect($html) - ->toContain('Identifiers for this resource. Read-only') + ->toContain('readonly') ->toContain('pt-1') ->not->toContain('-mt-4'); }); @@ -38,20 +38,18 @@ it('renders copy fields as visible readonly controls with an accessible copy act expect($html) ->toContain('label class="flex gap-1 items-center mb-1 text-sm font-medium text-black dark:text-white"') ->toContain('readonly') - ->toContain('window.copyToClipboard') + ->toContain('x-data="copyButton"') ->toContain('input-with-copy-button') - ->toContain('copy-button') ->toContain('aria-label="Copy to clipboard"') - ->toContain('title="Copy to clipboard"') - ->toContain('class="size-[18px] text-green-500"'); + ->toContain('title="Copy to clipboard"'); }); -it('uses the shared copy field for newly issued api tokens', function () { +it('uses the shared copy button for newly issued api tokens', function () { $blade = file_get_contents(resource_path('views/livewire/security/api-tokens.blade.php')); expect($blade) - ->toContain('') - ->not->toContain('navigator.clipboard.writeText(@js(session(\'token\')))'); + ->toContain('not->toContain('navigator.clipboard'); }); it('keeps copy button padding above settings-workspace input overrides', function () { diff --git a/tests/Feature/TeamInvitationUiTest.php b/tests/Feature/TeamInvitationUiTest.php index 80a4a146df..38c8910986 100644 --- a/tests/Feature/TeamInvitationUiTest.php +++ b/tests/Feature/TeamInvitationUiTest.php @@ -51,25 +51,19 @@ it('renders a real copy button for pending invitation links', function () { $view = file_get_contents(resource_path('views/livewire/team/invitations.blade.php')); expect($view) - ->toContain('aria-label="Copy invitation link"') - ->toContain('window.copyToClipboard(@js($invite->link))') - ->toContain('class="button h-7! shrink-0 px-2!"'); + ->toContain(''); Livewire::test(Invitations::class, [ 'invitations' => TeamInvitation::ownedByCurrentTeam()->get(), ]) ->assertSee($invitation->link) ->assertSeeHtml('aria-label="Copy invitation link"') - ->assertSeeHtml('window.copyToClipboard(') + ->assertSeeHtml('x-data="copyButton"') ->assertSeeHtml('type="button"'); }); -it('exposes a resilient global copyToClipboard helper', function () { +it('keeps clipboard logic in the shared copy button instead of a global helper', function () { $layout = file_get_contents(resource_path('views/layouts/base.blade.php')); - expect($layout) - ->toContain('async function copyToClipboard(text)') - ->toContain('window.copyToClipboard = copyToClipboard') - ->toContain('document.execCommand(\'copy\')') - ->toContain('window.isSecureContext'); + expect($layout)->not->toContain('copyToClipboard'); });