browser_toolbox_options.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
  2. /* Any copyright is dedicated to the Public Domain.
  3. * http://creativecommons.org/publicdomain/zero/1.0/ */
  4. /* import-globals-from shared-head.js */
  5. "use strict";
  6. // Tests that changing preferences in the options panel updates the prefs
  7. // and toggles appropriate things in the toolbox.
  8. var doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
  9. const {LocalizationHelper} = require("devtools/shared/l10n");
  10. const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
  11. add_task(function* () {
  12. const URL = "data:text/html;charset=utf8,test for dynamically registering " +
  13. "and unregistering tools";
  14. registerNewTool();
  15. let tab = yield addTab(URL);
  16. let target = TargetFactory.forTab(tab);
  17. toolbox = yield gDevTools.showToolbox(target);
  18. doc = toolbox.doc;
  19. yield testSelectTool();
  20. yield testOptionsShortcut();
  21. yield testOptions();
  22. yield testToggleTools();
  23. yield cleanup();
  24. });
  25. function registerNewTool() {
  26. let toolDefinition = {
  27. id: "test-tool",
  28. isTargetSupported: () => true,
  29. visibilityswitch: "devtools.test-tool.enabled",
  30. url: "about:blank",
  31. label: "someLabel"
  32. };
  33. ok(gDevTools, "gDevTools exists");
  34. ok(!gDevTools.getToolDefinitionMap().has("test-tool"),
  35. "The tool is not registered");
  36. gDevTools.registerTool(toolDefinition);
  37. ok(gDevTools.getToolDefinitionMap().has("test-tool"),
  38. "The tool is registered");
  39. }
  40. function* testSelectTool() {
  41. info("Checking to make sure that the options panel can be selected.");
  42. let onceSelected = toolbox.once("options-selected");
  43. toolbox.selectTool("options");
  44. yield onceSelected;
  45. ok(true, "Toolbox selected via selectTool method");
  46. }
  47. function* testOptionsShortcut() {
  48. info("Selecting another tool, then reselecting options panel with keyboard.");
  49. yield toolbox.selectTool("webconsole");
  50. is(toolbox.currentToolId, "webconsole", "webconsole is selected");
  51. synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
  52. is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (1)");
  53. synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
  54. is(toolbox.currentToolId, "webconsole", "webconsole is selected (1)");
  55. yield toolbox.selectTool("webconsole");
  56. is(toolbox.currentToolId, "webconsole", "webconsole is selected");
  57. synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
  58. is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
  59. synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
  60. is(toolbox.currentToolId, "webconsole", "webconsole is reselected (2)");
  61. synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
  62. is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
  63. }
  64. function* testOptions() {
  65. let tool = toolbox.getPanel("options");
  66. panelWin = tool.panelWin;
  67. let prefNodes = tool.panelDoc.querySelectorAll(
  68. "input[type=checkbox][data-pref]");
  69. // Store modified pref names so that they can be cleared on error.
  70. for (let node of tool.panelDoc.querySelectorAll("[data-pref]")) {
  71. let pref = node.getAttribute("data-pref");
  72. modifiedPrefs.push(pref);
  73. }
  74. for (let node of prefNodes) {
  75. let prefValue = GetPref(node.getAttribute("data-pref"));
  76. // Test clicking the checkbox for each options pref
  77. yield testMouseClick(node, prefValue);
  78. // Do again with opposite values to reset prefs
  79. yield testMouseClick(node, !prefValue);
  80. }
  81. let prefSelects = tool.panelDoc.querySelectorAll("select[data-pref]");
  82. for (let node of prefSelects) {
  83. yield testSelect(node);
  84. }
  85. }
  86. function* testSelect(select) {
  87. let pref = select.getAttribute("data-pref");
  88. let options = Array.from(select.options);
  89. info("Checking select for: " + pref);
  90. is(select.options[select.selectedIndex].value, GetPref(pref),
  91. "select starts out selected");
  92. for (let option of options) {
  93. if (options.indexOf(option) === select.selectedIndex) {
  94. continue;
  95. }
  96. let deferred = defer();
  97. gDevTools.once("pref-changed", (event, data) => {
  98. if (data.pref == pref) {
  99. ok(true, "Correct pref was changed");
  100. is(GetPref(pref), option.value, "Preference been switched for " + pref);
  101. } else {
  102. ok(false, "Pref " + pref + " was not changed correctly");
  103. }
  104. deferred.resolve();
  105. });
  106. select.selectedIndex = options.indexOf(option);
  107. let changeEvent = new Event("change");
  108. select.dispatchEvent(changeEvent);
  109. yield deferred.promise;
  110. }
  111. }
  112. function* testMouseClick(node, prefValue) {
  113. let deferred = defer();
  114. let pref = node.getAttribute("data-pref");
  115. gDevTools.once("pref-changed", (event, data) => {
  116. if (data.pref == pref) {
  117. ok(true, "Correct pref was changed");
  118. is(data.oldValue, prefValue, "Previous value is correct for " + pref);
  119. is(data.newValue, !prefValue, "New value is correct for " + pref);
  120. } else {
  121. ok(false, "Pref " + pref + " was not changed correctly");
  122. }
  123. deferred.resolve();
  124. });
  125. node.scrollIntoView();
  126. // We use executeSoon here to ensure that the element is in view and
  127. // clickable.
  128. executeSoon(function () {
  129. info("Click event synthesized for pref " + pref);
  130. EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
  131. });
  132. yield deferred.promise;
  133. }
  134. function* testToggleTools() {
  135. let toolNodes = panelWin.document.querySelectorAll(
  136. "#default-tools-box input[type=checkbox]:not([data-unsupported])," +
  137. "#additional-tools-box input[type=checkbox]:not([data-unsupported])");
  138. let enabledTools = [...toolNodes].filter(node => node.checked);
  139. let toggleableTools = gDevTools.getDefaultTools().filter(tool => {
  140. return tool.visibilityswitch;
  141. }).concat(gDevTools.getAdditionalTools());
  142. for (let node of toolNodes) {
  143. let id = node.getAttribute("id");
  144. ok(toggleableTools.some(tool => tool.id === id),
  145. "There should be a toggle checkbox for: " + id);
  146. }
  147. // Store modified pref names so that they can be cleared on error.
  148. for (let tool of toggleableTools) {
  149. let pref = tool.visibilityswitch;
  150. modifiedPrefs.push(pref);
  151. }
  152. // Toggle each tool
  153. for (let node of toolNodes) {
  154. yield toggleTool(node);
  155. }
  156. // Toggle again to reset tool enablement state
  157. for (let node of toolNodes) {
  158. yield toggleTool(node);
  159. }
  160. // Test that a tool can still be added when no tabs are present:
  161. // Disable all tools
  162. for (let node of enabledTools) {
  163. yield toggleTool(node);
  164. }
  165. // Re-enable the tools which are enabled by default
  166. for (let node of enabledTools) {
  167. yield toggleTool(node);
  168. }
  169. // Toggle first, middle, and last tools to ensure that toolbox tabs are
  170. // inserted in order
  171. let firstTool = toolNodes[0];
  172. let middleTool = toolNodes[(toolNodes.length / 2) | 0];
  173. let lastTool = toolNodes[toolNodes.length - 1];
  174. yield toggleTool(firstTool);
  175. yield toggleTool(firstTool);
  176. yield toggleTool(middleTool);
  177. yield toggleTool(middleTool);
  178. yield toggleTool(lastTool);
  179. yield toggleTool(lastTool);
  180. }
  181. function* toggleTool(node) {
  182. let deferred = defer();
  183. let toolId = node.getAttribute("id");
  184. if (node.checked) {
  185. gDevTools.once("tool-unregistered",
  186. checkUnregistered.bind(null, toolId, deferred));
  187. } else {
  188. gDevTools.once("tool-registered",
  189. checkRegistered.bind(null, toolId, deferred));
  190. }
  191. node.scrollIntoView();
  192. EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
  193. yield deferred.promise;
  194. }
  195. function checkUnregistered(toolId, deferred, event, data) {
  196. if (data.id == toolId) {
  197. ok(true, "Correct tool removed");
  198. // checking tab on the toolbox
  199. ok(!doc.getElementById("toolbox-tab-" + toolId),
  200. "Tab removed for " + toolId);
  201. } else {
  202. ok(false, "Something went wrong, " + toolId + " was not unregistered");
  203. }
  204. deferred.resolve();
  205. }
  206. function checkRegistered(toolId, deferred, event, data) {
  207. if (data == toolId) {
  208. ok(true, "Correct tool added back");
  209. // checking tab on the toolbox
  210. let radio = doc.getElementById("toolbox-tab-" + toolId);
  211. ok(radio, "Tab added back for " + toolId);
  212. if (radio.previousSibling) {
  213. ok(+radio.getAttribute("ordinal") >=
  214. +radio.previousSibling.getAttribute("ordinal"),
  215. "Inserted tab's ordinal is greater than equal to its previous tab." +
  216. "Expected " + radio.getAttribute("ordinal") + " >= " +
  217. radio.previousSibling.getAttribute("ordinal"));
  218. }
  219. if (radio.nextSibling) {
  220. ok(+radio.getAttribute("ordinal") <
  221. +radio.nextSibling.getAttribute("ordinal"),
  222. "Inserted tab's ordinal is less than its next tab. Expected " +
  223. radio.getAttribute("ordinal") + " < " +
  224. radio.nextSibling.getAttribute("ordinal"));
  225. }
  226. } else {
  227. ok(false, "Something went wrong, " + toolId + " was not registered");
  228. }
  229. deferred.resolve();
  230. }
  231. function GetPref(name) {
  232. let type = Services.prefs.getPrefType(name);
  233. switch (type) {
  234. case Services.prefs.PREF_STRING:
  235. return Services.prefs.getCharPref(name);
  236. case Services.prefs.PREF_INT:
  237. return Services.prefs.getIntPref(name);
  238. case Services.prefs.PREF_BOOL:
  239. return Services.prefs.getBoolPref(name);
  240. default:
  241. throw new Error("Unknown type");
  242. }
  243. }
  244. function* cleanup() {
  245. gDevTools.unregisterTool("test-tool");
  246. yield toolbox.destroy();
  247. gBrowser.removeCurrentTab();
  248. for (let pref of modifiedPrefs) {
  249. Services.prefs.clearUserPref(pref);
  250. }
  251. toolbox = doc = panelWin = modifiedPrefs = null;
  252. }