From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../extensions/test/browser/browser_ext_menus.js | 458 +++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 browser/components/extensions/test/browser/browser_ext_menus.js (limited to 'browser/components/extensions/test/browser/browser_ext_menus.js') diff --git a/browser/components/extensions/test/browser/browser_ext_menus.js b/browser/components/extensions/test/browser/browser_ext_menus.js new file mode 100644 index 0000000000..76ac3cf045 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_menus.js @@ -0,0 +1,458 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const PAGE = + "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html"; + +add_task(async function test_permissions() { + function background() { + browser.test.sendMessage("apis", { + menus: typeof browser.menus, + contextMenus: typeof browser.contextMenus, + menusInternal: typeof browser.menusInternal, + }); + } + + const first = ExtensionTestUtils.loadExtension({ + manifest: { permissions: ["menus"] }, + background, + }); + const second = ExtensionTestUtils.loadExtension({ + manifest: { permissions: ["contextMenus"] }, + background, + }); + + await first.startup(); + await second.startup(); + + const apis1 = await first.awaitMessage("apis"); + const apis2 = await second.awaitMessage("apis"); + + is(apis1.menus, "object", "browser.menus available with 'menus' permission"); + is( + apis1.contextMenus, + "undefined", + "browser.contextMenus unavailable with 'menus' permission" + ); + is( + apis1.menusInternal, + "undefined", + "browser.menusInternal is never available" + ); + + is( + apis2.menus, + "undefined", + "browser.menus unavailable with 'contextMenus' permission" + ); + is( + apis2.contextMenus, + "object", + "browser.contextMenus unavailable with 'contextMenus' permission" + ); + is( + apis2.menusInternal, + "undefined", + "browser.menusInternal is never available" + ); + + await first.unload(); + await second.unload(); +}); + +add_task(async function test_actionContextMenus() { + const manifest = { + page_action: {}, + browser_action: { + default_area: "navbar", + }, + permissions: ["menus"], + }; + + async function background() { + const contexts = ["page_action", "browser_action"]; + + const parentId = browser.menus.create({ contexts, title: "parent" }); + browser.menus.create({ parentId, title: "click A" }); + browser.menus.create({ parentId, title: "click B" }); + + for (let i = 1; i < 9; i++) { + browser.menus.create({ contexts, id: `${i}`, title: `click ${i}` }); + } + + browser.menus.onClicked.addListener((info, tab) => { + browser.test.sendMessage("click", { info, tab }); + }); + + const [tab] = await browser.tabs.query({ active: true }); + await browser.pageAction.show(tab.id); + browser.test.sendMessage("ready", tab.id); + } + + const extension = ExtensionTestUtils.loadExtension({ manifest, background }); + const tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "http://example.com/" + ); + + await extension.startup(); + const tabId = await extension.awaitMessage("ready"); + + for (const kind of ["page", "browser"]) { + const menu = await openActionContextMenu(extension, kind); + const [submenu, second, , , , last, separator] = menu.children; + + is(submenu.tagName, "menu", "Correct submenu type"); + is(submenu.label, "parent", "Correct submenu title"); + + const popup = await openSubmenu(submenu); + is(popup, submenu.menupopup, "Correct submenu opened"); + is(popup.children.length, 2, "Correct number of submenu items"); + + let idPrefix = `${makeWidgetId(extension.id)}-menuitem-_`; + + is(second.tagName, "menuitem", "Second menu item type is correct"); + is(second.label, "click 1", "Second menu item title is correct"); + is(second.id, `${idPrefix}1`, "Second menu item id is correct"); + + is(last.tagName, "menu", "Last menu item type is correct"); + is(last.label, "Generated extension", "Last menu item title is correct"); + is( + last.getAttribute("ext-type"), + "top-level-menu", + "Last menu ext-type is correct" + ); + is(separator.tagName, "menuseparator", "Separator after last menu item"); + + // Verify that menu items exceeding ACTION_MENU_TOP_LEVEL_LIMIT are moved into a submenu. + let overflowPopup = await openSubmenu(last); + is( + overflowPopup.children.length, + 4, + "Excess items should be moved into a submenu" + ); + is( + overflowPopup.firstElementChild.id, + `${idPrefix}5`, + "First submenu item ID is correct" + ); + is( + overflowPopup.lastElementChild.id, + `${idPrefix}8`, + "Last submenu item ID is correct" + ); + + await closeActionContextMenu(overflowPopup.firstElementChild, kind); + const { info, tab } = await extension.awaitMessage("click"); + is(info.pageUrl, "http://example.com/", "Click info pageUrl is correct"); + is(tab.id, tabId, "Click event tab ID is correct"); + } + + BrowserTestUtils.removeTab(tab); + await extension.unload(); +}); + +add_task(async function test_bookmarkContextMenu() { + const ext = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["menus", "bookmarks"], + }, + background() { + browser.menus.onShown.addListener(() => { + browser.test.sendMessage("hello"); + }); + browser.menus.create({ title: "blarg", contexts: ["bookmark"] }, () => { + browser.test.sendMessage("ready"); + }); + }, + }); + + await ext.startup(); + await ext.awaitMessage("ready"); + await toggleBookmarksToolbar(true); + + let menu = await openChromeContextMenu( + "placesContext", + "#PlacesToolbarItems .bookmark-item" + ); + let children = Array.from(menu.children); + let item = children[children.length - 1]; + is(item.label, "blarg", "Menu item label is correct"); + await ext.awaitMessage("hello"); // onShown listener fired + + closeChromeContextMenu("placesContext", item); + await ext.unload(); + await toggleBookmarksToolbar(false); +}); + +add_task(async function test_tabContextMenu() { + const first = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["menus"], + }, + async background() { + browser.menus.create({ + id: "alpha-beta-parent", + title: "alpha-beta parent", + contexts: ["tab"], + }); + + browser.menus.create({ parentId: "alpha-beta-parent", title: "alpha" }); + browser.menus.create({ parentId: "alpha-beta-parent", title: "beta" }); + + browser.menus.create({ title: "dummy", contexts: ["page"] }); + + browser.menus.onClicked.addListener((info, tab) => { + browser.test.sendMessage("click", { info, tab }); + }); + + const [tab] = await browser.tabs.query({ active: true }); + browser.test.sendMessage("ready", tab.id); + }, + }); + + const second = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["menus"], + }, + background() { + browser.menus.create({ + title: "invisible", + contexts: ["tab"], + documentUrlPatterns: ["http://does/not/match"], + }); + browser.menus.create( + { + title: "gamma", + contexts: ["tab"], + documentUrlPatterns: ["http://example.com/"], + }, + () => { + browser.test.sendMessage("ready"); + } + ); + }, + }); + + const tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "http://example.com/" + ); + await first.startup(); + await second.startup(); + + const tabId = await first.awaitMessage("ready"); + await second.awaitMessage("ready"); + + const menu = await openTabContextMenu(); + const [separator, submenu, gamma] = Array.from(menu.children).slice(-3); + is( + separator.tagName, + "menuseparator", + "Separator before first extension item" + ); + + is(submenu.tagName, "menu", "Correct submenu type"); + is(submenu.label, "alpha-beta parent", "Correct submenu title"); + + isnot( + gamma.label, + "dummy", + "`page` context menu item should not appear here" + ); + + is(gamma.tagName, "menuitem", "Third menu item type is correct"); + is(gamma.label, "gamma", "Third menu item label is correct"); + + const popup = await openSubmenu(submenu); + is(popup, submenu.menupopup, "Correct submenu opened"); + is(popup.children.length, 2, "Correct number of submenu items"); + + const [alpha, beta] = popup.children; + is(alpha.tagName, "menuitem", "First menu item type is correct"); + is(alpha.label, "alpha", "First menu item label is correct"); + is(beta.tagName, "menuitem", "Second menu item type is correct"); + is(beta.label, "beta", "Second menu item label is correct"); + + await closeTabContextMenu(beta); + const click = await first.awaitMessage("click"); + is( + click.info.pageUrl, + "http://example.com/", + "Click info pageUrl is correct" + ); + is(click.tab.id, tabId, "Click event tab ID is correct"); + is(click.info.frameId, undefined, "no frameId on chrome"); + + BrowserTestUtils.removeTab(tab); + await first.unload(); + await second.unload(); +}); + +add_task(async function test_onclick_frameid() { + const manifest = { + permissions: ["menus"], + }; + + function background() { + function onclick(info) { + browser.test.sendMessage("click", info); + } + browser.menus.create( + { contexts: ["frame", "page"], title: "modify", onclick }, + () => { + browser.test.sendMessage("ready"); + } + ); + } + + const extension = ExtensionTestUtils.loadExtension({ manifest, background }); + const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE); + + await extension.startup(); + await extension.awaitMessage("ready"); + + async function click(menu) { + const items = menu.getElementsByAttribute("label", "modify"); + is(items.length, 1, "found menu item"); + await closeExtensionContextMenu(items[0]); + return extension.awaitMessage("click"); + } + + let info = await click(await openContextMenu("body")); + is(info.frameId, 0, "top level click"); + info = await click(await openContextMenuInFrame()); + isnot(info.frameId, undefined, "frame click, frameId is not undefined"); + isnot(info.frameId, 0, "frame click, frameId probably okay"); + + BrowserTestUtils.removeTab(tab); + await extension.unload(); +}); + +add_task(async function test_multiple_contexts_init() { + const manifest = { + permissions: ["menus"], + }; + + function background() { + browser.menus.create({ id: "parent", title: "parent" }, () => { + browser.tabs.create({ url: "tab.html", active: false }); + }); + } + + const files = { + "tab.html": + "", + "tab.js": function () { + browser.menus.onClicked.addListener(info => { + browser.test.sendMessage("click", info); + }); + browser.menus.create( + { parentId: "parent", id: "child", title: "child" }, + () => { + browser.test.sendMessage("ready"); + } + ); + }, + }; + + const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE); + const extension = ExtensionTestUtils.loadExtension({ + manifest, + background, + files, + }); + + await extension.startup(); + await extension.awaitMessage("ready"); + + const menu = await openContextMenu(); + const items = menu.getElementsByAttribute("label", "parent"); + + is(items.length, 1, "Found parent menu item"); + is(items[0].tagName, "menu", "And it has children"); + + const popup = await openSubmenu(items[0]); + is(popup.firstElementChild.label, "child", "Correct child menu item"); + await closeExtensionContextMenu(popup.firstElementChild); + + const info = await extension.awaitMessage("click"); + is(info.menuItemId, "child", "onClicked the correct item"); + + BrowserTestUtils.removeTab(tab); + await extension.unload(); +}); + +add_task(async function test_tools_menu() { + const first = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["menus"], + }, + background() { + browser.menus.create({ title: "alpha", contexts: ["tools_menu"] }); + browser.menus.create({ title: "beta", contexts: ["tools_menu"] }, () => { + browser.test.sendMessage("ready"); + }); + }, + }); + + const second = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["menus"], + }, + async background() { + browser.menus.create({ title: "gamma", contexts: ["tools_menu"] }); + browser.menus.onClicked.addListener((info, tab) => { + browser.test.sendMessage("click", { info, tab }); + }); + + const [tab] = await browser.tabs.query({ active: true }); + browser.test.sendMessage("ready", tab.id); + }, + }); + + const tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "http://example.com/" + ); + await first.startup(); + await second.startup(); + + await first.awaitMessage("ready"); + const tabId = await second.awaitMessage("ready"); + const menu = await openToolsMenu(); + + const [separator, submenu, gamma] = Array.from(menu.children).slice(-3); + is( + separator.tagName, + "menuseparator", + "Separator before first extension item" + ); + + is(submenu.tagName, "menu", "Correct submenu type"); + is( + submenu.getAttribute("label"), + "Generated extension", + "Correct submenu title" + ); + is(submenu.menupopup.children.length, 2, "Correct number of submenu items"); + + is(gamma.tagName, "menuitem", "Third menu item type is correct"); + is(gamma.getAttribute("label"), "gamma", "Third menu item label is correct"); + + closeToolsMenu(gamma); + + const click = await second.awaitMessage("click"); + is( + click.info.pageUrl, + "http://example.com/", + "Click info pageUrl is correct" + ); + is(click.tab.id, tabId, "Click event tab ID is correct"); + + BrowserTestUtils.removeTab(tab); + await first.unload(); + await second.unload(); +}); -- cgit v1.2.3