Testing
Overview
All examples in this guide will be written using Pest. However, you can easily adapt this to a PHPUnit.
Since all actions are mounted to a Livewire component, we're just using Livewire testing helpers everywhere. If you've never tested Livewire components before, please read this guide from the Livewire docs.
Getting started
You can call an action by passing its name or class to callAction()
:
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callAction('send');
expect($invoice->refresh())
->isSent()->toBeTrue();
});
To pass an array of data into an action, use the data
parameter:
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callAction('send', data: [
'email' => $email = fake()->email(),
])
->assertHasNoActionErrors();
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($email);
});
If you ever need to only set an action's data without immediately calling it, you can use setActionData()
:
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountAction('send')
->setActionData('send', data: [
'email' => $email = fake()->email(),
])
});
Execution
To check if an action has been halted, you can use assertActionHalted()
:
use function Pest\Livewire\livewire;
it('stops sending if invoice has no email address', function () {
$invoice = Invoice::factory(['email' => null])->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callAction('send')
->assertActionHalted('send');
});
Errors
assertHasNoActionErrors()
is used to assert that no validation errors occurred when submitting the action form.
To check if a validation error has occurred with the data, use assertHasActionErrors()
, similar to assertHasErrors()
in Livewire:
use function Pest\Livewire\livewire;
it('can validate invoice recipient email', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callAction('send', data: [
'email' => Str::random(),
])
->assertHasActionErrors(['email' => ['email']]);
});
To check if an action is pre-filled with data, you can use the assertActionDataSet()
method:
use function Pest\Livewire\livewire;
it('can send invoices to the primary contact by default', function () {
$invoice = Invoice::factory()->create();
$recipientEmail = $invoice->company->primaryContact->email;
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountAction('send')
->assertActionDataSet([
'email' => $recipientEmail,
])
->callMountedAction()
->assertHasNoActionErrors();
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($recipientEmail);
});
Action state
To ensure that an action exists or doesn't in a table, you can use the assertActionExists()
or assertActionDoesNotExist()
method:
use function Pest\Livewire\livewire;
it('can send but not unsend invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionExists('send')
->assertActionDoesNotExist('unsend');
});
To ensure an action is hidden or visible for a user, you can use the assertActionHidden()
or assertActionVisible()
methods:
use function Pest\Livewire\livewire;
it('can only print invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionHidden('send')
->assertActionVisible('print');
});
To ensure an action is enabled or disabled for a user, you can use the assertActionEnabled()
or assertActionDisabled()
methods:
use function Pest\Livewire\livewire;
it('can only print a sent invoice', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionDisabled('send')
->assertActionEnabled('print');
});
To ensure sets of actions exist in the correct order, you can use assertActionsExistInOrder()
:
use function Pest\Livewire\livewire;
it('can have actions in order', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionsExistInOrder(['send', 'export']);
});
To check if an action is hidden to a user, you can use the assertActionHidden()
method:
use function Pest\Livewire\livewire;
it('can not send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionHidden('send');
});
Button appearance
To ensure an action has the correct label, you can use assertActionHasLabel()
and assertActionDoesNotHaveLabel()
:
use function Pest\Livewire\livewire;
it('send action has correct label', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionHasLabel('send', 'Email Invoice')
->assertActionDoesNotHaveLabel('send', 'Send');
});
To ensure an action's button is showing the correct icon, you can use assertActionHasIcon()
or assertActionDoesNotHaveIcon()
:
use function Pest\Livewire\livewire;
it('when enabled the send button has correct icon', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionEnabled('send')
->assertActionHasIcon('send', 'envelope-open')
->assertActionDoesNotHaveIcon('send', 'envelope');
});
To ensure that an action's button is displaying the right color, you can use assertActionHasColor()
or assertActionDoesNotHaveColor()
:
use function Pest\Livewire\livewire;
it('actions display proper colors', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionHasColor('delete', 'danger')
->assertActionDoesNotHaveColor('print', 'danger');
});
URL
To ensure an action has the correct URL, you can use assertActionHasUrl()
, assertActionDoesNotHaveUrl()
, assertActionShouldOpenUrlInNewTab()
, and assertActionShouldNotOpenUrlInNewTab()
:
use function Pest\Livewire\livewire;
it('links to the correct Filament sites', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionHasUrl('filament', 'https://filamentphp.com/')
->assertActionDoesNotHaveUrl('filament', 'https://github.com/filamentphp/filament')
->assertActionShouldOpenUrlInNewTab('filament')
->assertActionShouldNotOpenUrlInNewTab('github');
});