Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Easy Testings Laravel Package

sakanjo/filament-easy-testings

Simplify testing Filament admin panels with sakanjo/filament-easy-testings. This Laravel package provides convenient helpers and assertions for resources, pages, forms, tables, and actions, helping you write reliable feature tests faster with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Install (dev only):

composer require --dev sakanjo/filament-easy-testings:^3.0

v3.0.0 is a major bump and the release notes are only a bare changelog link — before adopting, check the composer.json constraints of the tag (php, filament/filament, livewire/livewire, pestphp/pest) and skim the full changelog at https://github.com/sakanjo/filament-easy-testings/compare/v2.0.0...v3.0.0 for renamed traits/namespaces. If you were on v2, expect a short upgrade pass (namespace or helper renames) rather than a drop-in.

Where to look first:

  1. README.md — the available traits/helpers and their signatures (this package is thin sugar over Livewire::test() + Filament's own test helpers, so the surface is small).
  2. src/ — the base TestCase / trait you are meant to use in tests/Pest.php or tests/TestCase.php.
  3. Any publishable config: php artisan vendor:publish --tag="filament-easy-testings-config" (skip if the tag doesn't exist — the package may be config-free).
  4. The package's own tests/ directory — it doubles as the most accurate usage documentation.

First use case — one smoke test for a resource list page:

it('lists posts', function () {
    $user = User::factory()->create();
    $post = Post::factory()->for($user)->create();

    $this->actingAs($user)
        ->get(PostResource::getUrl('index'))
        ->assertOk()
        ->assertCanSeeTableRecords([$post]);
});

That single test proves your panel boots, the resource resolves, the policy allows access, and the table query is wired — the four things that break most often after a Filament upgrade.

Implementation Patterns

Extend, don't duplicate. Put the package's test case/trait in tests/Pest.php (uses(YourPanelTestCase::class)->in('Feature')) so every Filament test inherits panel bootstrapping, setUp() panel selection, and DB refresh. One place to fix when v4 lands.

Data-provider over resources. Because Filament resources are statically discoverable, iterate them:

it('renders index pages', function (string $resource) {
    $this->actingAs(admin())->get($resource::getUrl('index'))->assertOk();
})->with(fn () => collect(Filament::getPanel('admin')->getResources())
    ->map(fn ($r) => $r::class)  // Pest resolves class-strings lazily
    ->all());

Guard with $resource::canViewAny() so permission-gated resources don't produce false failures.

Resource CRUD as three tests, not one. (a) list + table assertions, (b) create form happy path + validation failure, (c) edit + delete via callAction. Splitting keeps failures diagnosable and lets you skip (b)/(c) for read-only resources.

Table interactions — chain against the page component: assertCanSeeTableRecords, assertCanNotSeeTableRecords, searchTable('foo'), sortTable('title','desc'), filterTable('status', 'published'), assertTableColumnStateSet('status','published',$record). Always pass records, not raw IDs; the helpers hydrate models and compare against the rendered collection, which is what you actually care about.

Forms — fillForm([...]) then call('create'), and assert both directions: assertHasNoFormErrors() on the happy path, assertHasFormErrors(['title' => 'required']) on the failure path. fillForm bypasses the browser but not Filament's validation, so it is a genuine test of your rules — including ->live() dependent fields, which require a call('$refresh') or a subsequent fillForm to settle.

Actions — table actions need callTableAction('delete', $record); page/header actions need callAction(). Assert side effects in the DB (assertDatabaseMissing) and the UI signal (assertNotified()), because Filament catches exceptions and converts them to notifications — a swallowed 500 looks green if you only assert the redirect.

Auth realism. Seed roles/permissions in the base case and test at least one denied path per resource. Most Filament production incidents are policy/shield misconfigurations, not rendering bugs, and the cheap assertForbidden() covers a huge class of them.

Tenancy. For tenant-scoped panels, always ->for($tenant) on factories and set the tenant explicitly before get(); otherwise getUrl() returns a URL with the wrong tenant slug and you get a 404 that costs 20 minutes to diagnose.

CI. sqlite :memory: + RefreshDatabase is enough. If you run --parallel, remember Filament's panel registry is static per-process — that's fine — but seeded reference data must be created per-test, not in a global setUpBeforeClass.

Gotchas and Tips

  • Major-version ambiguity. v3.0.0 ships with a changelog link and no prose. Treat it as breaking until proven otherwise: upgrade on a branch, run the full suite, and diff composer.json requirements first. If the package pins filament/filament:^4.0, it will silently drag your panel along.
  • Static panel state leaks. Filament::setCurrentPanel() and Filament::setServingStatus() persist across tests in the same process. Set them in setUp() and, if you have multiple panels, reset in tearDown() — otherwise panel-A tests pass or fail depending on file order.
  • Livewire::test() takes the page class. Passing the resource class gives a confusing "component not found" or a bare 500. The resource is for getUrl(); the page is for Livewire::test().
  • Route caching. If route:cache ran in a deploy step on your CI image, getUrl() can 404. Clear it in the CI script before php artisan test.
  • Translation-dependent assertions. assertSee('Create') breaks the moment someone adds a lang/ file. Prefer assertSee(__('filament-actions::create.single.label')) or assert on the record's attribute.
  • Pagination vs assertCanSeeTableRecords. Records on page 2 are not visible. Either set ->defaultPaginationPageOption(50) in the test or keep fixtures small; a "flaky" test here is usually just 26 seeded rows.
  • SQLite vs production DB. Case-insensitive searchTable() behaves differently on MySQL/Postgres (LIKE vs ILIKE, collation). Anything asserting search/sort semantics deserves one run against a real engine or a database connection in CI.
  • Silent exception swallowing. A red notification is not a green test. Add ->withoutExceptionHandling() while writing a test, then remove it once it passes, and check storage/logs/laravel.log whenever an action "just didn't work."
  • Debugging loop. dump($component->html()) (Livewire's html()) or ->assertSee('marker') beats guessing; $component->errors() exposes the error bag directly when assertHasFormErrors feels opaque.
  • Extension points. Prefer composing your own base TestCase (panel boot + roles + factories) around whatever the package exposes over copying its helpers; when you need behaviour it lacks, Livewire::test() + Filament's native assertions (assertFormExists, assertTableExists, assertActionExists) are stable public APIs and won't move with this package's majors. Wrap them in your own assertions trait so a v4 upgrade touches one file.
  • Pin the major. "sakanjo/filament-easy-testings": "^3.0" — with release notes this thin, a * or dev-main constraint is asking for a surprise.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource