symfony/browser-kit
Symfony BrowserKit simulates a web browser in PHP, letting you make requests, click links, and submit forms programmatically. Includes an HttpClient-based implementation for real HTTP requests, ideal for functional tests and scraping.
What it actually buys us. BrowserKit is a browser simulation abstraction — request, click a link, fill and submit a form by field name, follow redirects, carry cookies, walk back and forward through history. It is not a test runner, not an HTTP client, and not, on its own, a way to test a Laravel app. It supports these product decisions:
Illuminate\Http\Request and calling the HTTP kernel. Symfony keeps that class (KernelBrowser) in framework-bundle, not here. Budget 200–400 LOC plus its own tests, not a composer require.isFirstPage()/isLastPage() plus matching PHPUnit constraints landed in 7.4/8.0, which directly reduces flaky-test debugging time.$this->get(), $this->post(), assertRedirect). Those stay the default for API/JSON assertions. BrowserKit is a narrow addition for flows where "click the Checkout link and submit the form" is the behaviour under test.Maintenance signal is good, and it matters for planning. Recent releases show active bug-fixing in exactly the areas that cause flaky tests: cookie values containing +, most-specific-cookie matching, PHP 8.6 deprecation fixes, form submission with empty file fields. That is a healthy component, not an abandoned one.
Adopt when:
symfony/dom-crawler and symfony/css-selector — both required for selector-based methods and neither a Laravel default.Look elsewhere when:
Known risk worth putting in the decision record: Symfony 8 enforced return types across components. A glue class written against 7.x can fail to compile on 8.x. Treat our glue as a version-locked artifact with an owner and a scheduled review at each Symfony major.
To executives: This is a low-cost, low-risk testing capability with zero production blast radius — the entire integration lives under tests/, uses an MIT licence, requires no browser binaries or Node toolchain, and is reversible in an afternoon. The return is developer velocity and regression confidence on our highest-value user journeys, not a user-facing feature. It will not, by itself, fix test coverage; it makes a specific category of coverage — multi-step form and navigation flows — affordable to write and fast to run.
To engineering: You get link clicking, form filling with hidden fields, cookie/session persistence, redirect handling, and history assertions for free. You own one class that bridges BrowserKit to the Laravel kernel, plus its tests. You inherit two real dependencies (dom-crawler, css-selector) and a coupling to Symfony majors that we should pin deliberately. It composes cleanly with PHPUnit and Pest.
The ask: A timeboxed spike — one to two engineer-weeks — to build the glue and port three to five existing journey tests, then compare runtime and flake rate against the status quo (and against Dusk if JS flows are in scope). Decision gate at the end: keep for JS-free journeys, or fold into Dusk and drop the dependency. Do not adopt organisation-wide before that gate.
How can I help you explore Laravel packages today?