Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: tsan OR http3 OR http2
- Manifest: devtools/client/performance-new/test/browser/browser.toml
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
"use strict";
// This is the same value used by CustomizableUI tests.
const kForceOverflowWidthPx = 450;
function isActive() {
return Services.profiler.IsActive();
}
/**
* Force focus to an element that isn't focusable.
* Toolbar buttons aren't focusable because if they were, clicking them would
* focus them, which is undesirable. Therefore, they're only made focusable
* when a user is navigating with the keyboard. This function forces focus as
* is done during toolbar keyboard navigation.
*/
function forceFocus(elem) {
elem.setAttribute("tabindex", "-1");
elem.focus();
elem.removeAttribute("tabindex");
}
async function waitForProfileAndCloseTab() {
await waitUntil(
() => !button.classList.contains("profiler-paused"),
"Waiting until the profiler is no longer paused"
);
await checkTabLoadedProfile({
initialTitle: "Waiting on the profile",
successTitle: "Profile received",
errorTitle: "Error",
});
}
var button;
var dropmarker;
add_setup(async function () {
info(
"Add the profiler button to the toolbar and ensure capturing a profile loads a local url."
);
await setProfilerFrontendUrl(
"/browser/devtools/client/performance-new/test/browser/fake-frontend.html"
);
await makeSureProfilerPopupIsEnabled();
button = document.getElementById("profiler-button-button");
dropmarker = document.getElementById("profiler-button-dropmarker");
});
add_task(async function click_icon() {
info("Test that the profiler icon starts and captures a profile.");
ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
ok(!isActive(), "should start with the profiler inactive");
button.click();
await getElementByTooltip(document, "The profiler is recording a profile");
ok(isActive(), "should have started the profiler");
button.click();
// We're not testing for the tooltip "capturing a profile" because this might
// be racy.
await waitForProfileAndCloseTab();
// Back to the inactive state.
await getElementByTooltip(document, "Record a performance profile");
});
add_task(async function click_dropmarker() {
info("Test that the profiler icon dropmarker opens the panel.");
ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
ok(!isActive(), "should start with the profiler inactive");
const popupShownPromise = waitForProfilerPopupEvent(window, "popupshown");
dropmarker.click();
await popupShownPromise;
info("Ensure the panel is open and the profiler still inactive.");
Assert.equal(dropmarker.getAttribute("open"), "true", "panel should be open");
ok(!isActive(), "profiler should still be inactive");
await getElementByLabel(document, "Start Recording");
info("Press Escape to close the panel.");
const popupHiddenPromise = waitForProfilerPopupEvent(window, "popuphidden");
EventUtils.synthesizeKey("KEY_Escape");
await popupHiddenPromise;
ok(!dropmarker.hasAttribute("open"), "panel should be closed");
});
add_task(async function click_overflowed_icon() {
info("Test that the profiler icon opens the panel when overflowed.");
const overflowMenu = document.getElementById("widget-overflow");
const profilerPanel = document.getElementById("PanelUI-profiler");
ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
ok(!isActive(), "should start with the profiler inactive");
const navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
ok(
!navbar.hasAttribute("overflowing"),
"Should start with a non-overflowing toolbar."
);
info("Force the toolbar to overflow.");
const originalWindowWidth = window.outerWidth;
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await TestUtils.waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
info("Open the overflow menu.");
const chevron = document.getElementById("nav-bar-overflow-button");
chevron.click();
await TestUtils.waitForCondition(() => overflowMenu.state == "open");
info("Open the profiler panel.");
button.click();
await TestUtils.waitForCondition(() =>
profilerPanel?.hasAttribute("visible")
);
info("Ensure the panel is open and the profiler still inactive.");
ok(profilerPanel?.hasAttribute("visible"), "panel should be open");
ok(!isActive(), "profiler should still be inactive");
await getElementByLabel(document, "Start Recording");
info("Press Escape to close the panel.");
EventUtils.synthesizeKey("KEY_Escape");
await TestUtils.waitForCondition(() => overflowMenu.state == "closed");
ok(!dropmarker.hasAttribute("open"), "panel should be closed");
info("Undo the forced toolbar overflow.");
window.resizeTo(originalWindowWidth, window.outerHeight);
return TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
});
add_task(async function space_key() {
info("Test that the Space key starts and captures a profile.");
ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
ok(!isActive(), "should start with the profiler inactive");
forceFocus(button);
info("Press Space to start the profiler.");
EventUtils.synthesizeKey(" ");
ok(isActive(), "should have started the profiler");
info("Press Space again to capture the profile.");
EventUtils.synthesizeKey(" ");
await waitForProfileAndCloseTab();
});
add_task(async function enter_key() {
info("Test that the Enter key starts and captures a profile.");
ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
ok(!isActive(), "should start with the profiler inactive");
forceFocus(button);
const isMacOS = Services.appinfo.OS === "Darwin";
if (isMacOS) {
// On macOS, pressing Enter on a focused toolbarbutton does not fire a
// command event, so we do not expect Enter to start the profiler.
return;
}
info("Pressing Enter should start the profiler.");
EventUtils.synthesizeKey("KEY_Enter");
ok(isActive(), "should have started the profiler");
info("Pressing Enter again to capture the profile.");
EventUtils.synthesizeKey("KEY_Enter");
await waitForProfileAndCloseTab();
});