summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/browser/browser_manage_shortcuts_remove.js
blob: 1aa25acd5c21fcc6862a12d1efa04ad57e249e46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"use strict";

async function loadShortcutsView() {
  let managerWin = await open_manager(null);
  managerWin.gViewController.loadView("addons://shortcuts/shortcuts");
  await wait_for_view_load(managerWin);
  return managerWin.document;
}

async function closeShortcutsView(doc) {
  let managerWin = doc.defaultView.parent;
  await close_manager(managerWin);
}

function getShortcutCard(doc, extension) {
  return doc.querySelector(`.shortcut[addon-id="${extension.id}"]`);
}

function getShortcutByName(doc, extension, name) {
  let card = getShortcutCard(doc, extension);
  return card && card.querySelector(`.shortcut-input[name="${name}"]`);
}

async function waitForShortcutSet(input, expected) {
  let doc = input.ownerDocument;
  await BrowserTestUtils.waitForCondition(
    () => input.getAttribute("shortcut") == expected,
    `Shortcut should be set to ${JSON.stringify(expected)}`
  );
  ok(doc.activeElement != input, "The input is no longer focused");
  checkHasRemoveButton(input, expected !== "");
}

function removeButtonForInput(input) {
  let removeButton = input.parentNode.querySelector(".shortcut-remove-button");
  ok(removeButton, "has remove button");
  return removeButton;
}

function checkHasRemoveButton(input, expected) {
  let removeButton = removeButtonForInput(input);
  let visibility = input.ownerGlobal.getComputedStyle(removeButton).visibility;
  if (expected) {
    is(visibility, "visible", "Remove button should be visible");
  } else {
    is(visibility, "hidden", "Remove button should be hidden");
  }
}

add_task(async function test_remove_shortcut() {
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      commands: {
        commandEmpty: {},
        commandOne: {
          suggested_key: { default: "Shift+Alt+1" },
        },
        commandTwo: {
          suggested_key: { default: "Shift+Alt+2" },
        },
      },
    },
    background() {
      browser.commands.onCommand.addListener(commandName => {
        browser.test.sendMessage("oncommand", commandName);
      });
    },
    useAddonManager: "temporary",
  });

  await extension.startup();

  let doc = await loadShortcutsView();

  let input = getShortcutByName(doc, extension, "commandOne");

  checkHasRemoveButton(input, true);

  // First: Verify that Shift-Del is not valid, but doesn't do anything.
  input.focus();
  EventUtils.synthesizeKey("KEY_Delete", { shiftKey: true });
  let errorElem = doc.querySelector(".error-message");
  is(errorElem.style.visibility, "visible", "Expected error message");
  let errorId = doc.l10n.getAttributes(
    errorElem.querySelector(".error-message-label")
  ).id;
  if (AppConstants.platform == "macosx") {
    is(errorId, "shortcuts-modifier-mac", "Shift-Del is not a valid shortcut");
  } else {
    is(errorId, "shortcuts-modifier-other", "Shift-Del isn't a valid shortcut");
  }
  checkHasRemoveButton(input, true);

  // Now, verify that the original shortcut still works.
  EventUtils.synthesizeKey("KEY_Escape");
  ok(doc.activeElement != input, "The input is no longer focused");
  is(errorElem.style.visibility, "hidden", "The error is hidden");

  EventUtils.synthesizeKey("1", { altKey: true, shiftKey: true });
  await extension.awaitMessage("oncommand");

  // Alt-Shift-Del is a valid shortcut.
  input.focus();
  EventUtils.synthesizeKey("KEY_Delete", { altKey: true, shiftKey: true });
  await waitForShortcutSet(input, "Alt+Shift+Delete");
  EventUtils.synthesizeKey("KEY_Delete", { altKey: true, shiftKey: true });
  await extension.awaitMessage("oncommand");

  // Del without modifiers should clear the shortcut.
  input.focus();
  EventUtils.synthesizeKey("KEY_Delete");
  await waitForShortcutSet(input, "");
  // Trigger the shortcuts that were originally associated with commandOne,
  // and then trigger commandTwo. The extension should only see commandTwo.
  EventUtils.synthesizeKey("1", { altKey: true, shiftKey: true });
  EventUtils.synthesizeKey("KEY_Delete", { altKey: true, shiftKey: true });
  EventUtils.synthesizeKey("2", { altKey: true, shiftKey: true });
  is(
    await extension.awaitMessage("oncommand"),
    "commandTwo",
    "commandOne should be disabled, commandTwo should still be enabled"
  );

  // Set a shortcut where the default was not set.
  let inputEmpty = getShortcutByName(doc, extension, "commandEmpty");
  is(inputEmpty.getAttribute("shortcut"), "", "Empty shortcut by default");
  checkHasRemoveButton(input, false);
  inputEmpty.focus();
  EventUtils.synthesizeKey("3", { altKey: true, shiftKey: true });
  await waitForShortcutSet(inputEmpty, "Alt+Shift+3");
  EventUtils.synthesizeKey("3", { altKey: true, shiftKey: true });
  await extension.awaitMessage("oncommand");
  // Clear shortcut.
  inputEmpty.focus();
  EventUtils.synthesizeKey("KEY_Delete");
  await waitForShortcutSet(inputEmpty, "");
  EventUtils.synthesizeKey("3", { altKey: true, shiftKey: true });
  EventUtils.synthesizeKey("2", { altKey: true, shiftKey: true });
  is(
    await extension.awaitMessage("oncommand"),
    "commandTwo",
    "commandEmpty should be disabled, commandTwo should still be enabled"
  );

  // Now verify that the Backspace button does the same thing as Delete.
  inputEmpty.focus();
  EventUtils.synthesizeKey("3", { altKey: true, shiftKey: true });
  await waitForShortcutSet(inputEmpty, "Alt+Shift+3");
  inputEmpty.focus();
  EventUtils.synthesizeKey("KEY_Backspace");
  await waitForShortcutSet(input, "");
  EventUtils.synthesizeKey("3", { altKey: true, shiftKey: true });
  EventUtils.synthesizeKey("2", { altKey: true, shiftKey: true });
  is(
    await extension.awaitMessage("oncommand"),
    "commandTwo",
    "commandEmpty should be disabled again by Backspace"
  );

  // Check that the remove button works as expected.
  let inputTwo = getShortcutByName(doc, extension, "commandTwo");
  is(inputTwo.getAttribute("shortcut"), "Shift+Alt+2", "initial shortcut");
  checkHasRemoveButton(inputTwo, true);
  removeButtonForInput(inputTwo).click();
  is(inputTwo.getAttribute("shortcut"), "", "cleared shortcut");
  checkHasRemoveButton(inputTwo, false);
  ok(doc.activeElement != inputTwo, "input of removed shortcut is not focused");

  await closeShortcutsView(doc);

  await extension.unload();
});