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

Browser Laravel Package

zenstruck/browser

zenstruck/browser is an expressive, fluent wrapper around Symfony's functional testing features, letting you visit pages, assert content, fill fields, and click buttons in chainable code. Pair it with zenstruck/foundry for succinct, readable tests.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — low for a Laravel estate, high for Symfony services. zenstruck/browser is explicitly a Symfony package: its KernelBrowser drives the Symfony Kernel through symfony/browser-kit, and its PantherBrowser wraps symfony/panther. It is not a Laravel package and carries no Laravel service provider, facade, or testing trait for Illuminate\Foundation\Testing\TestCase. Laravel's own HTTP test layer (MakesHttpRequests + TestResponse) already occupies this niche, and Laravel teams that need real browsers use Dusk or Pest 3's Playwright-based browser testing. Where the package genuinely fits is a Symfony application's WebTestCase/KernelTestCase suites, replacing verbose $client->request() + $crawler->filter() chains with a fluent, auto-completable DSL. v1.13.0 does not change this positioning.

Integration feasibility — near-trivial on Symfony, not attempted on Laravel. Adoption is a dev-only Composer require, an optional PHPUnit extension registration, and a use HasBrowser trait on test classes. No production code, config, or container changes. v1.13.0 adds one small ergonomic capability — the HTTP session can now be injected into use() — which simplifies reusing an authenticated/pre-seeded session across a fluent chain instead of rebuilding it per test; useful, not a reason to adopt on its own. The realistic "Laravel" value remains conceptual: its API is a good benchmark for internal test-style guidelines (chained assertions, artifact capture on failure), not a dependency.

Technical risk — contained, and modestly reduced by this release, but with one behavioral change to check.

  • Bus factor / ecosystem size. 229 stars, MIT, effectively a single-maintainer project (Zenstruck/Kevin Bond), though v1.13.0 shows external contributors landing fixes — a mild positive signal on bus factor. The reported "0 dependents" and a release date of 2026-10-10 are metadata anomalies worth verifying against Packagist and GitHub "Used by" before citing either in a business case.
  • Dev-only blast radius. Worst case is deleting the package and reverting to native assertions; it cannot break production traffic.
  • Semantic traps that produce misleading green builds — partially closed in v1.13.0. The release makes the browser fail when acted upon after an expected exception, instead of silently continuing; that directly addresses the "assert against an error page and go green" failure mode. Two caveats remain: (a) this is a behavior change — suites on ≤1.12 that deliberately caught an exception and then continued asserting may now fail, so treat it as a semi-breaking patch on upgrade; (b) BROWSER_CATCH_EXCEPTIONS, auto-followed redirects, and kernel reboot between requests are unchanged and still require knowing the defaults.
  • State leakage — improved. v1.13.0 stops mutating the default HTTP options when merging per-request options, removing a class of order-dependent flakiness that was previously hard to diagnose.

Key questions for the adopting team.

  1. Do we operate any Symfony application (including legacy/admin/back-office services), or is this purely conceptual interest for Laravel?
  2. Which PHPUnit major are we on — 8/9 (<extension class=...>) vs 10+ (<bootstrap class=...>) changes the install snippet?
  3. Is JavaScript/browser coverage in scope? If yes, symfony/panther implies Chrome + a reachable web server in CI, a materially larger commitment — and note the release pins Playwright 1.62.1 in the package's own CI, which is upstream's harness, not ours.
  4. Do we already have functional tests worth converting, or would this be greenfield test scaffolding? If converting, do any of them assert after an expected exception (the v1.13.0 behavior change will surface there)?
  5. Do we run PHPUnit under ParaTest, or plan to? v1.13.0 makes artifact filenames unique under paratest, so parallel suites are now a supported path rather than a source of collisions.
  6. Who owns the internal style guide and version pin for a single-maintainer dev dependency?

Integration Approach

Stack fit. Adopt only where the stack is Symfony 5/6/7 + PHPUnit. Treat KernelBrowser as the default (fast, in-process, no browser) and PantherBrowser as an opt-in for JS-critical flows. Pull in zenstruck/foundry only if factories are already the team's fixture pattern; the two compose well but are independent decisions. For Laravel, record the outcome as "not applicable — use Laravel's HTTP test assertions / Dusk / Pest browser plugin," and mine the README for conventions rather than code.

