tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_split-toolbar-button.js (6719B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 function isActive() {
      8  return Services.profiler.IsActive();
      9 }
     10 
     11 /**
     12 * Force focus to an element that isn't focusable.
     13 * Toolbar buttons aren't focusable because if they were, clicking them would
     14 * focus them, which is undesirable. Therefore, they're only made focusable
     15 * when a user is navigating with the keyboard. This function forces focus as
     16 * is done during toolbar keyboard navigation.
     17 */
     18 function forceFocus(elem) {
     19  elem.setAttribute("tabindex", "-1");
     20  elem.focus();
     21  elem.removeAttribute("tabindex");
     22 }
     23 
     24 async function waitForProfileAndCloseTab() {
     25  await waitUntil(
     26    () => !button.classList.contains("profiler-paused"),
     27    "Waiting until the profiler is no longer paused"
     28  );
     29 
     30  await checkTabLoadedProfile({
     31    initialTitle: "Waiting on the profile",
     32    successTitle: "Profile received",
     33    errorTitle: "Error",
     34  });
     35 }
     36 var button;
     37 var dropmarker;
     38 
     39 add_setup(async function () {
     40  info(
     41    "Add the profiler button to the toolbar and ensure capturing a profile loads a local url."
     42  );
     43  await setProfilerFrontendUrl(
     44    "https://example.com",
     45    "/browser/devtools/client/performance-new/test/browser/fake-frontend.html"
     46  );
     47  await makeSureProfilerPopupIsEnabled();
     48  button = document.getElementById("profiler-button-button");
     49  dropmarker = document.getElementById("profiler-button-dropmarker");
     50 });
     51 
     52 add_task(async function click_icon() {
     53  info("Test that the profiler icon starts and captures a profile.");
     54 
     55  ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
     56  ok(!isActive(), "should start with the profiler inactive");
     57 
     58  button.click();
     59  await getElementByTooltip(document, "The profiler is recording a profile");
     60  ok(isActive(), "should have started the profiler");
     61 
     62  button.click();
     63  // We're not testing for the tooltip "capturing a profile" because this might
     64  // be racy.
     65  await waitForProfileAndCloseTab();
     66 
     67  // Back to the inactive state.
     68  await getElementByTooltip(document, "Record a performance profile");
     69 });
     70 
     71 add_task(async function click_dropmarker() {
     72  info("Test that the profiler icon dropmarker opens the panel.");
     73 
     74  ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
     75  ok(!isActive(), "should start with the profiler inactive");
     76 
     77  const popupShownPromise = waitForProfilerPopupEvent(window, "popupshown");
     78  dropmarker.click();
     79  await popupShownPromise;
     80 
     81  info("Ensure the panel is open and the profiler still inactive.");
     82  Assert.equal(dropmarker.getAttribute("open"), "true", "panel should be open");
     83  ok(!isActive(), "profiler should still be inactive");
     84  await getElementByLabel(document, "Start Recording");
     85 
     86  info("Press Escape to close the panel.");
     87  const popupHiddenPromise = waitForProfilerPopupEvent(window, "popuphidden");
     88  EventUtils.synthesizeKey("KEY_Escape");
     89  await popupHiddenPromise;
     90  ok(!dropmarker.hasAttribute("open"), "panel should be closed");
     91 });
     92 
     93 add_task(async function click_overflowed_icon() {
     94  info("Test that the profiler icon opens the panel when overflowed.");
     95 
     96  const toolbaritem = button.parentNode;
     97  const chevron = document.getElementById("nav-bar-overflow-button");
     98  const overflowMenu = document.getElementById("widget-overflow");
     99  const profilerPanel = document.getElementById("PanelUI-profiler");
    100  const originalPlacement = CustomizableUI.getPlacementOfWidget(toolbaritem.id);
    101 
    102  ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
    103  ok(!isActive(), "should start with the profiler inactive");
    104  ok(
    105    BrowserTestUtils.isHidden(chevron),
    106    "Should start with the overflow button hidden."
    107  );
    108 
    109  info("Pinning button to overflow panel.");
    110  CustomizableUI.addWidgetToArea(
    111    toolbaritem.id,
    112    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL,
    113    0
    114  );
    115  await TestUtils.waitForCondition(
    116    () => BrowserTestUtils.isVisible(chevron),
    117    "Waiting for the overflow button to become visible"
    118  );
    119 
    120  info("Open the overflow menu.");
    121  chevron.click();
    122  await TestUtils.waitForCondition(() => overflowMenu.state == "open");
    123 
    124  info("Open the profiler panel.");
    125  button.click();
    126  await TestUtils.waitForCondition(() =>
    127    profilerPanel?.hasAttribute("visible")
    128  );
    129 
    130  info("Ensure the panel is open and the profiler still inactive.");
    131  ok(profilerPanel?.hasAttribute("visible"), "panel should be open");
    132  ok(!isActive(), "profiler should still be inactive");
    133  await getElementByLabel(document, "Start Recording");
    134 
    135  info("Press Escape to close the panel.");
    136  EventUtils.synthesizeKey("KEY_Escape");
    137  await TestUtils.waitForCondition(() => overflowMenu.state == "closed");
    138  ok(!dropmarker.hasAttribute("open"), "panel should be closed");
    139 
    140  info("Removing button from overflow panel.");
    141  CustomizableUI.addWidgetToArea(
    142    toolbaritem.id,
    143    originalPlacement.area,
    144    originalPlacement.position
    145  );
    146 });
    147 
    148 add_task(async function space_key() {
    149  info("Test that the Space key starts and captures a profile.");
    150 
    151  ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
    152  ok(!isActive(), "should start with the profiler inactive");
    153  forceFocus(button);
    154 
    155  info("Press Space to start the profiler.");
    156  EventUtils.synthesizeKey(" ");
    157  ok(isActive(), "should have started the profiler");
    158 
    159  info("Press Space again to capture the profile.");
    160  EventUtils.synthesizeKey(" ");
    161  await waitForProfileAndCloseTab();
    162 });
    163 
    164 add_task(async function enter_key() {
    165  info("Test that the Enter key starts and captures a profile.");
    166 
    167  ok(!dropmarker.hasAttribute("open"), "should start with the panel closed");
    168  ok(!isActive(), "should start with the profiler inactive");
    169  forceFocus(button);
    170 
    171  const isMacOS = Services.appinfo.OS === "Darwin";
    172  if (isMacOS) {
    173    // On macOS, pressing Enter on a focused toolbarbutton does not fire a
    174    // command event, so we do not expect Enter to start the profiler.
    175    return;
    176  }
    177 
    178  info("Pressing Enter should start the profiler.");
    179  EventUtils.synthesizeKey("KEY_Enter");
    180  ok(isActive(), "should have started the profiler");
    181 
    182  info("Pressing Enter again to capture the profile.");
    183  EventUtils.synthesizeKey("KEY_Enter");
    184  await waitForProfileAndCloseTab();
    185 });
    186 
    187 /**
    188 * Tests that dropmarker has l10n attributes.
    189 */
    190 add_task(async function dropmarker_has_l10n() {
    191  ok(
    192    BrowserTestUtils.isVisible(dropmarker),
    193    "Profiler button dropmarker is visible"
    194  );
    195 
    196  is(
    197    dropmarker.getAttribute("data-l10n-id"),
    198    "profiler-button-dropmarker",
    199    "Profiler button dropmarker has l10n attributes set"
    200  );
    201 });