Skip to content

feat: support system-installed browsers via channel and executable path - #243

Open
SantosVilanculos wants to merge 2 commits into
pestphp:5.xfrom
SantosVilanculos:feat/system-browsers
Open

feat: support system-installed browsers via channel and executable path#243
SantosVilanculos wants to merge 2 commits into
pestphp:5.xfrom
SantosVilanculos:feat/system-browsers

Conversation

@SantosVilanculos

@SantosVilanculos SantosVilanculos commented Aug 3, 2026

Copy link
Copy Markdown

Summary

Adds two new pest()->browser() configuration options to launch system-installed browsers instead of the Playwright-bundled browsers:

// Google Chrome or Microsoft Edge via Playwright's "channel" mechanism
pest()->browser()->usingChannel('chrome');

// a Chromium-family binary via its absolute path
pest()->browser()->usingExecutablePath('/usr/bin/google-chrome');

The supported channels match Playwright's #configure-browsers docs: chrome, chrome-beta, chrome-dev, chrome-canary, msedge, msedge-beta, msedge-dev, msedge-canary.

Motivation

No downloaded Playwright browser bundles are needed — great for environments that already have Chrome/Edge installed and want to avoid npx playwright install.

Unlocks browsers on distros Playwright's installer refuses to support

Playwright's channel install scripts (bin/reinstall_chrome_stable_linux.sh, bin/reinstall_msedge_*_linux.sh) are hard-gated to Ubuntu/Debian: they source /etc/os-release and abort otherwise. On Linux Mint:

ERROR: cannot install on linuxmint distribution - only Ubuntu and Debian are supported

So a machine that already has Chrome installed still can't use the chrome channel when npx playwright install chrome is part of the bootstrap. This PR removes that whole step: the browser is launched in place, so there is no download, no distro gate, and the system installation is never touched. (On Ubuntu/Debian the Playwright installer would even apt-get remove google-chrome and reinstall the .deb — a disruptive no-op for anyone who already has Chrome.)

Verified end-to-end on Linux Mint (an unsupported distro) with the system Chrome 151: visit(...)->screenshot(...) emits real screenshots while ~/.cache/ms-playwright stays empty. Same benefit on Fedora, Arch, openSUSE, etc., and in CI images that preinstall browsers.

Implementation

  • Configuration::usingChannel(string) and Configuration::usingExecutablePath(string) config methods, plus static channel/executablePath state on Playwright
  • Both are forwarded as launch options in the Playwright client; the payload is URL-encoded (via http_build_query) so executable paths containing spaces or special characters round-trip correctly
  • Playwright's run-server is started with --unsafe when an executablePath is set, because the server otherwise filters that launch option out (see filterLaunchOptions in playwright-core); channel is always accepted without --unsafe
  • usingChannel() and usingExecutablePath() are mutually exclusive and throw an InvalidArgumentException if combined

Scope

Playwright only supports Chromium-family binaries via channel/executablePath. Branded Firefox and Safari builds are not supported because Playwright relies on its own patched builds of those browsers — so usingExecutablePath('/usr/bin/firefox') does not work. Use the bundled Firefox (inFirefox()) for Firefox tests.

Tests

  • tests/Unit/Configuration/SystemBrowserConfigurationTest.php — channel/path configuration, fluent chaining, mutual-exclusion
  • tests/Unit/Playwright/ClientTest.php — launch-option forwarding and connection-query encoding
  • Unit + arch tests pass; Pint and PHPStan are clean

Notes

  • channel is the recommended approach for Chromium-based system browsers and requires no server flags.
  • executablePath requires the --unsafe server mode (added conditionally).

Add two new configuration options to launch system-installed browsers
instead of the bundled Playwright browsers:

- pest()->browser()->usingChannel('chrome') for branded browsers such as
  Google Chrome or Microsoft Edge, which Playwright's server accepts out
  of the box.
- pest()->browser()->usingExecutablePath('/usr/bin/firefox') for any
  browser binary; the Playwright server is started with --unsafe so the
  executablePath launch option is not filtered out.

Both options are forwarded as launch options in the Playwright client.
@SantosVilanculos
SantosVilanculos marked this pull request as ready for review August 3, 2026 12:31
- Restrict usingChannel() to Chromium-family channels (chrome, msedge and
  their beta/dev/canary variants) and document that Playwright only
  supports Chromium-family binaries via executablePath, so branded
  Firefox/Safari builds (e.g. /usr/bin/firefox) are not valid examples.
- Make usingChannel() and usingExecutablePath() mutually exclusive by
  throwing an InvalidArgumentException when combined.
- URL-encode the launch-options payload in the Playwright connection query
  instead of interpolating raw JSON, so paths with spaces or special
  characters round-trip correctly.
- Extract launchOptions() and connectionQuery() on Client and cover the
  new behavior with tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant