summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/base/content/test/pageActions/browser_PageActions_removeExtension.js')
-rw-r--r--browser/base/content/test/pageActions/browser_PageActions_removeExtension.js368
1 files changed, 368 insertions, 0 deletions
diff --git a/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js b/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
new file mode 100644
index 0000000000..6654f870ec
--- /dev/null
+++ b/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
@@ -0,0 +1,368 @@
+"use strict";
+
+const TELEMETRY_EVENTS_FILTERS = {
+ category: "addonsManager",
+ method: "action",
+};
+
+// Initialization. Must run first.
+add_setup(async function() {
+ // The page action urlbar button, and therefore the panel, is only shown when
+ // the current tab is actionable -- i.e., a normal web page. about:blank is
+ // not, so open a new tab first thing, and close it when this test is done.
+ let tab = await BrowserTestUtils.openNewForegroundTab({
+ gBrowser,
+ url: "http://example.com/",
+ });
+
+ // The prompt service is mocked later, so set it up to be restored.
+ let { prompt } = Services;
+
+ registerCleanupFunction(async () => {
+ BrowserTestUtils.removeTab(tab);
+ Services.prompt = prompt;
+ });
+});
+
+add_task(async function contextMenu_removeExtension_panel() {
+ Services.telemetry.clearEvents();
+
+ // We use an extension that shows a page action so that we can test the
+ // "remove extension" item in the context menu.
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ name: "Test contextMenu",
+ page_action: { show_matches: ["<all_urls>"] },
+ },
+
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+
+ let actionId = ExtensionCommon.makeWidgetId(extension.id);
+
+ const url = "data:text/html,<h1>A Page</h1>";
+ let win = await BrowserTestUtils.openNewBrowserWindow();
+ await SimpleTest.promiseFocus(win);
+ BrowserTestUtils.loadURI(win.gBrowser, url);
+ await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
+
+ info("Shrink the window if necessary, check the meatball menu is visible");
+ let originalOuterWidth = win.outerWidth;
+ await promiseStableResize(500, win);
+
+ // The pageAction implementation enables the button at the next animation
+ // frame, so before we look for the button we should wait one animation frame
+ // as well.
+ await promiseAnimationFrame(win);
+
+ let meatballButton = win.document.getElementById("pageActionButton");
+ Assert.ok(BrowserTestUtils.is_visible(meatballButton));
+
+ // Open the panel.
+ await promisePageActionPanelOpen(win);
+
+ info("Open the context menu");
+ let panelButton = win.BrowserPageActions.panelButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu", win);
+ EventUtils.synthesizeMouseAtCenter(
+ panelButton,
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ win
+ );
+ let contextMenu = await contextMenuPromise;
+
+ let removeExtensionItem = getRemoveExtensionItem(win);
+ Assert.ok(removeExtensionItem, "'Remove' item exists");
+ Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
+ Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
+
+ // Click the "remove extension" item, a prompt should be displayed and then
+ // the add-on should be uninstalled. We mock the prompt service to confirm
+ // the removal of the add-on.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu", win);
+ let addonUninstalledPromise = promiseAddonUninstalled(extension.id);
+ mockPromptService();
+ contextMenu.activateItem(removeExtensionItem);
+ await Promise.all([contextMenuPromise, addonUninstalledPromise]);
+
+ // Done, clean up.
+ await extension.unload();
+
+ TelemetryTestUtils.assertEvents(
+ [
+ {
+ object: "pageAction",
+ value: "accepted",
+ extra: { addonId: extension.id, action: "uninstall" },
+ },
+ ],
+ TELEMETRY_EVENTS_FILTERS
+ );
+
+ await promiseStableResize(originalOuterWidth, win);
+ await BrowserTestUtils.closeWindow(win);
+});
+
+add_task(async function contextMenu_removeExtension_urlbar() {
+ Services.telemetry.clearEvents();
+
+ // We use an extension that shows a page action so that we can test the
+ // "remove extension" item in the context menu.
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ name: "Test contextMenu",
+ page_action: { show_matches: ["<all_urls>"] },
+ },
+
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ // The pageAction implementation enables the button at the next animation
+ // frame, so before we look for the button we should wait one animation frame
+ // as well.
+ await promiseAnimationFrame();
+
+ let actionId = ExtensionCommon.makeWidgetId(extension.id);
+
+ // Open the context menu on the action's urlbar button.
+ let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu");
+ EventUtils.synthesizeMouseAtCenter(urlbarButton, {
+ type: "contextmenu",
+ button: 2,
+ });
+ let contextMenu = await contextMenuPromise;
+
+ let menuItems = collectContextMenuItems();
+ Assert.equal(menuItems.length, 2, "Context menu has two children");
+ let removeExtensionItem = getRemoveExtensionItem();
+ Assert.ok(removeExtensionItem, "'Remove' item exists");
+ Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
+ Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
+ let manageExtensionItem = getManageExtensionItem();
+ Assert.ok(manageExtensionItem, "'Manage' item exists");
+ Assert.ok(!manageExtensionItem.hidden, "'Manage' item is visible");
+ Assert.ok(!manageExtensionItem.disabled, "'Manage' item is not disabled");
+
+ // Click the "remove extension" item, a prompt should be displayed and then
+ // the add-on should be uninstalled. We mock the prompt service to cancel the
+ // removal of the add-on.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+ let promptService = mockPromptService();
+ let promptCancelledPromise = new Promise(resolve => {
+ promptService.confirmEx = () => resolve();
+ });
+ contextMenu.activateItem(removeExtensionItem);
+ await Promise.all([contextMenuPromise, promptCancelledPromise]);
+
+ // Done, clean up.
+ await extension.unload();
+
+ TelemetryTestUtils.assertEvents(
+ [
+ {
+ object: "pageAction",
+ value: "cancelled",
+ extra: { addonId: extension.id, action: "uninstall" },
+ },
+ ],
+ TELEMETRY_EVENTS_FILTERS
+ );
+
+ // urlbar tests that run after this one can break if the mouse is left over
+ // the area where the urlbar popup appears, which seems to happen due to the
+ // above synthesized mouse events. Move it over the urlbar.
+ EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
+ gURLBar.focus();
+});
+
+add_task(async function contextMenu_removeExtension_disabled_in_urlbar() {
+ // We use an extension that shows a page action so that we can test the
+ // "remove extension" item in the context menu.
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ name: "Test contextMenu",
+ page_action: { show_matches: ["<all_urls>"] },
+ },
+
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ // The pageAction implementation enables the button at the next animation
+ // frame, so before we look for the button we should wait one animation frame
+ // as well.
+ await promiseAnimationFrame();
+ // Add a policy to prevent the add-on from being uninstalled.
+ await EnterprisePolicyTesting.setupPolicyEngineWithJson({
+ policies: {
+ Extensions: {
+ Locked: [extension.id],
+ },
+ },
+ });
+
+ let actionId = ExtensionCommon.makeWidgetId(extension.id);
+
+ // Open the context menu on the action's urlbar button.
+ let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu");
+ EventUtils.synthesizeMouseAtCenter(urlbarButton, {
+ type: "contextmenu",
+ button: 2,
+ });
+ let contextMenu = await contextMenuPromise;
+
+ let menuItems = collectContextMenuItems();
+ Assert.equal(menuItems.length, 2, "Context menu has two children");
+ let removeExtensionItem = getRemoveExtensionItem();
+ Assert.ok(removeExtensionItem, "'Remove' item exists");
+ Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
+ Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
+ let manageExtensionItem = getManageExtensionItem();
+ Assert.ok(manageExtensionItem, "'Manage' item exists");
+ Assert.ok(!manageExtensionItem.hidden, "'Manage' item is visible");
+ Assert.ok(!manageExtensionItem.disabled, "'Manage' item is not disabled");
+
+ // Hide the context menu.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+ contextMenu.hidePopup();
+ await contextMenuPromise;
+
+ // Done, clean up.
+ await extension.unload();
+ await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
+
+ // urlbar tests that run after this one can break if the mouse is left over
+ // the area where the urlbar popup appears, which seems to happen due to the
+ // above synthesized mouse events. Move it over the urlbar.
+ EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
+ gURLBar.focus();
+});
+
+add_task(async function contextMenu_removeExtension_disabled_in_panel() {
+ // We use an extension that shows a page action so that we can test the
+ // "remove extension" item in the context menu.
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ name: "Test contextMenu",
+ page_action: { show_matches: ["<all_urls>"] },
+ },
+
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ // Add a policy to prevent the add-on from being uninstalled.
+ await EnterprisePolicyTesting.setupPolicyEngineWithJson({
+ policies: {
+ Extensions: {
+ Locked: [extension.id],
+ },
+ },
+ });
+
+ let actionId = ExtensionCommon.makeWidgetId(extension.id);
+
+ const url = "data:text/html,<h1>A Page</h1>";
+ let win = await BrowserTestUtils.openNewBrowserWindow();
+ await SimpleTest.promiseFocus(win);
+ BrowserTestUtils.loadURI(win.gBrowser, url);
+ await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
+
+ info("Shrink the window if necessary, check the meatball menu is visible");
+ let originalOuterWidth = win.outerWidth;
+ await promiseStableResize(500, win);
+
+ // The pageAction implementation enables the button at the next animation
+ // frame, so before we look for the button we should wait one animation frame
+ // as well.
+ await promiseAnimationFrame(win);
+
+ let meatballButton = win.document.getElementById("pageActionButton");
+ Assert.ok(BrowserTestUtils.is_visible(meatballButton));
+
+ // Open the panel.
+ await promisePageActionPanelOpen(win);
+
+ info("Open the context menu");
+ let panelButton = win.BrowserPageActions.panelButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu", win);
+ EventUtils.synthesizeMouseAtCenter(
+ panelButton,
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ win
+ );
+ let contextMenu = await contextMenuPromise;
+
+ let removeExtensionItem = getRemoveExtensionItem(win);
+ Assert.ok(removeExtensionItem, "'Remove' item exists");
+ Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
+ Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
+
+ // Hide the context menu.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu", win);
+ contextMenu.hidePopup();
+ await contextMenuPromise;
+
+ // Done, clean up.
+ await extension.unload();
+ await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
+
+ await promiseStableResize(originalOuterWidth, win);
+ await BrowserTestUtils.closeWindow(win);
+});
+
+function promiseAddonUninstalled(addonId) {
+ return new Promise(resolve => {
+ let listener = {};
+ listener.onUninstalled = addon => {
+ if (addon.id == addonId) {
+ AddonManager.removeAddonListener(listener);
+ resolve();
+ }
+ };
+ AddonManager.addAddonListener(listener);
+ });
+}
+
+function mockPromptService() {
+ let promptService = {
+ // The prompt returns 1 for cancelled and 0 for accepted.
+ _response: 0,
+ QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
+ confirmEx: () => promptService._response,
+ };
+
+ Services.prompt = promptService;
+
+ return promptService;
+}
+
+function getRemoveExtensionItem(win = window) {
+ return win.document.querySelector(
+ "#pageActionContextMenu > menuitem[label='Remove Extension']"
+ );
+}
+
+function getManageExtensionItem(win = window) {
+ return win.document.querySelector(
+ "#pageActionContextMenu > menuitem[label='Manage Extension…']"
+ );
+}
+
+function collectContextMenuItems(win = window) {
+ let contextMenu = win.document.getElementById("pageActionContextMenu");
+ return Array.prototype.filter.call(contextMenu.children, node => {
+ return win.getComputedStyle(node).visibility == "visible";
+ });
+}