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

Dusk Updater Api Laravel Package

orchestra/dusk-updater-api

A standardised API from Orchestra for fetching and downloading ChromeDriver binaries used by Laravel Dusk, simplifying driver version discovery and updates in test environments.

View on GitHub
Deep Wiki
Context7

Getting Started

Install as a dev dependency only — this has no business in require:

composer require --dev orchestra/dusk-updater-api

There is no service provider, no config file, and no Artisan command. That's the single most important thing to internalise before you start: unlike its predecessor orchestra/dusk-updater, this package ships no orchestration. You instantiate the classes yourself.

Where to look first, in this order:

  1. src/ChromeVersionFinder.php — resolves which ChromeDriver version corresponds to a given Chrome/Chromium version, and (per the v1.0.3 fix) exposes installedChromeDriverVersion(), which returns the driver version currently on disk. Note the return type: it is nullable, so treat "no driver installed" as a real branch, not an error.
  2. src/ChromeDriverDownloader.php — turns a resolved version + platform slug into a downloaded binary.
  3. src/Contracts/* — the interfaces. These are what you should type-hint against in your own wrapper so the package can be swapped later.
  4. chromeDriverSlug() — the platform/arch mapping method (typed as of v1.0.1). Read it before assuming arm64 or Alpine is covered.

First use case, five minutes: on a machine where Dusk already runs, ask the finder what driver is installed, compare it to your Chrome version, and dump the resolved download URL. Don't download yet — just print the URL and eyeball it. You want to confirm which upstream endpoint it contacts and that it's HTTPS before you let it execute anything.

$finder = new \Orchestra\DuskUpdaterApi\ChromeVersionFinder();

dump($finder->installedChromeDriverVersion()); // string|null

If that returns a sensible version, the package works in your environment. If it returns null or throws, you've found your real integration problem on day one rather than in CI three weeks later.

Implementation Patterns

Wrap it. Never call it from a pipeline or a test directly. The package API is an ingredient, not a tool. Put it behind one project-owned Artisan command — something like php artisan chrome:sync — and let everything else call that.

// app/Console/Commands/SyncChromeDriver.php
public function handle(ChromeVersionFinder $finder, ChromeDriverDownloader $downloader)
{
    $localChrome = $this->chromeVersion();                 // your own detection
    $target      = $finder->findVersion($localChrome);     // resolve
    $current     = $finder->installedChromeDriverVersion();

    if ($current === $target) {
        $this->info("Up to date: {$target}");
        return self::SUCCESS;
    }

    $path = $downloader->download($target, $finder->chromeDriverSlug());
    $this->info("Downloaded {$target} to {$path}");
}

The Docker pattern is the strongest fit. Bake the driver into the image at build time so CI jobs never hit the network:

RUN composer install --no-dev --no-scripts \
 && php artisan chrome:sync \
 && rm -rf ~/.composer/cache

Resolution at build time, deterministic binaries at test time. This is the case the package was actually justified for.

Cache the resolved version. Chrome ships roughly every four weeks, but your CI image doesn't change that often. Cache the resolved version → URL mapping (Redis, a JSON file, whatever) with a TTL of a day or two. The resolver is a network call; a Dusk matrix of twelve jobs shouldn't make twelve of them.

Type-hint the interfaces, not the concretes. Inject ChromeVersionFinder's contract into your command and bind the concrete in a service provider of your app. That gives you a fake for tests and a single line to change when you swap the package out.

Handle "already correct" explicitly. Comparing installedChromeDriverVersion() against your target before downloading is the difference between a 3-second command and a 40-second one on every CI run. The v1.0.3 return-type fix exists precisely to make this comparison reliable.

Pair it with a pinned Chrome. The resolver only helps if Chrome itself is pinned in the image. If your CI image floats on chrome:latest, resolution will succeed and the binary will still be wrong ten minutes later. Pin both.

Gotchas and Tips

You are overlapping with dusk:install and dusk:update. Modern Laravel Dusk already resolves and downloads a compatible ChromeDriver itself, including Chrome-for-Testing handling. Adding this package gives you a second source of truth that both writes into vendor/laravel/dusk/bin. Before adopting, decide which one owns that directory and make sure the other is never invoked in the same job. If you can't articulate what dusk:install is failing to do for you, you don't need this package.

Nothing in the README tells you what gets downloaded or whether it's verified. The entire value proposition is fetching an executable and running it. Log the resolved URL, check it's HTTPS, and confirm the endpoint is official Chrome-for-Testing rather than a mirror. There is no documented checksum or signature verification — if that matters to your security posture (it should for a binary you execute), verify it yourself after download or don't adopt.

Platform coverage is the silent-failure trap. chromeDriverSlug() maps the current platform to a driver artefact, and if your CI fleet includes arm64 runners, Alpine/musl, or Windows agents, resolution may return something wrong or nothing at all without a clear error. Test the command on every architecture in your fleet before promoting it, and assert on the result rather than assuming success.

Verify the dependency envelope against your lockfile, not the release notes. v1.0.6 claims Guzzle 8 support; v1.0.4 added Symfony Process 8 and PHP 8.5; v1.0.2 pulled in orchestra/sidekick. In a large monorepo with a shared lockfile, each of those widenings is a potential conflict. Run composer why orchestra/sidekick after install and know what you've inherited. If you're pinned to Guzzle 7, read the actual composer.json constraint rather than trusting the changelog.

Debugging resolution failures. When the browser fails to launch mid-suite with an opaque "chromedriver exited unexpectedly," it's almost never this package — it's a version mismatch between the resolved driver and the Chrome your image actually runs. Two commands settle it: google-chrome --version and whatever your wrapper reports for the installed driver. If those disagree, your pin is wrong. Also check whether chromeDriverSlug() resolved to the architecture you think it did; on multi-arch builds that's the usual culprit.

Pin the package version exactly. Single maintainer, zero dependents, no support SLA. Use "orchestra/dusk-updater-api": "1.0.6" rather than ^1.0. You want upgrades to be a deliberate act you can test, not something that arrives with an unrelated composer update.

Keep the wrapper thin enough to delete. The whole thing should be a few dozen lines. If the package is abandoned or a Chrome endpoint changes, swapping to a direct call against the Chrome-for-Testing JSON API should be an afternoon, not a sprint. Don't leak package types into your test suite or your CI scripts — that's what makes the exit expensive.

Extension points are effectively nil. No config, no driver abstraction, no mirror/proxy setting, no retry policy. Anything you need along those lines — proxy config, timeouts, fallback URLs — you implement around the package, not inside it. Plan for that in the estimate; treating this as a "just add the dependency" ticket is how the wrapper ends up unwritten and the whole thing gets abandoned mid-adoption.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style