tor-browser

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

commit 9f26b70518667560b0634a83d3a7312b54217ae3
parent 3b4d8f108883ffbb08269ca07ee6bf1a08852796
Author: Sam Foster <sfoster@mozilla.com>
Date:   Sat, 18 Oct 2025 04:30:45 +0000

Bug 1994212 - Dispatch an event when the sidebar context menu is populated and update that test to account for asyncronicity. r=kcochrane

Differential Revision: https://phabricator.services.mozilla.com/D268974

Diffstat:
Mbrowser/components/sidebar/sidebar-main.mjs | 5++++-
Mbrowser/components/sidebar/tests/browser/browser_customize_sidebar.js | 11++++++++++-
Mbrowser/components/sidebar/tests/browser/browser_sidebar_context_menu.js | 471+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mbrowser/components/sidebar/tests/browser/head.js | 37+++++++++++++++----------------------
4 files changed, 260 insertions(+), 264 deletions(-)

diff --git a/browser/components/sidebar/sidebar-main.mjs b/browser/components/sidebar/sidebar-main.mjs @@ -539,7 +539,10 @@ export default class SidebarMain extends MozLitElement { e.target.id ) ) { - this.onSidebarPopupShowing(e); + this.onSidebarPopupShowing(e).then(() => { + // populating the context menu can be async, so dispatch an event when ready + this.dispatchEvent(new CustomEvent("sidebar-contextmenu-ready")); + }); } break; case "popuphidden": diff --git a/browser/components/sidebar/tests/browser/browser_customize_sidebar.js b/browser/components/sidebar/tests/browser/browser_customize_sidebar.js @@ -5,8 +5,17 @@ requestLongerTimeout(2); +let initialSidebarVisibility = Services.prefs.getStringPref( + SIDEBAR_VISIBILITY_PREF +); + registerCleanupFunction(() => { - Services.prefs.clearUserPref(SIDEBAR_VISIBILITY_PREF); + // sidebar.visibility gets set during startup and should be restored + // to that value, not the default value + Services.prefs.setStringPref( + SIDEBAR_VISIBILITY_PREF, + initialSidebarVisibility + ); Services.prefs.clearUserPref(POSITION_SETTING_PREF); Services.prefs.clearUserPref(VERTICAL_TABS_PREF); }); diff --git a/browser/components/sidebar/tests/browser/browser_sidebar_context_menu.js b/browser/components/sidebar/tests/browser/browser_sidebar_context_menu.js @@ -8,6 +8,12 @@ add_setup(async () => { await SpecialPowers.pushPrefEnv({ set: [["sidebar.animation.enabled", false]], }); + await ensureSidebarLauncherIsVisible(); + Assert.equal( + SidebarController.sidebarRevampVisibility, + "hide-sidebar", + "revamp.visibility has the expected value" + ); }); const initialTabDirection = Services.prefs.getBoolPref(VERTICAL_TABS_PREF) @@ -17,9 +23,9 @@ const initialTabDirection = Services.prefs.getBoolPref(VERTICAL_TABS_PREF) add_task(async function test_extension_context_menu() { const win = await BrowserTestUtils.openNewBrowserWindow(); await waitForBrowserWindowActive(win); + await ensureSidebarLauncherIsVisible(win); const { document } = win; const sidebar = document.querySelector("sidebar-main"); - await sidebar.updateComplete; ok(BrowserTestUtils.isVisible(sidebar), "Sidebar is shown."); const manageStub = sinon.stub(sidebar, "manageExtension"); @@ -38,70 +44,61 @@ add_task(async function test_extension_context_menu() { const contextMenu = document.getElementById("sidebar-context-menu"); is(contextMenu.state, "closed", "Checking if context menu is closed"); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - // Check sidebar context menu buttons are hidden - () => { - ok( - document.getElementById("sidebar-context-menu-hide-sidebar").hidden, - "Hide sidebar button is hidden" - ); - ok( - document.getElementById("sidebar-context-menu-enable-vertical-tabs") - .hidden, - "Enable vertical tabs button is hidden" - ); - ok( - document.getElementById("sidebar-context-menu-customize-sidebar") - .hidden, - "Customize sidebar button is hidden" - ); - }; - } + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + // Check sidebar context menu buttons are hidden + ok( + document.getElementById("sidebar-context-menu-hide-sidebar").hidden, + "Hide sidebar button is hidden" + ); + ok( + document.getElementById("sidebar-context-menu-enable-vertical-tabs").hidden, + "Enable vertical tabs button is hidden" + ); + ok( + document.getElementById("sidebar-context-menu-customize-sidebar").hidden, + "Customize sidebar button is hidden" + ); + // There should be a separator in this menu + Assert.ok( + !contextMenu.querySelector("menuseparator").hidden, + "menuseparator is visible" ); contextMenu.hidePopup(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - // Click "Manage Extension" - const manageExtensionButtonEl = document.getElementById( - "sidebar-context-menu-manage-extension" - ); - manageExtensionButtonEl.click(); - } + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + // Click "Manage Extension" + const manageExtensionButtonEl = document.getElementById( + "sidebar-context-menu-manage-extension" ); + manageExtensionButtonEl.click(); + ok(manageStub.called, "Manage Extension called"); contextMenu.hidePopup(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - // Click "Report Extension" - const reportExtensionButtonEl = document.getElementById( - "sidebar-context-menu-report-extension" - ); - reportExtensionButtonEl.click(); - } + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + // Click "Report Extension" + const reportExtensionButtonEl = document.getElementById( + "sidebar-context-menu-report-extension" ); + reportExtensionButtonEl.click(); ok(reportStub.called, "Report Extension called"); contextMenu.hidePopup(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - // Click "Remove Extension" - const removeExtensionButtonEl = document.getElementById( - "sidebar-context-menu-remove-extension" - ); - removeExtensionButtonEl.click(); - } - ); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + // Click "Remove Extension" + document.getElementById("sidebar-context-menu-remove-extension").click(); ok(removeStub.called, "Remove Extension called"); contextMenu.hidePopup(); @@ -111,35 +108,27 @@ add_task(async function test_extension_context_menu() { await SpecialPowers.pushPrefEnv({ set: [["extensions.abuseReport.enabled", false]], }); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - const reportExtensionButtonEl = document.getElementById( - "sidebar-context-menu-report-extension" - ); - is( - reportExtensionButtonEl.disabled, - true, - "Expect report item to be disabled" - ); - } + + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + is( + document.getElementById("sidebar-context-menu-report-extension").disabled, + true, + "Expect report item to be disabled" ); contextMenu.hidePopup(); await SpecialPowers.popPrefEnv(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - const reportExtensionButtonEl = document.getElementById( - "sidebar-context-menu-report-extension" - ); - is( - reportExtensionButtonEl.disabled, - false, - "Expect report item to be enabled" - ); - } + + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + is( + document.getElementById("sidebar-context-menu-report-extension").disabled, + false, + "Expect report item to be enabled" ); contextMenu.hidePopup(); @@ -156,50 +145,35 @@ add_task(async function test_extension_context_menu() { }, }, }); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - const removeExtensionButtonEl = document.getElementById( - "sidebar-context-menu-remove-extension" - ); - is( - removeExtensionButtonEl.disabled, - true, - "Expect remove item to be disabled" - ); - } + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + is( + document.getElementById("sidebar-context-menu-remove-extension").disabled, + true, + "Expect remove item to be disabled" ); await EnterprisePolicyTesting.setupPolicyEngineWithJson(""); contextMenu.hidePopup(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - const removeExtensionButtonEl = document.getElementById( - "sidebar-context-menu-remove-extension" - ); - is( - removeExtensionButtonEl.disabled, - false, - "Expect remove item to be enabled" - ); - } - ); - contextMenu.hidePopup(); - await openAndWaitForContextMenu( - contextMenu, - sidebar.extensionButtons[0], - () => { - // Click "Remove from Sidebar" - const unpinButtonEl = document.getElementById( - "sidebar-context-menu-unpin-extension" - ); - unpinButtonEl.click(); - } + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + is( + document.getElementById("sidebar-context-menu-remove-extension").disabled, + false, + "Expect remove item to be enabled" ); + contextMenu.hidePopup(); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebar, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebar.extensionButtons[0]), + ]); + // Click "Remove from Sidebar" + document.getElementById("sidebar-context-menu-unpin-extension").click(); await sidebar.updateComplete; is( sidebar.extensionButtons.length, @@ -218,67 +192,85 @@ add_task(async function test_extension_context_menu() { add_task(async function test_sidebar_context_menu() { const { sidebarMain, sidebarContainer } = SidebarController; - await SidebarController.initializeUIState({ - launcherVisible: true, - }); - ok(BrowserTestUtils.isVisible(sidebarMain), "Sidebar is shown."); + await ensureSidebarLauncherIsVisible(); const contextMenu = document.getElementById("sidebar-context-menu"); is(contextMenu.state, "closed", "Checking if context menu is closed"); - await openAndWaitForContextMenu(contextMenu, sidebarMain, () => { - // Check extension context menu buttons are hidden - () => { - ok( - document.getElementById("sidebar-context-menu-report-extension").hidden, - "Report extension button is hidden" - ); - ok( - document.getElementById("sidebar-context-menu-remove-extension").hidden, - "Remove extension tabs button is hidden" - ); - ok( - document.getElementById("sidebar-context-menu-manage-extension").hidden, - "Manage extension button is hidden" - ); - }; - }); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebarMain, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebarMain), + ]); + ok( + document.getElementById("sidebar-context-menu-report-extension").hidden, + "Report extension button is hidden" + ); + ok( + document.getElementById("sidebar-context-menu-remove-extension").hidden, + "Remove extension tabs button is hidden" + ); + ok( + document.getElementById("sidebar-context-menu-manage-extension").hidden, + "Manage extension button is hidden" + ); contextMenu.hidePopup(); - await openAndWaitForContextMenu(contextMenu, sidebarMain, () => { - // Click customize sidebar - const customizeSidebarMenuItem = document.getElementById( - "sidebar-context-menu-customize-sidebar" - ); - customizeSidebarMenuItem.click(); - }); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebarMain, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebarMain), + ]); + // Click customize sidebar + const customizeSidebarMenuItem = document.getElementById( + "sidebar-context-menu-customize-sidebar" + ); + ok( + BrowserTestUtils.isVisible(customizeSidebarMenuItem), + "The customize menu item is visible" + ); + const promiseSidebarFocused = BrowserTestUtils.waitForEvent( + window, + "SidebarFocused" + ); + + customizeSidebarMenuItem.click(); + // Wait for the sidebar panel to load before continuing + await promiseSidebarFocused; + is( SidebarController.currentID, "viewCustomizeSidebar", "Customize sidebar panel is open" ); + // Calling .click() directly doesn't dismiss the context menu popop, we need to do that. contextMenu.hidePopup(); - await openAndWaitForContextMenu(contextMenu, sidebarMain, () => { - // Click hide sidebar - const hideSidebarMenuItem = document.getElementById( - "sidebar-context-menu-hide-sidebar" - ); - hideSidebarMenuItem.click(); - }); - ok(sidebarContainer.hidden, "Sidebar is not visible"); - ok(!SidebarController.isOpen, "Sidebar panel is closed"); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebarMain, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebarMain), + ]); + // Click hide sidebar + const hideSidebarMenuItem = document.getElementById( + "sidebar-context-menu-hide-sidebar" + ); + hideSidebarMenuItem.click(); + await BrowserTestUtils.waitForMutationCondition( + SidebarController.sidebarContainer, + { attributes: true, attributeFilter: ["hidden"] }, + () => sidebarContainer.hidden + ); contextMenu.hidePopup(); - SidebarController._state.updateVisibility(true); + ok(sidebarContainer.hidden, "Sidebar is not visible"); + ok(!SidebarController.isOpen, "Sidebar panel is closed"); - await openAndWaitForContextMenu(contextMenu, sidebarMain, () => { - // Click turn on vertical tabs - const enableVerticalTabsMenuItem = document.getElementById( - "sidebar-context-menu-enable-vertical-tabs" - ); - enableVerticalTabsMenuItem.click(); - }); + await ensureSidebarLauncherIsVisible(); + await openAndWaitForContextMenu(contextMenu, sidebarMain); + // Click turn on vertical tabs + const enableVerticalTabsMenuItem = document.getElementById( + "sidebar-context-menu-enable-vertical-tabs" + ); + enableVerticalTabsMenuItem.click(); + await waitForTabstripOrientation("vertical"); contextMenu.hidePopup(); ok( Services.prefs.getBoolPref(VERTICAL_TABS_PREF, false), @@ -300,37 +292,39 @@ add_task(async function test_tool_context_menu() { 'moz-button[view="viewGenaiChatSidebar"]' ); - await openAndWaitForContextMenu(contextMenu, aichatTool, () => { - Assert.ok( - document.getElementById("sidebar-context-menu-report-extension").hidden, - "Report extension button is hidden" - ); - Assert.ok( - document.getElementById("sidebar-context-menu-remove-extension").hidden, - "Remove extension tabs button is hidden" - ); - Assert.ok( - document.getElementById("sidebar-context-menu-manage-extension").hidden, - "Manage extension button is hidden" - ); - Assert.ok( - document.getElementById("sidebar-context-menu-hide-sidebar").hidden, - "Hide sidebar button is hidden" - ); - Assert.ok( - document.getElementById("sidebar-context-menu-enable-vertical-tabs") - .hidden, - "Enable vertical tab button is hidden" - ); - Assert.ok( - document.getElementById("sidebar-context-menu-customize-sidebar").hidden, - "Customize sidebar button is hidden" - ); - Assert.ok( - contextMenu.querySelector("menuseparator").hidden, - "menuseparator is hidden" - ); - }); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebarMain, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, aichatTool), + ]); + + Assert.ok( + document.getElementById("sidebar-context-menu-report-extension").hidden, + "Report extension button is hidden" + ); + Assert.ok( + document.getElementById("sidebar-context-menu-remove-extension").hidden, + "Remove extension tabs button is hidden" + ); + Assert.ok( + document.getElementById("sidebar-context-menu-manage-extension").hidden, + "Manage extension button is hidden" + ); + Assert.ok( + document.getElementById("sidebar-context-menu-hide-sidebar").hidden, + "Hide sidebar button is hidden" + ); + Assert.ok( + document.getElementById("sidebar-context-menu-enable-vertical-tabs").hidden, + "Enable vertical tab button is hidden" + ); + Assert.ok( + document.getElementById("sidebar-context-menu-customize-sidebar").hidden, + "Customize sidebar button is hidden" + ); + Assert.ok( + contextMenu.querySelector("menuseparator").hidden, + "menuseparator is hidden" + ); // The submenu is populated asynchronously. await BrowserTestUtils.waitForMutationCondition( @@ -349,35 +343,30 @@ add_task(async function test_tool_context_menu() { contextMenu.hidePopup(); - await openAndWaitForContextMenu(contextMenu, sidebarMain, () => { - // Check tool menuitems are hidden and sidebar-main context menus are visible - () => { - Assert.ok( - !document.getElementById("sidebar-context-menu-hide-sidebar").hidden, - "Hide sidebar button is visible" - ); - Assert.ok( - !document.getElementById("sidebar-context-menu-enable-vertical-tabs") - .hidden, - "Remove extension tabs button is visible" - ); - Assert.ok( - !document.getElementById("sidebar-context-menu-customize-sidebar") - .hidden, - "Enable vertical tab button is visible" - ); + await Promise.all([ + BrowserTestUtils.waitForEvent(sidebarMain, "sidebar-contextmenu-ready"), + openAndWaitForContextMenu(contextMenu, sidebarMain), + ]); - Assert.ok( - !contextMenu.querySelector("menuseparator").hidden, - "menuseparator is visible" - ); + // Check tool menuitems are hidden and sidebar-main context menus are visible + Assert.ok( + !document.getElementById("sidebar-context-menu-hide-sidebar").hidden, + "Hide sidebar button is visible" + ); + Assert.ok( + !document.getElementById("sidebar-context-menu-enable-vertical-tabs") + .hidden, + "Remove extension tabs button is visible" + ); + Assert.ok( + !document.getElementById("sidebar-context-menu-customize-sidebar").hidden, + "Enable vertical tab button is visible" + ); - const toolMenuItems = [ - ...contextMenu.querySelectorAll("[customized-tool='true']"), - ]; - Assert.ok(toolMenuItems[0].hidden, "One of tool menuitems is hidden"); - }; - }); + const toolMenuItems = [ + ...contextMenu.querySelectorAll("[customized-tool='true']"), + ]; + Assert.ok(toolMenuItems[0].hidden, "One of tool menuitems is hidden"); contextMenu.hidePopup(); await SpecialPowers.popPrefEnv(); @@ -403,16 +392,17 @@ add_task(async function test_toggle_vertical_tabs_from_sidebar_button() { "toolbar-context-customize-sidebar" ); const sidebarButton = document.getElementById("sidebar-button"); - await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton, () => { - Assert.deepEqual( - document.l10n.getAttributes(toggleMenuItem), - { id: "toolbar-context-turn-on-vertical-tabs", args: null }, - "Context menu item indicates that it enables vertical tabs." - ); - toggleMenuItem.click(); - }); + await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton); + Assert.deepEqual( + document.l10n.getAttributes(toggleMenuItem), + { id: "toolbar-context-turn-on-vertical-tabs", args: null }, + "Context menu item indicates that it enables vertical tabs." + ); + toggleMenuItem.click(); + await waitForTabstripOrientation("vertical"); ok(gBrowser.tabContainer.verticalMode, "Vertical tabs are enabled."); + toolbarContextMenu.hidePopup(); Assert.equal( @@ -422,9 +412,9 @@ add_task(async function test_toggle_vertical_tabs_from_sidebar_button() { ); // Open customize sidebar panel from context menu - await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton, () => { - customizeSidebarItem.click(); - }); + await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton); + + customizeSidebarItem.click(); ok(SidebarController.isOpen, "Sidebar is open"); Assert.equal( SidebarController.currentID, @@ -434,14 +424,15 @@ add_task(async function test_toggle_vertical_tabs_from_sidebar_button() { toolbarContextMenu.hidePopup(); info("Disable vertical tabs from right clicking the sidebar-button"); - await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton, () => { - Assert.deepEqual( - document.l10n.getAttributes(toggleMenuItem), - { id: "toolbar-context-turn-off-vertical-tabs", args: null }, - "Context menu item indicates that it disables vertical tabs." - ); - toggleMenuItem.click(); - }); + await openAndWaitForContextMenu(toolbarContextMenu, sidebarButton); + + Assert.deepEqual( + document.l10n.getAttributes(toggleMenuItem), + { id: "toolbar-context-turn-off-vertical-tabs", args: null }, + "Context menu item indicates that it disables vertical tabs." + ); + toggleMenuItem.click(); + await waitForTabstripOrientation("horizontal"); ok(!gBrowser.tabContainer.verticalMode, "Vertical tabs are disabled."); Assert.equal( diff --git a/browser/components/sidebar/tests/browser/head.js b/browser/components/sidebar/tests/browser/head.js @@ -134,29 +134,22 @@ function waitForBrowserWindowActive(win) { }); } -function openAndWaitForContextMenu(popup, button, onShown) { - return new Promise(resolve => { - function onPopupShown() { - info("onPopupShown"); - popup.removeEventListener("popupshown", onPopupShown); - - onShown && onShown(); - resolve(popup); - } - - popup.addEventListener("popupshown", onPopupShown); - - info("wait for the context menu to open"); +async function openAndWaitForContextMenu(popup, button, onShown) { + const menuShownPromise = BrowserTestUtils.waitForPopupEvent(popup, "shown"); + button.scrollIntoView(); - button.scrollIntoView(); - const eventDetails = { type: "contextmenu", button: 2 }; - EventUtils.synthesizeMouseAtCenter( - button, - eventDetails, - // eslint-disable-next-line mozilla/use-ownerGlobal - button.ownerDocument.defaultView - ); - }); + const eventDetails = { type: "contextmenu", button: 2 }; + EventUtils.synthesizeMouseAtCenter( + button, + eventDetails, + // eslint-disable-next-line mozilla/use-ownerGlobal + button.ownerDocument.defaultView + ); + await menuShownPromise; + if (onShown) { + await onShown(); + } + return popup; } function isActiveElement(el) {