Bug 915141 - WebConsole: Listen to the 'command' event of 'Log Request and Response Bodies' menuitems instead of 'click'; r=msucan
authorSami Jaktholm <sjakthol@outlook.com>
Tue, 25 Feb 2014 13:44:36 +0200
changeset 170869 5bc4fa17cd79ca9994b37d1b7a04c1557f984649
parent 170868 70f928fe9ecf274d026b25946dcea07acbc281cf
child 170870 4aecbfc2da19ff6edb09a38509b9fede440fc690
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersmsucan
bugs915141
milestone30.0a1
Bug 915141 - WebConsole: Listen to the 'command' event of 'Log Request and Response Bodies' menuitems instead of 'click'; r=msucan
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js
browser/devtools/webconsole/webconsole.js
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -221,16 +221,17 @@ run-if = os == "win"
 [browser_webconsole_bug_770099_violation.js]
 [browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
 [browser_webconsole_bug_804845_ctrl_key_nav.js]
 run-if = os == "mac"
 [browser_webconsole_bug_817834_add_edited_input_to_history.js]
 [browser_webconsole_bug_821877_csp_errors.js]
 [browser_webconsole_bug_837351_securityerrors.js]
 [browser_webconsole_bug_846918_hsts_invalid-headers.js]
+[browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js]
 [browser_webconsole_cached_autocomplete.js]
 [browser_webconsole_change_font_size.js]
 [browser_webconsole_chrome.js]
 [browser_webconsole_closure_inspection.js]
 [browser_webconsole_completion.js]
 [browser_webconsole_console_extras.js]
 [browser_webconsole_console_logging_api.js]
 [browser_webconsole_count.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js
@@ -0,0 +1,112 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Tests that the 'Log Request and Response Bodies' buttons can be toggled with keyboard.
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 915141: Toggle log response bodies with keyboard";
+let hud;
+
+function test() {
+  let saveBodiesMenuItem;
+  let saveBodiesContextMenuItem;
+
+  loadTab(TEST_URI).then(({tab: tab}) => {
+    return openConsole(tab);
+  })
+  .then((aHud) => {
+    hud = aHud;
+    saveBodiesMenuItem = hud.ui.rootElement.querySelector("#saveBodies");
+    saveBodiesContextMenuItem = hud.ui.rootElement.querySelector("#saveBodiesContextMenu");
+
+    // Test the context menu action.
+    info("Testing 'Log Request and Response Bodies' menuitem of right click context menu.");
+
+    return openPopup(saveBodiesContextMenuItem);
+  })
+  .then(() => {
+    is(saveBodiesContextMenuItem.getAttribute("checked"), "false",
+       "Context menu: 'log responses' is not checked before action.");
+    is(hud.ui._saveRequestAndResponseBodies, false,
+       "Context menu: Responses are not logged before action.");
+
+    EventUtils.synthesizeKey("VK_DOWN", {});
+    EventUtils.synthesizeKey("VK_RETURN", {});
+
+   return waitForUpdate(saveBodiesContextMenuItem);
+  })
+  .then(() => {
+    is(saveBodiesContextMenuItem.getAttribute("checked"), "true",
+       "Context menu: 'log responses' is checked after menuitem was selected with keyboard.");
+    is(hud.ui._saveRequestAndResponseBodies, true,
+       "Context menu: Responses are saved after menuitem was selected with keyboard.");
+
+    return openPopup(saveBodiesMenuItem);
+  })
+  .then(() => {
+    // Test the 'Net' menu item.
+    info("Testing 'Log Request and Response Bodies' menuitem of 'Net' menu in the console.");
+    // 'Log Request and Response Bodies' should be selected due to previous test.
+
+    is(saveBodiesMenuItem.getAttribute("checked"), "true",
+       "Console net menu: 'log responses' is checked before action.");
+    is(hud.ui._saveRequestAndResponseBodies, true,
+       "Console net menu: Responses are logged before action.");
+
+    // The correct item is the last one in the menu.
+    EventUtils.synthesizeKey("VK_UP", {});
+    EventUtils.synthesizeKey("VK_RETURN", {});
+
+   return waitForUpdate(saveBodiesMenuItem);
+  })
+  .then(() => {
+    is(saveBodiesMenuItem.getAttribute("checked"), "false",
+       "Console net menu: 'log responses' is NOT checked after menuitem was selected with keyboard.");
+    is(hud.ui._saveRequestAndResponseBodies, false,
+       "Responses are NOT saved after menuitem was selected with keyboard.");
+  })
+  .then(finishTest);
+}
+
+/**
+ * Opens and waits for the menu containing aMenuItem to open.
+ * @param aMenuItem MenuItem
+ *        A MenuItem in a menu that should be opened.
+ * @return A promise that's resolved once menu is open.
+ */
+function openPopup(aMenuItem) {
+  let menu = aMenuItem.parentNode;
+
+  let menuOpened = promise.defer();
+  let uiUpdated = promise.defer();
+  // The checkbox menuitem is updated asynchronously on 'popupshowing' event so
+  // it's better to wait for both the update to happen and the menu to open
+  // before continuing or the test might fail due to a race between menu being
+  // shown and the item updated to have the correct state.
+  hud.ui.once("save-bodies-ui-toggled", uiUpdated.resolve);
+  menu.addEventListener("popupshown", function onPopup () {
+    menu.removeEventListener("popupshown", onPopup);
+    menuOpened.resolve();
+  });
+
+  menu.openPopup();
+  return Promise.all([menuOpened.promise, uiUpdated.promise]);
+}
+
+/**
+ * Waits for the settings and menu containing aMenuItem to update.
+ * @param aMenuItem MenuItem
+ *        The menuitem that should be updated.
+ * @return A promise that's resolved once the settings and menus are updated.
+ */
+function waitForUpdate(aMenuItem) {
+  info("Waiting for settings update to complete.");
+  let deferred = promise.defer();
+  hud.ui.once("save-bodies-pref-reversed", function () {
+    hud.ui.once("save-bodies-ui-toggled", deferred.resolve);
+    // The checked state is only updated once the popup is shown.
+    aMenuItem.parentNode.openPopup();
+  });
+  return deferred.promise;
+}
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -532,22 +532,22 @@ WebConsoleFrame.prototype = {
       this.getSaveRequestAndResponseBodies().then(aValue => {
         this.setSaveRequestAndResponseBodies(!aValue);
         aElement.setAttribute("checked", aValue);
         this.emit("save-bodies-pref-reversed");
       });
     }
 
     let saveBodies = doc.getElementById("saveBodies");
-    saveBodies.addEventListener("click", reverseSaveBodiesPref);
+    saveBodies.addEventListener("command", reverseSaveBodiesPref);
     saveBodies.disabled = !this.getFilterState("networkinfo") &&
                           !this.getFilterState("network");
 
     let saveBodiesContextMenu = doc.getElementById("saveBodiesContextMenu");
-    saveBodiesContextMenu.addEventListener("click", reverseSaveBodiesPref);
+    saveBodiesContextMenu.addEventListener("command", reverseSaveBodiesPref);
     saveBodiesContextMenu.disabled = !this.getFilterState("networkinfo") &&
                                      !this.getFilterState("network");
 
     saveBodies.parentNode.addEventListener("popupshowing", () => {
       updateSaveBodiesPrefUI(saveBodies);
       saveBodies.disabled = !this.getFilterState("networkinfo") &&
                             !this.getFilterState("network");
     });