orchestra/testbench-browser-kit
BrowserKit Testbench component helps package developers write Laravel tests using laravel/browser-kit-testing. Swap your base TestCase for Orchestra\Testbench\BrowserKit\TestCase and use the fluent visit, see, and form APIs.
Architecture fit. This is a narrowly scoped, dev-only shim: it subclasses Orchestra\Testbench\TestCase and layers the laravel/browser-kit-testing API surface on top of Testbench's package-bootstrapping harness. It provides value only for packages that ship routes, controllers, views, or forms — i.e., UI-facing Laravel packages. For headless libraries (DTOs, clients, service wrappers, facades with no HTTP surface) the package contributes nothing and should not be added. Treat it as an E2E-layer tool for package test suites, not a general testing dependency.
Integration feasibility. Extremely low. One composer require --dev, one base-class swap (Orchestra\Testbench\TestCase → Orchestra\Testbench\BrowserKit\TestCase), one $baseUrl property. No service provider registration, no config publishing, no middleware changes. The 4.x→10.x compatibility matrix (Laravel 6→12) is a strong, current signal of maintained parity with the framework's release train.
Technical risk. The dominant risk is upstream fragility, not integration cost:
visit, see, click, type, press) derives from laravel/browser-kit-testing, which Laravel core deprecated in favor of the native MakesHttpRequests assertions. This package is a volunteer-maintained compatibility layer over a legacy contract.factory(App\User::class)->create(), DatabaseTransactions, DatabaseMigrations traits). Documentation freshness trails code freshness; do not use the README as a behavioral spec.json, seeJson, seeJsonStructure, actingAs, withSession, assertSessionHas*) is redundant — those already exist in native Testbench/Laravel testing. Only the DOM-driven interaction layer is genuinely additive.Key questions to resolve before adoption.
$this->get('/')->assertSee(...) cover 80%+ of our cases? If yes, the marginal value is the click/press/attach form interaction only.laravel/browser-kit-testing is archived or a future Laravel major breaks the matrix?ext-dom availability and a stable $baseUrl convention in CI?Social-proof caveat: 0 listed dependents and no star count are likely Packagist/GitHub reporting artifacts rather than adoption signals, but they do mean we cannot infer production-hardening from downstream usage.
Stack fit. Laravel 9–12 package development on Testbench 7/8/9/10, PHP 8.1+, PHPUnit 10/11. Consumes no runtime dependencies. Pairs cleanly with orchestra/testbench and existing CI matrix jobs; adds a small composer resolve cost only.
Compatibility. Match package major to Laravel major (Laravel 12 → v10, 11 → v9, 10 → v8). Verify the release tag against our PHPUnit major; note that assertViewHas, assertRedirectedToRoute, and session assertions have shifted semantics across PHPUnit majors. Ensure Testbench's getEnvironmentSetUp() configures a session driver and app.url consistent with $baseUrl, or visit()/actingAs() will fail in confusing ways.
Migration path. Two routes:
| From | To | Effort |
|---|---|---|
| Native Testbench only | BrowserKit base class | One-line base-class change per test class |
| Existing app-style BrowserKit tests | Lift into package Testbench | Moderate — resolve $baseUrl, session, and DB trait assumptions |
| BrowserKit → native HTTP tests | Mechanical rewrite | Low for JSON/status/session assertions; no native equivalent for click() and press() — you re-issue raw requests against extracted URLs |
The third row matters strategically: adoption should be reversible. Write tests so the assertion logic is not entangled with visit() chaining, keeping the exit ramp cheap.
Sequencing.
$baseUrl, session config, and database trait strategy.Maintenance. The package is low-churn by design (thin subclass, no runtime footprint), but we inherit upstream churn. Budget one dependency bump per Laravel major release, plus a PHPUnit-major reconciliation when applicable. Pin the major in composer.json and let Renovate/Dependabot surface matrix drift. The real maintenance cost is not the package — it is the test suite it enables: DOM-coupled assertions require updates whenever markup changes.
Support. Single-maintainer, community-supported, README-only documentation. No vendor SLA. Our internal runbook must cover: base-class swap, $baseUrl/session configuration, the version matrix, and the fallback to native HTTP tests. Do not plan on upstream responsiveness for time-sensitive fixes; plan on a fork-and-patch contingency.
Scaling. BrowserKit tests are full-stack in-process — materially slower than unit tests and not parallelization-friendly without care around session/DB state. This should be a thin layer (tens of tests), not the bulk of the suite. If a team starts porting every controller test, suite runtime and flake rate will degrade. Set an explicit ceiling: E2E-style coverage for critical user journeys only; business logic coverage stays in unit/feature tests using native assertions.
Failure modes to instrument against.
see()/click() silently or noisily; mitigate by asserting on stable, semantic text and seeRouteIs over seePageIs where possible.$baseUrl, wrong app.url, missing session driver produces non-obvious failures; encode in the base test case, not per-test.laravel/browser-kit-testing deprecation cascading into this package; detect via abandoned-package flags in Composer audit and keep the native-assertion exit ramp warm.withoutMiddleware() scope policy.Ramp-up. Near-zero for developers already fluent in Laravel testing — the mental model (visit/see) is a small shift from native (get/assertSee). Provide a one-page mapping table (BrowserKit method → native equivalent) at onboarding so engineers understand this as an optional convenience layer over native testing, not a separate discipline. The larger ramp-up cost is organizational: convincing teams to keep the E2E suite thin rather than treating visit() as a license to test everything through the browser.
How can I help you explore Laravel packages today?