Bug 1945959 - Add tests for sidebar expand on hover feature r=sidebar-reviewers,nsharpley

Differential Revision: https://phabricator.services.mozilla.com/D237646
This commit is contained in:
Kelly Cochrane
2025-03-18 19:12:25 +00:00
parent f55d8290f5
commit 852e54ea33
4 changed files with 225 additions and 15 deletions

View File

@@ -88,6 +88,7 @@ export class SidebarCustomize extends SidebarPage {
positionInput: "#position",
visibilityInput: "#hide-sidebar",
verticalTabsInput: "#vertical-tabs",
expandOnHoverInput: "#expand-on-hover",
};
connectedCallback() {

View File

@@ -43,6 +43,8 @@ skip-if = [
["browser_sidebar_context_menu.js"]
["browser_sidebar_expand_on_hover.js"]
["browser_sidebar_macmenu.js"]
run-if = ["os == 'mac'"] # Mac only feature

View File

@@ -0,0 +1,192 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_setup(async () => {
await SpecialPowers.pushPrefEnv({
set: [
["sidebar.verticalTabs", true],
["sidebar.expandOnHover", true],
],
});
});
registerCleanupFunction(async () => {
await SpecialPowers.popPrefEnv();
while (gBrowser.tabs.length > 1) {
BrowserTestUtils.removeTab(gBrowser.tabs.at(-1));
}
});
async function mouseOverSidebarToExpand() {
// Disable non-test mouse events
window.windowUtils.disableNonTestMouseEvents(true);
EventUtils.synthesizeMouse(SidebarController.sidebarContainer, 1, 80, {
type: "mousemove",
});
await BrowserTestUtils.waitForMutationCondition(
SidebarController.sidebarContainer,
{ attributes: true },
async () => {
await SidebarController._waitForOngoingAnimations();
return (
SidebarController.sidebarContainer.hasAttribute(
"sidebar-launcher-expanded"
) &&
SidebarController.sidebarMain.expanded &&
SidebarController._state.launcherExpanded &&
window.getComputedStyle(SidebarController.sidebarContainer).position ===
"absolute"
);
},
"The sidebar launcher is expanded"
);
info("The sidebar launcher is expanded on mouse over");
window.windowUtils.disableNonTestMouseEvents(false);
}
async function mouseOutSidebarToCollapse() {
// Disable non-test mouse events
window.windowUtils.disableNonTestMouseEvents(true);
EventUtils.synthesizeMouseAtCenter(SidebarController.contentArea, {
type: "mousemove",
});
await BrowserTestUtils.waitForMutationCondition(
SidebarController.sidebarContainer,
{ attributes: true },
async () => {
await SidebarController._waitForOngoingAnimations();
return (
!SidebarController.sidebarContainer.hasAttribute(
"sidebar-launcher-expanded"
) &&
!SidebarController.sidebarMain.expanded &&
!SidebarController._state.launcherExpanded &&
window.getComputedStyle(SidebarController.sidebarContainer).position ===
"relative"
);
},
"The sidebar launcher is collapsed"
);
info("The sidebar launcher is collapsed on mouse out");
window.windowUtils.disableNonTestMouseEvents(false);
}
add_task(async function test_enable_expand_on_hover() {
await SidebarController.show("viewCustomizeSidebar");
let rootEl = document.documentElement;
let browserEl = document.getElementById("browser");
const panel =
SidebarController.browser.contentDocument.querySelector(
"sidebar-customize"
);
const sidebarBox = document.getElementById("sidebar-box");
await BrowserTestUtils.waitForMutationCondition(
browserEl,
{ childList: true, subtree: true },
() =>
BrowserTestUtils.isVisible(sidebarBox) &&
panel.expandOnHoverInput?.shadowRoot.querySelector("input"),
"Sidebar panel is visible and input is displayed"
);
info("Sidebar panel is visible and input is displayed");
// Enable expand on hover
panel.expandOnHoverInput.click();
EventUtils.synthesizeMouseAtCenter(SidebarController.contentArea, {
type: "mousemove",
});
await BrowserTestUtils.waitForMutationCondition(
SidebarController.sidebarContainer,
{ attributes: true },
() =>
rootEl.hasAttribute("sidebar-expand-on-hover") &&
!SidebarController.sidebarContainer.hasAttribute(
"sidebar-launcher-expanded"
) &&
!SidebarController._state.launcherExpanded &&
SidebarController.sidebarRevampVisibility === "expand-on-hover" &&
window.getComputedStyle(SidebarController.sidebarContainer).position ===
"relative",
"Expand on hover has been enabled"
);
info("Expand on hover has been enabled");
ok(
rootEl.hasAttribute("sidebar-expand-on-hover"),
"#browser element has sidebar-expand-on-hover attribute"
);
await mouseOverSidebarToExpand();
await mouseOutSidebarToCollapse();
panel.positionInput.click();
await BrowserTestUtils.waitForMutationCondition(
SidebarController.sidebarContainer,
{ attributes: true },
() =>
SidebarController.sidebarContainer.hasAttribute("sidebar-positionend"),
"The sidebar is positioned on the right"
);
await mouseOverSidebarToExpand();
await mouseOutSidebarToCollapse();
// Move the sidebar back to the left
panel.positionInput.click();
await BrowserTestUtils.waitForMutationCondition(
SidebarController.sidebarContainer,
{ attributes: true },
() =>
!SidebarController.sidebarContainer.hasAttribute("sidebar-positionend"),
"The sidebar is positioned on the left"
);
let newTabButton = document.getElementById("tabs-newtab-button");
info("Open 2 new tabs using the new tab button.");
newTabButton.click();
newTabButton.click();
is(gBrowser.tabs.length, 3, "Tabstrip now has three tabs");
gBrowser.selectedTab.toggleMuteAudio();
gBrowser.pinTab(gBrowser.selectedTab);
let unpinnedTabs = gBrowser.visibleTabs.filter(tab => !tab.pinned);
gBrowser.pinTab(unpinnedTabs[0]);
let pinnedTabs = gBrowser.visibleTabs.filter(tab => tab.pinned);
await mouseOverSidebarToExpand();
let verticalPinnedTabsContainer = document.getElementById(
"vertical-pinned-tabs-container"
);
let verticalTabsComputedStyle = window.getComputedStyle(
verticalPinnedTabsContainer
);
let inlineMuteButton =
gBrowser.selectedTab.querySelector(".tab-audio-button");
let muteButtonComputedStyle = window.getComputedStyle(inlineMuteButton);
await mouseOutSidebarToCollapse();
await mouseOverSidebarToExpand();
let pinnedTabComputedStyle = window.getComputedStyle(pinnedTabs[0]);
is(
Math.round(parseInt(verticalTabsComputedStyle.width)),
Math.round(parseInt(pinnedTabComputedStyle.width)),
"The pinned tabs are full width when expanded"
);
is(
muteButtonComputedStyle.display,
"none",
"The expanded pinned tab is not showing the inline audio button."
);
await mouseOutSidebarToCollapse();
});

View File

@@ -108,10 +108,16 @@ add_task(async function test_tabs() {
for (const [i, client] of tabClients.entries()) {
const card = component.cards[i];
Assert.equal(card.heading, client.name, "Device name is correct.");
const rows = await TestUtils.waitForCondition(() => {
await BrowserTestUtils.waitForMutationCondition(
card.querySelector("sidebar-tab-list").shadowRoot,
{ childList: true },
() => {
const { rowEls } = card.querySelector("sidebar-tab-list");
return rowEls.length === client.tabs.length && rowEls;
}, "Device has the correct number of tabs.");
},
"Device has the correct number of tabs."
);
const rows = card.querySelector("sidebar-tab-list").rowEls;
for (const [j, row] of rows.entries()) {
const tabData = client.tabs[j];
Assert.equal(row.title, tabData.title, `Tab ${j + 1} has correct title.`);
@@ -130,7 +136,7 @@ add_task(async function test_tabs() {
// to ensure we properly test that path
if (client.id === 2) {
Assert.ok(
!row.renderRoot.querySelector(".dismiss-button"),
!row.secondaryButtonEl,
`Dismiss button should NOT appear for tab ${
j + 1
} on the client that does not have available commands.`
@@ -138,37 +144,46 @@ add_task(async function test_tabs() {
} else {
// We need to use renderRoot since Lit components querySelector
// won't return the right things
await BrowserTestUtils.waitForCondition(
() => row.renderRoot.querySelector(".dismiss-button") !== null,
await BrowserTestUtils.waitForMutationCondition(
row.shadowRoot,
{ childList: true },
() => row.secondaryButtonEl,
`Dismiss button should appear for tab ${j + 1}`
);
// Check the presence of the dismiss button
const dismissButton = row.renderRoot.querySelector(".dismiss-button");
const dismissButton = row.secondaryButtonEl;
Assert.ok(dismissButton, `Dismiss button is present on tab ${j + 1}.`);
// Simulate clicking the dismiss button
EventUtils.synthesizeMouseAtCenter(dismissButton, {}, content);
await TestUtils.waitForCondition(
await BrowserTestUtils.waitForMutationCondition(
row.secondaryButtonEl,
{ attributes: true },
() => {
const undoButton = row.renderRoot.querySelector(".undo-button");
return undoButton && undoButton.style.display !== "none";
const undoButton = row.secondaryButtonEl;
return (
undoButton.classList.contains("undo-button") &&
undoButton.style.display !== "none"
);
},
`Undo button is shown after dismissing tab ${j + 1}.`
);
// Simulate clicking the undo button
const undoButton = row.renderRoot.querySelector(".undo-button");
const undoButton = row.secondaryButtonEl;
EventUtils.synthesizeMouseAtCenter(
row.mainEl,
{ type: "mouseover" },
content
);
EventUtils.synthesizeMouseAtCenter(undoButton, {}, content);
await TestUtils.waitForCondition(
await BrowserTestUtils.waitForMutationCondition(
row.secondaryButtonEl,
{ attributes: true },
() => {
return (
row.renderRoot.querySelector(".dismiss-button") &&
!row.renderRoot.querySelector(".undo-button")
row.secondaryButtonEl.classList.contains("dismiss-button") &&
!row.secondaryButtonEl.classList.contains("undo-button")
);
},
`Dismiss button is restored after undoing tab ${j + 1}.`