browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,256 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +let gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
    1.11 +let gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget"));
    1.12 +
    1.13 +const kBookmarksButton = "bookmarks-menu-button";
    1.14 +const kBookmarksItems = "personal-bookmarks";
    1.15 +const kOriginalWindowWidth = window.outerWidth;
    1.16 +const kSmallWidth = 400;
    1.17 +
    1.18 +/**
    1.19 + * Helper function that opens the bookmarks menu, and returns a Promise that
    1.20 + * resolves as soon as the menu is ready for interaction.
    1.21 + */
    1.22 +function bookmarksMenuPanelShown() {
    1.23 +  let deferred = Promise.defer();
    1.24 +  let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
    1.25 +  let onTransitionEnd = (e) => {
    1.26 +    if (e.target == bookmarksMenuPopup) {
    1.27 +      bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
    1.28 +      deferred.resolve();
    1.29 +    }
    1.30 +  }
    1.31 +  bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
    1.32 +  return deferred.promise;
    1.33 +}
    1.34 +
    1.35 +/**
    1.36 + * Checks that the placesContext menu is correctly attached to the
    1.37 + * controller of some view. Returns a Promise that resolves as soon
    1.38 + * as the context menu is closed.
    1.39 + *
    1.40 + * @param aItemWithContextMenu the item that we need to synthesize hte
    1.41 + *        right click on in order to open the context menu.
    1.42 + */
    1.43 +function checkPlacesContextMenu(aItemWithContextMenu) {
    1.44 +  return Task.spawn(function* () {
    1.45 +    let contextMenu = document.getElementById("placesContext");
    1.46 +    let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
    1.47 +    let shownPromise = popupShown(contextMenu);
    1.48 +    EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu,
    1.49 +                                       {type: "contextmenu", button: 2});
    1.50 +    yield shownPromise;
    1.51 +
    1.52 +    ok(!newBookmarkItem.hasAttribute("disabled"),
    1.53 +       "New bookmark item shouldn't be disabled");
    1.54 +
    1.55 +    yield closePopup(contextMenu);
    1.56 +  });
    1.57 +}
    1.58 +
    1.59 +/**
    1.60 + * Opens the bookmarks menu panel, and then opens each of the "special"
    1.61 + * submenus in that list. Then it checks that those submenu's context menus
    1.62 + * are properly hooked up to a controller.
    1.63 + */
    1.64 +function checkSpecialContextMenus() {
    1.65 +  return Task.spawn(function* () {
    1.66 +    let contextMenu = document.getElementById("placesContext");
    1.67 +    let bookmarksMenuButton = document.getElementById(kBookmarksButton);
    1.68 +    let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
    1.69 +
    1.70 +    const kSpecialItemIDs = {
    1.71 +      "BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup",
    1.72 +      "BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup",
    1.73 +    };
    1.74 +
    1.75 +    // Open the bookmarks menu button context menus and ensure that
    1.76 +    // they have the proper views attached.
    1.77 +    let shownPromise = bookmarksMenuPanelShown();
    1.78 +    let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton,
    1.79 +                                                             "anonid", "dropmarker");
    1.80 +    EventUtils.synthesizeMouseAtCenter(dropmarker, {});
    1.81 +    info("Waiting for bookmarks menu popup to show after clicking dropmarker.")
    1.82 +    yield shownPromise;
    1.83 +
    1.84 +    for (let menuID in kSpecialItemIDs) {
    1.85 +      let menuItem = document.getElementById(menuID);
    1.86 +      let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
    1.87 +      let shownPromise = popupShown(menuPopup);
    1.88 +      menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
    1.89 
    1.90 +      yield shownPromise;
    1.91 +
    1.92 +      yield checkPlacesContextMenu(menuPopup);
    1.93 +      yield closePopup(menuPopup);
    1.94 +    }
    1.95 +
    1.96 +    yield closePopup(bookmarksMenuPopup);
    1.97 +  });
    1.98 +}
    1.99 +
   1.100 +/**
   1.101 + * Closes a focused popup by simulating pressing the Escape key,
   1.102 + * and returns a Promise that resolves as soon as the popup is closed.
   1.103 + *
   1.104 + * @param aPopup the popup node to close.
   1.105 + */
   1.106 +function closePopup(aPopup) {
   1.107 +  let hiddenPromise = popupHidden(aPopup);
   1.108 +  EventUtils.synthesizeKey("VK_ESCAPE", {});
   1.109 +  return hiddenPromise;
   1.110 +}
   1.111 +
   1.112 +/**
   1.113 + * Helper function that checks that the context menu of the
   1.114 + * bookmark toolbar items chevron popup is correctly hooked up
   1.115 + * to the controller of a view.
   1.116 + */
   1.117 +function checkBookmarksItemsChevronContextMenu() {
   1.118 +  return Task.spawn(function*() {
   1.119 +    let chevronPopup = document.getElementById("PlacesChevronPopup");
   1.120 +    let shownPromise = popupShown(chevronPopup);
   1.121 +    let chevron = document.getElementById("PlacesChevron");
   1.122 +    EventUtils.synthesizeMouseAtCenter(chevron, {});
   1.123 +    yield shownPromise;
   1.124 +    yield waitForCondition(() => {
   1.125 +      for (let child of chevronPopup.children) {
   1.126 +        if (child.style.visibility != "hidden")
   1.127 +          return true;
   1.128 +      }
   1.129 +    });
   1.130 +    yield checkPlacesContextMenu(chevronPopup);
   1.131 +    yield closePopup(chevronPopup);
   1.132 +  });
   1.133 +}
   1.134 +
   1.135 +/**
   1.136 + * Forces the window to a width that causes the nav-bar to overflow
   1.137 + * its contents. Returns a Promise that resolves as soon as the
   1.138 + * overflowable nav-bar is showing its chevron.
   1.139 + */
   1.140 +function overflowEverything() {
   1.141 +  window.resizeTo(kSmallWidth, window.outerHeight);
   1.142 +  return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
   1.143 +}
   1.144 +
   1.145 +/**
   1.146 + * Returns the window to its original size from the start of the test,
   1.147 + * and returns a Promise that resolves when the nav-bar is no longer
   1.148 + * overflowing.
   1.149 + */
   1.150 +function stopOverflowing() {
   1.151 +  window.resizeTo(kOriginalWindowWidth, window.outerHeight);
   1.152 +  return waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
   1.153 +}
   1.154 +
   1.155 +/**
   1.156 + * Checks that an item with ID aID is overflowing in the nav-bar.
   1.157 + *
   1.158 + * @param aID the ID of the node to check for overflowingness.
   1.159 + */
   1.160 +function checkOverflowing(aID) {
   1.161 +  ok(!gNavBar.querySelector("#" + aID),
   1.162 +     "Item with ID " + aID + " should no longer be in the gNavBar");
   1.163 +  let item = gOverflowList.querySelector("#" + aID);
   1.164 +  ok(item, "Item with ID " + aID + " should be overflowing");
   1.165 +  is(item.getAttribute("overflowedItem"), "true",
   1.166 +     "Item with ID " + aID + " should have overflowedItem attribute");
   1.167 +}
   1.168 +
   1.169 +/**
   1.170 + * Checks that an item with ID aID is not overflowing in the nav-bar.
   1.171 + *
   1.172 + * @param aID the ID of hte node to check for non-overflowingness.
   1.173 + */
   1.174 +function checkNotOverflowing(aID) {
   1.175 +  ok(!gOverflowList.querySelector("#" + aID),
   1.176 +     "Item with ID " + aID + " should no longer be overflowing");
   1.177 +  let item = gNavBar.querySelector("#" + aID);
   1.178 +  ok(item, "Item with ID " + aID + " should be in the nav bar");
   1.179 +  ok(!item.hasAttribute("overflowedItem"),
   1.180 +     "Item with ID " + aID + " should not have overflowedItem attribute");
   1.181 +}
   1.182 +
   1.183 +/**
   1.184 + * Test that overflowing the bookmarks menu button doesn't break the
   1.185 + * context menus for the Unsorted and Bookmarks Toolbar menu items.
   1.186 + */
   1.187 +add_task(function* testOverflowingBookmarksButtonContextMenu() {
   1.188 +  ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
   1.189 +  ok(CustomizableUI.inDefaultState, "Should start in default state.");
   1.190 +
   1.191 +  // Open the Unsorted and Bookmarks Toolbar context menus and ensure
   1.192 +  // that they have views attached.
   1.193 +  yield checkSpecialContextMenus();
   1.194 +
   1.195 +  yield overflowEverything();
   1.196 +  checkOverflowing(kBookmarksButton);
   1.197 +
   1.198 +  yield stopOverflowing();
   1.199 +  checkNotOverflowing(kBookmarksButton);
   1.200 +
   1.201 +  yield checkSpecialContextMenus();
   1.202 +});
   1.203 +
   1.204 +/**
   1.205 + * Test that the bookmarks toolbar items context menu still works if moved
   1.206 + * to the menu from the overflow panel, and then back to the toolbar.
   1.207 + */
   1.208 +add_task(function* testOverflowingBookmarksItemsContextMenu() {
   1.209 +  yield PanelUI.ensureReady();
   1.210 +
   1.211 +  let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
   1.212 +  gCustomizeMode.addToToolbar(bookmarksToolbarItems);
   1.213 +  yield checkPlacesContextMenu(bookmarksToolbarItems);
   1.214 +
   1.215 +  yield overflowEverything();
   1.216 +  checkOverflowing(kBookmarksItems)
   1.217 +
   1.218 +  gCustomizeMode.addToPanel(bookmarksToolbarItems);
   1.219 +
   1.220 +  yield stopOverflowing();
   1.221 +
   1.222 +  gCustomizeMode.addToToolbar(bookmarksToolbarItems);
   1.223 +  yield checkPlacesContextMenu(bookmarksToolbarItems);
   1.224 +});
   1.225 +
   1.226 +/**
   1.227 + * Test that overflowing the bookmarks toolbar items doesn't cause the
   1.228 + * context menu in the bookmarks toolbar items chevron to stop working.
   1.229 + */
   1.230 +add_task(function* testOverflowingBookmarksItemsChevronContextMenu() {
   1.231 +  // If it's not already there, let's move the bookmarks toolbar items to
   1.232 +  // the nav-bar.
   1.233 +  let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
   1.234 +  gCustomizeMode.addToToolbar(bookmarksToolbarItems);
   1.235 +
   1.236 +  // We make the PlacesToolbarItems element be super tiny in order to force
   1.237 +  // the bookmarks toolbar items into overflowing and making the chevron
   1.238 +  // show itself.
   1.239 +  let placesToolbarItems = document.getElementById("PlacesToolbarItems");
   1.240 +  let placesChevron = document.getElementById("PlacesChevron");
   1.241 +  placesToolbarItems.style.maxWidth = "10px";
   1.242 +  yield waitForCondition(() => !placesChevron.collapsed);
   1.243 +
   1.244 +  yield checkBookmarksItemsChevronContextMenu();
   1.245 +
   1.246 +  yield overflowEverything();
   1.247 +  checkOverflowing(kBookmarksItems);
   1.248 +
   1.249 +  yield stopOverflowing();
   1.250 +  checkNotOverflowing(kBookmarksItems);
   1.251 +
   1.252 +  yield checkBookmarksItemsChevronContextMenu();
   1.253 +
   1.254 +  placesToolbarItems.style.removeProperty("max-width");
   1.255 +});
   1.256 +
   1.257 +add_task(function* asyncCleanup() {
   1.258 +  window.resizeTo(kOriginalWindowWidth, window.outerHeight);
   1.259 +  yield resetCustomization();
   1.260 +});

mercurial