eldinbiz/laravel-rubberstamp
Laravel Rubberstamp helps you automatically stamp Eloquent models with contextual metadata, such as who created, updated, or approved a record. Simple configuration cuts repetitive boilerplate and keeps consistent, reliable audit trails across your application without cluttering your models.
RubberStamp sits between you and Pest's browser/scenario suite: it streams live progress while tests run, tidies the terminal afterward, and triages stalls. v0.4 is the release that makes it usable as a default wrapper rather than something you enable when debugging.
Minimal setup:
composer require --dev eldinbiz/laravel-rubberstamp
php artisan vendor:publish --tag="rubberstamp-config" # if a config file is offered
Then run your browser suite through the package rather than calling pest directly — check the package README for the exact binary/artisan command, but the intent is that it wraps the Pest process and owns the console lifecycle.
Where to look first:
⏳ <testName> ... → ✓ <testName> ... 4.20s transitions. That output is your new primary feedback loop.waitForSelector on something that never appears).First use case: take an existing, slow, flaky Pest browser suite and run it unchanged through RubberStamp. You should get the same green/red summary with per-test durations and no duplicated lines. If the output differs from plain Pest, that's a bug worth reporting before you build anything on top of it.
Make it the standard entrypoint, not an opt-in. The value compounds when every browser run goes through it — you get comparable per-test timings across branches and a consistent failure surface. Wire it into your composer.json scripts ("test:browser": "...") and into CI so local and pipeline semantics don't drift.
Use durations as a regression signal. The per-test timing printed on completion is effectively free performance telemetry. Keep an eye on tests that creep from ~1s to ~5s; in browser suites that's usually an actionability wait silently burning its timeout rather than a genuinely slower page.
Keep your dev stack running while you test. The strengthened BrowserProcessSanitizer in v0.4 exists so that composer dev, Vite, php artisan serve, and queue listeners aren't mistaken for orphaned runners. The day-to-day pattern this unlocks is: leave your dev environment up, run the browser suite in a second terminal, and trust that the cleanup pass won't kill your Vite server. Verify this once on your own process names before relying on it.
Triage stalls in the order the banner suggests. When a run hangs, the diagnostic distinguishes a browser-side freeze (element actionability, scroll timeout) from a socket conflict caused by back-to-back runs. Treat that as the first branch in your debugging tree: UI freeze → inspect the selector/wait; socket conflict → wait a beat and re-run before you start editing code.
Separate local runs from CI runs deliberately. The animated ticker and line-clearing are interactive-terminal features. In CI you want a stable, append-only log. Decide per-environment whether you use the live output or fall back to the underlying runner, and make that explicit in your pipeline config rather than letting ANSI behaviour decide for you.
Wrap long suites, not single tests. The clearing/spacing work in v0.4 (Pest suite spacing, rewind on class gaps) is only visible when multiple test classes run. If you're running a single file you're paying wrapper overhead for little gain.
--no-interaction, or under a process supervisor. Test your CI path once with the wrapper enabled and confirm the failure output is still readable — that's the output people actually read at 2am.sail, herd, Octane, or a renamed queue listener could still be candidates for misidentification. If cleanup kills something it shouldn't, path normalization is the extension point to inspect — canonical paths are what the matching is based on, so symlinked project directories are a classic source of mismatch.How can I help you explore Laravel packages today?