Skip to content

fix: support Chrome 137+ in web-ext run -t chromium (+functional tests) #3434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 19, 2025

Conversation

Rob--W
Copy link
Member

@Rob--W Rob--W commented May 28, 2025

Fixes #3388.

This PR gets web-ext run -t chromium working again in Chrome 137+.

It uses the Extensions.loadUnpacked CDP command, with a fallback to --load-extension for versions before Chrome 126 (all based on feature detection; there are no explicit version checks in the implementation, to allow it to work with any Chromium-based browser).

Since the implementation now uses CDP, it also replaces the "web-ext Reload Manager Extension" helper extension with a CDP-based mechanism to reload the extension.

All of this is covered by extensive functional tests, with a fake chrome binary that accurately simulates the relevant behaviors. I have verified the behaviors Chrome 69, 70, 75, 77, 88, 100, 122, 125, 126, 134, 139. Relevant findings of version-specific behavior is documented in #3388 (comment). The tests with real Chrome are disabled by default to not slow down CI, but if interested one can run them by setting the TEST_WEBEXT_USE_REAL_CHROME=1 environment variable. More tips on debugging are documented in tests/functional/test.cli.run-target-chromium.js.

@Rob--W Rob--W requested a review from willdurand May 28, 2025 13:51
Rob--W added 5 commits May 29, 2025 00:07
The existing unit tests for web-ext run -t chromium are at
tests/unit/test-extension-runners/test.chromium.js but are testing
implementation details without verifying that Chrome is actually going
to launch the extension.

Before refactoring the implementation as needed to support Chrome 137+
and later, this introduces a unit test that verifies the behavior
against the real Chrome (skipped by default), and a fake Chrome binary
that behaves like the real Chrome binary where relevant.

This will help us with catching regressions in the implementation and/or
downstream dependencies (chrome-launcher).

These Chrome behavior has been verified across Chrome 69, 70, 75, 77,
88, 100, 122, 125, 126, 134, 139.

The auto-reload case of the "real Chrome" test in Chrome 134 requires
manual intervention in the form of visiting chrome://extensions/,
enabling 'Developer Mode' and then manually reloading the extension, for
the following reasons:

- The bundled "web-ext Reload Manager Extension" uses Manifest Version
  2, which is disabled by default in recent Chrome.

- When 'Developer Mode' is off (by default), an attempt to reload
  extensions that were loaded with --load-extension causes the extension
  to be disabled.

These two issues will be resolved once we switch to the new CDP-based
method of loading Chrome extensions.
The new CDP-based chrome extension loader does not need WebSockets to
manage extension reloading logic. This patch removes all traces of
WebSocket based extension reloading from web-ext, including unit tests
that tested WebSocket-specific logic.

The following commits will restore this functionality using CDP.
This is a re-implementation of auto-reload support in Chrome,
by opening chrome://extensions/ and using a private API.
It has been confirmed to work with Chrome 69 until 139.

The functional unit tests only work in Chrome 75 until 133:
- Chrome 74 and earlier do not support MV3 background service_worker,
  and the test extension uses it. Rewriting the extension to the MV2
  variant causes it to pass in Chrome 69.
- Chrome 134 disables unpacked extensions upon reload when Developer
  Mode is disabled: https://issues.chromium.org/issues/362756477

The next commit will introduce a more reliable mechanism of reloading
extensions, using the same mechanism as loading the extension, which
works in Chrome 126+.

Tested as follows for various relevant versions of Chromium:
CHROME_PATH=/path/to/chrome75/chromium TEST_LOG_VERBOSE=1 TEST_WEBEXT_USE_REAL_CHROME=1 ./node_modules/.bin/mocha tests/functional/test.cli.run-target-chromium.js --grep='with auto-reload run real'

Unit tests with fake Chrome binary that simulates the real binary:
./node_modules/.bin/mocha tests/functional/test.cli.run-target-chromium.js --grep=auto-reload

Pre-existing unit test that tested web-ext internals:
./node_modules/.bin/mocha tests/unit/test-extension-runners/test.chromium.js
This finalizes the work needed to get `web-ext run -t chromium`
working again in Chrome 137+, following the deprecation of the
previously used `--load-extension` flag as announced at
https://groups.google.com/a/chromium.org/g/chromium-extensions/c/aEHdhDZ-V0E/m/UWP4-k32AgAJ

This patch uses the `Extensions.loadUnpacked` CDP command to achieve
this, and falls back to `--load-extension` when it detects the lack of
support for the `Extensions.loadUnpacked` CDP command.

This has been verified with Chrome 69+ (released 7 years ago). The
function unit tests work with Chrome 75+ due to MV3, as explained in an
earlier commit message.

Functional verification (tested Chrome 69, 125, 126, 131, 138, 139):
CHROME_PATH=/path/to/chrome69/chromium TEST_WEBEXT_USE_REAL_CHROME=1 ./node_modules/.bin/mocha tests/functional/test.cli.run-target-chromium.js

Unit tests (internals):
./node_modules/.bin/mocha tests/unit/test-extension-runners/test.chromium.js
When auto-reload is enabled, and the developer accidentally breaks the
extension, then web-ext will try to reload the extension, which causes
it to be disabled in the browser. In the case of Chrome, the new
CDP-based method can successfully reload the extension (Chrome 126+).

The fallback for older Chrome does not work. This patch adds test
coverage for that scenario, and updates the fake-chrome-binary to
accurately simulate that scenario.

Tested with real Chrome 75, 131, 138, 139.

CHROME_PATH=/path/to/chrome75/chromium TEST_WEBEXT_USE_REAL_CHROME=1 ./node_modules/.bin/mocha tests/functional/test.cli.run-target-chromium.js
Copy link
Member

@willdurand willdurand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me, thanks!

@willdurand willdurand removed the request for review from rpl June 19, 2025 13:13
@Rob--W Rob--W merged commit b5e0e25 into mozilla:master Jun 19, 2025
4 checks passed
@Rob--W
Copy link
Member Author

Rob--W commented Jun 19, 2025

This PR is part of the 8.8.0 release (https://github.com/mozilla/web-ext/releases/tag/8.8.0).

It is possible for websites to treat the launched Chrome differently when they check navigator.webdriver as explained in #3388 (comment)

A work-around to that is to use web-ext run -t chromium --args=--disable-blink-features=AutomationControlled

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.

Replace deprecated --load-extension with Extensions.loadUnpacked CDP to continue "web-ext run" support in Chrome
2 participants