tor-browser

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

browser_customization_context_menus.js (25948B)


      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 requestLongerTimeout(2);
      8 
      9 const isOSX = Services.appinfo.OS === "Darwin";
     10 
     11 const overflowButton = document.getElementById("nav-bar-overflow-button");
     12 const overflowPanel = document.getElementById("widget-overflow");
     13 
     14 // Right-click on the stop/reload button should
     15 // show a context menu with options to move it.
     16 add_task(async function home_button_context() {
     17  let contextMenu = document.getElementById("toolbar-context-menu");
     18  let shownPromise = popupShown(contextMenu);
     19  let stopReloadButton = document.getElementById("stop-reload-button");
     20  EventUtils.synthesizeMouse(stopReloadButton, 2, 2, {
     21    type: "contextmenu",
     22    button: 2,
     23  });
     24  await shownPromise;
     25 
     26  let expectedEntries = [
     27    [".customize-context-moveToPanel", true],
     28    [".customize-context-removeFromToolbar", true],
     29    ["---"],
     30  ];
     31  if (!isOSX) {
     32    expectedEntries.push(["#toggle_toolbar-menubar", true]);
     33  }
     34  expectedEntries.push(
     35    ["#toggle_PersonalToolbar", true],
     36    ["---"],
     37    [".viewCustomizeToolbar", true]
     38  );
     39  checkContextMenu(contextMenu, expectedEntries);
     40 
     41  let hiddenPromise = popupHidden(contextMenu);
     42  contextMenu.hidePopup();
     43  await hiddenPromise;
     44 });
     45 
     46 // Right-click on the sidebar button should show a context
     47 // menu with options to toggle vertical tabs and customize.
     48 add_task(async function sidebar_button_context() {
     49  let contextMenu = document.getElementById("toolbar-context-menu");
     50  let shownPromise = popupShown(contextMenu);
     51  CustomizableUI.addWidgetToArea("sidebar-button", "nav-bar");
     52  let sidebarButton = document.getElementById("sidebar-button");
     53  EventUtils.synthesizeMouse(sidebarButton, 2, 2, {
     54    type: "contextmenu",
     55    button: 2,
     56  });
     57  await shownPromise;
     58 
     59  let expectedEntries = [
     60    ["#toolbar-context-toggle-vertical-tabs", true],
     61    ["---"],
     62    [".customize-context-moveToPanel", true],
     63    [".customize-context-removeFromToolbar", true],
     64    ["---"],
     65  ];
     66  if (!isOSX) {
     67    expectedEntries.push(["#toggle_toolbar-menubar", true]);
     68  }
     69  expectedEntries.push(
     70    ["#toggle_PersonalToolbar", true],
     71    ["---"],
     72    [".viewCustomizeToolbar", true]
     73  );
     74  checkContextMenu(contextMenu, expectedEntries);
     75 
     76  let hiddenPromise = popupHidden(contextMenu);
     77  contextMenu.hidePopup();
     78  await hiddenPromise;
     79 });
     80 
     81 // Right-click on an empty bit of tabstrip should
     82 // show a context menu without options to move it,
     83 // but with tab-specific options instead.
     84 add_task(async function tabstrip_context() {
     85  // ensure there are tabs to reload/bookmark:
     86  let extraTab = await BrowserTestUtils.openNewForegroundTab(
     87    gBrowser,
     88    "http://example.com/"
     89  );
     90  let contextMenu = document.getElementById("toolbar-context-menu");
     91  let shownPromise = popupShown(contextMenu);
     92  let tabstrip = document.getElementById("tabbrowser-tabs");
     93  let rect = tabstrip.getBoundingClientRect();
     94  EventUtils.synthesizeMouse(tabstrip, rect.width - 2, 2, {
     95    type: "contextmenu",
     96    button: 2,
     97  });
     98  await shownPromise;
     99 
    100  let closedTabsAvailable = SessionStore.getClosedTabCount() == 0;
    101  info("Closed tabs: " + closedTabsAvailable);
    102  let expectedEntries = [
    103    ["#toolbar-context-openANewTab", true],
    104    ["---"],
    105    ["#toolbar-context-reloadSelectedTab", true],
    106    ["#toolbar-context-bookmarkSelectedTab", true],
    107    ["#toolbar-context-selectAllTabs", true],
    108    ["#toolbar-context-undoCloseTab", !closedTabsAvailable],
    109    ["---"],
    110    ["#toolbar-context-toggle-vertical-tabs", true],
    111    ["---"],
    112  ];
    113  if (!isOSX) {
    114    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    115  }
    116  expectedEntries.push(
    117    ["#toggle_PersonalToolbar", true],
    118    ["---"],
    119    [".viewCustomizeToolbar", true]
    120  );
    121  checkContextMenu(contextMenu, expectedEntries);
    122 
    123  let hiddenPromise = popupHidden(contextMenu);
    124  contextMenu.hidePopup();
    125  await hiddenPromise;
    126  BrowserTestUtils.removeTab(extraTab);
    127 });
    128 
    129 // Right-click on the title bar spacer before the tabstrip should show a
    130 // context menu without options to move it and no tab-specific options.
    131 add_task(async function titlebar_spacer_context() {
    132  if (!CustomTitlebar.enabled) {
    133    info("Skipping test that requires tabs in the title bar.");
    134    return;
    135  }
    136 
    137  let contextMenu = document.getElementById("toolbar-context-menu");
    138  let shownPromise = popupShown(contextMenu);
    139  let spacer = document.querySelector(
    140    "#TabsToolbar .titlebar-spacer[type='pre-tabs']"
    141  );
    142  await waitForElementShown(spacer);
    143  EventUtils.synthesizeMouseAtCenter(spacer, {
    144    type: "contextmenu",
    145    button: 2,
    146  });
    147  await shownPromise;
    148 
    149  let expectedEntries = [
    150    ["#toolbar-context-toggle-vertical-tabs", true],
    151    ["---"],
    152  ];
    153  if (!isOSX) {
    154    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    155  }
    156  expectedEntries.push(
    157    ["#toggle_PersonalToolbar", true],
    158    ["---"],
    159    [".viewCustomizeToolbar", true]
    160  );
    161  checkContextMenu(contextMenu, expectedEntries);
    162 
    163  let hiddenPromise = popupHidden(contextMenu);
    164  contextMenu.hidePopup();
    165  await hiddenPromise;
    166 });
    167 
    168 // Right-click on an empty bit of extra toolbar should
    169 // show a context menu with moving options disabled,
    170 // and a toggle option for the extra toolbar
    171 add_task(async function empty_toolbar_context() {
    172  let contextMenu = document.getElementById("toolbar-context-menu");
    173  let shownPromise = popupShown(contextMenu);
    174  let toolbar = createToolbarWithPlacements("880164_empty_toolbar", []);
    175  toolbar.setAttribute("context", "toolbar-context-menu");
    176  toolbar.setAttribute("toolbarname", "Fancy Toolbar for Context Menu");
    177  EventUtils.synthesizeMouseAtCenter(toolbar, {
    178    type: "contextmenu",
    179    button: 2,
    180  });
    181  await shownPromise;
    182 
    183  let expectedEntries = [];
    184  if (!isOSX) {
    185    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    186  }
    187  expectedEntries.push(
    188    ["#toggle_PersonalToolbar", true],
    189    ["#toggle_880164_empty_toolbar", true],
    190    ["---"],
    191    [".viewCustomizeToolbar", true]
    192  );
    193  checkContextMenu(contextMenu, expectedEntries);
    194 
    195  let hiddenPromise = popupHidden(contextMenu);
    196  contextMenu.hidePopup();
    197  await hiddenPromise;
    198  removeCustomToolbars();
    199 });
    200 
    201 // Right-click on the urlbar-container should
    202 // show a context menu with disabled options to move it.
    203 add_task(async function urlbar_context() {
    204  let contextMenu = document.getElementById("toolbar-context-menu");
    205  let shownPromise = popupShown(contextMenu);
    206  let urlBarContainer = document.getElementById("urlbar-container");
    207  // This clicks in the urlbar container margin, to avoid hitting the urlbar field.
    208  EventUtils.synthesizeMouse(urlBarContainer, -2, 4, {
    209    type: "contextmenu",
    210    button: 2,
    211  });
    212  await shownPromise;
    213 
    214  let expectedEntries = [];
    215  if (!isOSX) {
    216    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    217  }
    218  expectedEntries.push(
    219    ["#toggle_PersonalToolbar", true],
    220    ["---"],
    221    [".viewCustomizeToolbar", true]
    222  );
    223  checkContextMenu(contextMenu, expectedEntries);
    224 
    225  let hiddenPromise = popupHidden(contextMenu);
    226  contextMenu.hidePopup();
    227  await hiddenPromise;
    228 });
    229 
    230 // Right-click on the searchbar and moving it to the menu
    231 // and back should move the search-container instead.
    232 add_task(async function searchbar_context_move_to_panel_and_back() {
    233  // This is specifically testing the addToPanel function for the search bar, so
    234  // we have to move it to its correct position in the navigation toolbar first.
    235  // The preference will be restored when the customizations are reset later.
    236  let searchbar = await gCUITestUtils.addSearchBar();
    237  // This fails if the screen resolution is small and the search bar overflows
    238  // from the nav bar.
    239  await gCustomizeMode.addToPanel(searchbar);
    240  let placement = CustomizableUI.getPlacementOfWidget("search-container");
    241  is(
    242    placement.area,
    243    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL,
    244    "Should be in panel"
    245  );
    246 
    247  await waitForOverflowButtonShown();
    248 
    249  let shownPanelPromise = popupShown(overflowPanel);
    250  overflowButton.click();
    251  await shownPanelPromise;
    252  let hiddenPanelPromise = popupHidden(overflowPanel);
    253  overflowPanel.hidePopup();
    254  await hiddenPanelPromise;
    255 
    256  gCustomizeMode.addToToolbar(searchbar);
    257  placement = CustomizableUI.getPlacementOfWidget("search-container");
    258  is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in navbar");
    259  await gCustomizeMode.removeFromArea(searchbar);
    260  placement = CustomizableUI.getPlacementOfWidget("search-container");
    261  is(placement, null, "Should be in palette");
    262  CustomizableUI.reset();
    263  placement = CustomizableUI.getPlacementOfWidget("search-container");
    264  is(placement, null, "Should be in palette");
    265 });
    266 
    267 // Right-click on an item within the panel should
    268 // show a context menu with options to move it.
    269 add_task(async function context_within_panel() {
    270  CustomizableUI.addWidgetToArea(
    271    "new-window-button",
    272    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
    273  );
    274 
    275  await waitForOverflowButtonShown();
    276 
    277  let shownPanelPromise = popupShown(overflowPanel);
    278  overflowButton.click();
    279  await shownPanelPromise;
    280 
    281  let contextMenu = document.getElementById(
    282    "customizationPanelItemContextMenu"
    283  );
    284  let shownContextPromise = popupShown(contextMenu);
    285  let newWindowButton = document.getElementById("new-window-button");
    286  ok(newWindowButton, "new-window-button was found");
    287  EventUtils.synthesizeMouse(newWindowButton, 2, 2, {
    288    type: "contextmenu",
    289    button: 2,
    290  });
    291  await shownContextPromise;
    292 
    293  is(overflowPanel.state, "open", "The overflow panel should still be open.");
    294 
    295  let expectedEntries = [
    296    [".customize-context-moveToToolbar", true],
    297    [".customize-context-removeFromPanel", true],
    298    ["---"],
    299    [".viewCustomizeToolbar", true],
    300  ];
    301  checkContextMenu(contextMenu, expectedEntries);
    302 
    303  let hiddenContextPromise = popupHidden(contextMenu);
    304  contextMenu.hidePopup();
    305  await hiddenContextPromise;
    306 
    307  let hiddenPromise = popupHidden(overflowPanel);
    308  overflowPanel.hidePopup();
    309  await hiddenPromise;
    310 
    311  CustomizableUI.removeWidgetFromArea("new-window-button");
    312 });
    313 
    314 // Right-click on the stop/reload button while in customization mode
    315 // should show a context menu with options to move it.
    316 add_task(async function context_home_button_in_customize_mode() {
    317  await startCustomizing();
    318  let contextMenu = document.getElementById("toolbar-context-menu");
    319  let shownPromise = popupShown(contextMenu);
    320  let stopReloadButton = document.getElementById("wrapper-stop-reload-button");
    321  EventUtils.synthesizeMouse(stopReloadButton, 2, 2, {
    322    type: "contextmenu",
    323    button: 2,
    324  });
    325  await shownPromise;
    326 
    327  let expectedEntries = [
    328    [".customize-context-moveToPanel", true],
    329    [".customize-context-removeFromToolbar", true],
    330    ["---"],
    331  ];
    332  if (!isOSX) {
    333    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    334  }
    335  expectedEntries.push(
    336    ["#toggle_PersonalToolbar", true],
    337    ["---"],
    338    [".viewCustomizeToolbar", false]
    339  );
    340  checkContextMenu(contextMenu, expectedEntries);
    341 
    342  let hiddenContextPromise = popupHidden(contextMenu);
    343  contextMenu.hidePopup();
    344  await hiddenContextPromise;
    345 });
    346 
    347 // Right-click on an item in the palette should
    348 // show a context menu with options to move it.
    349 add_task(async function context_click_in_palette() {
    350  let contextMenu = document.getElementById(
    351    "customizationPaletteItemContextMenu"
    352  );
    353  let shownPromise = popupShown(contextMenu);
    354  let openFileButton = document.getElementById("wrapper-open-file-button");
    355  EventUtils.synthesizeMouse(openFileButton, 2, 2, {
    356    type: "contextmenu",
    357    button: 2,
    358  });
    359  await shownPromise;
    360 
    361  let expectedEntries = [
    362    [".customize-context-addToToolbar", true],
    363    [".customize-context-addToPanel", true],
    364  ];
    365  checkContextMenu(contextMenu, expectedEntries);
    366 
    367  let hiddenContextPromise = popupHidden(contextMenu);
    368  contextMenu.hidePopup();
    369  await hiddenContextPromise;
    370 });
    371 
    372 // Right-click on an item in the panel while in customization mode
    373 // should show a context menu with options to move it.
    374 add_task(async function context_click_in_customize_mode() {
    375  CustomizableUI.addWidgetToArea(
    376    "new-window-button",
    377    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
    378  );
    379  let contextMenu = document.getElementById(
    380    "customizationPanelItemContextMenu"
    381  );
    382  let shownPromise = popupShown(contextMenu);
    383  let newWindowButton = document.getElementById("wrapper-new-window-button");
    384  EventUtils.synthesizeMouse(newWindowButton, 2, 2, {
    385    type: "contextmenu",
    386    button: 2,
    387  });
    388  await shownPromise;
    389 
    390  let expectedEntries = [
    391    [".customize-context-moveToToolbar", true],
    392    [".customize-context-removeFromPanel", true],
    393    ["---"],
    394    [".viewCustomizeToolbar", false],
    395  ];
    396  checkContextMenu(contextMenu, expectedEntries);
    397 
    398  let hiddenContextPromise = popupHidden(contextMenu);
    399  contextMenu.hidePopup();
    400  await hiddenContextPromise;
    401  CustomizableUI.removeWidgetFromArea("new-window-button");
    402  await endCustomizing();
    403 });
    404 
    405 // Test the toolbarbutton panel context menu in customization mode
    406 // without opening the panel before customization mode
    407 add_task(async function context_click_customize_mode_panel_not_opened() {
    408  CustomizableUI.addWidgetToArea(
    409    "new-window-button",
    410    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
    411  );
    412  this.otherWin = await openAndLoadWindow(null, true);
    413 
    414  await new Promise(resolve => waitForFocus(resolve, this.otherWin));
    415 
    416  await startCustomizing(this.otherWin);
    417 
    418  let contextMenu = this.otherWin.document.getElementById(
    419    "customizationPanelItemContextMenu"
    420  );
    421  let shownPromise = popupShown(contextMenu);
    422  let newWindowButton = this.otherWin.document.getElementById(
    423    "wrapper-new-window-button"
    424  );
    425  EventUtils.synthesizeMouse(
    426    newWindowButton,
    427    2,
    428    2,
    429    { type: "contextmenu", button: 2 },
    430    this.otherWin
    431  );
    432  await shownPromise;
    433 
    434  let expectedEntries = [
    435    [".customize-context-moveToToolbar", true],
    436    [".customize-context-removeFromPanel", true],
    437    ["---"],
    438    [".viewCustomizeToolbar", false],
    439  ];
    440  checkContextMenu(contextMenu, expectedEntries, this.otherWin);
    441 
    442  let hiddenContextPromise = popupHidden(contextMenu);
    443  contextMenu.hidePopup();
    444  await hiddenContextPromise;
    445  await endCustomizing(this.otherWin);
    446  CustomizableUI.removeWidgetFromArea("new-window-button");
    447  await promiseWindowClosed(this.otherWin);
    448  this.otherWin = null;
    449 
    450  await new Promise(resolve => waitForFocus(resolve, window));
    451 });
    452 
    453 // Bug 945191 - Combined buttons show wrong context menu options
    454 // when they are in the toolbar.
    455 add_task(async function context_combined_buttons_toolbar() {
    456  CustomizableUI.addWidgetToArea(
    457    "zoom-controls",
    458    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
    459  );
    460  await startCustomizing();
    461  let contextMenu = document.getElementById(
    462    "customizationPanelItemContextMenu"
    463  );
    464  let shownPromise = popupShown(contextMenu);
    465  let zoomControls = document.getElementById("wrapper-zoom-controls");
    466  EventUtils.synthesizeMouse(zoomControls, 2, 2, {
    467    type: "contextmenu",
    468    button: 2,
    469  });
    470  await shownPromise;
    471  // Execute the command to move the item from the panel to the toolbar.
    472  let moveToToolbar = contextMenu.querySelector(
    473    ".customize-context-moveToToolbar"
    474  );
    475  moveToToolbar.doCommand();
    476  let hiddenPromise = popupHidden(contextMenu);
    477  contextMenu.hidePopup();
    478  await hiddenPromise;
    479  await endCustomizing();
    480 
    481  zoomControls = document.getElementById("zoom-controls");
    482  is(
    483    zoomControls.parentNode.id,
    484    "nav-bar-customization-target",
    485    "Zoom-controls should be on the nav-bar"
    486  );
    487 
    488  contextMenu = document.getElementById("toolbar-context-menu");
    489  shownPromise = popupShown(contextMenu);
    490  EventUtils.synthesizeMouse(zoomControls, 2, 2, {
    491    type: "contextmenu",
    492    button: 2,
    493  });
    494  await shownPromise;
    495 
    496  let expectedEntries = [
    497    [".customize-context-moveToPanel", true],
    498    [".customize-context-removeFromToolbar", true],
    499    ["---"],
    500  ];
    501  if (!isOSX) {
    502    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    503  }
    504  expectedEntries.push(
    505    ["#toggle_PersonalToolbar", true],
    506    ["---"],
    507    [".viewCustomizeToolbar", true]
    508  );
    509  checkContextMenu(contextMenu, expectedEntries);
    510 
    511  hiddenPromise = popupHidden(contextMenu);
    512  contextMenu.hidePopup();
    513  await hiddenPromise;
    514  await resetCustomization();
    515 });
    516 
    517 // Bug 947586 - After customization, panel items show wrong context menu options
    518 add_task(async function context_after_customization_panel() {
    519  info("Check panel context menu is correct after customization");
    520  await startCustomizing();
    521  await endCustomizing();
    522 
    523  CustomizableUI.addWidgetToArea(
    524    "new-window-button",
    525    CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
    526  );
    527  let shownPanelPromise = popupShown(overflowPanel);
    528  overflowButton.click();
    529  await shownPanelPromise;
    530 
    531  let contextMenu = document.getElementById(
    532    "customizationPanelItemContextMenu"
    533  );
    534  let shownContextPromise = popupShown(contextMenu);
    535  let newWindowButton = document.getElementById("new-window-button");
    536  ok(newWindowButton, "new-window-button was found");
    537  EventUtils.synthesizeMouse(newWindowButton, 2, 2, {
    538    type: "contextmenu",
    539    button: 2,
    540  });
    541  await shownContextPromise;
    542 
    543  is(overflowPanel.state, "open", "The panel should still be open.");
    544 
    545  let expectedEntries = [
    546    [".customize-context-moveToToolbar", true],
    547    [".customize-context-removeFromPanel", true],
    548    ["---"],
    549    [".viewCustomizeToolbar", true],
    550  ];
    551  checkContextMenu(contextMenu, expectedEntries);
    552 
    553  let hiddenContextPromise = popupHidden(contextMenu);
    554  contextMenu.hidePopup();
    555  await hiddenContextPromise;
    556 
    557  let hiddenPromise = popupHidden(overflowPanel);
    558  overflowPanel.hidePopup();
    559  await hiddenPromise;
    560  CustomizableUI.removeWidgetFromArea("new-window-button");
    561 });
    562 
    563 // Bug 982027 - moving icon around removes custom context menu.
    564 add_task(async function custom_context_menus() {
    565  let widgetId = "custom-context-menu-toolbarbutton";
    566  let expectedContext = "myfancycontext";
    567  let widget = createDummyXULButton(widgetId, "Test ctxt menu");
    568  widget.setAttribute("context", expectedContext);
    569  CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR);
    570  is(
    571    widget.getAttribute("context"),
    572    expectedContext,
    573    "Should have context menu when added to the toolbar."
    574  );
    575 
    576  await startCustomizing();
    577  is(
    578    widget.getAttribute("context"),
    579    null,
    580    "Should not have own context menu in the toolbar now that we're customizing."
    581  );
    582  is(
    583    widget.getAttribute("wrapped-context"),
    584    expectedContext,
    585    "Should keep own context menu wrapped when in toolbar."
    586  );
    587 
    588  let panel = document.getElementById("widget-overflow-fixed-list");
    589  simulateItemDrag(widget, panel);
    590  is(
    591    widget.getAttribute("context"),
    592    null,
    593    "Should not have own context menu when in the panel."
    594  );
    595  is(
    596    widget.getAttribute("wrapped-context"),
    597    expectedContext,
    598    "Should keep own context menu wrapped now that we're in the panel."
    599  );
    600 
    601  simulateItemDrag(
    602    widget,
    603    CustomizableUI.getCustomizationTarget(document.getElementById("nav-bar"))
    604  );
    605  is(
    606    widget.getAttribute("context"),
    607    null,
    608    "Should not have own context menu when back in toolbar because we're still customizing."
    609  );
    610  is(
    611    widget.getAttribute("wrapped-context"),
    612    expectedContext,
    613    "Should keep own context menu wrapped now that we're back in the toolbar."
    614  );
    615 
    616  await endCustomizing();
    617  is(
    618    widget.getAttribute("context"),
    619    expectedContext,
    620    "Should have context menu again now that we're out of customize mode."
    621  );
    622  CustomizableUI.removeWidgetFromArea(widgetId);
    623  widget.remove();
    624  ok(
    625    CustomizableUI.inDefaultState,
    626    "Should be in default state after removing button."
    627  );
    628 });
    629 
    630 // Bug 1690575 - 'pin to overflow menu' and 'remove from toolbar' should be hidden
    631 // for flexible spaces
    632 add_task(async function flexible_space_context_menu() {
    633  CustomizableUI.addWidgetToArea("spring", "nav-bar");
    634  let springs = document.querySelectorAll("#nav-bar toolbarspring");
    635  let lastSpring = springs[springs.length - 1];
    636  ok(lastSpring, "we added a spring");
    637  let contextMenu = document.getElementById("toolbar-context-menu");
    638  let shownPromise = popupShown(contextMenu);
    639  EventUtils.synthesizeMouse(lastSpring, 2, 2, {
    640    type: "contextmenu",
    641    button: 2,
    642  });
    643  await shownPromise;
    644 
    645  let expectedEntries = [
    646    ["#toolbar-context-toggle-vertical-tabs", true],
    647    ["---"],
    648  ];
    649 
    650  if (!isOSX) {
    651    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    652  }
    653 
    654  expectedEntries.push(
    655    ["#toggle_PersonalToolbar", true],
    656    ["---"],
    657    [".viewCustomizeToolbar", true]
    658  );
    659 
    660  checkContextMenu(contextMenu, expectedEntries);
    661  contextMenu.hidePopup();
    662  gCustomizeMode.removeFromArea(lastSpring);
    663  ok(!lastSpring.parentNode, "Spring should have been removed successfully.");
    664 });
    665 
    666 // Right-click on the downloads button should show a context
    667 // menu with options specific to downloads.
    668 add_task(async function downloads_button_context() {
    669  await SpecialPowers.pushPrefEnv({
    670    set: [["browser.download.autohideButton", false]],
    671  });
    672  let contextMenu = document.getElementById("toolbar-context-menu");
    673  let shownPromise = popupShown(contextMenu);
    674  CustomizableUI.addWidgetToArea("downloads-button", "nav-bar");
    675  let downloadsButton = document.getElementById("downloads-button");
    676  EventUtils.synthesizeMouse(downloadsButton, 2, 2, {
    677    type: "contextmenu",
    678    button: 2,
    679  });
    680  await shownPromise;
    681 
    682  let expectedEntries = [
    683    [".customize-context-moveToPanel", true],
    684    ["#toolbar-context-autohide-downloads-button", true],
    685    [".customize-context-removeFromToolbar", true],
    686    ["---"],
    687    ["#toolbar-context-always-open-downloads-panel", true],
    688    ["---"],
    689  ];
    690  if (!isOSX) {
    691    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    692  }
    693  expectedEntries.push(
    694    ["#toggle_PersonalToolbar", true],
    695    ["---"],
    696    [".viewCustomizeToolbar", true]
    697  );
    698  checkContextMenu(contextMenu, expectedEntries);
    699 
    700  let hiddenPromise = popupHidden(contextMenu);
    701  contextMenu.hidePopup();
    702  await hiddenPromise;
    703  await SpecialPowers.popPrefEnv();
    704 });
    705 
    706 // Bug 1992031 - During customization mode, a separator should be shown
    707 // between "Remove from toolbar" and "Menu Bar" for flexible spaces
    708 add_task(async function flexible_space_context_menu_customize_mode() {
    709  await startCustomizing();
    710  CustomizableUI.addWidgetToArea("spring", "nav-bar");
    711  let springs = document.querySelectorAll("#nav-bar toolbarspring");
    712  let lastSpring = springs[springs.length - 1];
    713  ok(lastSpring, "we added a spring");
    714  let contextMenu = document.getElementById("toolbar-context-menu");
    715  let shownPromise = popupShown(contextMenu);
    716  EventUtils.synthesizeMouse(lastSpring, 2, 2, {
    717    type: "contextmenu",
    718    button: 2,
    719  });
    720  await shownPromise;
    721 
    722  let expectedEntries = [
    723    ["#toolbar-context-toggle-vertical-tabs", true],
    724    ["---"],
    725    [".customize-context-moveToPanel", false],
    726    [".customize-context-removeFromToolbar", true],
    727    ["---"],
    728  ];
    729 
    730  if (!isOSX) {
    731    expectedEntries.push(["#toggle_toolbar-menubar", true]);
    732  }
    733 
    734  expectedEntries.push(
    735    ["#toggle_PersonalToolbar", true],
    736    ["---"],
    737    [".viewCustomizeToolbar", false]
    738  );
    739 
    740  checkContextMenu(contextMenu, expectedEntries);
    741  contextMenu.hidePopup();
    742  gCustomizeMode.removeFromArea(lastSpring);
    743  ok(!lastSpring.parentNode, "Spring should have been removed successfully.");
    744  await endCustomizing();
    745 });
    746 
    747 // Menu Bar spacer context menu
    748 add_task(async function menubar_spacer_context_menu() {
    749  if (isOSX) {
    750    info("Skipping test that requires menu bar.");
    751    return;
    752  }
    753 
    754  let menubar = document.getElementById("toolbar-menubar");
    755  menubar.removeAttribute("autohide");
    756  ok(!menubar.hasAttribute("autohide"), "Menu bar is visible");
    757  let spacer = menubar.querySelector("spacer");
    758  ok(spacer, "Found menubar spacer");
    759  await waitForElementShown(spacer);
    760  let contextMenu = document.getElementById("toolbar-context-menu");
    761  let shownPromise = popupShown(contextMenu);
    762  EventUtils.synthesizeMouseAtCenter(spacer, {
    763    type: "contextmenu",
    764    button: 2,
    765  });
    766  await shownPromise;
    767 
    768  let expectedEntries = [
    769    ["#toolbar-context-toggle-vertical-tabs", true],
    770    ["---"],
    771    ["#toggle_toolbar-menubar", true],
    772    ["#toggle_PersonalToolbar", true],
    773    ["---"],
    774    [".viewCustomizeToolbar", true],
    775  ];
    776 
    777  checkContextMenu(contextMenu, expectedEntries);
    778  let hiddenPromise = popupHidden(contextMenu);
    779  contextMenu.hidePopup();
    780  await hiddenPromise;
    781  menubar.setAttribute("autohide", "true");
    782  ok(menubar.hasAttribute("autohide"), "Menu bar is hidden");
    783 });
    784 
    785 //  Menu Bar spacer context menu in customization mode
    786 add_task(async function menu_bar_spacer_context_menu_customize_mode() {
    787  if (isOSX) {
    788    info("Skipping test that requires menu bar.");
    789    return;
    790  }
    791 
    792  await startCustomizing();
    793  let menubar = document.getElementById("toolbar-menubar");
    794  menubar.removeAttribute("autohide");
    795  ok(!menubar.hasAttribute("autohide"), "Menu bar is visible");
    796  let spacer = menubar.querySelector("spacer");
    797  ok(spacer, "Found menubar spacer");
    798  await waitForElementShown(spacer);
    799  let contextMenu = document.getElementById("toolbar-context-menu");
    800  let shownPromise = popupShown(contextMenu);
    801  EventUtils.synthesizeMouseAtCenter(spacer, {
    802    type: "contextmenu",
    803    button: 2,
    804  });
    805  await shownPromise;
    806 
    807  let expectedEntries = [
    808    ["#toolbar-context-toggle-vertical-tabs", true],
    809    ["---"],
    810    ["#toggle_toolbar-menubar", true],
    811    ["#toggle_PersonalToolbar", true],
    812    ["---"],
    813    [".viewCustomizeToolbar", false],
    814  ];
    815 
    816  checkContextMenu(contextMenu, expectedEntries);
    817  let hiddenPromise = popupHidden(contextMenu);
    818  contextMenu.hidePopup();
    819  await hiddenPromise;
    820  menubar.setAttribute("autohide", "true");
    821  ok(menubar.hasAttribute("autohide"), "Menu bar is hidden");
    822  await endCustomizing();
    823 });