# Write Tests for a Filament Admin Panel

Yes. An agent writes Pest tests with Filament's Livewire helpers for the resources and relation managers that lack them, runs the suite and opens a PR.

[Run this on Rush](https://cloud.getrush.ai/run/write-filament-tests/filament/), in a Project that has your repository.

## What the agent does

The agent maps the panel's classes to the tests that exist before writing any, so it fills gaps rather than duplicating coverage. In filamentphp/demo, `composer.json` requires `filament/filament` `^5.0` on `laravel/framework` `^12.0` with `pestphp/pest` `^3.0`, and `app/Filament/Resources` holds 15 resources across Blog, HR and Shop. Every resource page already has a test under `tests/Filament/Resources`, from `CreateBrandTest` to `ViewLeaveRequestTest`. The gap is in relation managers: there are 12 under `RelationManagers/` directories, and only one, `Shop/Products/RelationManagers/CommentsRelationManager`, has a test.

So the run's work list is the other 11: `AddressesRelationManager` and `PaymentsRelationManager` on customers, `PaymentsRelationManager` on orders, `ProductsRelationManager` on shop categories, `AddressesRelationManager` and `ProductsRelationManager` on brands, `TasksRelationManager` and `TimesheetsRelationManager` on projects, `EmployeesRelationManager` on departments, and `LeaveRequestsRelationManager` and `TimesheetsRelationManager` on employees. For each it reads the class's `form()` and `table()` to list the fields, validation rules, filters and actions it defines.

It writes the tests in the style the suite already uses. `tests/Pest.php` extends `TestCase`, uses `RefreshDatabase` and logs in a fresh `User` before every test in `Filament`, and `CommentsRelationManagerTest` mounts a manager with `Livewire::test(CommentsRelationManager::class, ['ownerRecord' => $product, 'pageClass' => EditProduct::class])` and creates records with `callAction(TestAction::make('create')->table(), [...])`. Each new file follows that: it renders, the table lists the owner's related records and not another owner's (`assertCanSeeTableRecords` and `assertCanNotSeeTableRecords`), the create action saves with valid data and fails with `assertHasFormErrors` on each required field, edit and delete actions change the database, and each filter narrows the rows. Records come from the model factories under `database/factories`.

It prepares the environment the way `.github/workflows/tests.yml` does: PHP 8.4 with `pdo_sqlite`, `cp .env.example .env`, `composer install`, `npm ci && npm run build`, `php artisan key:generate` and an empty `database/database.sqlite`. Then it runs `composer test:pest`, which is `pest --parallel`, until the suite passes, and runs it again to make sure no new test depends on parallel ordering.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Write Pest tests with Filament's Livewire testing helpers for the parts of this panel that have none. First list every resource page and relation manager under app/Filament and the tests under tests/Filament, and work only on the ones without a test. For each relation manager, mount it with Livewire::test(..., ['ownerRecord' => ..., 'pageClass' => ...]) like CommentsRelationManagerTest and cover: it renders, the table shows only the owner's records, create with valid data and with each required field missing, edit and delete actions, and each table filter. Use the model factories. Set up the environment as .github/workflows/tests.yml does, run composer test:pest until it passes, and open a pull request.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The pull request adds one test file per untested relation manager, each at the path that mirrors its class, for example `tests/Filament/Resources/Shop/Orders/RelationManagers/PaymentsRelationManagerTest.php` and `tests/Filament/Resources/HR/Employees/RelationManagers/LeaveRequestsRelationManagerTest.php`. If a model the tests need has no factory state for a case, such as a payment in a particular status, it adds that state to the factory and says so. Nothing under `app/` changes.

The description has a table of the 11 relation managers with the cases covered for each, quotes the `pest --parallel` summary from the sandbox run, and lists anything it could not test with the Livewire helpers, with the reason. The repository's `tests` workflow runs the same command on the pull request, and the session's record keeps each run the agent made, including failures it fixed along the way.

A reviewer checks that each validation case matches the rule in the manager's `form()`, that the scoping test really creates a record on a second owner, and that the suite is still green under `composer test`, which also runs `phpstan analyse` over the new files.

## Run it on every Filament resource added

Filament makes it quick to generate a resource or relation manager with `php artisan make:filament-resource`, which is also how panels end up with untested ones. A GitHub trigger on `pull_request.opened` can run this request on every pull request that adds files under `app/Filament`, asking for tests of the new classes in the same style, so new admin screens arrive tested.

A weekly schedule trigger works too, for teams that prefer one pull request of tests on a Monday morning: the prompt asks for every resource, page and relation manager added since the last run that has no test file at its mirrored path.

## Why run it on Rush?

Running a Filament suite needs PHP 8.4 with the right extensions, a Composer install, a Vite build of the panel assets and a database, and `pest --parallel` uses every core it can find. In a Rush sandbox the agent sets all of that up from the workflow file, runs the suite as often as it takes, and leaves your local PHP and database alone.

The tests are proven by their runs: the Pest output in the session's record, and the repository's own workflow on the pull request. Writing 11 relation manager tests is repetitive work that is easy to review and slow to type, and on Rush it happens while you do something else, with one pull request to read at the end.

## Frequently asked questions

### Does it use Pest or PHPUnit?

Whatever your suite uses. The Filament demo uses Pest 3 with `tests/Pest.php` setting up `RefreshDatabase` and an authenticated user, so the new files are Pest tests that rely on that. In a PHPUnit project the agent writes test classes extending your `TestCase` instead.

### Which Filament version do the helpers target?

The one in your `composer.lock`. Filament 4 and 5 test table actions with `TestAction::make(...)->table()`, as the demo's existing test does, while Filament 3 uses `callTableAction`. The agent reads your existing tests and the installed version and writes the matching calls.

### Will it test multi-tenant panels?

Yes, if your panel uses tenancy. It sets the current tenant the way your existing tests do, and adds a case that a record from another tenant does not appear, which is the scoping check that matters most in a tenant panel.

### Will it change my resources to make them testable?

No. If a manager cannot be tested without a change, such as a missing factory relation, it changes the factory, not the resource, and anything that would need application code is listed in the pull request instead.
