Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* 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 =
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,
);
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,
);
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,
"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":
"<!DOCTYPE html><meta charset=utf-8><script src=tab.js></script>",
"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,
);
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,
"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();
});