summaryrefslogtreecommitdiffstats
path: root/devtools/client/performance-new/test/browser/browser_split-toolbar-button.js
blob: 4caa55291058b7ec612e4e50d3a94973b7ca2aa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* 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
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"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(
    "http://example.com",
    "/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();
});