diff --git a/docs/10-testing/05-testing-actions.md b/docs/10-testing/05-testing-actions.md index 1ee3847188..d6654b83f4 100644 --- a/docs/10-testing/05-testing-actions.md +++ b/docs/10-testing/05-testing-actions.md @@ -225,7 +225,7 @@ it('can send invoices to the primary contact by default', function () { ## Testing the content of an action modal -To assert the content of a modal, you should first mount the action (rather than call it which closes the modal). You can then use [Livewire assertions](https://livewire.laravel.com/docs/testing#assertions) such as `assertSee()` to assert the modal contains the content that you expect it to: +To assert the content of a modal, you should first mount the action (rather than call it which closes the modal). You can then use `assertMountedActionModalSee()`, `assertMountedActionModalDontSee()`, `assertMountedActionModalSeeHtml()` or `assertMountedActionModalDontSeeHtml()` to assert the modal contains the content that you expect it to: ```php use function Pest\Livewire\livewire; @@ -238,7 +238,7 @@ it('confirms the target address before sending', function () { 'invoice' => $invoice, ]) ->mountAction('send') - ->assertSee($recipientEmail); + ->assertMountedActionModalSee($recipientEmail); }); ``` diff --git a/packages/actions/.stubs.php b/packages/actions/.stubs.php index b21728f08b..f960614b72 100644 --- a/packages/actions/.stubs.php +++ b/packages/actions/.stubs.php @@ -61,6 +61,14 @@ namespace Livewire\Features\SupportTesting { public function assertActionNotMounted(string | TestAction | array $actions = []): static {} + public function assertMountedActionModalSee(string | array $values, bool $escape = true): static {} + + public function assertMountedActionModalDontSee(string | array $values, bool $escape = true): static {} + + public function assertMountedActionModalSeeHtml(string | array $values): static {} + + public function assertMountedActionModalDontSeeHtml(string | array $values): static {} + public function assertActionHalted(string | TestAction | array $actions = []): static {} /** diff --git a/packages/actions/src/Testing/TestsActions.php b/packages/actions/src/Testing/TestsActions.php index 083c810f9b..bdd4a23105 100644 --- a/packages/actions/src/Testing/TestsActions.php +++ b/packages/actions/src/Testing/TestsActions.php @@ -503,6 +503,90 @@ class TestsActions }; } + public function assertMountedActionModalSee(): Closure + { + return function (string | array $values, $escape = true) { + /** + * @var string $html + * + * @phpstan-ignore-next-line + */ + $html = $this->getMountedActionModalHtml(); + + foreach (Arr::wrap($values) as $value) { + Assert::assertStringContainsString( + $escape ? e($value) : $value, + $html + ); + } + + return $this; + }; + } + + public function assertMountedActionModalDontSee(): Closure + { + return function (string | array $values, bool $escape = true) { + /** + * @var string $html + * + * @phpstan-ignore-next-line + */ + $html = $this->getMountedActionModalHtml(); + + foreach (Arr::wrap($values) as $value) { + Assert::assertStringNotContainsString( + $escape ? e($value) : $value, + $html + ); + } + + return $this; + }; + } + + public function assertMountedActionModalSeeHtml(): Closure + { + return function (string | array $values) { + /** + * @var string $html + * + * @phpstan-ignore-next-line + */ + $html = $this->getMountedActionModalHtml(); + + foreach (Arr::wrap($values) as $value) { + Assert::assertStringContainsString( + $value, + $html + ); + } + + return $this; + }; + } + + public function assertMountedActionModalDontSeeHtml(): Closure + { + return function (string | array $values) { + /** + * @var string $html + * + * @phpstan-ignore-next-line + */ + $html = $this->getMountedActionModalHtml(); + + foreach (Arr::wrap($values) as $value) { + Assert::assertStringNotContainsString( + $value, + $html + ); + } + + return $this; + }; + } + public function assertActionHalted(): Closure { return $this->assertActionMounted(); @@ -670,4 +754,29 @@ class TestsActions return $actions; }; } + + /** + * @internal + */ + public function getMountedActionModalHtml(): Closure + { + return function (): string { + $partials = data_get($this->lastState->getEffects(), 'partials', []); + + $partialName = 'action-modals'; + + if (array_key_exists($partialName, $partials)) { + return $partials[$partialName]; + } + + $nestingIndex = count($this->instance()->mountedActions) - 1; + $partialName = "{$partialName}.{$nestingIndex}"; + + if (array_key_exists($partialName, $partials)) { + return $partials[$partialName]; + } + + Assert::fail('No mounted action modal content was found.'); + }; + } }