Bug 1947678 - [webdriver-bidi] Install web extensions temporary by default and add "moz:permanent" flag. r=webdriver-reviewers,jdescottes

Differential Revision: https://phabricator.services.mozilla.com/D243384
This commit is contained in:
Henrik Skupin
2025-04-01 17:48:57 +00:00
parent 76dc51f7ca
commit 24696a73a7
8 changed files with 145 additions and 11 deletions

View File

@@ -60,8 +60,12 @@ WebDriver BiDi
--------------
`The WebDriver BiDi specification <https://w3c.github.io/webdriver-bidi>`_
extends WebDriver HTTP to add bidirectional communication. Dedicated
documentation will be added as the Firefox implementation makes progress.
extends WebDriver HTTP to add bidirectional communication.
.. toctree::
:maxdepth: 1
webdriver-bidi/Extensions.md
Architecture
============

View File

@@ -0,0 +1,24 @@
# Extensions
The WebDriver BiDi specification provides a flexible framework that allows browser vendors to define custom modules and arguments. This document outlines the Firefox-specific extensions implemented in WebDriver BiDi, including any custom functionality beyond the core specification.
## Modules
There are currently no custom modules defined in the Firefox implementation of WebDriver BiDi.
## Parameters
Firefox provides additional parameters for certain commands, as detailed in the list below.
### webExtension.install
```CDDL
webExtension.InstallParameters = {
extensionData: webExtension.ExtensionData,
? moz:permanent: bool .default false,
}
```
Description:
* `moz:permanent`: When set to `true`, the web extension will be installed permanently. This requires the extension to be signed. Unsigned extensions can only be installed temporarily, which is the default behavior.

View File

@@ -83,6 +83,8 @@ class WebExtensionModule extends RootBiDiModule {
* @param {object=} options
* @param {ExtensionArchivePath|ExtensionPath|ExtensionBase64} options.extensionData
* The WebExtension to be installed.
* @param {boolean=} options.moz_permanent (moz:permanent)
* If true, install the web extension permanently. Defaults to `false`.
*
* @returns {InstallResult}
* The id of the installed WebExtension.
@@ -93,7 +95,7 @@ class WebExtensionModule extends RootBiDiModule {
* Tried to install an invalid WebExtension.
*/
async install(options = {}) {
const { extensionData } = options;
const { extensionData, "moz:permanent": permanent = false } = options;
lazy.assert.object(
extensionData,
@@ -110,6 +112,11 @@ class WebExtensionModule extends RootBiDiModule {
lazy.pprint`got ${type}`
)(type);
lazy.assert.boolean(
permanent,
lazy.pprint`Expected "moz:permanent" to be a boolean, got ${permanent}`
);
let extensionId;
switch (type) {
@@ -119,7 +126,11 @@ class WebExtensionModule extends RootBiDiModule {
lazy.pprint`Expected "extensionData.value" to be a string, got ${value}`
);
extensionId = await lazy.Addon.installWithBase64(value, false, false);
extensionId = await lazy.Addon.installWithBase64(
value,
!permanent,
false
);
break;
case ExtensionDataType.ArchivePath:
case ExtensionDataType.Path:
@@ -128,7 +139,7 @@ class WebExtensionModule extends RootBiDiModule {
lazy.pprint`Expected "extensionData.path" to be a string, got ${path}`
);
extensionId = await lazy.Addon.installWithPath(path, false, false);
extensionId = await lazy.Addon.installWithPath(path, !permanent, false);
}
return {

View File

@@ -1,9 +1,10 @@
[install.py]
[test_install_from_path]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1947684
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_from_archive_path]
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL

View File

@@ -0,0 +1,30 @@
[moz_permanent.py]
[test_install_with_permanent[archivePath-default\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_with_permanent[archivePath-permanent\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_with_permanent[archivePath-temporary\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_with_permanent[path-default\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_with_permanent[path-permanent\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL
[test_install_with_permanent[path-temporary\]]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066
expected:
if os == "android": FAIL

View File

@@ -0,0 +1,18 @@
import pytest
from webdriver.bidi import error
pytestmark = pytest.mark.asyncio
@pytest.mark.parametrize("value", ["", 42, [], {}])
async def test_params_moz_permanent_invalid_type(bidi_session, extension_data, value):
kwargs = {"moz:permanent": value}
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extension_data={
"type": "base64",
"value": extension_data["base64"],
},
**kwargs
)

View File

@@ -0,0 +1,46 @@
import pytest
from support.addons import is_addon_temporary_installed
from tests.bidi.web_extension import assert_extension_id
from webdriver.bidi import error
pytestmark = pytest.mark.asyncio
@pytest.mark.allow_system_access
@pytest.mark.parametrize(
"permanent", [None, False, True], ids=["default", "temporary", "permanent"]
)
@pytest.mark.parametrize("mode", ["archivePath", "base64", "path"])
async def test_install_with_permanent(
bidi_session, current_session, extension_data, mode, permanent
):
data = {"type": mode}
if mode == "base64":
data.update({"value": extension_data[mode]})
else:
data.update({"path": extension_data[mode]})
kwargs = {"moz:permanent": permanent} if permanent is not None else {}
if mode == "path" and permanent:
# Only signed webextensions in XPI format can be installed permanently
with pytest.raises(error.InvalidWebExtensionException):
await bidi_session.web_extension.install(
extension_data=data,
**kwargs,
)
return
web_extension = await bidi_session.web_extension.install(
extension_data=data,
**kwargs,
)
try:
assert_extension_id(web_extension, extension_data)
assert is_addon_temporary_installed(current_session, web_extension) is not bool(
permanent
)
finally:
# Clean up the extension.
await bidi_session.web_extension.uninstall(extension=web_extension)