/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; add_task(async function test_user_defined_commands() { const testCommands = [ // Ctrl Shortcuts { name: "toggle-ctrl-a", shortcut: "Ctrl+A", key: "A", 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", 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, }, }, { name: "toggle-alt-shift-a", shortcut: "Alt+Shift+A", key: "A", 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, }, }, ]; // Create a window before the extension is loaded. let win1 = await BrowserTestUtils.openNewBrowserWindow(); BrowserTestUtils.loadURIString(win1.gBrowser.selectedBrowser, "about:robots"); await BrowserTestUtils.browserLoaded(win1.gBrowser.selectedBrowser); // We would have previously focused the window's content area after the // navigation from about:blank to about:robots, but bug 1596738 changed this // to prevent the browser element from stealing focus from the urlbar. // // Some of these command tests (specifically alt-a on linux) were designed // based on focus being in the browser content, so we need to manually focus // the browser here to preserve that assumption. win1.gBrowser.selectedBrowser.focus(); 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 => { browser.test.sendMessage("oncommand", commandName); }); browser.test.sendMessage("ready"); } let extension = ExtensionTestUtils.loadExtension({ manifest: { commands: 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/, }, ]); }); ExtensionTestUtils.failOnSchemaWarnings(false); await extension.startup(); ExtensionTestUtils.failOnSchemaWarnings(true); await extension.awaitMessage("ready"); async function runTest(window) { for (let testCommand of testCommands) { if (testCommand.shortcutMac && !testCommand.shortcut && !isMac) { continue; } EventUtils.synthesizeKey(testCommand.key, testCommand.modifiers, window); let message = await extension.awaitMessage("oncommand"); is( message, testCommand.name, `Expected onCommand listener to fire with the correct name: ${testCommand.name}` ); } } // Create another window after the extension is loaded. let win2 = await BrowserTestUtils.openNewBrowserWindow(); BrowserTestUtils.loadURIString(win2.gBrowser.selectedBrowser, "about:robots"); await BrowserTestUtils.browserLoaded(win2.gBrowser.selectedBrowser); // See comment above. win2.gBrowser.selectedBrowser.focus(); let totalTestCommands = Object.keys(testCommands).length + numberNumericCommands; let expectedCommandsRegistered = isMac ? totalTestCommands : totalTestCommands - totalMacOnlyCommands; // Confirm the keysets have been added to both 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 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 to have the correct number of children" ); // Confirm that the commands are registered to both windows. await focusWindow(win1); await runTest(win1); await focusWindow(win2); await runTest(win2); let privateWin = await BrowserTestUtils.openNewBrowserWindow({ private: true, }); BrowserTestUtils.loadURIString( privateWin.gBrowser.selectedBrowser, "about:robots" ); await BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser); // See comment above. privateWin.gBrowser.selectedBrowser.focus(); keyset = privateWin.document.getElementById(keysetID); is(keyset, null, "Expected keyset is not added to private windows"); await extension.unload(); // Confirm that the keysets have been removed from both windows after the extension is unloaded. keyset = win1.document.getElementById(keysetID); is(keyset, null, "Expected keyset to be removed from the window"); keyset = win2.document.getElementById(keysetID); is(keyset, null, "Expected keyset to be removed from the window"); // Test that given permission the keyset is added to the private window. extension = ExtensionTestUtils.loadExtension({ manifest: { commands: commands, }, incognitoOverride: "spanning", background, }); // unrecognized_property in manifest triggers warning. ExtensionTestUtils.failOnSchemaWarnings(false); await extension.startup(); ExtensionTestUtils.failOnSchemaWarnings(true); await extension.awaitMessage("ready"); keysetID = `ext-keyset-id-${makeWidgetId(extension.id)}`; keyset = win1.document.getElementById(keysetID); ok(keyset != null, "Expected keyset to exist on win1"); is( keyset.children.length, expectedCommandsRegistered, "Expected keyset to have the correct number of children" ); keyset = win2.document.getElementById(keysetID); ok(keyset != null, "Expected keyset to exist on win2"); is( keyset.children.length, expectedCommandsRegistered, "Expected keyset to have the correct number of children" ); keyset = privateWin.document.getElementById(keysetID); ok(keyset != null, "Expected keyset was added to private windows"); is( keyset.children.length, expectedCommandsRegistered, "Expected keyset to have the correct number of children" ); await focusWindow(privateWin); await runTest(privateWin); await extension.unload(); keyset = privateWin.document.getElementById(keysetID); is(keyset, null, "Expected keyset to be removed from the private window"); await BrowserTestUtils.closeWindow(win1); await BrowserTestUtils.closeWindow(win2); await BrowserTestUtils.closeWindow(privateWin); SimpleTest.endMonitorConsole(); await waitForConsole; }); add_task(async function test_commands_event_page() { await SpecialPowers.pushPrefEnv({ set: [["extensions.eventPages.enabled", true]], }); let extension = ExtensionTestUtils.loadExtension({ useAddonManager: "permanent", manifest: { browser_specific_settings: { gecko: { id: "eventpage@commands" } }, background: { persistent: false }, commands: { "toggle-feature": { suggested_key: { default: "Alt+Shift+J", }, }, }, }, background() { browser.commands.onCommand.addListener(name => { browser.test.assertEq(name, "toggle-feature", "command received"); browser.test.sendMessage("onCommand"); }); browser.test.sendMessage("ready"); }, }); await extension.startup(); await extension.awaitMessage("ready"); assertPersistentListeners(extension, "commands", "onCommand", { primed: false, }); // test events waken background await extension.terminateBackground(); assertPersistentListeners(extension, "commands", "onCommand", { primed: true, }); EventUtils.synthesizeKey("j", { altKey: true, shiftKey: true }); await extension.awaitMessage("ready"); await extension.awaitMessage("onCommand"); ok(true, "persistent event woke background"); assertPersistentListeners(extension, "commands", "onCommand", { primed: false, }); await extension.unload(); await SpecialPowers.popPrefEnv(); });