summaryrefslogtreecommitdiffstats
path: root/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js')
-rw-r--r--browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js302
1 files changed, 302 insertions, 0 deletions
diff --git a/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
new file mode 100644
index 0000000000..6d2295cc16
--- /dev/null
+++ b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
@@ -0,0 +1,302 @@
+/* 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";
+
+var gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
+var gOverflowList = document.getElementById(
+ gNavBar.getAttribute("default-overflowtarget")
+);
+
+const kBookmarksButton = "bookmarks-menu-button";
+const kBookmarksItems = "personal-bookmarks";
+const kOriginalWindowWidth = window.outerWidth;
+
+/**
+ * Helper function that opens the bookmarks menu, and returns a Promise that
+ * resolves as soon as the menu is ready for interaction.
+ */
+function bookmarksMenuPanelShown() {
+ return new Promise(resolve => {
+ let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
+ let onPopupShown = e => {
+ if (e.target == bookmarksMenuPopup) {
+ bookmarksMenuPopup.removeEventListener("popupshown", onPopupShown);
+ resolve();
+ }
+ };
+ bookmarksMenuPopup.addEventListener("popupshown", onPopupShown);
+ });
+}
+
+/**
+ * Checks that the placesContext menu is correctly attached to the
+ * controller of some view. Returns a Promise that resolves as soon
+ * as the context menu is closed.
+ *
+ * @param aItemWithContextMenu the item that we need to synthesize the
+ * right click on in order to open the context menu.
+ */
+function checkPlacesContextMenu(aItemWithContextMenu) {
+ return (async function () {
+ let contextMenu = document.getElementById("placesContext");
+ let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
+ info("Waiting for context menu on " + aItemWithContextMenu.id);
+ let shownPromise = popupShown(contextMenu);
+ EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu, {
+ type: "contextmenu",
+ button: 2,
+ });
+ await shownPromise;
+
+ ok(
+ !newBookmarkItem.hasAttribute("disabled"),
+ "New bookmark item shouldn't be disabled"
+ );
+
+ info("Closing context menu");
+ let hiddenPromise = popupHidden(contextMenu);
+ // Use hidePopup instead of the closePopup helper because macOS native
+ // context menus can't be closed by synthesized ESC in automation.
+ contextMenu.hidePopup();
+ await hiddenPromise;
+ })();
+}
+
+/**
+ * Opens the bookmarks menu panel, and then opens each of the "special"
+ * submenus in that list. Then it checks that those submenu's context menus
+ * are properly hooked up to a controller.
+ */
+function checkSpecialContextMenus() {
+ return (async function () {
+ let bookmarksMenuButton = document.getElementById(kBookmarksButton);
+ let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
+
+ const kSpecialItemIDs = {
+ BMB_bookmarksToolbar: "BMB_bookmarksToolbarPopup",
+ BMB_unsortedBookmarks: "BMB_unsortedBookmarksPopup",
+ };
+
+ // Open the bookmarks menu button context menus and ensure that
+ // they have the proper views attached.
+ let shownPromise = bookmarksMenuPanelShown();
+
+ EventUtils.synthesizeMouseAtCenter(bookmarksMenuButton, {});
+ info("Waiting for bookmarks menu popup to show after clicking dropmarker.");
+ await shownPromise;
+
+ for (let menuID in kSpecialItemIDs) {
+ let menuItem = document.getElementById(menuID);
+ let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
+ info("Waiting to open menu for " + menuID);
+ shownPromise = popupShown(menuPopup);
+ menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
+ await shownPromise;
+
+ await checkPlacesContextMenu(menuPopup);
+ info("Closing menu for " + menuID);
+ await closePopup(menuPopup);
+ }
+
+ info("Closing bookmarks menu");
+ await closePopup(bookmarksMenuPopup);
+ })();
+}
+
+/**
+ * Closes a focused popup by simulating pressing the Escape key,
+ * and returns a Promise that resolves as soon as the popup is closed.
+ *
+ * @param aPopup the popup node to close.
+ */
+function closePopup(aPopup) {
+ let hiddenPromise = popupHidden(aPopup);
+ EventUtils.synthesizeKey("KEY_Escape");
+ return hiddenPromise;
+}
+
+/**
+ * Helper function that checks that the context menu of the
+ * bookmark toolbar items chevron popup is correctly hooked up
+ * to the controller of a view.
+ */
+function checkBookmarksItemsChevronContextMenu() {
+ return (async function () {
+ let chevronPopup = document.getElementById("PlacesChevronPopup");
+ let shownPromise = popupShown(chevronPopup);
+ let chevron = document.getElementById("PlacesChevron");
+ EventUtils.synthesizeMouseAtCenter(chevron, {});
+ info("Waiting for bookmark toolbar item chevron popup to show");
+ await shownPromise;
+ await TestUtils.waitForCondition(() => {
+ for (let child of chevronPopup.children) {
+ if (child.style.visibility != "hidden") {
+ return true;
+ }
+ }
+ return false;
+ });
+ await checkPlacesContextMenu(chevronPopup);
+ info("Waiting for bookmark toolbar item chevron popup to close");
+ await closePopup(chevronPopup);
+ })();
+}
+
+/**
+ * Forces the window to a width that causes the nav-bar to overflow
+ * its contents. Returns a Promise that resolves as soon as the
+ * overflowable nav-bar is showing its chevron.
+ */
+function overflowEverything() {
+ info("Waiting for overflow");
+ window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
+ return TestUtils.waitForCondition(() => gNavBar.hasAttribute("overflowing"));
+}
+
+/**
+ * Returns the window to its original size from the start of the test,
+ * and returns a Promise that resolves when the nav-bar is no longer
+ * overflowing.
+ */
+function stopOverflowing() {
+ info("Waiting until we stop overflowing");
+ window.resizeTo(kOriginalWindowWidth, window.outerHeight);
+ return TestUtils.waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
+}
+
+/**
+ * Checks that an item with ID aID is overflowing in the nav-bar.
+ *
+ * @param aID the ID of the node to check for overflowingness.
+ */
+function checkOverflowing(aID) {
+ ok(
+ !gNavBar.querySelector("#" + aID),
+ "Item with ID " + aID + " should no longer be in the gNavBar"
+ );
+ let item = gOverflowList.querySelector("#" + aID);
+ ok(item, "Item with ID " + aID + " should be overflowing");
+ is(
+ item.getAttribute("overflowedItem"),
+ "true",
+ "Item with ID " + aID + " should have overflowedItem attribute"
+ );
+}
+
+/**
+ * Checks that an item with ID aID is not overflowing in the nav-bar.
+ *
+ * @param aID the ID of hte node to check for non-overflowingness.
+ */
+function checkNotOverflowing(aID) {
+ ok(
+ !gOverflowList.querySelector("#" + aID),
+ "Item with ID " + aID + " should no longer be overflowing"
+ );
+ let item = gNavBar.querySelector("#" + aID);
+ ok(item, "Item with ID " + aID + " should be in the nav bar");
+ ok(
+ !item.hasAttribute("overflowedItem"),
+ "Item with ID " + aID + " should not have overflowedItem attribute"
+ );
+}
+
+/**
+ * Test that overflowing the bookmarks menu button doesn't break the
+ * context menus for the Unsorted and Bookmarks Toolbar menu items.
+ */
+add_task(async function testOverflowingBookmarksButtonContextMenu() {
+ ok(CustomizableUI.inDefaultState, "Should start in default state.");
+ // The DevEdition has the DevTools button in the toolbar by default. Remove it
+ // to prevent branch-specific available toolbar space.
+ CustomizableUI.removeWidgetFromArea("developer-button");
+ CustomizableUI.removeWidgetFromArea(
+ "library-button",
+ CustomizableUI.AREA_NAVBAR
+ );
+ CustomizableUI.addWidgetToArea(kBookmarksButton, CustomizableUI.AREA_NAVBAR);
+ ok(
+ !gNavBar.hasAttribute("overflowing"),
+ "Should start with a non-overflowing toolbar."
+ );
+
+ // Open the Unsorted and Bookmarks Toolbar context menus and ensure
+ // that they have views attached.
+ await checkSpecialContextMenus();
+
+ await overflowEverything();
+ checkOverflowing(kBookmarksButton);
+
+ await stopOverflowing();
+ checkNotOverflowing(kBookmarksButton);
+
+ await checkSpecialContextMenus();
+});
+
+/**
+ * Test that the bookmarks toolbar items context menu still works if moved
+ * to the menu from the overflow panel, and then back to the toolbar.
+ */
+add_task(async function testOverflowingBookmarksItemsContextMenu() {
+ info("Ensuring panel is ready.");
+ await PanelUI.ensureReady();
+
+ let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
+ await gCustomizeMode.addToToolbar(bookmarksToolbarItems);
+ await TestUtils.waitForCondition(
+ () => document.getElementById("PlacesToolbar")._placesView
+ );
+ await checkPlacesContextMenu(bookmarksToolbarItems);
+
+ await overflowEverything();
+ checkOverflowing(kBookmarksItems);
+
+ await gCustomizeMode.addToPanel(bookmarksToolbarItems);
+
+ await stopOverflowing();
+
+ await gCustomizeMode.addToToolbar(bookmarksToolbarItems);
+ await TestUtils.waitForCondition(
+ () => document.getElementById("PlacesToolbar")._placesView
+ );
+ await checkPlacesContextMenu(bookmarksToolbarItems);
+});
+
+/**
+ * Test that overflowing the bookmarks toolbar items doesn't cause the
+ * context menu in the bookmarks toolbar items chevron to stop working.
+ */
+add_task(async function testOverflowingBookmarksItemsChevronContextMenu() {
+ // If it's not already there, let's move the bookmarks toolbar items to
+ // the nav-bar.
+ let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
+ await gCustomizeMode.addToToolbar(bookmarksToolbarItems);
+
+ // We make the PlacesToolbarItems element be super tiny in order to force
+ // the bookmarks toolbar items into overflowing and making the chevron
+ // show itself.
+ let placesToolbarItems = document.getElementById("PlacesToolbarItems");
+ let placesChevron = document.getElementById("PlacesChevron");
+ placesToolbarItems.style.maxWidth = "10px";
+ info("Waiting for chevron to no longer be collapsed");
+ await TestUtils.waitForCondition(() => !placesChevron.collapsed);
+
+ await checkBookmarksItemsChevronContextMenu();
+
+ await overflowEverything();
+ checkOverflowing(kBookmarksItems);
+
+ await stopOverflowing();
+ checkNotOverflowing(kBookmarksItems);
+
+ await checkBookmarksItemsChevronContextMenu();
+
+ placesToolbarItems.style.removeProperty("max-width");
+});
+
+add_task(async function asyncCleanup() {
+ window.resizeTo(kOriginalWindowWidth, window.outerHeight);
+ await resetCustomization();
+});