summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js249
1 files changed, 249 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js b/browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js
new file mode 100644
index 0000000000..168a9c11b5
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_optionsPage_popups.js
@@ -0,0 +1,249 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+async function openContextMenuInOptionsPage(optionsBrowser) {
+ let contentAreaContextMenu = document.getElementById(
+ "contentAreaContextMenu"
+ );
+ let popupShownPromise = BrowserTestUtils.waitForEvent(
+ contentAreaContextMenu,
+ "popupshown"
+ );
+
+ info("Trigger context menu in the extension options page");
+
+ // Instead of BrowserTestUtils.synthesizeMouseAtCenter, we are dispatching a contextmenu
+ // event directly on the target element to prevent intermittent failures on debug builds
+ // (especially linux32-debug), see Bug 1519808 for a rationale.
+ SpecialPowers.spawn(optionsBrowser, [], () => {
+ let el = content.document.querySelector("a");
+ el.dispatchEvent(
+ new content.MouseEvent("contextmenu", {
+ bubbles: true,
+ cancelable: true,
+ view: el.ownerGlobal,
+ })
+ );
+ });
+
+ info("Wait the context menu to be shown");
+ await popupShownPromise;
+
+ return contentAreaContextMenu;
+}
+
+async function contextMenuClosed(contextMenu) {
+ info("Wait context menu popup to be closed");
+ await closeContextMenu(contextMenu);
+ is(contextMenu.state, "closed", "The context menu popup has been closed");
+}
+
+add_task(async function test_tab_options_popups() {
+ async function backgroundScript() {
+ browser.menus.onShown.addListener(info => {
+ browser.test.sendMessage("extension-menus-onShown", info);
+ });
+
+ await browser.menus.create({
+ id: "sidebaronly",
+ title: "sidebaronly",
+ viewTypes: ["sidebar"],
+ });
+ await browser.menus.create({
+ id: "tabonly",
+ title: "tabonly",
+ viewTypes: ["tab"],
+ });
+ await browser.menus.create({ id: "anypage", title: "anypage" });
+
+ browser.runtime.openOptionsPage();
+ }
+
+ function optionsScript() {
+ browser.test.sendMessage("options-page:loaded", document.documentURI);
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ useAddonManager: "temporary",
+
+ manifest: {
+ permissions: ["tabs", "menus"],
+ options_ui: {
+ page: "options.html",
+ },
+ },
+ files: {
+ "options.html": `<!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <script src="options.js" type="text/javascript"></script>
+ </head>
+ <body style="height: 100px;">
+ <h1>Extensions Options</h1>
+ <a href="http://mochi.test:8888/">options page link</a>
+ </body>
+ </html>`,
+ "options.js": optionsScript,
+ },
+ background: backgroundScript,
+ });
+
+ const aboutAddonsTab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "about:addons"
+ );
+
+ await extension.startup();
+
+ const pageUrl = await extension.awaitMessage("options-page:loaded");
+
+ const optionsBrowser = getInlineOptionsBrowser(gBrowser.selectedBrowser);
+
+ const contentAreaContextMenu = await openContextMenuInOptionsPage(
+ optionsBrowser
+ );
+
+ let contextMenuItemIds = [
+ "context-openlinkintab",
+ "context-openlinkprivate",
+ "context-copylink",
+ ];
+
+ // Test that the "open link in container" menu is available if the containers are enabled
+ // (which is the default on Nightly, but not on Beta).
+ if (Services.prefs.getBoolPref("privacy.userContext.enabled")) {
+ contextMenuItemIds.push("context-openlinkinusercontext-menu");
+ }
+
+ for (const itemID of contextMenuItemIds) {
+ const item = contentAreaContextMenu.querySelector(`#${itemID}`);
+
+ ok(!item.hidden, `${itemID} should not be hidden`);
+ ok(!item.disabled, `${itemID} should not be disabled`);
+ }
+
+ const menuDetails = await extension.awaitMessage("extension-menus-onShown");
+
+ isnot(
+ menuDetails.targetElementId,
+ undefined,
+ "Got a targetElementId in the menu details"
+ );
+ delete menuDetails.targetElementId;
+
+ Assert.deepEqual(
+ menuDetails,
+ {
+ menuIds: ["anypage"],
+ contexts: ["link", "all"],
+ viewType: undefined,
+ frameId: 0,
+ editable: false,
+ linkText: "options page link",
+ linkUrl: "http://mochi.test:8888/",
+ pageUrl,
+ },
+ "Got the expected menu details from menus.onShown"
+ );
+
+ await contextMenuClosed(contentAreaContextMenu);
+
+ BrowserTestUtils.removeTab(aboutAddonsTab);
+
+ await extension.unload();
+});
+
+add_task(async function overrideContext_in_options_page() {
+ function optionsScript() {
+ document.addEventListener(
+ "contextmenu",
+ () => {
+ browser.menus.overrideContext({});
+ browser.test.sendMessage("contextmenu-overridden");
+ },
+ { once: true }
+ );
+ browser.test.sendMessage("options-page:loaded");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ useAddonManager: "temporary",
+ manifest: {
+ permissions: ["tabs", "menus", "menus.overrideContext"],
+ options_ui: {
+ page: "options.html",
+ },
+ },
+ files: {
+ "options.html": `<!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <script src="options.js" type="text/javascript"></script>
+ </head>
+ <body style="height: 100px;">
+ <h1>Extensions Options</h1>
+ <a href="http://mochi.test:8888/">options page link</a>
+ </body>
+ </html>`,
+ "options.js": optionsScript,
+ },
+ async background() {
+ // Expected to match and be shown.
+ await new Promise(resolve => {
+ browser.menus.create({ id: "bg_1_1", title: "bg_1_1" });
+ browser.menus.create({ id: "bg_1_2", title: "bg_1_2" });
+ // Expected to not match and be hidden.
+ browser.menus.create(
+ {
+ id: "bg_1_3",
+ title: "bg_1_3",
+ targetUrlPatterns: ["*://nomatch/*"],
+ },
+ // menus.create returns a number and gets a callback, the order
+ // is deterministic and so we just need to wait for the last one.
+ resolve
+ );
+ });
+ browser.runtime.openOptionsPage();
+ },
+ });
+
+ const aboutAddonsTab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "about:addons"
+ );
+
+ await extension.startup();
+ await extension.awaitMessage("options-page:loaded");
+
+ const optionsBrowser = getInlineOptionsBrowser(gBrowser.selectedBrowser);
+ const contentAreaContextMenu = await openContextMenuInOptionsPage(
+ optionsBrowser
+ );
+
+ await extension.awaitMessage("contextmenu-overridden");
+
+ const allVisibleMenuItems = Array.from(contentAreaContextMenu.children)
+ .filter(elem => {
+ return !elem.hidden;
+ })
+ .map(elem => elem.id);
+
+ Assert.deepEqual(
+ allVisibleMenuItems,
+ [
+ `${makeWidgetId(extension.id)}-menuitem-_bg_1_1`,
+ `${makeWidgetId(extension.id)}-menuitem-_bg_1_2`,
+ ],
+ "Expected only extension menu items"
+ );
+
+ await contextMenuClosed(contentAreaContextMenu);
+
+ BrowserTestUtils.removeTab(aboutAddonsTab);
+
+ await extension.unload();
+});