summaryrefslogtreecommitdiffstats
path: root/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js')
-rw-r--r--browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js601
1 files changed, 601 insertions, 0 deletions
diff --git a/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js b/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js
new file mode 100644
index 0000000000..89171deb1f
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js
@@ -0,0 +1,601 @@
+/* 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/. */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+
+"use strict";
+
+const bookmarksInfo = [
+ {
+ title: "firefox",
+ url: "http://example.com",
+ },
+ {
+ title: "rules",
+ url: "http://example.com/2",
+ },
+ {
+ title: "yo",
+ url: "http://example.com/2",
+ },
+];
+
+/**
+ * Test showing the "Other Bookmarks" folder in the bookmarks toolbar.
+ */
+
+// Setup.
+add_setup(async function () {
+ // Disable window occlusion. See bug 1733955 / bug 1779559.
+ if (navigator.platform.indexOf("Win") == 0) {
+ await SpecialPowers.pushPrefEnv({
+ set: [["widget.windows.window_occlusion_tracking.enabled", false]],
+ });
+ }
+
+ let toolbar = document.getElementById("PersonalToolbar");
+ let wasCollapsed = toolbar.collapsed;
+
+ await setupBookmarksToolbar();
+
+ // Cleanup.
+ registerCleanupFunction(async () => {
+ // Collapse the personal toolbar if needed.
+ if (wasCollapsed) {
+ await promiseSetToolbarVisibility(toolbar, false);
+ }
+ await PlacesUtils.bookmarks.eraseEverything();
+ });
+});
+
+// Test the "Other Bookmarks" folder is shown in the toolbar when
+// bookmarks are stored under that folder.
+add_task(async function testShowingOtherBookmarksInToolbar() {
+ info("Check the initial state of the Other Bookmarks folder.");
+ let win = await BrowserTestUtils.openNewBrowserWindow();
+ await setupBookmarksToolbar(win);
+ ok(
+ !win.document.getElementById("OtherBookmarks"),
+ "Shouldn't have an Other Bookmarks button."
+ );
+ await BrowserTestUtils.closeWindow(win);
+
+ info("Check visibility of an empty Other Bookmarks folder.");
+ await testIsOtherBookmarksHidden(true);
+
+ info("Ensure folder appears in toolbar when a new bookmark is added.");
+ let bookmarks = await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: bookmarksInfo,
+ });
+ await testIsOtherBookmarksHidden(false);
+
+ info("Ensure folder disappears from toolbar when no bookmarks are present.");
+ await PlacesUtils.bookmarks.remove(bookmarks);
+ await testIsOtherBookmarksHidden(true);
+});
+
+// Test that folder visibility is correct when moving bookmarks to an empty
+// "Other Bookmarks" folder and vice versa.
+add_task(async function testOtherBookmarksVisibilityWhenMovingBookmarks() {
+ info("Add bookmarks to Bookmarks Toolbar.");
+ let bookmarks = await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.toolbarGuid,
+ children: bookmarksInfo,
+ });
+ await testIsOtherBookmarksHidden(true);
+
+ info("Move toolbar bookmarks to Other Bookmarks folder.");
+ await PlacesUtils.bookmarks.moveToFolder(
+ bookmarks.map(b => b.guid),
+ PlacesUtils.bookmarks.unfiledGuid,
+ PlacesUtils.bookmarks.DEFAULT_INDEX
+ );
+ await testIsOtherBookmarksHidden(false);
+
+ info("Move bookmarks from Other Bookmarks back to the toolbar.");
+ await PlacesUtils.bookmarks.moveToFolder(
+ bookmarks.map(b => b.guid),
+ PlacesUtils.bookmarks.toolbarGuid,
+ PlacesUtils.bookmarks.DEFAULT_INDEX
+ );
+ await testIsOtherBookmarksHidden(true);
+});
+
+// Test OtherBookmarksPopup in toolbar.
+add_task(async function testOtherBookmarksMenuPopup() {
+ info("Add bookmarks to Other Bookmarks folder.");
+ let bookmarks = await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: bookmarksInfo,
+ });
+
+ await testIsOtherBookmarksHidden(false);
+
+ info("Check the popup menu has correct number of children.");
+ await openMenuPopup("#OtherBookmarksPopup", "#OtherBookmarks");
+ testNumberOfMenuPopupChildren("#OtherBookmarksPopup", 3);
+ await closeMenuPopup("#OtherBookmarksPopup");
+
+ info("Remove a bookmark.");
+ await PlacesUtils.bookmarks.remove(bookmarks[0]);
+
+ await openMenuPopup("#OtherBookmarksPopup", "#OtherBookmarks");
+ testNumberOfMenuPopupChildren("#OtherBookmarksPopup", 2);
+ await closeMenuPopup("#OtherBookmarksPopup");
+});
+
+// Test that folders in the Other Bookmarks folder expand
+add_task(async function testFolderPopup() {
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: [
+ {
+ title: "folder",
+ type: PlacesUtils.bookmarks.TYPE_FOLDER,
+ children: [
+ {
+ title: "example",
+ url: "http://example.com/3",
+ },
+ ],
+ },
+ ],
+ });
+
+ info("Check for popup showing event when folder menuitem is selected.");
+ await openMenuPopup("#OtherBookmarksPopup", "#OtherBookmarks");
+ await openMenuPopup(
+ "#OtherBookmarksPopup menu menupopup",
+ "#OtherBookmarksPopup menu"
+ );
+ ok(true, "Folder menu stored in Other Bookmarks expands.");
+ testNumberOfMenuPopupChildren("#OtherBookmarksPopup menu menupopup", 1);
+ await closeMenuPopup("#OtherBookmarksPopup");
+});
+
+add_task(async function testOnlyShowOtherFolderInBookmarksToolbar() {
+ await setupBookmarksToolbar();
+
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: bookmarksInfo,
+ });
+
+ await testIsOtherBookmarksHidden(false);
+
+ // Test that moving the personal-bookmarks widget out of the
+ // Bookmarks Toolbar will hide the "Other Bookmarks" folder.
+ let widgetId = "personal-bookmarks";
+ CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR);
+ await testIsOtherBookmarksHidden(true);
+
+ CustomizableUI.reset();
+ await testIsOtherBookmarksHidden(false);
+});
+
+// Test that the menu popup updates when menu items are deleted from it while
+// it's open.
+add_task(async function testDeletingMenuItems() {
+ await setupBookmarksToolbar();
+
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: bookmarksInfo,
+ });
+
+ await testIsOtherBookmarksHidden(false);
+
+ await openMenuPopup("#OtherBookmarksPopup", "#OtherBookmarks");
+ testNumberOfMenuPopupChildren("#OtherBookmarksPopup", 3);
+
+ info("Open context menu for popup.");
+ let placesContext = document.getElementById("placesContext");
+ let popupEventPromise = BrowserTestUtils.waitForPopupEvent(
+ placesContext,
+ "shown"
+ );
+ let menuitem = document.querySelector("#OtherBookmarksPopup menuitem");
+ EventUtils.synthesizeMouseAtCenter(menuitem, { type: "contextmenu" });
+ await popupEventPromise;
+
+ info("Delete bookmark menu item from popup.");
+ let deleteMenuBookmark = document.getElementById(
+ "placesContext_deleteBookmark"
+ );
+ placesContext.activateItem(deleteMenuBookmark);
+
+ await TestUtils.waitForCondition(() => {
+ let popup = document.querySelector("#OtherBookmarksPopup");
+ let items = popup.querySelectorAll("menuitem");
+ return items.length === 2;
+ }, "Failed to delete bookmark menuitem. Expected 2 menu items after deletion.");
+ ok(true, "Menu item was removed from the popup.");
+ await closeMenuPopup("#OtherBookmarksPopup");
+});
+
+add_task(async function no_errors_when_bookmarks_placed_in_palette() {
+ CustomizableUI.removeWidgetFromArea("personal-bookmarks");
+
+ let consoleErrors = 0;
+
+ let errorListener = {
+ observe(error) {
+ ok(false, `${error.message}, ${error.stack}, ${JSON.stringify(error)}`);
+ consoleErrors++;
+ },
+ };
+ Services.console.registerListener(errorListener);
+
+ let bookmarks = await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: bookmarksInfo,
+ });
+ is(consoleErrors, 0, "There should be no console errors");
+
+ Services.console.unregisterListener(errorListener);
+ await PlacesUtils.bookmarks.remove(bookmarks);
+ CustomizableUI.reset();
+});
+
+// Test "Show Other Bookmarks" menu item visibility in toolbar context menu.
+add_task(async function testShowingOtherBookmarksContextMenuItem() {
+ await setupBookmarksToolbar();
+
+ info("Add bookmark to Other Bookmarks.");
+ let bookmark = await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: [{ title: "firefox", url: "http://example.com" }],
+ });
+
+ info("'Show Other Bookmarks' menu item should be checked by default.");
+ await testOtherBookmarksCheckedState(true);
+
+ info("Toggle off showing the Other Bookmarks folder.");
+ await selectShowOtherBookmarksMenuItem();
+ await testOtherBookmarksCheckedState(false);
+ await testIsOtherBookmarksHidden(true);
+
+ info("Toggle on showing the Other Bookmarks folder.");
+ await selectShowOtherBookmarksMenuItem();
+ await testOtherBookmarksCheckedState(true);
+ await testIsOtherBookmarksHidden(false);
+
+ info(
+ "Ensure 'Show Other Bookmarks' isn't shown when Other Bookmarks is empty."
+ );
+ await PlacesUtils.bookmarks.remove(bookmark);
+ await testIsOtherBookmarksMenuItemEnabled(false);
+
+ info("Add a bookmark to the empty Other Bookmarks folder.");
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: [{ title: "firefox", url: "http://example.com" }],
+ });
+ await testIsOtherBookmarksMenuItemEnabled(true);
+
+ info(
+ "Ensure that displaying Other Bookmarks is consistent across separate windows."
+ );
+ let newWin = await BrowserTestUtils.openNewBrowserWindow();
+
+ await TestUtils.waitForCondition(() => {
+ let otherBookmarks = newWin.document.getElementById("OtherBookmarks");
+ return otherBookmarks && !otherBookmarks.hidden;
+ }, "Other Bookmarks folder failed to show in other window.");
+
+ info("Hide the Other Bookmarks folder from the original window.");
+ await selectShowOtherBookmarksMenuItem();
+
+ await TestUtils.waitForCondition(() => {
+ let otherBookmarks = newWin.document.getElementById("OtherBookmarks");
+ return !otherBookmarks || otherBookmarks.hidden;
+ }, "Other Bookmarks folder failed to be hidden in other window.");
+ ok(true, "Other Bookmarks was successfully hidden in other window.");
+
+ info("Show the Other Bookmarks folder from the original window.");
+ await selectShowOtherBookmarksMenuItem();
+
+ await TestUtils.waitForCondition(() => {
+ let otherBookmarks = newWin.document.getElementById("OtherBookmarks");
+ return otherBookmarks && !otherBookmarks.hidden;
+ }, "Other Bookmarks folder failed to be shown in other window.");
+ ok(true, "Other Bookmarks was successfully shown in other window.");
+
+ await BrowserTestUtils.closeWindow(newWin);
+});
+
+// Test 'Show Other Bookmarks' isn't shown when pref is false.
+add_task(async function showOtherBookmarksMenuItemPrefDisabled() {
+ await setupBookmarksToolbar();
+ await testIsOtherBookmarksMenuItemEnabled(false);
+});
+
+// Test that node visibility for toolbar overflow is consisten when the "Other Bookmarks"
+// folder is shown/hidden.
+add_task(async function testOtherBookmarksToolbarOverFlow() {
+ await setupBookmarksToolbar();
+
+ info(
+ "Ensure that visible nodes when showing/hiding Other Bookmarks is consistent across separate windows."
+ );
+ // Add bookmarks to other bookmarks
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.unfiledGuid,
+ children: [{ title: "firefox", url: "http://example.com" }],
+ });
+
+ let newWin = await BrowserTestUtils.openNewBrowserWindow();
+
+ // Add bookmarks to the toolbar
+ await PlacesUtils.bookmarks.insertTree({
+ guid: PlacesUtils.bookmarks.toolbarGuid,
+ children: Array(100)
+ .fill("")
+ .map((_, i) => ({ title: `test ${i}`, url: `http:example.com/${i}` })),
+ });
+
+ info("Hide the Other Bookmarks folder from the original window.");
+ await selectShowOtherBookmarksMenuItem("#OtherBookmarks");
+ await BrowserTestUtils.waitForEvent(
+ document.getElementById("PersonalToolbar"),
+ "BookmarksToolbarVisibilityUpdated"
+ );
+ ok(true, "Nodes successfully updated for both windows.");
+ await testUpdatedNodeVisibility(newWin);
+
+ info("Show the Other Bookmarks folder from the original window.");
+ await selectShowOtherBookmarksMenuItem("#PlacesChevron");
+ await BrowserTestUtils.waitForEvent(
+ document.getElementById("PersonalToolbar"),
+ "BookmarksToolbarVisibilityUpdated"
+ );
+ ok(true, "Nodes successfully updated for both windows.");
+ await testUpdatedNodeVisibility(newWin);
+
+ await BrowserTestUtils.closeWindow(newWin);
+});
+
+/**
+ * Tests whether or not the "Other Bookmarks" folder is visible.
+ *
+ * @param {boolean} expected
+ * The expected state of the Other Bookmarks folder. There are 3:
+ * - the folder node isn't initialized and is therefore not visible,
+ * - the folder node is initialized and is hidden
+ * - the folder node is initialized and is visible
+ */
+async function testIsOtherBookmarksHidden(expected) {
+ info("Test whether or not the 'Other Bookmarks' folder is visible.");
+
+ // Ensure the toolbar is visible.
+ let toolbar = document.getElementById("PersonalToolbar");
+ await promiseSetToolbarVisibility(toolbar, true);
+
+ let otherBookmarks = document.getElementById("OtherBookmarks");
+
+ await TestUtils.waitForCondition(() => {
+ otherBookmarks = document.getElementById("OtherBookmarks");
+ let isHidden = !otherBookmarks || otherBookmarks.hidden;
+ return isHidden === expected;
+ }, "Other Bookmarks folder failed to change hidden state.");
+
+ ok(true, `Other Bookmarks folder "hidden" state should be ${expected}.`);
+}
+
+/**
+ * Tests number of menu items in Other Bookmarks popup.
+ *
+ * @param {string} selector
+ * The selector for getting the menupopup element we want to test.
+ * @param {number} expected
+ * The expected number of menuitem elements inside the menupopup.
+ */
+function testNumberOfMenuPopupChildren(selector, expected) {
+ let popup = document.querySelector(selector);
+ let items = popup.querySelectorAll("menuitem");
+
+ is(
+ items.length,
+ expected,
+ `Number of menu items for ${selector} should be ${expected}.`
+ );
+}
+
+/**
+ * Test helper for checking the 'checked' state of the "Show Other Bookmarks" menu item
+ * after selecting it from the context menu.
+ *
+ * @param {boolean} expectedCheckedState
+ * Whether or not the menu item is checked.
+ */
+async function testOtherBookmarksCheckedState(expectedCheckedState) {
+ info("Check 'Show Other Bookmarks' menu item state");
+ await openToolbarContextMenu();
+
+ let otherBookmarksMenuItem = document.querySelector(
+ "#show-other-bookmarks_PersonalToolbar"
+ );
+
+ is(
+ otherBookmarksMenuItem.getAttribute("checked"),
+ `${expectedCheckedState}`,
+ `Other Bookmarks item's checked state should be ${expectedCheckedState}`
+ );
+
+ await closeToolbarContextMenu();
+}
+
+/**
+ * Test helper for checking whether or not the 'Show Other Bookmarks' menu item
+ * is enabled in the toolbar's context menu.
+ *
+ * @param {boolean} expected
+ * Whether or not the menu item is enabled in the toolbar conext menu.
+ */
+async function testIsOtherBookmarksMenuItemEnabled(expected) {
+ await openToolbarContextMenu();
+
+ let otherBookmarksMenuItem = document.querySelector(
+ "#show-other-bookmarks_PersonalToolbar"
+ );
+
+ is(
+ !otherBookmarksMenuItem.disabled,
+ expected,
+ "'Show Other Bookmarks' menu item appearance state is correct."
+ );
+
+ await closeToolbarContextMenu();
+}
+
+/**
+ * Helper for opening a menu popup.
+ *
+ * @param {string} popupSelector
+ * The selector for the menupopup element we want to open.
+ * @param {string} targetSelector
+ * The selector for the element with the popup showing event.
+ */
+async function openMenuPopup(popupSelector, targetSelector) {
+ let popup = document.querySelector(popupSelector);
+ let target = document.querySelector(targetSelector);
+
+ EventUtils.synthesizeMouseAtCenter(target, {});
+
+ await BrowserTestUtils.waitForPopupEvent(popup, "shown");
+}
+
+/**
+ * Helper for closing a menu popup.
+ *
+ * @param {string} popupSelector
+ * The selector for the menupopup element we want to close.
+ */
+async function closeMenuPopup(popupSelector) {
+ let popup = document.querySelector(popupSelector);
+
+ info("Closing menu popup.");
+ popup.hidePopup();
+ await BrowserTestUtils.waitForPopupEvent(popup, "hidden");
+}
+
+/**
+ * Helper for opening the toolbar context menu.
+ *
+ * @param {string} toolbarSelector
+ * Optional. The selector for the toolbar context menu.
+ * Defaults to #PlacesToolbarItems.
+ */
+async function openToolbarContextMenu(toolbarSelector = "#PlacesToolbarItems") {
+ let contextMenu = document.getElementById("placesContext");
+ let toolbar = document.querySelector(toolbarSelector);
+ let openToolbarContextMenuPromise = BrowserTestUtils.waitForPopupEvent(
+ contextMenu,
+ "shown"
+ );
+
+ // Use the end of the toolbar because the beginning (and even middle, on
+ // some resolutions) might be occluded by the empty toolbar message, which
+ // has a different context menu.
+ let bounds = toolbar.getBoundingClientRect();
+ EventUtils.synthesizeMouse(toolbar, bounds.width - 5, 5, {
+ type: "contextmenu",
+ });
+
+ await openToolbarContextMenuPromise;
+}
+
+/**
+ * Helper for closing the toolbar context menu.
+ */
+async function closeToolbarContextMenu() {
+ let contextMenu = document.getElementById("placesContext");
+ let closeToolbarContextMenuPromise = BrowserTestUtils.waitForPopupEvent(
+ contextMenu,
+ "hidden"
+ );
+ contextMenu.hidePopup();
+ await closeToolbarContextMenuPromise;
+}
+
+/**
+ * Helper for setting up the bookmarks toolbar state. This ensures the beginning
+ * of a task will always have the bookmark toolbar in a state that makes the
+ * Other Bookmarks folder testable.
+ *
+ * @param {object} [win]
+ * The window object to use.
+ */
+async function setupBookmarksToolbar(win = window) {
+ let toolbar = win.document.getElementById("PersonalToolbar");
+ let wasCollapsed = toolbar.collapsed;
+
+ // Uncollapse the personal toolbar if needed.
+ if (wasCollapsed) {
+ await promiseSetToolbarVisibility(toolbar, true);
+ }
+
+ await PlacesUtils.bookmarks.eraseEverything();
+}
+
+/**
+ * Helper for selecting the "Show Other Bookmarks" menu item from the bookmarks
+ * toolbar context menu.
+ *
+ * @param {string} selector
+ * Optional. The selector for the node that triggers showing the
+ * "Show Other Bookmarks" context menu item in the toolbar.
+ * Defaults to #PlacesToolbarItem when `openToolbarContextMenu` is
+ * called.
+ */
+async function selectShowOtherBookmarksMenuItem(selector) {
+ info("Select 'Show Other Bookmarks' menu item");
+ await openToolbarContextMenu(selector);
+
+ let otherBookmarksMenuItem = document.querySelector(
+ "#show-other-bookmarks_PersonalToolbar"
+ );
+ let contextMenu = document.getElementById("placesContext");
+
+ contextMenu.activateItem(otherBookmarksMenuItem);
+
+ await BrowserTestUtils.waitForPopupEvent(contextMenu, "hidden");
+ await closeToolbarContextMenu();
+}
+
+/**
+ * Test helper for node visibility in the bookmarks toolbar between two windows.
+ *
+ * @param {Window} otherWin
+ * The other window whose toolbar items we want to compare with.
+ */
+function testUpdatedNodeVisibility(otherWin) {
+ // Get visible toolbar nodes for both the current and other windows.
+ let toolbarItems = document.getElementById("PlacesToolbarItems");
+ let currentVisibleNodes = [];
+
+ for (let node of toolbarItems.children) {
+ if (node.style.visibility === "visible") {
+ currentVisibleNodes.push(node);
+ }
+ }
+
+ let otherToolbarItems =
+ otherWin.document.getElementById("PlacesToolbarItems");
+ let otherVisibleNodes = [];
+
+ for (let node of otherToolbarItems.children) {
+ if (node.style.visibility === "visible") {
+ otherVisibleNodes.push(node);
+ }
+ }
+
+ let lastIdx = otherVisibleNodes.length - 1;
+
+ is(
+ currentVisibleNodes[lastIdx]?.bookmarkGuid,
+ otherVisibleNodes[lastIdx]?.bookmarkGuid,
+ "Last visible toolbar bookmark is the same in both windows."
+ );
+}