Migration path.

  1. composer require zenstruck/browser --dev, committed to the lockfile with a caret constraint — target ^1.13 for greenfield adoption, since it carries the exception-after-action guard and the HTTP-option mutation fix.
  2. Enable BrowserExtension in phpunit.xml for failure-artifact capture (source, screenshots, JS console) — highest value per line of config, because it shortens debugging of intermittent CI failures.
  3. Pilot on one mid-sized controller test class, converting existing WebTestCase assertions rather than rewriting whole suites.
  4. Convert new tests to the fluent style first; backfill legacy tests opportunistically on touch.
  5. Standardize only after the pilot: a short internal guide covering exception/redirect/reboot defaults, selector conventions, and artifact retention.

Compatibility and sequencing.

  • Upgrading an existing ≤1.12 adoption: read this as a semi-breaking bump, not a routine patch. Run the full suite and triage any test that catches an expected exception and then continues to act on the browser — those now fail by design. The HTTP-option merge fix can also legitimately change request outcomes in suites that relied on leaked defaults.
  • Parallel CI: the unique-artifact-filename change means a ParaTest-run browser suite no longer races on output files, so parallelization can be planned alongside the pilot rather than deferred.
  • Keep the pilot in the same CI job as the existing suite so pass/fail parity is directly observable for one or two sprints before any legacy assertions are deleted. Keep mtdowling/jmespath.php out of initial scope; add it only if API/JSON assertions are a stated need. Sequence Panther last — it changes CI infrastructure, not just test code, and should be justified by a concrete flow (payment widget, multi-step JS form) that KernelBrowser cannot verify.

Operational Impact

Maintenance. Low absolute effort, but it is a small-team OSS dependency: pin to a minor line, review changelogs on bump, and expect to absorb occasional breakage from Symfony's BrowserKit/DomCrawler deprecations. v1.13.0 is a low-risk upgrade for anyone starting fresh and a review-then-upgrade for anyone already on the 1.x line, because of the exception-after-action behavior change. Budget roughly a person-day per Symfony major upgrade plus an hour for this bump's triage, and near-zero in between. The dev-only scope means no security patching obligation for production images.

Support. Upstream is issue-driven and responsive for a project of this size, and this release reflects two outside contributors landing merged fixes — better than the bus-factor profile suggests. There is still no vendor SLA. Mitigate with an internal champion, a two-paragraph "how we test" doc, and a deliberate decision that reverting to native assertions is always an acceptable fallback. Ramp-up is genuinely low: the API is autocompletable in any IDE, so a competent Symfony developer is productive in an afternoon and fluent within a sprint.

Scaling. KernelBrowser suites scale like any PHPUnit suite — parallelize with ParaTest, no new infrastructure, and as of v1.13.0 the artifact writer is race-safe under parallel execution, which removes the main friction that previously argued for keeping browser tests serialized. PantherBrowser still scales poorly by comparison (seconds per test, Chrome processes, memory), so cap it to a small tagged subset and run it in a separate, non-blocking job initially. The residual artifact concern is volume rather than correctness: failed-test sources and screenshots land in var/browser (or BROWSER_SOURCE_DIR), which on a noisy suite can accumulate into CI disk pressure. Set an explicit artifact directory, retention window, and upload-as-CI-artifact step before enabling the extension broadly — unique filenames make retention policy more important, not less, since nothing overwrites.

Failure modes to monitor.

  • False confidence (reduced, not eliminated): acting on the browser after an expected exception now fails, which is the right default. Auto-followed redirects and BROWSER_CATCH_EXCEPTIONS can still let assertions pass against an error page; enforce ->throwExceptions() and ->interceptRedirects() where behavior matters.
  • Cross-test leakage (reduced): default HTTP options are no longer mutated by per-request merges. disableReboot() used casually still produces order-dependent tests; treat it as an exception requiring a comment.
  • Upgrade surprise: tests that intentionally asserted after a caught exception will now fail. That is a correctness win but should be triaged deliberately rather than "fixed" by reintroducing a catch.
  • Brittle selectors: assertSeeIn('h1', ...) and CSS-path assertions break on markup refactors; prefer stable IDs/data attributes.
  • Auth edge cases: the documented remember-me / lazy-firewall LogicException with assertAuthenticated() will surface as unexplained CI failures unless withProfiling() or framework.profiler.collect: true is configured up front.
  • Version drift: a stale pin against a newer Symfony can fail in confusing ways; keep the dev dependency on the same upgrade cadence as the framework.

Net recommendation. Worth a scoped pilot on Symfony services where functional tests are already verbose and maintained — cheap to adopt, cheap to abandon, with measurable gains in test readability and failure debuggability. v1.13.0 strengthens the case modestly: it closes a real false-green hole, removes a flakiness source, and makes parallel execution with artifacts safe. It does not move the Laravel verdict — for Laravel, capture the DSL conventions as internal guidance and move on.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib