protonemedia/laravel-dusk-fakes
Laravel Dusk Fakes lets you replace real Dusk browser sessions with fakes in your tests. It offers a fluent API to simulate browser interactions and assert Dusk calls, so you can test Dusk-dependent code quickly without launching a real browser.
Architecture fit. Laravel Dusk exercises the application through a real browser hitting a separate PHP process, while Laravel's native fakes (Event::fake(), Queue::fake(), Mail::fake(), Notification::fake(), Bus::fake()) only affect the process in which the test runs. That mismatch is the single biggest ergonomic gap in Dusk-based suites: you cannot natively assert "an email would have been sent" from a browser test. This package closes that gap by swapping the framework's fakes for persistent variants that record interactions to a shared store (cache/file/database) that the browser-driven app process also reads, letting the test process assert on what the app process did. Architecturally it is a thin, opt-in shim over Laravel's fake infrastructure rather than a new testing paradigm — which is the right shape for this problem, but also means its correctness is coupled to private-ish framework internals.
Integration feasibility. Low effort, unchanged by 1.10.0. Composer install, package auto-discovery, publishable config for the persistence backend, and per-test opt-in. No production code changes, no schema changes beyond whatever store you choose, and no runtime surface outside the test environment. A developer familiar with Dusk can have a working spike in under a day.
Technical risk. The dominant risk is still signal quality about the package itself. 21 stars and 0 dependents means effectively zero downstream validation: no one has stress-tested this against unusual Laravel configurations, and there is no ecosystem of forks, blog posts, or issue threads to fall back on. Protone Media (Pascal Baljet) is a credible Laravel package author, which offsets but does not eliminate single-maintainer/bus-factor risk. Release 1.10.0 is a positive but modest signal on this axis: it ships Laravel 13 support (the framework-coupling risk being actively managed rather than left to drift) and a small feature addition (an Inertia Modal link, PR #36). It is a minor, non-breaking release — no deprecations, no migration work — and it does not change the zero-downstream-validation picture. Secondary risk remains framework coupling: fake classes and container bindings have shifted across Laravel majors, and while 13 support is now claimed, "supported" and "verified in your configuration" are different things. Tertiary risk is statefulness — a persisted fake store introduces cross-test contamination as a new failure class that native fakes do not have.
Key questions.
composer.json constraint? (New in 1.10.0 — worth confirming before relying on it.).env.dusk.local) and in containerized CI?Stack fit. Best fit is a Laravel 10/11+ application (now explicitly including 13) with an existing Dusk suite that already tests flows involving mail, notifications, jobs, or events, and where the team has hit the "I can't assert on side effects from a browser test" wall. Poor fit for teams using Pest browser testing, Cypress/Playwright, or Http::fake()-at-the-boundary strategies, where the same assertion goal is achieved without a persistent store.
Migration path. Treat this as an additive capability, not a replacement. Keep native fakes for feature/integration tests where they already work, and scope the package to Dusk tests only. Pilot in a single test class covering one high-value flow (e.g., "user registers → welcome notification queued"), and keep the previous assertion strategy (database assertions, log scraping, Mailhog) available as a fallback behind a helper so individual tests can opt out if the package misbehaves. Pin the package version in composer.json and mark it require-dev explicitly — it must never enter a production artifact. Pin to ^1.10 rather than floating; the 1.9→1.10 delta is additive, so upgrading existing installs is a low-risk bump, but the pin still belongs in the ADR.
Compatibility. Verify against your exact Laravel minor before rollout, not just the constraint in composer.json — this now matters more, not less, since Laravel 13 is newly claimed and has less field mileage than 10/11. Confirm the persistence backend you choose is available in the Dusk environment (a database store requires the Dusk env to point at the same test database; a cache store requires a shared driver, not array). If you run Dusk in parallel or sharded CI, validate that store keys are namespaced per worker, or disable sharding for fake-backed tests. If you are mid-migration to Laravel 13, this release removes a blocker to adopting the package, but do not let "13 is supported" substitute for running the spike on 13.
Sequencing.
tearDown(), and exposes helper assertions.Maintenance. The package itself is small and unlikely to need frequent updates, and 1.10.0 shows the maintainer is tracking Laravel majors rather than letting the package lag — that materially reduces (but does not remove) the upgrade-fragility concern. You still inherit an implicit maintenance obligation: every Laravel major upgrade requires verifying that the fake bindings still attach correctly. Budget a half-day per framework upgrade for validation, plus a standing "is this still maintained?" review each release cycle. If it goes unmaintained, the fork cost is moderate — the surface area is small enough that a single engineer could vendor and patch it, and a Laravel 13-compatible baseline is now a better fork starting point than 1.9.0 was.
Support. Community-only. No SLA, no commercial backing, and with 21 stars the issue tracker is thin — you will often be the first person to hit a given problem. This requires naming an internal owner (typically the engineer who owns the Dusk suite) and documenting failure triage in a runbook. Escalation path is: read the source (it's small), patch locally, then upstream or fork. The maintainer is responsive enough to have shipped 13 support promptly, which is a good sign for upstreaming fixes.
Scaling. Dev-only dependency, so zero production blast radius — the primary scaling dimension is test-suite growth. Each additional fake-backed test adds store state that must be cleaned up; if the store is a database table or cache driver, watch for accumulation in long-lived CI environments. Suite runtime is largely unaffected. Parallelism is the real ceiling: Dusk parallelization is already awkward, and a shared persistent store makes it worse unless keys are worker-scoped.
Failure modes.
require-dev and an explicit check in build tooling.Ramp-up. Low, and unchanged. Any Laravel developer already fluent in Mail::fake() and assertQueued() will read the README once and be productive. Expect roughly half a day of onboarding per engineer, plus the shared convention layer (base test case + helpers) that makes the pattern discoverable rather than folklore. The main investment is documentation: an internal note explaining when to reach for persistent fakes versus database assertions, because the package's value depends entirely on that judgment call. If the Inertia Modal helper proves useful, add it to that note so it is adopted deliberately rather than discovered ad hoc.
How can I help you explore Laravel packages today?