/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html"; add_task(async function accesskeys() { let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE); gBrowser.selectedTab = tab; async function background() { // description is informative. // title is passed to menus.create. // label and key are compared with the actual values. const TESTCASES = [ { description: "Amp at start", title: "&accesskey", label: "accesskey", key: "a", }, { description: "amp in between", title: "A& b", label: "A b", key: " ", }, { description: "lonely amp", title: "&", label: "", key: "", }, { description: "amp at end", title: "End &", label: "End ", key: "", }, { description: "escaped amp", title: "A && B", label: "A & B", key: "", }, { description: "amp before escaped amp", title: "A &T&& before", label: "A T& before", key: "T", }, { description: "amp after escaped amp", title: "A &&&T after", label: "A &T after", key: "T", }, { // Only the first amp should be used as the access key. description: "amp, escaped amp, amp to ignore", title: "First &1 comes && first &2 serves", label: "First 1 comes & first 2 serves", key: "1", }, { description: "created with amp, updated without amp", title: "temp with &X", // will be updated below. label: "remove amp", key: "", }, { description: "created without amp, update with amp", title: "temp without access key", // will be updated below. label: "add ampY", key: "Y", }, ]; let menuIds = TESTCASES.map(({ title }) => browser.menus.create({ title })); // Should clear the access key: await browser.menus.update(menuIds[menuIds.length - 2], { title: "remove amp", }); // Should add an access key: await browser.menus.update(menuIds[menuIds.length - 1], { title: "add amp&Y", }); // Should not clear the access key because title is not set: await browser.menus.update(menuIds[menuIds.length - 1], { enabled: true }); browser.test.sendMessage("testCases", TESTCASES); } let extension = ExtensionTestUtils.loadExtension({ manifest: { permissions: ["menus"], }, background, }); await extension.startup(); const TESTCASES = await extension.awaitMessage("testCases"); let menu = await openExtensionContextMenu(); let items = menu.getElementsByTagName("menuitem"); is(items.length, TESTCASES.length, "Expected menu items for page"); TESTCASES.forEach(({ description, label, key }, i) => { is(items[i].label, label, `Label for item ${i} (${description})`); is(items[i].accessKey, key, `Accesskey for item ${i} (${description})`); }); await closeExtensionContextMenu(); await extension.unload(); BrowserTestUtils.removeTab(tab); }); add_task(async function accesskeys_selection() { const PAGE_WITH_AMPS = "data:text/plain;charset=utf-8,PageSelection&Amp"; let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, PAGE_WITH_AMPS ); gBrowser.selectedTab = tab; async function background() { const TESTCASES = [ { description: "Selection without amp", title: "percent-s: %s.", label: "percent-s: PageSelection&Amp.", key: "", }, { description: "Selection with amp after %s", title: "percent-s: %s &A.", label: "percent-s: PageSelection&Amp A.", key: "A", }, { description: "Selection with amp before %s", title: "percent-s: &B %s.", label: "percent-s: B PageSelection&Amp.", key: "B", }, { description: "Amp-percent", title: "Amp-percent: &%.", label: "Amp-percent: %.", key: "%", }, { // "&%s" should be treated as "%s", and "ignore this" with amps should be ignored. description: "Selection with amp-percent-s", title: "Amp-percent-s: &%s.&i&g&n&o&r&e& &t&h&i&s", label: "Amp-percent-s: PageSelection&Amp.ignore this", // Chrome uses the first character of the selection as access key. // Let's not copy that behavior... key: "", }, { description: "Selection with amp before amp-percent-s", title: "Amp-percent-s: &_ &%s.", label: "Amp-percent-s: _ PageSelection&Amp.", key: "_", }, ]; let lastMenuId; for (let { title } of TESTCASES) { lastMenuId = browser.menus.create({ contexts: ["selection"], title }); } // Round-trip to ensure that the menus have been registered. await browser.menus.update(lastMenuId, {}); browser.test.sendMessage("testCases", TESTCASES); } let extension = ExtensionTestUtils.loadExtension({ manifest: { permissions: ["menus"], }, background, }); await extension.startup(); // Select all await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function (arg) { let doc = content.document; let range = doc.createRange(); let selection = content.getSelection(); selection.removeAllRanges(); range.selectNodeContents(doc.body); selection.addRange(range); }); const TESTCASES = await extension.awaitMessage("testCases"); let menu = await openExtensionContextMenu(); let items = menu.getElementsByTagName("menuitem"); is(items.length, TESTCASES.length, "Expected menu items for page"); TESTCASES.forEach(({ description, label, key }, i) => { is(items[i].label, label, `Label for item ${i} (${description})`); is(items[i].accessKey, key, `Accesskey for item ${i} (${description})`); }); await closeExtensionContextMenu(); await extension.unload(); BrowserTestUtils.removeTab(tab); });