Backed out 3 changesets (bug 1934551, bug 1934553) for causing remote failures @ browser_Addon.js CLOSED TREE

Backed out changeset 6b0eb519cda0 (bug 1934553)
Backed out changeset 0194b87bcb08 (bug 1934553)
Backed out changeset d41a6261a338 (bug 1934551)
This commit is contained in:
Sandor Molnar
2025-02-13 20:41:43 +02:00
parent 9a33cd620e
commit e1b88b4302
22 changed files with 7 additions and 514 deletions

View File

@@ -53,8 +53,9 @@ async function installAddon(file, temporary, allowPrivateBrowsing) {
}
}
} catch (e) {
throw new lazy.error.InvalidWebExtensionError(
`Could not install Add-on: ${e.message}`
throw new lazy.error.UnknownError(
`Could not install add-on: ${e.message}`,
e
);
}
@@ -178,26 +179,22 @@ export class Addon {
*
* @throws {UnknownError}
* If there is a problem uninstalling the addon.
* @throws {NoSuchWebExtensionError}
* Raised if the WebExtension with provided id could not be found.
*/
static async uninstall(id) {
let candidate = await lazy.AddonManager.getAddonByID(id);
if (candidate === null) {
// `AddonManager.getAddonByID` never rejects but instead
// returns `null` if the requested addon cannot be found.
throw new lazy.error.NoSuchWebExtensionError(
`Add-on with ID "${id}" is not installed.`
);
throw new lazy.error.UnknownError(`Addon ${id} is not installed`);
}
return new Promise((resolve, reject) => {
return new Promise(resolve => {
let listener = {
onOperationCancelled: addon => {
if (addon.id === candidate.id) {
lazy.AddonManager.removeAddonListener(listener);
throw new lazy.error.UnknownError(
`Uninstall of Add-on with ID "${candidate.id}" was canceled.`
`Uninstall of ${candidate.id} has been canceled`
);
}
},
@@ -211,14 +208,7 @@ export class Addon {
};
lazy.AddonManager.addAddonListener(listener);
candidate.uninstall().catch(e => {
lazy.AddonManager.removeAddonListener(listener);
reject(
new lazy.error.UnknownError(
`Failed to uninstall Add-on with ID "${id}": ${e.message}`
)
);
});
candidate.uninstall();
});
}
}

View File

@@ -21,7 +21,6 @@ const ERRORS = new Set([
"InvalidElementStateError",
"InvalidSelectorError",
"InvalidSessionIDError",
"InvalidWebExtensionError",
"JavaScriptError",
"MoveTargetOutOfBoundsError",
"NoSuchAlertError",
@@ -35,7 +34,6 @@ const ERRORS = new Set([
"NoSuchScriptError",
"NoSuchShadowRootError",
"NoSuchUserContextError",
"NoSuchWebExtensionError",
"NoSuchWindowError",
"ScriptTimeoutError",
"SessionNotCreatedError",
@@ -464,22 +462,6 @@ class InvalidSessionIDError extends WebDriverError {
}
}
/**
* Tried to install an invalid web extension.
*
* @param {(string|Error)=} obj
* Optional string describing error situation or Error instance
* to propagate.
* @param {object=} data
* Additional error data helpful in diagnosing the error.
*/
class InvalidWebExtensionError extends WebDriverError {
constructor(obj, data = {}) {
super(obj, data);
this.status = "invalid web extension";
}
}
/**
* An error occurred whilst executing JavaScript supplied by the user.
*
@@ -709,22 +691,6 @@ class NoSuchUserContextError extends WebDriverError {
}
}
/**
* A command tried to reference an unknown web extension.
*
* @param {(string|Error)=} obj
* Optional string describing error situation or Error instance
* to propagate.
* @param {object=} data
* Additional error data helpful in diagnosing the error.
*/
class NoSuchWebExtensionError extends WebDriverError {
constructor(obj, data = {}) {
super(obj, data);
this.status = "no such web extension";
}
}
/**
* A command to switch to a window could not be satisfied because
* the window could not be found.
@@ -933,7 +899,6 @@ const STATUSES = new Map([
["invalid element state", InvalidElementStateError],
["invalid selector", InvalidSelectorError],
["invalid session id", InvalidSessionIDError],
["invalid web extension", InvalidWebExtensionError],
["javascript error", JavaScriptError],
["move target out of bounds", MoveTargetOutOfBoundsError],
["no such alert", NoSuchAlertError],
@@ -947,7 +912,6 @@ const STATUSES = new Map([
["no such script", NoSuchScriptError],
["no such shadow root", NoSuchShadowRootError],
["no such user context", NoSuchUserContextError],
["no such web extension", NoSuchWebExtensionError],
["no such window", NoSuchWindowError],
["script timeout", ScriptTimeoutError],
["session not created", SessionNotCreatedError],

View File

@@ -19,7 +19,6 @@ const errors = [
error.InvalidElementStateError,
error.InvalidSelectorError,
error.InvalidSessionIDError,
error.InvalidWebExtensionError,
error.JavaScriptError,
error.MoveTargetOutOfBoundsError,
error.NoSuchAlertError,
@@ -361,14 +360,6 @@ add_task(function test_InvalidSessionIDError() {
ok(err instanceof error.WebDriverError);
});
add_task(function test_InvalidWebExtensionError() {
let err = new error.InvalidWebExtensionError("foo");
equal("InvalidWebExtensionError", err.name);
equal("foo", err.message);
equal("invalid web extension", err.status);
ok(err instanceof error.WebDriverError);
});
add_task(function test_JavaScriptError() {
let err = new error.JavaScriptError("foo");
equal("JavaScriptError", err.name);
@@ -472,14 +463,6 @@ add_task(function test_NoSuchUserContextError() {
ok(err instanceof error.WebDriverError);
});
add_task(function test_NoSuchWebExtensionError() {
let err = new error.NoSuchWebExtensionError("foo");
equal("NoSuchWebExtensionError", err.name);
equal("foo", err.message);
equal("no such web extension", err.status);
ok(err instanceof error.WebDriverError);
});
add_task(function test_NoSuchWindowError() {
let err = new error.NoSuchWindowError("foo");
equal("NoSuchWindowError", err.name);

View File

@@ -26,7 +26,6 @@ remote.jar:
content/webdriver-bidi/modules/root/script.sys.mjs (modules/root/script.sys.mjs)
content/webdriver-bidi/modules/root/session.sys.mjs (modules/root/session.sys.mjs)
content/webdriver-bidi/modules/root/storage.sys.mjs (modules/root/storage.sys.mjs)
content/webdriver-bidi/modules/root/webExtension.sys.mjs (modules/root/webExtension.sys.mjs)
# WebDriver BiDi windowglobal modules
content/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs (modules/windowglobal/browsingContext.sys.mjs)

View File

@@ -25,8 +25,6 @@ ChromeUtils.defineESModuleGetters(modules.root, {
"chrome://remote/content/webdriver-bidi/modules/root/session.sys.mjs",
storage:
"chrome://remote/content/webdriver-bidi/modules/root/storage.sys.mjs",
webExtension:
"chrome://remote/content/webdriver-bidi/modules/root/webExtension.sys.mjs",
});
// eslint-disable-next-line mozilla/lazy-getter-object-name

View File

@@ -1,167 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { RootBiDiModule } from "chrome://remote/content/webdriver-bidi/modules/RootBiDiModule.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
Addon: "chrome://remote/content/shared/Addon.sys.mjs",
assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs",
pprint: "chrome://remote/content/shared/Format.sys.mjs",
});
/**
* A WebExtension id.
*
* @typedef {string} Extension
*/
/**
* Return value of the install command.
*
* @typedef InstallResult
*
* @property {Extension} extension
*/
/**
* Enum of types supported by the webExtension.install command.
*
* @readonly
* @enum {ExtensionDataType}
*/
export const ExtensionDataType = {
Path: "path",
ArchivePath: "archivePath",
Base64: "base64",
};
/**
* Used as an argument for webExtension.install command
* to represent a WebExtension archive.
*
* @typedef ExtensionArchivePath
*
* @property {ExtensionDataType} [type=ExtensionDataType.ArchivePath]
* @property {string} path
*/
/**
* Used as an argument for webExtension.install command
* to represent an unpacked WebExtension.
*
* @typedef ExtensionPath
*
* @property {ExtensionDataType} [type=ExtensionDataType.Path]
* @property {string} path
*/
/**
* Used as an argument for webExtension.install command
* to represent a WebExtension archive encoded as base64 string.
*
* @typedef ExtensionBase64
*
* @property {ExtensionDataType} [type=ExtensionDataType.Base64]
* @property {string} value
*/
class WebExtensionModule extends RootBiDiModule {
constructor(messageHandler) {
super(messageHandler);
}
destroy() {}
/**
* Installs a WebExtension.
*
* @see https://w3c.github.io/webdriver-bidi/#command-webExtension-install
*
* @param {object=} options
* @param {ExtensionArchivePath|ExtensionPath|ExtensionBase64} options.extensionData
* The WebExtension to be installed.
*
* @returns {InstallResult}
* The id of the installed WebExtension.
*
* @throws {InvalidArgumentError}
* Raised if an argument is of an invalid type or value.
* @throws {InvalidWebExtensionError}
* Tried to install an invalid WebExtension.
*/
async install(options = {}) {
const { extensionData } = options;
lazy.assert.object(
extensionData,
`Expected "extensionData" to be an object, ` +
lazy.pprint`got ${extensionData}`
);
const { path, type, value } = extensionData;
const extensionDataTypes = Object.values(ExtensionDataType);
lazy.assert.that(
extensionDataType => extensionDataTypes.includes(extensionDataType),
`Expected "extensionData.type" to be one of ${extensionDataTypes}, ` +
lazy.pprint`got ${type}`
)(type);
let extensionId;
switch (type) {
case ExtensionDataType.Base64:
lazy.assert.string(
value,
lazy.pprint`Expected "extensionData.value" to be a string, got ${value}`
);
extensionId = await lazy.Addon.installWithBase64(value, false, false);
break;
case ExtensionDataType.ArchivePath:
case ExtensionDataType.Path:
lazy.assert.string(
path,
lazy.pprint`Expected "extensionData.path" to be a string, got ${path}`
);
extensionId = await lazy.Addon.installWithPath(path, false, false);
}
return {
extension: extensionId,
};
}
/**
* Uninstalls a WebExtension.
*
* @see https://w3c.github.io/webdriver-bidi/#command-webExtension-uninstall
*
* @param {object=} options
* @param {Extension} options.extension
* The id of the WebExtension to be uninstalled.
*
* @throws {InvalidArgumentError}
* Raised if an argument is of an invalid type or value.
* @throws {NoSuchWebExtensionError}
* Raised if the WebExtension with provided id could not be found.
* @throws {UnknownError}
* Raised if the WebExtension cannot be uninstalled.
*/
async uninstall(options = {}) {
const { extension: addonId } = options;
lazy.assert.string(
addonId,
lazy.pprint`Expected "extension" to be a string, got ${addonId}`
);
await lazy.Addon.uninstall(addonId);
}
}
export const webExtension = WebExtensionModule;

View File

@@ -1,9 +0,0 @@
[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
[test_install_from_archive_path]
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066

View File

@@ -1,7 +0,0 @@
[invalid.py]
[test_params_extension_data_path_invalid_webextension]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1947683
expected: FAIL
[test_params_extension_data_archive_path_invalid_webextension]
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1762066

View File

@@ -99,7 +99,6 @@ class BidiSession:
self.script = modules.Script(self)
self.session = modules.Session(self)
self.storage = modules.Storage(self)
self.web_extension = modules.WebExtension(self)
@property
def event_loop(self):

View File

@@ -43,10 +43,6 @@ class InvalidSessionIDError(BidiException):
error_code = "invalid session id"
class InvalidWebExtensionException(BidiException):
error_code = "invalid web extension"
class MoveTargetOutOfBoundsException(BidiException):
error_code = "move target out of bounds"
@@ -91,10 +87,6 @@ class NoSuchUserContextException(BidiException):
error_code = "no such user context"
class NoSuchWebExtensionException(BidiException):
error_code = "no such web extension"
class UnableToCaptureScreenException(BidiException):
error_code = "unable to capture screen"

View File

@@ -9,4 +9,3 @@ from .permissions import Permissions
from .script import Script
from .session import Session
from .storage import Storage
from .web_extension import WebExtension

View File

@@ -1,18 +0,0 @@
from typing import Any, Mapping, MutableMapping
from ._module import BidiModule, command
class WebExtension(BidiModule):
@command
def install(self, extensionData: Mapping[str, Any]) -> Mapping[str, Any]:
params: MutableMapping[str, Any] = { "extensionData": extensionData }
return params
@install.result
def _install(self, result: Mapping[str, Any]) -> str:
return result.get("extension")
@command
def uninstall(self, extension: str):
params: MutableMapping[str, Any] = { "extension": extension }
return params

View File

@@ -1,50 +0,0 @@
import pytest
from tests.support.helpers import get_addon_path, get_base64_for_addon_file
EXTENSION_ID = "{d3e7c1f1-2e35-4a49-89fe-9f46eb8abf0a}"
@pytest.mark.asyncio
async def test_install_from_base64(bidi_session):
web_extension = await bidi_session.web_extension.install(
extensionData={
"type": "base64",
"value": get_base64_for_addon_file("webextension-unsigned.xpi")
}
)
try:
assert web_extension == EXTENSION_ID
finally:
# Clean up the addon.
await bidi_session.web_extension.uninstall(extension=web_extension)
@pytest.mark.asyncio
async def test_install_from_path(bidi_session):
web_extension = await bidi_session.web_extension.install(
extensionData={
"type": "path",
"path": get_addon_path("unpacked")
}
)
try:
assert web_extension == EXTENSION_ID
finally:
# Clean up the addon.
await bidi_session.web_extension.uninstall(extension=web_extension)
@pytest.mark.asyncio
async def test_install_from_archive_path(bidi_session):
web_extension = await bidi_session.web_extension.install(
extensionData={
"type": "archivePath",
"path": get_addon_path("webextension-unsigned.xpi")
}
)
try:
assert web_extension == EXTENSION_ID
finally:
# Clean up the addon.
await bidi_session.web_extension.uninstall(extension=web_extension)

View File

@@ -1,106 +0,0 @@
import pytest
import webdriver.bidi.error as error
from tests.support.helpers import get_addon_path
pytestmark = pytest.mark.asyncio
@pytest.mark.parametrize("value", [None, False, 42, [], ""])
async def test_params_extension_data_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData=value
)
async def test_params_extension_data_invalid_value(bidi_session):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={}
)
@pytest.mark.parametrize("value", [None, False, 42, {}, []])
async def test_params_extension_data_type_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": value }
)
@pytest.mark.parametrize("value", ["", "unknown-type"])
async def test_params_extension_data_type_invalid_value(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": value }
)
@pytest.mark.parametrize("value", ["path", "archivePath"])
async def test_params_extension_data_path_missing(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": value }
)
@pytest.mark.parametrize("value", [None, False, 42, {}, []])
@pytest.mark.parametrize("data_type", ["path", "archivePath"])
async def test_params_extension_data_path_invalid_type(bidi_session, data_type, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": data_type, "path": value }
)
@pytest.mark.parametrize("value", ["", "invalid path"])
@pytest.mark.parametrize("data_type", ["path", "archivePath"])
async def test_params_extension_data_path_invalid_value(bidi_session, data_type, value):
with pytest.raises(error.UnknownErrorException):
await bidi_session.web_extension.install(
extensionData={ "type": data_type, "path": value }
)
async def test_params_extension_data_archive_path_invalid_webextension(bidi_session):
with pytest.raises(error.InvalidWebExtensionException):
await bidi_session.web_extension.install(
extensionData={ "type": "archivePath", "path": get_addon_path("unpacked") }
)
async def test_params_extension_data_path_invalid_webextension(bidi_session):
with pytest.raises(error.InvalidWebExtensionException):
await bidi_session.web_extension.install(
extensionData={ "type": "path", "path": get_addon_path("webextension-unsigned.xpi") }
)
async def test_params_extension_data_value_missing(bidi_session):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": "base64" }
)
@pytest.mark.parametrize("value", [None, False, 42, {}, []])
async def test_params_extension_data_value_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.install(
extensionData={ "type": "base64", "value": value }
)
async def test_params_extension_data_value_invalid_value(bidi_session):
with pytest.raises(error.UnknownErrorException):
await bidi_session.web_extension.install(
extensionData={ "type": "base64", "value": "not a base64" }
)
@pytest.mark.parametrize("value", ["", "dGVzdA=="])
async def test_params_extension_data_value_invalid_webextension(bidi_session, value):
with pytest.raises(error.InvalidWebExtensionException):
await bidi_session.web_extension.install(
extensionData={ "type": "base64", "value": value }
)

View File

@@ -1,26 +0,0 @@
import pytest
import webdriver.bidi.error as error
pytestmark = pytest.mark.asyncio
async def test_uninstall_missing_addon(bidi_session):
with pytest.raises(error.NoSuchWebExtensionException):
await bidi_session.web_extension.uninstall(
extension="test"
)
@pytest.mark.parametrize("value", [None, False, 42, {}, []])
async def test_params_extension_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.web_extension.uninstall(
extension=value
)
async def test_params_extension_invalid_value(bidi_session):
with pytest.raises(error.UnknownErrorException):
await bidi_session.web_extension.uninstall(
extension=""
)

View File

@@ -1,21 +0,0 @@
import pytest
import webdriver.bidi.error as error
from tests.support.helpers import get_base64_for_addon_file
@pytest.mark.asyncio
async def test_uninstall(bidi_session):
web_extension = await bidi_session.web_extension.install(
extensionData={
"type": "base64",
"value": get_base64_for_addon_file("webextension-unsigned.xpi")
}
)
await bidi_session.web_extension.uninstall(
extension=web_extension
)
# proof that the uninstall was successful
with pytest.raises(error.NoSuchWebExtensionException):
await bidi_session.web_extension.uninstall(
extension=web_extension
)

View File

@@ -1,4 +1,3 @@
import base64
import collections
import math
import sys
@@ -299,17 +298,3 @@ def wait_for_new_handle(session, handles_before):
message="No new window has been opened")
return wait.until(find_new_handle)
def get_addon_path(filename):
return os.path.join(
os.path.abspath(os.path.dirname(__file__)), "webextensions", filename
)
def get_base64_for_addon_file(filename):
with open(
get_addon_path(filename),
"rb",
) as file:
return base64.b64encode(file.read()).decode("utf-8")

View File

@@ -1,12 +0,0 @@
{
"manifest_version": 3,
"name": "install test",
"description": "install test",
"key": "{d3e7c1f1-2e35-4a49-89fe-9f46eb8abf0a}",
"version": "1.0",
"browser_specific_settings": {
"gecko": {
"id": "{d3e7c1f1-2e35-4a49-89fe-9f46eb8abf0a}"
}
}
}