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

Pest Plugin Agent Laravel Package

pestphp/pest-plugin-agent

Pest Plugin Agent extends Pest with agent-focused testing helpers and expectations, making it simple to write expressive, reliable tests for AI agent workflows in Laravel and PHP projects. Integrates with Pest's familiar syntax for confident agent testing.

View on GitHub
Deep Wiki
Context7

Getting Started

What it is: a thin wrapper that turns vendor/bin/pest --agent="<php snippet>" into a one-shot verification run — materialize a temp it('verify', fn () => …) test, run it against your existing Pest config, delete it. It is a probe, not a test framework.

Minimum steps:

  1. Confirm you're on Laravel + Pest with tests/Pest.php uses() bindings already wired (factory, seeder, actingAs() helpers available). Without those bindings the plugin has nothing to hang onto.
  2. Install as a dev dependency, pinned:
    composer require --dev pestphp/pest-plugin-agent
    
    Optional, only if you want visual/design verification: pestphp/pest-plugin-browser plus npx playwright install.
  3. Read the bundled SKILL.md first. It is the contract. Most failure modes (quoting, FQCN, browser API drift) are documented there, and skipping it is why people think the tool "doesn't work."
  4. Ensure your test DB is in-memory SQLite or otherwise disposable. Do not flip RefreshDatabase against a persistent database.
  5. Smoke test it:
    vendor/bin/pest --agent='$user = \App\Models\User::factory()->create(); expect($user->exists)->toBeTrue();'
    

First real use case: agent (or you) finishes a backend edit, self-verifies before handoff:

vendor/bin/pest --agent='$user = \App\Models\User::factory()->create(); $response = $this->actingAs($user)->get("/api/users"); $response->assertStatus(200);'

Pass/fail, no scratch file on disk, no throwaway commit. That is the entire value proposition — everything else is detail.

Implementation Patterns

Backend self-verification after edits. Seed inline with factories; never rely on pre-existing state (the in-memory DB starts empty each run):

$post = \App\Models\Post::factory()->create();
expect($post->author)->not->toBeNull();

Mail / notification / queue assertions. Standard Laravel fakes work because you're inside a bootstrapped app with the project's Pest bindings:

\Illuminate\Support\Facades\Mail::fake();
\App\Models\User::factory()->create()->notify(new \App\Notifications\Welcome());
\Illuminate\Support\Facades\Notification::assertSentTo(/* … */);

Visual / design review loop. Drive a page after a Blade/Livewire/CSS change, capture across viewports:

visit("/dashboard")->on()->mobile()->assertSee("Overview");

Use the documented chain — ->on()->mobile(), ->on()->iPhone14Pro(), ->resize(w, h). Do not invent onMobile(); it doesn't exist.

Full-stack smoke. Drive the UI, assert a frontend signal, then assert the backend side effect — mail sent, order row created. This is where agents claim "looks right" and this pattern catches it.

Agent workflow integration (the real pattern).

  • Bake "self-verify before handoff" into your agent instructions / AGENTS.md. Load the skill the moment a prompt is about checking, confirming, or making sure something works.
  • Codify a short runbook: single outer quotes, FQCN everywhere, documented browser API only, apostrophe fallback, screenshot hygiene.
  • Gate --agent out of production and release pipelines. It's a dev/CI-local tool.

Pre-handoff review evidence. Have the agent paste the --agent command and result into the PR description. A reviewer gets a reproduced check instead of a claim — that's your review-cycle saver.

Seeding for pages that need data. Feed/list/dashboard pages render empty state unless you seed first inside the snippet ($this->seed(...)) — the DB is ephemeral per run.

Apostrophe fallback. When the snippet needs a literal ' (e.g. ->type("bio", "I'm here")), write it to a scratch .php file — plain body statements, no <?php, no use — and pass it verbatim:

vendor/bin/pest --agent="$(cat /path/to/snippet.php)"

The plugin resolves suite uses bindings itself, so the scratch file's location doesn't matter. Delete the scratch file after.

Gotchas and Tips

Double outer quotes are the trap. --agent="…$user…" makes the shell interpolate $user to an empty string before PHP sees it — the login-form check silently weakens or produces a false pass. Always single outer quotes: --agent='…'. Never hand-escape \$. If you catch yourself typing \$, you're doing it wrong.

No use statements in the generated file. Every class must be fully qualified — \App\Models\User, \Illuminate\Support\Facades\Mail, \App\Notifications\WelcomeNotification. Unqualified User yields Class "User" not found.

Valid PHP, not natural language. --agent="visit '/' and check it works" is a parse error. Translate the request into statements before invoking.

Use vendor/bin/pest, never bare pest. Bare pest often isn't on PATH; you'll get "command not found" and misread it as a plugin failure.

RefreshDatabase against a persistent DB is destructive. It's commented out by default for a reason — leave it that way unless you know the target DB is disposable. This is the single most dangerous failure mode.

Temp files are cleaned up by Pest, not by you — and not on SIGKILL. Expect residue on hard crashes. Snippet scratch files from the apostrophe fallback are your responsibility — delete them.

Screenshots churn into tests/Browser/Screenshots/ (hardcoded). Delete throwaway smoke screenshots after eyeballing. For design-review workflows, keep them in a gitignored subfolder and clean periodically.

Browser API surface drifts. onMobile() doesn't exist; waitForText() is deprecated. Only use methods documented in SKILL.md. Unsupported browser methods are a top source of confusing failures.

Don't paper over missing setup. If a probe fails because a factory, seeder, or migration is missing, stop and fix the underlying setup — don't bend --agent invocations into a fixture harness.

Probe ≠ regression test. Institutionalize the boundary: probes answer "does this work right now," committed tests answer "this must never break again." If a behavior deserves a guard, write a real test file. Shipping agent-verified code with zero regression coverage is the classic way this gets misused.

It executes arbitrary PHP inside a bootstrapped app by design. Dev/CI-only, sandboxed DB, no production-adjacent environments.

Young package, thin bus factor (7 stars, 0 dependents). Pin the version, subscribe to releases, budget upgrade work when Pest/PHP/Laravel majors move. Undocumented version support matrix — validate before rollout. Migration cost to inline-it-yourself is near zero, so treat this as a reversible, contained bet rather than load-bearing infrastructure.

Measure it if you adopt it. Track % of agent tasks that self-verify before handoff, verification runs per task, false-negative rate (watch the quote-interpolation trap), screenshot churn, and review cycles saved. Those numbers — not the star count — justify keeping it.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo