summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/pageActions/browser_PageActions_removeExtension.js')
-rw-r--r--browser/base/content/test/pageActions/browser_PageActions_removeExtension.js320
1 files changed, 320 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..8efc9b077c
--- /dev/null
+++ b/browser/base/content/test/pageActions/browser_PageActions_removeExtension.js
@@ -0,0 +1,320 @@
+"use strict";
+
+const { EnterprisePolicyTesting } = ChromeUtils.import(
+ "resource://testing-common/EnterprisePolicyTesting.jsm"
+);
+
+const { ExtensionCommon } = ChromeUtils.import(
+ "resource://gre/modules/ExtensionCommon.jsm"
+);
+
+const { TelemetryTestUtils } = ChromeUtils.import(
+ "resource://testing-common/TelemetryTestUtils.jsm"
+);
+
+const TELEMETRY_EVENTS_FILTERS = {
+ category: "addonsManager",
+ method: "action",
+};
+
+// Initialization. Must run first.
+add_task(async function init() {
+ // 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);
+
+ // Open the panel and then open the context menu on the action's item.
+ await promisePageActionPanelOpen();
+ let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu");
+ EventUtils.synthesizeMouseAtCenter(panelButton, {
+ type: "contextmenu",
+ button: 2,
+ });
+ await contextMenuPromise;
+
+ 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");
+
+ // 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");
+ let addonUninstalledPromise = promiseAddonUninstalled(extension.id);
+ mockPromptService();
+ EventUtils.synthesizeMouseAtCenter(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
+ );
+
+ // 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_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,
+ });
+ await contextMenuPromise;
+
+ 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");
+
+ // 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();
+ });
+ EventUtils.synthesizeMouseAtCenter(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_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);
+
+ // Open the panel and then open the context menu on the action's item.
+ await promisePageActionPanelOpen();
+ let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
+ let contextMenuPromise = promisePanelShown("pageActionContextMenu");
+ EventUtils.synthesizeMouseAtCenter(panelButton, {
+ type: "contextmenu",
+ button: 2,
+ });
+ await contextMenuPromise;
+
+ 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");
+
+ // Press escape to hide the context menu.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+ EventUtils.synthesizeKey("KEY_Escape");
+ 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_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,
+ });
+ await contextMenuPromise;
+
+ 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");
+
+ // Press escape to hide the context menu.
+ contextMenuPromise = promisePanelHidden("pageActionContextMenu");
+ EventUtils.synthesizeKey("KEY_Escape");
+ 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();
+});
+
+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() {
+ return document.querySelector(
+ "#pageActionContextMenu > menuitem[label='Remove Extension']"
+ );
+}
+
+async function promiseAnimationFrame(win = window) {
+ await new Promise(resolve => win.requestAnimationFrame(resolve));
+
+ let { tm } = Services;
+ return new Promise(resolve => tm.dispatchToMainThread(resolve));
+}