summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js269
1 files changed, 269 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js b/browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js
new file mode 100644
index 0000000000..6614bb62c2
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_click_types.js
@@ -0,0 +1,269 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+async function test_clickData({ manifest_version, persistent }) {
+ const action = manifest_version < 3 ? "browser_action" : "action";
+ const background = { scripts: ["background.js"] };
+
+ if (persistent != null) {
+ background.persistent = persistent;
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ manifest_version,
+ [action]: {},
+ background,
+ },
+
+ files: {
+ "background.js": function backgroundScript() {
+ function onClicked(tab, info) {
+ let button = info.button;
+ let modifiers = info.modifiers;
+ browser.test.sendMessage("onClick", { button, modifiers });
+ }
+
+ const apiNS =
+ browser.runtime.getManifest().manifest_version >= 3
+ ? "action"
+ : "browserAction";
+
+ browser[apiNS].onClicked.addListener(onClicked);
+ browser.test.sendMessage("ready");
+ },
+ },
+ });
+
+ const map = {
+ shiftKey: "Shift",
+ altKey: "Alt",
+ metaKey: "Command",
+ ctrlKey: "Ctrl",
+ };
+
+ function assertSingleModifier(info, modifier, area) {
+ if (modifier === "ctrlKey" && AppConstants.platform === "macosx") {
+ is(
+ info.modifiers.length,
+ 2,
+ `MacCtrl modifier with control click on Mac`
+ );
+ is(
+ info.modifiers[1],
+ "MacCtrl",
+ `MacCtrl modifier with control click on Mac`
+ );
+ } else {
+ is(
+ info.modifiers.length,
+ 1,
+ `No unnecessary modifiers for exactly one key on event`
+ );
+ }
+
+ is(info.modifiers[0], map[modifier], `Correct modifier on ${area} click`);
+ }
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ if (manifest_version >= 3 || persistent === false) {
+ // NOTE: even in MV3 where the API namespace is technically "action",
+ // the event listeners will be persisted into the startup data
+ // with "browserAction" as the module, because that is the name
+ // of the module shared by both MV2 browserAction and MV3 action APIs.
+ assertPersistentListeners(extension, "browserAction", "onClicked", {
+ primed: false,
+ });
+ await extension.terminateBackground();
+ assertPersistentListeners(extension, "browserAction", "onClicked", {
+ primed: true,
+ });
+ }
+
+ for (let area of [CustomizableUI.AREA_NAVBAR, getCustomizableUIPanelID()]) {
+ let widget = getBrowserActionWidget(extension);
+ CustomizableUI.addWidgetToArea(widget.id, area);
+
+ for (let modifier of Object.keys(map)) {
+ for (let i = 0; i < 2; i++) {
+ info(`test click with button ${i} modifier ${modifier}`);
+ let clickEventData = { button: i };
+ clickEventData[modifier] = true;
+ await clickBrowserAction(extension, window, clickEventData);
+ let details = await extension.awaitMessage("onClick");
+
+ is(details.button, i, `Correct button in ${area} click`);
+ assertSingleModifier(details, modifier, area);
+ }
+
+ info(`test keypress with modifier ${modifier}`);
+ let keypressEventData = {};
+ keypressEventData[modifier] = true;
+ await triggerBrowserActionWithKeyboard(extension, " ", keypressEventData);
+ let details = await extension.awaitMessage("onClick");
+
+ is(details.button, 0, `Key command emulates left click`);
+ assertSingleModifier(details, modifier, area);
+ }
+ }
+
+ if (manifest_version >= 3 || persistent === false) {
+ // The background event page is expected to have been
+ // spawned again to handle the action onClicked event.
+ await extension.awaitMessage("ready");
+ }
+
+ await extension.unload();
+}
+
+async function test_clickData_reset({ manifest_version }) {
+ const action = manifest_version < 3 ? "browser_action" : "action";
+ const browser_action_command =
+ manifest_version < 3 ? "_execute_browser_action" : "_execute_action";
+ const browser_action_key = "j";
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ manifest_version,
+ [action]: {
+ default_area: "navbar",
+ },
+ page_action: {},
+ commands: {
+ [browser_action_command]: {
+ suggested_key: {
+ default: "Alt+Shift+J",
+ },
+ },
+ },
+ },
+
+ async background() {
+ function onBrowserActionClicked(tab, info) {
+ browser.test.sendMessage("onClick", info);
+ }
+
+ function onPageActionClicked(tab, info) {
+ browser.test.sendMessage("open-popup");
+ }
+
+ const { manifest_version } = browser.runtime.getManifest();
+ const apiNS = manifest_version >= 3 ? "action" : "browserAction";
+
+ browser[apiNS].onClicked.addListener(onBrowserActionClicked);
+
+ // pageAction should only be available in MV2 extensions.
+ if (manifest_version < 3) {
+ browser.pageAction.onClicked.addListener(onPageActionClicked);
+
+ let [tab] = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ await browser.pageAction.show(tab.id);
+ }
+
+ browser.test.sendMessage("ready");
+ },
+ });
+
+ // Pollute the state of the browserAction's lastClickInfo
+ async function clickBrowserActionWithModifiers() {
+ await clickBrowserAction(extension, window, { button: 1, shiftKey: true });
+ let info = await extension.awaitMessage("onClick");
+ is(info.button, 1, "Got expected ClickData button details");
+ is(info.modifiers[0], "Shift", "Got expected ClickData modifiers details");
+ }
+
+ function assertInfoReset(info) {
+ is(info.button, 0, `ClickData button reset properly`);
+ is(info.modifiers.length, 0, `ClickData modifiers reset properly`);
+ }
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ if (manifest_version >= 3) {
+ // NOTE: even in MV3 where the API namespace is technically "action",
+ // the event listeners will be persisted into the startup data
+ // with "browserAction" as the module, because that is the name
+ // of the module shared by both MV2 browserAction and MV3 action APIs.
+ assertPersistentListeners(extension, "browserAction", "onClicked", {
+ primed: false,
+ });
+ await extension.terminateBackground();
+ assertPersistentListeners(extension, "browserAction", "onClicked", {
+ primed: true,
+ });
+ }
+
+ await clickBrowserActionWithModifiers();
+
+ if (manifest_version >= 3) {
+ // The background event page is expected to have been
+ // spawned again to handle the action onClicked event.
+ await extension.awaitMessage("ready");
+ } else {
+ extension.onMessage("open-popup", () => {
+ EventUtils.synthesizeKey(browser_action_key, {
+ altKey: true,
+ shiftKey: true,
+ });
+ });
+
+ // pageAction should only be available in MV2 extensions.
+ await clickPageAction(extension);
+
+ // NOTE: the pageAction event listener then triggers browserAction.onClicked
+ assertInfoReset(await extension.awaitMessage("onClick"));
+ }
+
+ await clickBrowserActionWithModifiers();
+
+ await triggerBrowserActionWithKeyboard(extension, " ");
+ assertInfoReset(await extension.awaitMessage("onClick"));
+
+ await clickBrowserActionWithModifiers();
+
+ await triggerBrowserActionWithKeyboard(extension, " ");
+ assertInfoReset(await extension.awaitMessage("onClick"));
+
+ await extension.unload();
+}
+
+add_task(function test_clickData_MV2() {
+ return test_clickData({ manifest_version: 2 });
+});
+
+add_task(async function test_clickData_MV2_eventpage() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.eventPages.enabled", true]],
+ });
+ await test_clickData({
+ manifest_version: 2,
+ persistent: false,
+ });
+ await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function test_clickData_MV3() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.manifestV3.enabled", true]],
+ });
+ await test_clickData({ manifest_version: 3 });
+ await SpecialPowers.popPrefEnv();
+});
+
+add_task(function test_clickData_reset_MV2() {
+ return test_clickData_reset({ manifest_version: 2 });
+});
+
+add_task(async function test_clickData_reset_MV3() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.manifestV3.enabled", true]],
+ });
+ await test_clickData_reset({ manifest_version: 3 });
+ await SpecialPowers.popPrefEnv();
+});