summaryrefslogtreecommitdiffstats
path: root/devtools/client/framework/test/browser_toolbox_meatball.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/framework/test/browser_toolbox_meatball.js')
-rw-r--r--devtools/client/framework/test/browser_toolbox_meatball.js135
1 files changed, 135 insertions, 0 deletions
diff --git a/devtools/client/framework/test/browser_toolbox_meatball.js b/devtools/client/framework/test/browser_toolbox_meatball.js
new file mode 100644
index 0000000000..04d9a3a0cd
--- /dev/null
+++ b/devtools/client/framework/test/browser_toolbox_meatball.js
@@ -0,0 +1,135 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Sanity test for meatball menu.
+//
+// We also use this to test the common Menu* components since we don't currently
+// have a means of testing React components in isolation.
+
+const {
+ focusableSelector,
+} = require("resource://devtools/client/shared/focus.js");
+const { Toolbox } = require("resource://devtools/client/framework/toolbox.js");
+
+add_task(async function () {
+ const tab = await addTab("about:blank");
+ const toolbox = await openToolboxForTab(
+ tab,
+ "inspector",
+ Toolbox.HostType.BOTTOM
+ );
+
+ info("Check opening meatball menu by clicking the menu button");
+ await openMeatballMenuWithClick(toolbox);
+ const menuDockToBottom = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-dock-bottom"
+ );
+ Assert.strictEqual(
+ menuDockToBottom.getAttribute("aria-checked"),
+ "true",
+ "menuDockToBottom has checked"
+ );
+
+ info("Check closing meatball menu by clicking outside the popup area");
+ await closeMeatballMenuWithClick(toolbox);
+
+ info("Check moving the focus element with key event");
+ await openMeatballMenuWithClick(toolbox);
+ checkKeyHandling(toolbox);
+
+ info("Check closing meatball menu with escape key");
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, toolbox.win);
+ await waitForMeatballMenuToClose(toolbox);
+
+ // F1 should trigger the settings panel and close the menu at the same time.
+ info("Check closing meatball menu with F1 key");
+ await openMeatballMenuWithClick(toolbox);
+ EventUtils.synthesizeKey("VK_F1", {}, toolbox.win);
+ await waitForMeatballMenuToClose(toolbox);
+
+ await toolbox.destroy();
+});
+
+async function openMeatballMenuWithClick(toolbox) {
+ const meatballButton = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-button"
+ );
+ await waitUntil(() => meatballButton.style.pointerEvents !== "none");
+ EventUtils.synthesizeMouseAtCenter(meatballButton, {}, toolbox.win);
+
+ const panel = toolbox.doc.querySelectorAll(".tooltip-xul-wrapper");
+ const shownListener = new Promise(res => {
+ panel[0].addEventListener("popupshown", res, { once: true });
+ });
+
+ const menuPanel = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-button-panel"
+ );
+ ok(menuPanel, "meatball panel is available");
+
+ info("Waiting for the menu panel to be displayed");
+
+ await shownListener;
+ await waitUntil(() => menuPanel.classList.contains("tooltip-visible"));
+}
+
+async function closeMeatballMenuWithClick(toolbox) {
+ const meatballButton = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-button"
+ );
+ await waitUntil(
+ () => toolbox.win.getComputedStyle(meatballButton).pointerEvents === "none"
+ );
+ meatballButton.click();
+
+ const menuPanel = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-button-panel"
+ );
+ ok(menuPanel, "meatball panel is available");
+
+ info("Waiting for the menu panel to be hidden");
+ await waitUntil(() => !menuPanel.classList.contains("tooltip-visible"));
+}
+
+async function waitForMeatballMenuToClose(toolbox) {
+ const menuPanel = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-button-panel"
+ );
+ ok(menuPanel, "meatball panel is available");
+
+ info("Waiting for the menu panel to be hidden");
+ await waitUntil(() => !menuPanel.classList.contains("tooltip-visible"));
+}
+
+function checkKeyHandling(toolbox) {
+ const selectable = toolbox.doc
+ .getElementById("toolbox-meatball-menu")
+ .querySelectorAll(focusableSelector);
+
+ EventUtils.synthesizeKey("VK_DOWN", {}, toolbox.win);
+ is(
+ toolbox.doc.activeElement,
+ selectable[0],
+ "First item selected with down key."
+ );
+ EventUtils.synthesizeKey("VK_UP", {}, toolbox.win);
+ is(
+ toolbox.doc.activeElement,
+ selectable[selectable.length - 1],
+ "End item selected with up key."
+ );
+ EventUtils.synthesizeKey("VK_HOME", {}, toolbox.win);
+ is(
+ toolbox.doc.activeElement,
+ selectable[0],
+ "First item selected with home key."
+ );
+ EventUtils.synthesizeKey("VK_END", {}, toolbox.win);
+ is(
+ toolbox.doc.activeElement,
+ selectable[selectable.length - 1],
+ "End item selected with down key."
+ );
+}