summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js')
-rw-r--r--comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js577
1 files changed, 577 insertions, 0 deletions
diff --git a/comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js b/comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js
new file mode 100644
index 0000000000..82928957f4
--- /dev/null
+++ b/comm/mail/components/extensions/test/browser/browser_ext_commands_onCommand.js
@@ -0,0 +1,577 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+var testCommands = [
+ // Ctrl Shortcuts
+ {
+ name: "toggle-ctrl-a",
+ shortcut: "Ctrl+A",
+ key: "A",
+ // Does not work in compose window on Linux.
+ skip: ["messageCompose", "content"],
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-up",
+ shortcut: "Ctrl+Up",
+ key: "VK_UP",
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ // Alt Shortcuts
+ {
+ name: "toggle-alt-a",
+ shortcut: "Alt+A",
+ key: "A",
+ // Does not work in compose window on Mac.
+ skip: ["messageCompose"],
+ modifiers: {
+ altKey: true,
+ },
+ },
+ {
+ name: "toggle-alt-down",
+ shortcut: "Alt+Down",
+ key: "VK_DOWN",
+ modifiers: {
+ altKey: true,
+ },
+ },
+ // Mac Shortcuts
+ {
+ name: "toggle-command-shift-page-up",
+ shortcutMac: "Command+Shift+PageUp",
+ key: "VK_PAGE_UP",
+ modifiers: {
+ accelKey: true,
+ shiftKey: true,
+ },
+ },
+ {
+ name: "toggle-mac-control-shift+period",
+ shortcut: "Ctrl+Shift+Period",
+ shortcutMac: "MacCtrl+Shift+Period",
+ key: "VK_PERIOD",
+ modifiers: {
+ ctrlKey: true,
+ shiftKey: true,
+ },
+ },
+ // Ctrl+Shift Shortcuts
+ {
+ name: "toggle-ctrl-shift-left",
+ shortcut: "Ctrl+Shift+Left",
+ key: "VK_LEFT",
+ modifiers: {
+ accelKey: true,
+ shiftKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-shift-1",
+ shortcut: "Ctrl+Shift+1",
+ key: "1",
+ modifiers: {
+ accelKey: true,
+ shiftKey: true,
+ },
+ },
+ // Alt+Shift Shortcuts
+ {
+ name: "toggle-alt-shift-1",
+ shortcut: "Alt+Shift+1",
+ key: "1",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
+ // TODO: This results in multiple events fired. See bug 1805375.
+ /*
+ {
+ name: "toggle-alt-shift-a",
+ shortcut: "Alt+Shift+A",
+ key: "A",
+ // Does not work in compose window on Mac.
+ skip: ["messageCompose"],
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
+ */
+ {
+ name: "toggle-alt-shift-right",
+ shortcut: "Alt+Shift+Right",
+ key: "VK_RIGHT",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
+ // Function keys
+ {
+ name: "function-keys-Alt+Shift+F3",
+ shortcut: "Alt+Shift+F3",
+ key: "VK_F3",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
+ {
+ name: "function-keys-F2",
+ shortcut: "F2",
+ key: "VK_F2",
+ modifiers: {
+ altKey: false,
+ shiftKey: false,
+ },
+ },
+ // Misc Shortcuts
+ {
+ name: "valid-command-with-unrecognized-property-name",
+ shortcut: "Alt+Shift+3",
+ key: "3",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ unrecognized_property: "with-a-random-value",
+ },
+ {
+ name: "spaces-in-shortcut-name",
+ shortcut: " Alt + Shift + 2 ",
+ key: "2",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-space",
+ shortcut: "Ctrl+Space",
+ key: "VK_SPACE",
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-comma",
+ shortcut: "Ctrl+Comma",
+ key: "VK_COMMA",
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-period",
+ shortcut: "Ctrl+Period",
+ key: "VK_PERIOD",
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-alt-v",
+ shortcut: "Ctrl+Alt+V",
+ key: "V",
+ modifiers: {
+ accelKey: true,
+ altKey: true,
+ },
+ },
+];
+
+requestLongerTimeout(2);
+
+add_task(async function test_user_defined_commands() {
+ let win1 = await openNewMailWindow();
+
+ let commands = {};
+ let isMac = AppConstants.platform == "macosx";
+ let totalMacOnlyCommands = 0;
+ let numberNumericCommands = 4;
+
+ for (let testCommand of testCommands) {
+ let command = {
+ suggested_key: {},
+ };
+
+ if (testCommand.shortcut) {
+ command.suggested_key.default = testCommand.shortcut;
+ }
+
+ if (testCommand.shortcutMac) {
+ command.suggested_key.mac = testCommand.shortcutMac;
+ }
+
+ if (testCommand.shortcutMac && !testCommand.shortcut) {
+ totalMacOnlyCommands++;
+ }
+
+ if (testCommand.unrecognized_property) {
+ command.unrecognized_property = testCommand.unrecognized_property;
+ }
+
+ commands[testCommand.name] = command;
+ }
+
+ function background() {
+ browser.commands.onCommand.addListener((commandName, activeTab) => {
+ browser.test.sendMessage("oncommand event received", {
+ commandName,
+ activeTab,
+ });
+ });
+ browser.test.sendMessage("ready");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ commands,
+ },
+ background,
+ });
+
+ SimpleTest.waitForExplicitFinish();
+ let waitForConsole = new Promise(resolve => {
+ SimpleTest.monitorConsole(resolve, [
+ {
+ message:
+ /Reading manifest: Warning processing commands.*.unrecognized_property: An unexpected property was found/,
+ },
+ ]);
+ });
+
+ // Unrecognized_property in manifest triggers warning.
+ ExtensionTestUtils.failOnSchemaWarnings(false);
+ await extension.startup();
+ ExtensionTestUtils.failOnSchemaWarnings(true);
+ await extension.awaitMessage("ready");
+
+ async function runTest(window, expectedTabType) {
+ for (let testCommand of testCommands) {
+ if (testCommand.skip && testCommand.skip.includes(expectedTabType)) {
+ continue;
+ }
+ if (testCommand.shortcutMac && !testCommand.shortcut && !isMac) {
+ continue;
+ }
+ await BrowserTestUtils.synthesizeKey(
+ testCommand.key,
+ testCommand.modifiers,
+ window.browsingContext
+ );
+ let message = await extension.awaitMessage("oncommand event received");
+ is(
+ message.commandName,
+ testCommand.name,
+ `Expected onCommand listener to fire with the correct name: ${testCommand.name}`
+ );
+ is(
+ message.activeTab.type,
+ expectedTabType,
+ `Expected onCommand listener to fire with the correct tab type: ${expectedTabType}`
+ );
+ }
+ }
+
+ // Create another window after the extension is loaded.
+ let win2 = await openNewMailWindow();
+
+ let totalTestCommands =
+ Object.keys(testCommands).length + numberNumericCommands;
+ let expectedCommandsRegistered = isMac
+ ? totalTestCommands
+ : totalTestCommands - totalMacOnlyCommands;
+
+ let account = createAccount();
+ addIdentity(account);
+ let win3 = await openComposeWindow(account);
+ // Some key combinations do not work if the TO field has focus.
+ win3.document.querySelector("editor").focus();
+
+ // Confirm the keysets have been added to all windows.
+ let keysetID = `ext-keyset-id-${makeWidgetId(extension.id)}`;
+
+ let keyset = win1.document.getElementById(keysetID);
+ ok(keyset != null, "Expected keyset to exist");
+ is(
+ keyset.children.length,
+ expectedCommandsRegistered,
+ "Expected keyset of window #1 to have the correct number of children"
+ );
+
+ keyset = win2.document.getElementById(keysetID);
+ ok(keyset != null, "Expected keyset to exist");
+ is(
+ keyset.children.length,
+ expectedCommandsRegistered,
+ "Expected keyset of window #2 to have the correct number of children"
+ );
+
+ keyset = win3.document.getElementById(keysetID);
+ ok(keyset != null, "Expected keyset to exist");
+ is(
+ keyset.children.length,
+ expectedCommandsRegistered,
+ "Expected keyset of window #3 to have the correct number of children"
+ );
+
+ // Confirm that the commands are registered to all windows.
+ await focusWindow(win1);
+ await runTest(win1, "mail");
+
+ await focusWindow(win2);
+ await runTest(win2, "mail");
+
+ await focusWindow(win3);
+ await runTest(win3, "messageCompose");
+
+ // Unload the extension and confirm that the keysets have been removed from all windows.
+ await extension.unload();
+
+ keyset = win1.document.getElementById(keysetID);
+ is(keyset, null, "Expected keyset to be removed from the window #1");
+
+ keyset = win2.document.getElementById(keysetID);
+ is(keyset, null, "Expected keyset to be removed from the window #2");
+
+ keyset = win3.document.getElementById(keysetID);
+ is(keyset, null, "Expected keyset to be removed from the window #3");
+
+ await BrowserTestUtils.closeWindow(win1);
+ await BrowserTestUtils.closeWindow(win2);
+ await BrowserTestUtils.closeWindow(win3);
+
+ SimpleTest.endMonitorConsole();
+ await waitForConsole;
+});
+
+add_task(async function test_commands_MV3_event_page() {
+ let win1 = await openNewMailWindow();
+
+ let commands = {};
+ let isMac = AppConstants.platform == "macosx";
+ let totalMacOnlyCommands = 0;
+ let numberNumericCommands = 4;
+
+ for (let testCommand of testCommands) {
+ let command = {
+ suggested_key: {},
+ };
+
+ if (testCommand.shortcut) {
+ command.suggested_key.default = testCommand.shortcut;
+ }
+
+ if (testCommand.shortcutMac) {
+ command.suggested_key.mac = testCommand.shortcutMac;
+ }
+
+ if (testCommand.shortcutMac && !testCommand.shortcut) {
+ totalMacOnlyCommands++;
+ }
+
+ if (testCommand.unrecognized_property) {
+ command.unrecognized_property = testCommand.unrecognized_property;
+ }
+
+ commands[testCommand.name] = command;
+ }
+
+ function background() {
+ // Whenever the extension starts or wakes up, the eventCounter is reset and
+ // allows to observe the order of events fired. In case of a wake-up, the
+ // first observed event is the one that woke up the background.
+ let eventCounter = 0;
+
+ browser.test.onMessage.addListener(async message => {
+ if (message == "createPopup") {
+ let popup = await browser.windows.create({
+ type: "popup",
+ url: "example.html",
+ });
+ browser.test.sendMessage("popupCreated", popup);
+ }
+ });
+
+ browser.commands.onCommand.addListener(async (commandName, activeTab) => {
+ browser.test.sendMessage("oncommand event received", {
+ eventCount: ++eventCounter,
+ commandName,
+ activeTab,
+ });
+ });
+ browser.test.sendMessage("ready");
+ }
+ let extension = ExtensionTestUtils.loadExtension({
+ files: {
+ "background.js": background,
+ "utils.js": await getUtilsJS(),
+ "example.html": `<!DOCTYPE HTML>
+ <html>
+ <head>
+ <title>EXAMPLE</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ </head>
+ <body>
+ <p>This is an example page</p>
+ </body>
+ </html>`,
+ },
+ manifest: {
+ manifest_version: 3,
+ background: { scripts: ["utils.js", "background.js"] },
+ browser_specific_settings: { gecko: { id: "commands@mochi.test" } },
+ commands,
+ },
+ });
+
+ SimpleTest.waitForExplicitFinish();
+ let waitForConsole = new Promise(resolve => {
+ SimpleTest.monitorConsole(resolve, [
+ {
+ message:
+ /Reading manifest: Warning processing commands.*.unrecognized_property: An unexpected property was found/,
+ },
+ ]);
+ });
+
+ // Unrecognized_property in manifest triggers warning.
+ ExtensionTestUtils.failOnSchemaWarnings(false);
+ await extension.startup();
+ ExtensionTestUtils.failOnSchemaWarnings(true);
+ await extension.awaitMessage("ready");
+
+ // Check for persistent listener.
+ assertPersistentListeners(extension, "commands", "onCommand", {
+ primed: false,
+ });
+
+ let gEventCounter = 0;
+ async function runTest(window, expectedTabType) {
+ // The second run will terminate the background script before each keypress,
+ // verifying that the background script is waking up correctly.
+ for (let terminateBackground of [false, true]) {
+ for (let testCommand of testCommands) {
+ if (testCommand.skip && testCommand.skip.includes(expectedTabType)) {
+ continue;
+ }
+ if (testCommand.shortcutMac && !testCommand.shortcut && !isMac) {
+ continue;
+ }
+
+ if (terminateBackground) {
+ gEventCounter = 0;
+ }
+
+ if (terminateBackground) {
+ // Terminate the background and verify the primed persistent listener.
+ await extension.terminateBackground({
+ disableResetIdleForTest: true,
+ });
+ assertPersistentListeners(extension, "commands", "onCommand", {
+ primed: true,
+ });
+ await BrowserTestUtils.synthesizeKey(
+ testCommand.key,
+ testCommand.modifiers,
+ window.browsingContext
+ );
+ // Wait for background restart.
+ await extension.awaitMessage("ready");
+ } else {
+ await BrowserTestUtils.synthesizeKey(
+ testCommand.key,
+ testCommand.modifiers,
+ window.browsingContext
+ );
+ }
+
+ let message = await extension.awaitMessage("oncommand event received");
+ is(
+ message.commandName,
+ testCommand.name,
+ `onCommand listener should fire with the correct command name`
+ );
+ is(
+ message.activeTab.type,
+ expectedTabType,
+ `onCommand listener should fire with the correct tab type`
+ );
+ is(
+ message.eventCount,
+ ++gEventCounter,
+ `Event counter should be correct`
+ );
+ }
+ }
+ }
+
+ // Create another window after the extension is loaded.
+ let win2 = await openNewMailWindow();
+
+ let totalTestCommands =
+ Object.keys(testCommands).length + numberNumericCommands;
+ let expectedCommandsRegistered = isMac
+ ? totalTestCommands
+ : totalTestCommands - totalMacOnlyCommands;
+
+ let account = createAccount();
+ addIdentity(account);
+ let win3 = await openComposeWindow(account);
+ // Some key combinations do not work if the TO field has focus.
+ win3.document.querySelector("editor").focus();
+
+ // Open a popup window.
+ let popupPromise = extension.awaitMessage("popupCreated");
+ extension.sendMessage("createPopup");
+ let popup = await popupPromise;
+ let win4 = Services.wm.getOuterWindowWithId(popup.id);
+
+ // Confirm the keysets have been added to all windows.
+ let keysetID = `ext-keyset-id-${makeWidgetId(extension.id)}`;
+
+ let windows = [
+ { window: win1, autoRemove: false, type: "mail" },
+ { window: win2, autoRemove: false, type: "mail" },
+ { window: win3, autoRemove: false, type: "messageCompose" },
+ { window: win4, autoRemove: true, type: "content" },
+ ];
+ for (let i in windows) {
+ let keyset = windows[i].window.document.getElementById(keysetID);
+ ok(keyset != null, "Expected keyset to exist");
+ is(
+ keyset.children.length,
+ expectedCommandsRegistered,
+ `Expected keyset of window #${i} to have the correct number of children`
+ );
+
+ // Confirm that the commands are registered to all windows.
+ await focusWindow(windows[i].window);
+ await runTest(windows[i].window, windows[i].type);
+ }
+
+ // Unload the extension and confirm that the keysets have been removed from
+ // all windows.
+ await extension.unload();
+ for (let i in windows) {
+ // Extension popup windows are removed/closed on extension unload, so they
+ // have to skip this part of the test.
+ if (windows[i].autoRemove) {
+ continue;
+ }
+ let keyset = windows[i].window.document.getElementById(keysetID);
+ is(keyset, null, `Expected keyset to be removed from the window #${i}`);
+ await BrowserTestUtils.closeWindow(windows[i].window);
+ }
+
+ SimpleTest.endMonitorConsole();
+ await waitForConsole;
+});