summaryrefslogtreecommitdiffstats
path: root/browser/modules/test
diff options
context:
space:
mode:
Diffstat (limited to 'browser/modules/test')
-rw-r--r--browser/modules/test/browser/browser.toml4
-rw-r--r--browser/modules/test/browser/browser_ProcessHangNotifications.js2
-rw-r--r--browser/modules/test/browser/browser_UnsubmittedCrashHandler.js6
-rw-r--r--browser/modules/test/browser/browser_UsageTelemetry_interaction.js206
-rw-r--r--browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js461
-rw-r--r--browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js115
6 files changed, 591 insertions, 203 deletions
diff --git a/browser/modules/test/browser/browser.toml b/browser/modules/test/browser/browser.toml
index 21b3cdf18c..82611ed4b2 100644
--- a/browser/modules/test/browser/browser.toml
+++ b/browser/modules/test/browser/browser.toml
@@ -36,6 +36,10 @@ support-files = [
"../../../base/content/test/tabs/file_mediaPlayback.html",
"../../../base/content/test/general/audio.ogg",
]
+skip-if = [
+ "os == 'linux' && os_version == '18.04' && asan", # Bug 1781868
+ "os == 'linux' && os_version == '18.04' && tsan", # Bug 1781868
+]
["browser_Telemetry_numberOfSiteOrigins.js"]
support-files = ["contain_iframe.html"]
diff --git a/browser/modules/test/browser/browser_ProcessHangNotifications.js b/browser/modules/test/browser/browser_ProcessHangNotifications.js
index 9150c36d4c..963dc2d4b4 100644
--- a/browser/modules/test/browser/browser_ProcessHangNotifications.js
+++ b/browser/modules/test/browser/browser_ProcessHangNotifications.js
@@ -184,7 +184,7 @@ add_task(async function waitForScriptTest() {
});
// Click the "Close" button this time, we shouldn't get a callback at all.
- notification.currentNotification.closeButtonEl.click();
+ notification.currentNotification.closeButton.click();
// send another hang pulse, we should not get a notification here
Services.obs.notifyObservers(hangReport, "process-hang-report");
diff --git a/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js b/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
index 6300bd17ba..d105e8374e 100644
--- a/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
+++ b/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
@@ -292,7 +292,7 @@ add_task(async function test_other_ignored() {
Assert.ok(notification, "There should be a notification");
// Dismiss notification, creating the .dmp.ignore file
- notification.closeButtonEl.click();
+ notification.closeButton.click();
gNotificationBox.removeNotification(notification, true);
await waitForIgnoredReports(toIgnore);
@@ -525,7 +525,7 @@ add_task(async function test_can_ignore() {
Assert.ok(notification, "There should be a notification");
// Dismiss the notification by clicking on the "X" button.
- notification.closeButtonEl.click();
+ notification.closeButton.click();
// We'll not wait for the notification to finish its transition -
// we'll just remove it right away.
gNotificationBox.removeNotification(notification, true);
@@ -599,7 +599,7 @@ add_task(async function test_shutdown_while_not_showing() {
Assert.ok(notification, "There should be a notification");
// Dismiss the notification by clicking on the "X" button.
- notification.closeButtonEl.click();
+ notification.closeButton.click();
// We'll not wait for the notification to finish its transition -
// we'll just remove it right away.
gNotificationBox.removeNotification(notification, true);
diff --git a/browser/modules/test/browser/browser_UsageTelemetry_interaction.js b/browser/modules/test/browser/browser_UsageTelemetry_interaction.js
index 5fa436a349..56a7f530ad 100644
--- a/browser/modules/test/browser/browser_UsageTelemetry_interaction.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_interaction.js
@@ -33,6 +33,8 @@ const AREAS = [
// keys in the scalars. Also runs keyed scalar checks against non-area types
// passed in through expectedOther.
function assertInteractionScalars(expectedAreas, expectedOther = {}) {
+ // Every time this checks Scalars, it clears them. So clear FOG too.
+ Services.fog.testResetFOG();
let processScalars =
Services.telemetry.getSnapshotForKeyedScalars("main", true)?.parent ?? {};
@@ -83,6 +85,7 @@ add_task(async function toolbarButtons() {
});
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
let tabClose = BrowserTestUtils.waitForTabClosing(newTab);
@@ -164,6 +167,22 @@ add_task(async function toolbarButtons() {
click(customButton);
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "stop-reload-button"],
+ ["nav-bar", "back-button"],
+ ["nav-bar", "back-button"],
+ ["all-tabs-panel-entrypoint", "alltabs-button"],
+ ["tabs-bar", "alltabs-button"],
+ ["tabs-bar", "tab-close-button"],
+ ["bookmarks-bar", "bookmark-item"],
+ ["nav-bar", "12foo"],
+ ],
+ events
+ );
assertInteractionScalars(
{
nav_bar: {
@@ -192,6 +211,7 @@ add_task(async function toolbarButtons() {
add_task(async function contextMenu() {
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
let tab = gBrowser.getTabForBrowser(browser);
let context = elem("tabContextMenu");
@@ -207,6 +227,16 @@ add_task(async function contextMenu() {
context.activateItem(document.getElementById("context_toggleMuteTab"));
await hidden;
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["tabs-context", "context-toggleMuteTab"],
+ ["tabs-context-entrypoint", "context-toggleMuteTab"],
+ ],
+ events
+ );
assertInteractionScalars({
tabs_context: {
"context-toggleMuteTab": 1,
@@ -233,6 +263,16 @@ add_task(async function contextMenu() {
);
await hidden;
+ events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["tabs-context", "toolbar-context-selectAllTabs"],
+ ["tabs-context-entrypoint", "toolbar-context-selectAllTabs"],
+ ],
+ events
+ );
assertInteractionScalars({
tabs_context: {
"toolbar-context-selectAllTabs": 1,
@@ -318,6 +358,7 @@ add_task(async function contextMenu_entrypoints() {
add_task(async function appMenu() {
await BrowserTestUtils.withNewTab("https://example.com", async () => {
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
let shown = BrowserTestUtils.waitForEvent(
elem("appMenu-popup"),
@@ -339,9 +380,21 @@ add_task(async function appMenu() {
nav_bar: {
"PanelUI-menu-button": 1,
},
- app_menu: {},
+ app_menu: {
+ [findButtonID]: 1,
+ },
};
- expectedScalars.app_menu[findButtonID] = 1;
+
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "PanelUI-menu-button"],
+ ["app-menu", findButtonID],
+ ],
+ events
+ );
assertInteractionScalars(expectedScalars);
});
@@ -350,6 +403,7 @@ add_task(async function appMenu() {
add_task(async function devtools() {
await BrowserTestUtils.withNewTab("https://example.com", async () => {
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
let shown = BrowserTestUtils.waitForEvent(
elem("appMenu-popup"),
@@ -381,6 +435,17 @@ add_task(async function devtools() {
BrowserTestUtils.removeTab(tab);
// Note that item ID's have '_' converted to '-'.
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "PanelUI-menu-button"],
+ ["app-menu", "appMenu-more-button2"],
+ ["app-menu", "key-viewSource"],
+ ],
+ events
+ );
assertInteractionScalars({
nav_bar: {
"PanelUI-menu-button": 1,
@@ -398,6 +463,7 @@ add_task(async function webextension() {
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
function background() {
browser.commands.onCommand.addListener(() => {
@@ -470,6 +536,11 @@ add_task(async function webextension() {
// As the first add-on interacted with this should show up as `addon0`.
click("random_addon_example_com-browser-action");
+ let events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["nav-bar", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
nav_bar: {
addon0: 1,
@@ -482,6 +553,11 @@ add_task(async function webextension() {
);
click("pageAction-urlbar-random_addon_example_com");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["pageaction-urlbar", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
pageaction_urlbar: {
addon0: 1,
@@ -490,6 +566,11 @@ add_task(async function webextension() {
EventUtils.synthesizeKey("j", { altKey: true, shiftKey: true });
await extension.awaitMessage("oncommand");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["keyboard", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
keyboard: {
addon0: 1,
@@ -498,6 +579,11 @@ add_task(async function webextension() {
EventUtils.synthesizeKey("q", { altKey: true, shiftKey: true });
await extension.awaitMessage("sidebar-opened");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["keyboard", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
keyboard: {
addon0: 1,
@@ -537,6 +623,11 @@ add_task(async function webextension() {
// A second extension should be `addon1`.
click("random_addon2_example_com-browser-action");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["nav-bar", "addon1"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
nav_bar: {
addon1: 1,
@@ -549,6 +640,11 @@ add_task(async function webextension() {
);
click("pageAction-urlbar-random_addon2_example_com");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["pageaction-urlbar", "addon1"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
pageaction_urlbar: {
addon1: 1,
@@ -557,6 +653,11 @@ add_task(async function webextension() {
EventUtils.synthesizeKey("9", { altKey: true, shiftKey: true });
await extension2.awaitMessage("oncommand");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["keyboard", "addon1"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
keyboard: {
addon1: 1,
@@ -565,6 +666,11 @@ add_task(async function webextension() {
// The first should have retained its ID.
click("random_addon_example_com-browser-action");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["nav-bar", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
nav_bar: {
addon0: 1,
@@ -573,6 +679,11 @@ add_task(async function webextension() {
EventUtils.synthesizeKey("j", { altKey: true, shiftKey: true });
await extension.awaitMessage("oncommand");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["keyboard", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
keyboard: {
addon0: 1,
@@ -580,6 +691,11 @@ add_task(async function webextension() {
});
click("pageAction-urlbar-random_addon_example_com");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["pageaction-urlbar", "addon0"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
pageaction_urlbar: {
addon0: 1,
@@ -590,11 +706,19 @@ add_task(async function webextension() {
// Clear the last opened ID so if this test runs again the sidebar won't
// automatically open when the extension is installed.
- window.SidebarUI.lastOpenedId = null;
+ window.SidebarController.lastOpenedId = null;
// The second should retain its ID.
click("random_addon2_example_com-browser-action");
click("random_addon2_example_com-browser-action");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [
+ ["nav-bar", "addon1"],
+ ["nav-bar", "addon1"],
+ ],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
nav_bar: {
addon1: 2,
@@ -602,6 +726,11 @@ add_task(async function webextension() {
});
click("pageAction-urlbar-random_addon2_example_com");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["pageaction-urlbar", "addon1"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
pageaction_urlbar: {
addon1: 1,
@@ -610,6 +739,11 @@ add_task(async function webextension() {
EventUtils.synthesizeKey("9", { altKey: true, shiftKey: true });
await extension2.awaitMessage("oncommand");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["keyboard", "addon1"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
keyboard: {
addon1: 1,
@@ -643,6 +777,11 @@ add_task(async function webextension() {
await shown;
click("random_addon3_example_com-browser-action");
+ events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["unified-extensions-area", "addon2"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
unified_extensions_area: {
addon2: 1,
@@ -669,6 +808,7 @@ add_task(async function mainMenu() {
await BrowserTestUtils.withNewTab("https://example.com", async () => {
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
CustomizableUI.setToolbarVisibility("toolbar-menubar", true);
@@ -686,6 +826,11 @@ add_task(async function mainMenu() {
click("menu_selectAll");
await hidden;
+ let events = Glean.browserUsage.interaction.testGetValue();
+ Assert.deepEqual(
+ [["menu-bar", "menu-selectAll"]],
+ events.map(e => [e.extra.source, e.extra.widget_id])
+ );
assertInteractionScalars({
menu_bar: {
// Note that the _ is replaced with - for telemetry identifiers.
@@ -706,6 +851,7 @@ add_task(async function preferences() {
await finalPrefPaneLoaded;
Services.telemetry.getSnapshotForKeyedScalars("main", true);
+ Services.fog.testResetFOG();
await BrowserTestUtils.synthesizeMouseAtCenter(
"#browserRestoreSession",
@@ -742,6 +888,16 @@ add_task(async function preferences() {
await onLearnMoreOpened;
gBrowser.removeCurrentTab();
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["preferences_paneGeneral", "browserRestoreSession"],
+ ["preferences_panePrivacy", "contentBlockingLearnMore"],
+ ],
+ events
+ );
assertInteractionScalars({
preferences_paneGeneral: {
browserRestoreSession: 1,
@@ -806,6 +962,17 @@ async function history_appMenu(useContextClick) {
app_menu: { "history-item": 1, "appMenu-history-button": 1 },
};
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "PanelUI-menu-button"],
+ ["app-menu", "appMenu-history-button"],
+ ["app-menu", "history-item"],
+ ],
+ events
+ );
assertInteractionScalars(expectedScalars);
});
}
@@ -852,6 +1019,17 @@ async function bookmarks_appMenu(useContextClick) {
app_menu: { "bookmark-item": 1, "appMenu-bookmarks-button": 1 },
};
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "PanelUI-menu-button"],
+ ["app-menu", "appMenu-bookmarks-button"],
+ ["app-menu", "bookmark-item"],
+ ],
+ events
+ );
assertInteractionScalars(expectedScalars);
});
}
@@ -893,6 +1071,17 @@ async function bookmarks_library_navbar(useContextClick) {
"appMenu-library-bookmarks-button": 1,
},
};
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "library-button"],
+ ["nav-bar", "appMenu-library-bookmarks-button"],
+ ["nav-bar", "bookmark-item"],
+ ],
+ events
+ );
assertInteractionScalars(expectedScalars);
});
@@ -940,6 +1129,17 @@ async function history_library_navbar(useContextClick) {
"appMenu-library-history-button": 1,
},
};
+ let events = Glean.browserUsage.interaction
+ .testGetValue()
+ .map(e => [e.extra.source, e.extra.widget_id]);
+ Assert.deepEqual(
+ [
+ ["nav-bar", "library-button"],
+ ["nav-bar", "appMenu-library-history-button"],
+ ["nav-bar", "history-item"],
+ ],
+ events
+ );
assertInteractionScalars(expectedScalars);
});
diff --git a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js
index 77db0d8286..d4dcd4fad6 100644
--- a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js
+++ b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js
@@ -7,9 +7,10 @@ const { FirefoxBridgeExtensionUtils } = ChromeUtils.importESModule(
"resource:///modules/FirefoxBridgeExtensionUtils.sys.mjs"
);
-const FIREFOX_SHELL_OPEN_COMMAND_PATH = "firefox\\shell\\open\\command";
-const FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH =
- "firefox-private\\shell\\open\\command";
+const OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL}\\shell\\open\\command`;
+const OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL}\\shell\\open\\command`;
+const FIREFOX_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL}\\shell\\open\\command`;
+const FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL}\\shell\\open\\command`;
class StubbedRegistryKey {
#children;
@@ -145,206 +146,274 @@ class StubbedDeleteBridgeProtocolRegistryEntryHelper {
}
add_task(async function test_DeleteWhenSameFirefoxInstall() {
- const applicationPath = "testPath";
-
- const firefoxEntries = new Map();
- firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`);
-
- const firefoxProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxEntries
- );
-
- const firefoxPrivateEntries = new Map();
- firefoxPrivateEntries.set(
- "",
- `\"${applicationPath}\" -osint -private-window \"%1\"`
- );
- const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxPrivateEntries
- );
-
- const children = new Map();
- children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey);
- children.set(
- FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
- firefoxPrivateProtocolRegKey
- );
-
- const registryRootKey = new StubbedRegistryKey(children, new Map());
-
- const stubbedDeleteBridgeProtocolRegistryHelper =
- new StubbedDeleteBridgeProtocolRegistryEntryHelper({
- applicationPath,
- registryRootKey,
- });
-
- FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
- stubbedDeleteBridgeProtocolRegistryHelper
- );
-
- ok(registryRootKey.wasCloseCalled, "Root key closed");
-
- ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
- ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
- ok(
- registryRootKey.isChildDeleted("firefox"),
- "Firefox protocol registry entry deleted"
- );
-
- ok(
- firefoxPrivateProtocolRegKey.wasOpenedForRead,
- "Firefox private key opened"
- );
- ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed");
- ok(
- registryRootKey.isChildDeleted("firefox-private"),
- "Firefox private protocol registry entry deleted"
- );
+ for (let protocols of [
+ [
+ FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL,
+ OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ [
+ FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL,
+ FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ ]) {
+ let [publicProtocol, privateProtocol, publicPath, privatePath] = protocols;
+ const applicationPath = "testPath";
+
+ const firefoxEntries = new Map();
+ firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`);
+
+ const firefoxProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxEntries
+ );
+
+ const firefoxPrivateEntries = new Map();
+ firefoxPrivateEntries.set(
+ "",
+ `\"${applicationPath}\" -osint -private-window \"%1\"`
+ );
+ const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxPrivateEntries
+ );
+
+ const children = new Map();
+ children.set(publicPath, firefoxProtocolRegKey);
+ children.set(privatePath, firefoxPrivateProtocolRegKey);
+
+ const registryRootKey = new StubbedRegistryKey(children, new Map());
+
+ const stubbedDeleteBridgeProtocolRegistryHelper =
+ new StubbedDeleteBridgeProtocolRegistryEntryHelper({
+ applicationPath,
+ registryRootKey,
+ });
+
+ FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
+ publicProtocol,
+ privateProtocol,
+ stubbedDeleteBridgeProtocolRegistryHelper
+ );
+
+ ok(registryRootKey.wasCloseCalled, "Root key closed");
+
+ ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
+ ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
+ ok(
+ registryRootKey.isChildDeleted(publicProtocol),
+ "Firefox protocol registry entry deleted"
+ );
+
+ ok(
+ firefoxPrivateProtocolRegKey.wasOpenedForRead,
+ "Firefox private key opened"
+ );
+ ok(
+ firefoxPrivateProtocolRegKey.wasCloseCalled,
+ "Firefox private key closed"
+ );
+ ok(
+ registryRootKey.isChildDeleted(privateProtocol),
+ "Firefox private protocol registry entry deleted"
+ );
+ }
});
add_task(async function test_DeleteWhenDifferentFirefoxInstall() {
- const applicationPath = "testPath";
- const badApplicationPath = "testPath2";
-
- const firefoxEntries = new Map();
- firefoxEntries.set("", `\"${badApplicationPath}\" -osint -url \"%1\"`);
-
- const firefoxProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxEntries
- );
-
- const firefoxPrivateEntries = new Map();
- firefoxPrivateEntries.set(
- "",
- `\"${badApplicationPath}\" -osint -private-window \"%1\"`
- );
- const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxPrivateEntries
- );
-
- const children = new Map();
- children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey);
- children.set(
- FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
- firefoxPrivateProtocolRegKey
- );
-
- const registryRootKey = new StubbedRegistryKey(children, new Map());
-
- const stubbedDeleteBridgeProtocolRegistryHelper =
- new StubbedDeleteBridgeProtocolRegistryEntryHelper({
- applicationPath,
- registryRootKey,
- });
-
- FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
- stubbedDeleteBridgeProtocolRegistryHelper
- );
-
- ok(registryRootKey.wasCloseCalled, "Root key closed");
-
- ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
- ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
- ok(
- !registryRootKey.isChildDeleted("firefox"),
- "Firefox protocol registry entry not deleted"
- );
-
- ok(
- firefoxPrivateProtocolRegKey.wasOpenedForRead,
- "Firefox private key opened"
- );
- ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed");
- ok(
- !registryRootKey.isChildDeleted("firefox-private"),
- "Firefox private protocol registry entry not deleted"
- );
+ for (let protocols of [
+ [
+ FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL,
+ OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ [
+ FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL,
+ FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ ]) {
+ let [publicProtocol, privateProtocol, publicPath, privatePath] = protocols;
+ const applicationPath = "testPath";
+ const badApplicationPath = "testPath2";
+
+ const firefoxEntries = new Map();
+ firefoxEntries.set("", `\"${badApplicationPath}\" -osint -url \"%1\"`);
+
+ const firefoxProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxEntries
+ );
+
+ const firefoxPrivateEntries = new Map();
+ firefoxPrivateEntries.set(
+ "",
+ `\"${badApplicationPath}\" -osint -private-window \"%1\"`
+ );
+ const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxPrivateEntries
+ );
+
+ const children = new Map();
+ children.set(publicPath, firefoxProtocolRegKey);
+ children.set(privatePath, firefoxPrivateProtocolRegKey);
+
+ const registryRootKey = new StubbedRegistryKey(children, new Map());
+
+ const stubbedDeleteBridgeProtocolRegistryHelper =
+ new StubbedDeleteBridgeProtocolRegistryEntryHelper({
+ applicationPath,
+ registryRootKey,
+ });
+
+ FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
+ publicProtocol,
+ privateProtocol,
+ stubbedDeleteBridgeProtocolRegistryHelper
+ );
+
+ ok(registryRootKey.wasCloseCalled, "Root key closed");
+
+ ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
+ ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
+ ok(
+ !registryRootKey.isChildDeleted(publicProtocol),
+ "Firefox protocol registry entry not deleted"
+ );
+
+ ok(
+ firefoxPrivateProtocolRegKey.wasOpenedForRead,
+ "Firefox private key opened"
+ );
+ ok(
+ firefoxPrivateProtocolRegKey.wasCloseCalled,
+ "Firefox private key closed"
+ );
+ ok(
+ !registryRootKey.isChildDeleted(privateProtocol),
+ "Firefox private protocol registry entry not deleted"
+ );
+ }
});
add_task(async function test_DeleteWhenNoRegistryEntries() {
- const applicationPath = "testPath";
-
- const firefoxPrivateEntries = new Map();
- const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxPrivateEntries
- );
-
- const children = new Map();
- children.set(
- FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
- firefoxPrivateProtocolRegKey
- );
-
- const registryRootKey = new StubbedRegistryKey(children, new Map());
-
- const stubbedDeleteBridgeProtocolRegistryHelper =
- new StubbedDeleteBridgeProtocolRegistryEntryHelper({
- applicationPath,
- registryRootKey,
- });
-
- FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
- stubbedDeleteBridgeProtocolRegistryHelper
- );
-
- ok(registryRootKey.wasCloseCalled, "Root key closed");
-
- ok(
- firefoxPrivateProtocolRegKey.wasOpenedForRead,
- "Firefox private key opened"
- );
- ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed");
- ok(
- !registryRootKey.isChildDeleted("firefox"),
- "Firefox protocol registry entry deleted when it shouldn't be"
- );
- ok(
- !registryRootKey.isChildDeleted("firefox-private"),
- "Firefox private protocol registry deleted when it shouldn't be"
- );
+ for (let protocols of [
+ [
+ FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL,
+ OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ [
+ FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL,
+ FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH,
+ ],
+ ]) {
+ let [publicProtocol, privateProtocol, privatePath] = protocols;
+ const applicationPath = "testPath";
+
+ const firefoxPrivateEntries = new Map();
+ const firefoxPrivateProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxPrivateEntries
+ );
+
+ const children = new Map();
+ children.set(privatePath, firefoxPrivateProtocolRegKey);
+
+ const registryRootKey = new StubbedRegistryKey(children, new Map());
+
+ const stubbedDeleteBridgeProtocolRegistryHelper =
+ new StubbedDeleteBridgeProtocolRegistryEntryHelper({
+ applicationPath,
+ registryRootKey,
+ });
+
+ FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
+ publicProtocol,
+ privateProtocol,
+ stubbedDeleteBridgeProtocolRegistryHelper
+ );
+
+ ok(registryRootKey.wasCloseCalled, "Root key closed");
+
+ ok(
+ firefoxPrivateProtocolRegKey.wasOpenedForRead,
+ "Firefox private key opened"
+ );
+ ok(
+ firefoxPrivateProtocolRegKey.wasCloseCalled,
+ "Firefox private key closed"
+ );
+ ok(
+ !registryRootKey.isChildDeleted(publicProtocol),
+ "Firefox protocol registry entry deleted when it shouldn't be"
+ );
+ ok(
+ !registryRootKey.isChildDeleted(privateProtocol),
+ "Firefox private protocol registry deleted when it shouldn't be"
+ );
+ }
});
add_task(async function test_DeleteWhenUnexpectedRegistryEntries() {
- const applicationPath = "testPath";
-
- const firefoxEntries = new Map();
- firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`);
- firefoxEntries.set("extraEntry", "extraValue");
- const firefoxProtocolRegKey = new StubbedRegistryKey(
- new Map(),
- firefoxEntries
- );
-
- const children = new Map();
- children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey);
-
- const registryRootKey = new StubbedRegistryKey(children, new Map());
-
- const stubbedDeleteBridgeProtocolRegistryHelper =
- new StubbedDeleteBridgeProtocolRegistryEntryHelper({
- applicationPath,
- registryRootKey,
- });
-
- FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
- stubbedDeleteBridgeProtocolRegistryHelper
- );
-
- ok(registryRootKey.wasCloseCalled, "Root key closed");
-
- ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
- ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
- ok(
- !registryRootKey.isChildDeleted("firefox"),
- "Firefox protocol registry entry deleted when it shouldn't be"
- );
- ok(
- !registryRootKey.isChildDeleted("firefox-private"),
- "Firefox private protocol registry deleted when it shouldn't be"
- );
+ for (let protocols of [
+ [
+ FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL,
+ OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ ],
+ [
+ FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL,
+ FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL,
+ FIREFOX_SHELL_OPEN_COMMAND_PATH,
+ ],
+ ]) {
+ let [publicProtocol, privateProtocol, publicPath] = protocols;
+ const applicationPath = "testPath";
+
+ const firefoxEntries = new Map();
+ firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`);
+ firefoxEntries.set("extraEntry", "extraValue");
+ const firefoxProtocolRegKey = new StubbedRegistryKey(
+ new Map(),
+ firefoxEntries
+ );
+
+ const children = new Map();
+ children.set(publicPath, firefoxProtocolRegKey);
+
+ const registryRootKey = new StubbedRegistryKey(children, new Map());
+
+ const stubbedDeleteBridgeProtocolRegistryHelper =
+ new StubbedDeleteBridgeProtocolRegistryEntryHelper({
+ applicationPath,
+ registryRootKey,
+ });
+
+ FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
+ publicProtocol,
+ privateProtocol,
+ stubbedDeleteBridgeProtocolRegistryHelper
+ );
+
+ ok(registryRootKey.wasCloseCalled, "Root key closed");
+
+ ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened");
+ ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed");
+ ok(
+ !registryRootKey.isChildDeleted(publicProtocol),
+ "Firefox protocol registry entry deleted when it shouldn't be"
+ );
+ ok(
+ !registryRootKey.isChildDeleted(privateProtocol),
+ "Firefox private protocol registry deleted when it shouldn't be"
+ );
+ }
});
diff --git a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js
index cef550d705..8686871255 100644
--- a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js
+++ b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js
@@ -16,6 +16,30 @@ const { FirefoxBridgeExtensionUtils } = ChromeUtils.importESModule(
const DUAL_BROWSER_EXTENSION_ORIGIN = ["chrome-extension://fake-origin/"];
const NATIVE_MESSAGING_HOST_ID = "org.mozilla.firefox_bridge_test";
+if (AppConstants.platform == "win") {
+ var { MockRegistry } = ChromeUtils.importESModule(
+ "resource://testing-common/MockRegistry.sys.mjs"
+ );
+}
+
+let registry = null;
+add_setup(() => {
+ if (AppConstants.platform == "win") {
+ registry = new MockRegistry();
+ registerCleanupFunction(() => {
+ registry.shutdown();
+ });
+ }
+});
+
+function resetMockRegistry() {
+ if (AppConstants.platform != "win") {
+ return;
+ }
+ registry.shutdown();
+ registry = new MockRegistry();
+}
+
let dir = FileUtils.getDir("TmpD", ["NativeMessagingHostsTest"]);
dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
@@ -75,6 +99,35 @@ function getExpectedOutput() {
};
}
+function DumpWindowsRegistry() {
+ let key = "";
+ let pathBuffer = [];
+
+ if (AppConstants.platform == "win") {
+ function bufferPrint(line) {
+ let regPath = line.trimStart();
+ if (regPath.includes(":")) {
+ // After trimming white space, keys are formatted as
+ // ": <key> (<value_type>)". We can assume it's only ever
+ // going to be of type REG_SZ for this test.
+ key = regPath.slice(2, regPath.length - " (REG_SZ)".length);
+ } else {
+ pathBuffer.push(regPath);
+ }
+ }
+
+ MockRegistry.dump(
+ MockRegistry.getRoot(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER),
+ "",
+ bufferPrint
+ );
+ } else {
+ Assert.ok(false, "Only windows has a registry!");
+ }
+
+ return [pathBuffer, key];
+}
+
add_task(async function test_maybeWriteManifestFiles() {
await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
USER_TEST_PATH,
@@ -196,6 +249,7 @@ add_task(async function test_ensureRegistered() {
appDir.path,
"Mozilla\\Firefox"
);
+ resetMockRegistry();
} else {
throw new Error("Unsupported platform");
}
@@ -219,4 +273,65 @@ add_task(async function test_ensureRegistered() {
let JSONContent = await IOUtils.readUTF8(expectedJSONPath);
await IOUtils.remove(expectedJSONPath);
Assert.equal(JSONContent, expectedOutput);
+
+ // Test that the registry key is written for Windows only
+ if (AppConstants.platform == "win") {
+ let [pathBuffer, key] = DumpWindowsRegistry();
+ Assert.equal(
+ pathBuffer.toString(),
+ [
+ "Software",
+ "Google",
+ "Chrome",
+ "NativeMessagingHosts",
+ nativeHostId,
+ ].toString()
+ );
+ Assert.equal(key, expectedJSONPath);
+ }
+});
+
+add_task(async function test_maybeWriteNativeMessagingRegKeys() {
+ if (AppConstants.platform != "win") {
+ return;
+ }
+ resetMockRegistry();
+ FirefoxBridgeExtensionUtils.maybeWriteNativeMessagingRegKeys(
+ "Test\\Path\\For\\Reg\\Key",
+ binFile.parent.path,
+ NATIVE_MESSAGING_HOST_ID
+ );
+ let [pathBuffer, key] = DumpWindowsRegistry();
+ registry.shutdown();
+ Assert.equal(
+ pathBuffer.toString(),
+ ["Test", "Path", "For", "Reg", "Key", NATIVE_MESSAGING_HOST_ID].toString()
+ );
+ console.log("The key is: " + key);
+ Assert.equal(key, `${binFile.parent.path}\\${NATIVE_MESSAGING_HOST_ID}.json`);
+});
+
+add_task(async function test_maybeWriteNativeMessagingRegKeysIncorrectValue() {
+ if (AppConstants.platform != "win") {
+ return;
+ }
+ resetMockRegistry();
+ registry.setValue(
+ Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
+ `Test\\Path\\For\\Reg\\Key\\${NATIVE_MESSAGING_HOST_ID}`,
+ "",
+ "IncorrectValue"
+ );
+ FirefoxBridgeExtensionUtils.maybeWriteNativeMessagingRegKeys(
+ "Test\\Path\\For\\Reg\\Key",
+ binFile.parent.path,
+ NATIVE_MESSAGING_HOST_ID
+ );
+ let [pathBuffer, key] = DumpWindowsRegistry();
+ registry.shutdown();
+ Assert.equal(
+ pathBuffer.toString(),
+ ["Test", "Path", "For", "Reg", "Key", NATIVE_MESSAGING_HOST_ID].toString()
+ );
+ Assert.equal(key, `${binFile.parent.path}\\${NATIVE_MESSAGING_HOST_ID}.json`);
});