summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js')
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js258
1 files changed, 258 insertions, 0 deletions
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js b/devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js
new file mode 100644
index 0000000000..3dc5066663
--- /dev/null
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_keyboard_accessibility.js
@@ -0,0 +1,258 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Check that basic keyboard shortcuts work in the web console.
+
+"use strict";
+
+const HTML_FILENAME = `test.html`;
+const HTML_CONTENT = `<!DOCTYPE html><p>Test keyboard accessibility</p>
+ <script>
+ for (let i = 1; i <= 100; i++) {
+ console.log("console message " + i);
+ }
+ function logTrace() {
+ const sub = () => console.trace("console trace message");
+ sub();
+ }
+ logTrace();
+ </script>
+ `;
+
+const TRACE_FRAME_LINE_REGEX = /test\.html:\d+:?\d*/;
+
+const httpServer = createTestHTTPServer();
+httpServer.registerContentType("html", "text/html");
+httpServer.registerPathHandler(
+ "/" + HTML_FILENAME,
+ function (request, response) {
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.write(HTML_CONTENT);
+ }
+);
+
+const port = httpServer.identity.primaryPort;
+const TEST_URI = `http://localhost:${port}/${HTML_FILENAME}`;
+
+add_task(async function () {
+ // Force tabfocus for all elements on OSX.
+ SpecialPowers.pushPrefEnv({ set: [["accessibility.tabfocus", 7]] });
+
+ const hud = await openNewTabAndConsole(TEST_URI);
+
+ info("Web Console opened");
+ const outputScroller = hud.ui.outputScroller;
+ const traceMsgNode = await waitFor(
+ () => findConsoleAPIMessage(hud, "console trace message"),
+ "waiting for all the messages to be displayed",
+ 100,
+ 1000
+ );
+
+ // wait for all the stacktrace frames to be rendered.
+ await waitFor(() =>
+ traceMsgNode.querySelector(".message-body-wrapper > .stacktrace .frames")
+ );
+
+ let currentPosition = outputScroller.scrollTop;
+ const bottom = currentPosition;
+ hud.jsterm.focus();
+
+ info("Check Page up keyboard shortcut");
+ EventUtils.synthesizeKey("KEY_PageUp");
+ isnot(
+ outputScroller.scrollTop,
+ currentPosition,
+ "scroll position changed after page up"
+ );
+
+ info("Check Page down keyboard shortcut");
+ currentPosition = outputScroller.scrollTop;
+ EventUtils.synthesizeKey("KEY_PageDown");
+ Assert.greater(
+ outputScroller.scrollTop,
+ currentPosition,
+ "scroll position now at bottom"
+ );
+
+ info("Check Home keyboard shortcut");
+ EventUtils.synthesizeKey("KEY_Home");
+ is(outputScroller.scrollTop, 0, "scroll position now at top");
+
+ info("Check End keyboard shortcut");
+ EventUtils.synthesizeKey("KEY_End");
+ const scrollTop = outputScroller.scrollTop;
+ ok(
+ scrollTop > 0 && Math.abs(scrollTop - bottom) <= 5,
+ "scroll position now at bottom"
+ );
+
+ info("Hit Shift-Tab to focus switch to editor mode button");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ outputScroller.ownerDocument.activeElement.classList.contains(
+ "webconsole-input-openEditorButton"
+ ),
+ "switch to editor mode button is focused"
+ );
+
+ info("Check stacktrace frames can be focused");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ outputScroller.ownerDocument.activeElement.closest(".message.trace"),
+ "The active element is in the trace message"
+ );
+ is(
+ TRACE_FRAME_LINE_REGEX.exec(
+ outputScroller.ownerDocument.activeElement.innerText
+ )?.[0],
+ "test.html:10",
+ `last frame of the stacktrace is focused ${outputScroller.ownerDocument.activeElement.innerText}`
+ );
+ is(
+ outputScroller.ownerDocument.activeElement.getAttribute("class"),
+ "frame",
+ "active element has expected class"
+ );
+
+ info("Hit Tab to navigate to second frame of the stacktrace");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ outputScroller.ownerDocument.activeElement.closest(".message.trace"),
+ "The active element is in the trace message"
+ );
+ is(
+ TRACE_FRAME_LINE_REGEX.exec(
+ outputScroller.ownerDocument.activeElement.innerText
+ )?.[0],
+ "test.html:8",
+ "second frame of the stacktrace is focused"
+ );
+ is(
+ outputScroller.ownerDocument.activeElement.getAttribute("class"),
+ "frame",
+ "active element has expected class"
+ );
+
+ info("Hit Tab to navigate to first frame of the stacktrace");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ outputScroller.ownerDocument.activeElement.closest(".message.trace"),
+ "The active element is in the trace message"
+ );
+ is(
+ TRACE_FRAME_LINE_REGEX.exec(
+ outputScroller.ownerDocument.activeElement.innerText
+ )?.[0],
+ "test.html:7",
+ "third frame of the stacktrace is focused"
+ );
+ is(
+ outputScroller.ownerDocument.activeElement.getAttribute("class"),
+ "frame",
+ "active element has expected class"
+ );
+
+ info("Hit Tab to navigate to the message location");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ outputScroller.ownerDocument.activeElement.closest(".message.trace"),
+ "The active element is in the trace message"
+ );
+ is(
+ outputScroller.ownerDocument.activeElement.getAttribute("class"),
+ "frame-link-source",
+ "active element is the console trace message location"
+ );
+ is(
+ TRACE_FRAME_LINE_REGEX.exec(
+ outputScroller.ownerDocument.activeElement.innerText
+ )?.[0],
+ "test.html:7:33",
+ "active element is expected message location"
+ );
+
+ info("Hit Tab to navigate to the previous message location");
+ EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
+ ok(
+ !outputScroller.ownerDocument.activeElement.closest(".message.trace"),
+ "The active element is not in the trace message"
+ );
+ is(
+ outputScroller.ownerDocument.activeElement.getAttribute("class"),
+ "frame-link-source",
+ "active element is the console trace message location"
+ );
+ is(
+ TRACE_FRAME_LINE_REGEX.exec(
+ outputScroller.ownerDocument.activeElement.innerText
+ )[0],
+ "test.html:4:15",
+ "active element is expected message location"
+ );
+
+ info("Clear output");
+ hud.jsterm.focus();
+
+ info("try ctrl-l to clear output");
+ let clearShortcut;
+ if (Services.appinfo.OS === "Darwin") {
+ clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX");
+ } else {
+ clearShortcut = WCUL10n.getStr("webconsole.clear.key");
+ }
+ synthesizeKeyShortcut(clearShortcut);
+ await waitFor(() => !findAllMessages(hud).length);
+ ok(isInputFocused(hud), "console was cleared and input is focused");
+
+ if (Services.appinfo.OS === "Darwin") {
+ info("Log a new message from the content page");
+ const onMessage = waitForMessageByType(
+ hud,
+ "another simple text message",
+ ".console-api"
+ );
+ SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
+ content.console.log("another simple text message");
+ });
+ await onMessage;
+
+ info("Send Cmd-K to clear console");
+ synthesizeKeyShortcut(WCUL10n.getStr("webconsole.clear.alternativeKeyOSX"));
+
+ await waitFor(() => !findAllMessages(hud).length);
+ ok(
+ isInputFocused(hud),
+ "console was cleared as expected with alternative shortcut"
+ );
+ }
+
+ // Focus filter
+ info("try ctrl-f to focus filter");
+ synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
+ ok(!isInputFocused(hud), "input is not focused");
+ ok(hasFocus(getFilterInput(hud)), "filter input is focused");
+
+ info("try ctrl-f when filter is already focused");
+ synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
+ ok(!isInputFocused(hud), "input is not focused");
+ is(
+ getFilterInput(hud),
+ outputScroller.ownerDocument.activeElement,
+ "filter input is focused"
+ );
+
+ info("Ctrl-U should open view:source when input is focused");
+ hud.jsterm.focus();
+ const onTabOpen = BrowserTestUtils.waitForNewTab(
+ gBrowser,
+ url => url.startsWith("view-source:"),
+ true
+ );
+ EventUtils.synthesizeKey("u", { accelKey: true });
+ await onTabOpen;
+ ok(
+ true,
+ "The view source tab was opened with the expected keyboard shortcut"
+ );
+});