Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: asan
- Manifest: devtools/client/webconsole/test/browser/_webconsole.toml
/* Any copyright is dedicated to the Public Domain.
// 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;
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"
);
});