This project is a self-contained Manifest V3 (MV3) Webextension that tests the extension APIs available in supported browsers against some expectations of how these APIs should behave. These expectations are largely based on the current Chrome Extension API Documentation, and the current defacto standard implementation in Chrome.
The purpose of this project is to document API differences across browsers, both for other extension developers, and to encourage convergence to consistent and compatbility Webextension API implementations.
You can load this extension in MV3 compatible browsers as follows:
- Open
chrome://extensions/
. - Toggle 'Developer mode' in the top right corner.
- Click 'Load unpacked', navigate to the
mv3-compat-tests/Shared (Extension)/Resources/
folder, and chose select. - The tests should automatically open and start running. The test page can also be re-opened by clicking the extension's action icon.
- Open
mv3-compat-tests.xcodeproj
in Xcode. - Run
mv3-compat-tests (macOS)
target. - Go to Safari settings -> Extensions and enable
mv3-compat-tests
. - Click
Edit Websites...
and grant permissions for all websites to the extension. - If the tests don't open automatically, click the extension's action icon to start them.
- Edit
manifest.json
, adding"scripts": ["background.js"]
underneath theservice_worker
line. - Navigate to
about:debugging
- Click 'Load Temporary Add-on...' and navigate to the
mv3-compat-tests/Shared (Extension)/Resources/
folder and selectmanifest.json
. - Go to
about:addons
, find 'mv3-compat-tests', click on the '...' menu and select 'Manage'. - Go to the 'Permissions' tab and check 'Access your data for all websites' under Optional permissions.
- Go back to
about:debugging
and click the 'Manifest URL' link. On that page, change the path totest.html
.
The tests currently cover parts of the scripting
and declarativeNetRequest
APIs that are relevant to the
duckduckgo-privacy-extension. The purpose is
to surface issues we've found testing MV3 APIs across platforms.
Current status table (only failing tests shown):
Test | Chrome 110 | Safari 17.2 | Safari Tech Preview 188 | Firefox Nightly 122 |
---|---|---|---|---|
scripting.executeScript : Returns an array of InjectionResult |
✅ | ✅ (fixed in Safari 17)1 | ✅ | ❌ |
scripting.registerContentScripts : Can register content-scripts at document_start |
✅ | ✅ (fixed in Safari 17)2 | ✅ | ❌3 |
declarativeNetRequest : requestDomains condition triggers on matched domains |
✅ | ❌4 | ❌ | ❌3 |
declarativeNetRequest : allowAllRequests disables static blocking rules when document URL matches |
✅ | ✅ (fixed in Safari 17.2) | ✅ | ❌3 |
declarativeNetRequest : allowAllRequests rules work when removeRuleIds is used in the same updateDynamicRules call |
✅ | ✅ | ✅ | ❌3 |
declarativeNetRequest : redirect to extension image url with anchored urlFilter |
✅ | ✅ | ✅ | ❌ |
declarativeNetRequest : queryTransform can add search parameters in main_frame requests |
✅ | ❌ | ❌ | ✅ |
declarativeNetRequest : modifyHeaders can add a Sec-GPC header |
✅ | ❌5 | ❌ | ✅ |
declarativeNetRequest : 'initiatorDomains' condition limits matches to requests initiated by matching domain |
✅ | ❌6 | ❌ | ❌3 |
declarativeNetRequest : 'initiatorDomains' condition list matches initators' subdomains |
✅ | ❌[^8] | ❌ | ❌3 |
declarativeNetRequest : 'domains' condition list matches initators' subdomains |
✅ | ✅ | ✅ | ❌7 |
declarativeNetRequest : redirect supports regexSubstitution |
✅ | ❌ | ❌ | ✅ |
Footnotes
-
This failure is due to this API not returning the result of
func
, the function passed to the script injection back to the background context. Instead, an array ofnull
is returned. ↩ -
"chrome.scripting.registerContentScripts is not a function". This API is not yet implemented in Safari 16.3. ↩
-
world
parameter ofscripting.registerContentScripts
is not supported in Firefox - this prevents many other tests from running, as we use a content-script as part of the test-suite. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
Rules using the
requestDomains
condition are not supported. ↩ -
Invalid call to declarativeNetRequest.updateDynamicRules(). Error with rule at index 0: Rule with id 5 is invalid.
modifyHeaders
is not a supported action type".modifyHeaders
is not supported. ↩ -
This option is only supported under the legacy 'domains' property. ↩
-
domains
condition for DNR is not supported in Firefox. ↩