diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /browser/base/content/test/pageActions/browser_PageActions_removeExtension.js | |
parent | Initial commit. (diff) | |
download | firefox-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.js | 368 |
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"; + }); +} |