mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-03 01:38:46 +02:00
Fixing the markup of the `profiler-icon` and `close-icon` image buttons and their visual styling to allow keyboard users and assistive technology access these controls while navigating the page. Also improving the hover and focus states to these controls to ensure it is clearly separate active UI from their containing row. Providing these image buttons with accessible roles and names as well as with an ability to be focused resolves multiple a11y-checks test failures (bug 1854228), thus removing a few `fail-if` notations from the test manifest. Note: The visually hidden buttons are still shown on focus only, until a further improvement is developed. Differential Revision: https://phabricator.services.mozilla.com/D180705
186 lines
5.3 KiB
JavaScript
186 lines
5.3 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
let doc, tbody, tabAboutProcesses;
|
|
|
|
const rowTypes = ["process", "window", "thread-summary", "thread"];
|
|
|
|
function promiseUpdate() {
|
|
return promiseAboutProcessesUpdated({
|
|
doc,
|
|
tbody,
|
|
force: true,
|
|
tabAboutProcesses,
|
|
});
|
|
}
|
|
|
|
async function setTabAboutProcesses() {
|
|
info("Setting up about:processes tab");
|
|
tabAboutProcesses = await BrowserTestUtils.openNewForegroundTab({
|
|
gBrowser,
|
|
opening: "about:processes",
|
|
waitForLoad: true,
|
|
});
|
|
|
|
doc = tabAboutProcesses.linkedBrowser.contentDocument;
|
|
tbody = doc.getElementById("process-tbody");
|
|
await promiseUpdate();
|
|
}
|
|
|
|
add_setup(async function () {
|
|
await setTabAboutProcesses();
|
|
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
// Ensure both types of buttons are shown
|
|
["toolkit.aboutProcesses.showThreads", "true"],
|
|
["toolkit.aboutProcesses.showProfilerIcons", "true"],
|
|
// Change profiler URL for the test to avoid opening a remote URL and crash
|
|
["devtools.performance.recording.ui-base-url", "https://example.com"],
|
|
],
|
|
});
|
|
});
|
|
|
|
add_task(async function test_profiler_icon_button() {
|
|
info("Verify the Profiler button is properly marked up.");
|
|
|
|
let processRow = tbody.querySelector(".process");
|
|
let profilerButton = processRow.querySelector(".profiler-icon");
|
|
Assert.ok(
|
|
profilerButton.hasAttribute("title"),
|
|
"The Profile Process icon button has a title"
|
|
);
|
|
Assert.equal(
|
|
profilerButton.getAttribute("role") || profilerButton.tagName.toLowerCase(),
|
|
"button",
|
|
"The Profile Process icon is programmatically a button"
|
|
);
|
|
// ToDo: Remove the "tabindex" check when the button is using <button> element
|
|
Assert.equal(
|
|
profilerButton.getAttribute("tabindex"),
|
|
"0",
|
|
"The Profile Process icon button is included in the focus order"
|
|
);
|
|
Assert.equal(
|
|
profilerButton.getAttribute("aria-pressed"),
|
|
"false",
|
|
"The Profile button has its pressed status set to false"
|
|
);
|
|
|
|
info("Verify the Profile button can be focused with a keyboard.");
|
|
|
|
profilerButton.focus();
|
|
|
|
const { display, opacity } = window.getComputedStyle(profilerButton);
|
|
|
|
Assert.equal(
|
|
display,
|
|
"inline-block",
|
|
"the Profiler image button is in the DOM"
|
|
);
|
|
Assert.equal(opacity, "1", "the Profiler image button is visible");
|
|
|
|
Assert.equal(
|
|
profilerButton,
|
|
doc.activeElement,
|
|
"the Profiler image button can be focused"
|
|
);
|
|
|
|
// Skip the rest if the profiler was already active when this test started:
|
|
if (!Services.profiler.IsActive()) {
|
|
let waitForPressed = BrowserTestUtils.waitForMutationCondition(
|
|
profilerButton,
|
|
{ attributeFilter: ["aria-pressed"] },
|
|
() => profilerButton.getAttribute("aria-pressed") == "true"
|
|
);
|
|
|
|
// Verify we can profile the process with a keyboard.
|
|
EventUtils.synthesizeKey(" ");
|
|
|
|
await waitForPressed;
|
|
|
|
Assert.equal(
|
|
profilerButton.getAttribute("aria-pressed"),
|
|
"true",
|
|
"Pressing Space on a Profile button changes its status to pressed"
|
|
);
|
|
|
|
Services.profiler.StopProfiler();
|
|
}
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
BrowserTestUtils.removeTab(tabAboutProcesses);
|
|
});
|
|
|
|
add_task(async function test_close_icon_button() {
|
|
await setTabAboutProcesses();
|
|
|
|
doc = tabAboutProcesses.linkedBrowser.contentDocument;
|
|
tbody = doc.getElementById("process-tbody");
|
|
|
|
info("Verify the Close button is properly marked up.");
|
|
|
|
let webTabRow = findTabRowByName(doc, "New Tab");
|
|
let closeButtons = webTabRow.querySelectorAll(".close-icon");
|
|
|
|
Assert.ok(webTabRow, `We should have found New Tab tab to close it`);
|
|
Assert.equal(
|
|
closeButtons.length,
|
|
1,
|
|
"This tab should have exactly one close icon"
|
|
);
|
|
Assert.ok(
|
|
closeButtons[0].hasAttribute("title"),
|
|
"The Close Tab icon button has a title"
|
|
);
|
|
Assert.equal(
|
|
closeButtons[0].getAttribute("role") ||
|
|
closeButtons[0].tagName.toLowerCase(),
|
|
"button",
|
|
"The Close Tab icon is programmatically a button"
|
|
);
|
|
// ToDo: Remove the "tabindex" check when the button is using <button> element
|
|
Assert.equal(
|
|
closeButtons[0].getAttribute("tabindex"),
|
|
"0",
|
|
"The Close Tab icon button is included in the focus order"
|
|
);
|
|
|
|
info("Verify the Close button can be focused with a keyboard.");
|
|
|
|
closeButtons[0].focus();
|
|
|
|
Assert.equal(
|
|
closeButtons[0],
|
|
doc.activeElement,
|
|
"the Close image button can be focused"
|
|
);
|
|
|
|
const { display, opacity } = window.getComputedStyle(closeButtons[0]);
|
|
|
|
Assert.equal(opacity, "1", "the Close image button is visible");
|
|
Assert.equal(display, "inline-block", "the Close image button is in the DOM");
|
|
|
|
// Verify we can kill the tab with a keyboard.
|
|
EventUtils.synthesizeKey("KEY_Enter");
|
|
|
|
Assert.ok(
|
|
webTabRow.hasAttribute("aria-busy"),
|
|
"Pressing Enter on a Close button adds an aria-busy to the row"
|
|
);
|
|
Assert.ok(
|
|
webTabRow.classList.contains("killing"),
|
|
"Pressing Enter on a Close button starts the process of killing the tab"
|
|
);
|
|
|
|
// Give Firefox a little time to close the tab and update about:processes.
|
|
// This might take two updates as we're racing between collecting data and
|
|
// processes actually being killed.
|
|
await promiseAboutProcessesUpdated({
|
|
doc,
|
|
force: true,
|
|
tabAboutProcesses,
|
|
});
|
|
});
|