Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 let gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
8 let gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget"));
10 const kBookmarksButton = "bookmarks-menu-button";
11 const kBookmarksItems = "personal-bookmarks";
12 const kOriginalWindowWidth = window.outerWidth;
13 const kSmallWidth = 400;
15 /**
16 * Helper function that opens the bookmarks menu, and returns a Promise that
17 * resolves as soon as the menu is ready for interaction.
18 */
19 function bookmarksMenuPanelShown() {
20 let deferred = Promise.defer();
21 let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
22 let onTransitionEnd = (e) => {
23 if (e.target == bookmarksMenuPopup) {
24 bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
25 deferred.resolve();
26 }
27 }
28 bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
29 return deferred.promise;
30 }
32 /**
33 * Checks that the placesContext menu is correctly attached to the
34 * controller of some view. Returns a Promise that resolves as soon
35 * as the context menu is closed.
36 *
37 * @param aItemWithContextMenu the item that we need to synthesize hte
38 * right click on in order to open the context menu.
39 */
40 function checkPlacesContextMenu(aItemWithContextMenu) {
41 return Task.spawn(function* () {
42 let contextMenu = document.getElementById("placesContext");
43 let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
44 let shownPromise = popupShown(contextMenu);
45 EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu,
46 {type: "contextmenu", button: 2});
47 yield shownPromise;
49 ok(!newBookmarkItem.hasAttribute("disabled"),
50 "New bookmark item shouldn't be disabled");
52 yield closePopup(contextMenu);
53 });
54 }
56 /**
57 * Opens the bookmarks menu panel, and then opens each of the "special"
58 * submenus in that list. Then it checks that those submenu's context menus
59 * are properly hooked up to a controller.
60 */
61 function checkSpecialContextMenus() {
62 return Task.spawn(function* () {
63 let contextMenu = document.getElementById("placesContext");
64 let bookmarksMenuButton = document.getElementById(kBookmarksButton);
65 let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
67 const kSpecialItemIDs = {
68 "BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup",
69 "BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup",
70 };
72 // Open the bookmarks menu button context menus and ensure that
73 // they have the proper views attached.
74 let shownPromise = bookmarksMenuPanelShown();
75 let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton,
76 "anonid", "dropmarker");
77 EventUtils.synthesizeMouseAtCenter(dropmarker, {});
78 info("Waiting for bookmarks menu popup to show after clicking dropmarker.")
79 yield shownPromise;
81 for (let menuID in kSpecialItemIDs) {
82 let menuItem = document.getElementById(menuID);
83 let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
84 let shownPromise = popupShown(menuPopup);
85 menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
87 yield shownPromise;
89 yield checkPlacesContextMenu(menuPopup);
90 yield closePopup(menuPopup);
91 }
93 yield closePopup(bookmarksMenuPopup);
94 });
95 }
97 /**
98 * Closes a focused popup by simulating pressing the Escape key,
99 * and returns a Promise that resolves as soon as the popup is closed.
100 *
101 * @param aPopup the popup node to close.
102 */
103 function closePopup(aPopup) {
104 let hiddenPromise = popupHidden(aPopup);
105 EventUtils.synthesizeKey("VK_ESCAPE", {});
106 return hiddenPromise;
107 }
109 /**
110 * Helper function that checks that the context menu of the
111 * bookmark toolbar items chevron popup is correctly hooked up
112 * to the controller of a view.
113 */
114 function checkBookmarksItemsChevronContextMenu() {
115 return Task.spawn(function*() {
116 let chevronPopup = document.getElementById("PlacesChevronPopup");
117 let shownPromise = popupShown(chevronPopup);
118 let chevron = document.getElementById("PlacesChevron");
119 EventUtils.synthesizeMouseAtCenter(chevron, {});
120 yield shownPromise;
121 yield waitForCondition(() => {
122 for (let child of chevronPopup.children) {
123 if (child.style.visibility != "hidden")
124 return true;
125 }
126 });
127 yield checkPlacesContextMenu(chevronPopup);
128 yield closePopup(chevronPopup);
129 });
130 }
132 /**
133 * Forces the window to a width that causes the nav-bar to overflow
134 * its contents. Returns a Promise that resolves as soon as the
135 * overflowable nav-bar is showing its chevron.
136 */
137 function overflowEverything() {
138 window.resizeTo(kSmallWidth, window.outerHeight);
139 return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
140 }
142 /**
143 * Returns the window to its original size from the start of the test,
144 * and returns a Promise that resolves when the nav-bar is no longer
145 * overflowing.
146 */
147 function stopOverflowing() {
148 window.resizeTo(kOriginalWindowWidth, window.outerHeight);
149 return waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
150 }
152 /**
153 * Checks that an item with ID aID is overflowing in the nav-bar.
154 *
155 * @param aID the ID of the node to check for overflowingness.
156 */
157 function checkOverflowing(aID) {
158 ok(!gNavBar.querySelector("#" + aID),
159 "Item with ID " + aID + " should no longer be in the gNavBar");
160 let item = gOverflowList.querySelector("#" + aID);
161 ok(item, "Item with ID " + aID + " should be overflowing");
162 is(item.getAttribute("overflowedItem"), "true",
163 "Item with ID " + aID + " should have overflowedItem attribute");
164 }
166 /**
167 * Checks that an item with ID aID is not overflowing in the nav-bar.
168 *
169 * @param aID the ID of hte node to check for non-overflowingness.
170 */
171 function checkNotOverflowing(aID) {
172 ok(!gOverflowList.querySelector("#" + aID),
173 "Item with ID " + aID + " should no longer be overflowing");
174 let item = gNavBar.querySelector("#" + aID);
175 ok(item, "Item with ID " + aID + " should be in the nav bar");
176 ok(!item.hasAttribute("overflowedItem"),
177 "Item with ID " + aID + " should not have overflowedItem attribute");
178 }
180 /**
181 * Test that overflowing the bookmarks menu button doesn't break the
182 * context menus for the Unsorted and Bookmarks Toolbar menu items.
183 */
184 add_task(function* testOverflowingBookmarksButtonContextMenu() {
185 ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
186 ok(CustomizableUI.inDefaultState, "Should start in default state.");
188 // Open the Unsorted and Bookmarks Toolbar context menus and ensure
189 // that they have views attached.
190 yield checkSpecialContextMenus();
192 yield overflowEverything();
193 checkOverflowing(kBookmarksButton);
195 yield stopOverflowing();
196 checkNotOverflowing(kBookmarksButton);
198 yield checkSpecialContextMenus();
199 });
201 /**
202 * Test that the bookmarks toolbar items context menu still works if moved
203 * to the menu from the overflow panel, and then back to the toolbar.
204 */
205 add_task(function* testOverflowingBookmarksItemsContextMenu() {
206 yield PanelUI.ensureReady();
208 let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
209 gCustomizeMode.addToToolbar(bookmarksToolbarItems);
210 yield checkPlacesContextMenu(bookmarksToolbarItems);
212 yield overflowEverything();
213 checkOverflowing(kBookmarksItems)
215 gCustomizeMode.addToPanel(bookmarksToolbarItems);
217 yield stopOverflowing();
219 gCustomizeMode.addToToolbar(bookmarksToolbarItems);
220 yield checkPlacesContextMenu(bookmarksToolbarItems);
221 });
223 /**
224 * Test that overflowing the bookmarks toolbar items doesn't cause the
225 * context menu in the bookmarks toolbar items chevron to stop working.
226 */
227 add_task(function* testOverflowingBookmarksItemsChevronContextMenu() {
228 // If it's not already there, let's move the bookmarks toolbar items to
229 // the nav-bar.
230 let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
231 gCustomizeMode.addToToolbar(bookmarksToolbarItems);
233 // We make the PlacesToolbarItems element be super tiny in order to force
234 // the bookmarks toolbar items into overflowing and making the chevron
235 // show itself.
236 let placesToolbarItems = document.getElementById("PlacesToolbarItems");
237 let placesChevron = document.getElementById("PlacesChevron");
238 placesToolbarItems.style.maxWidth = "10px";
239 yield waitForCondition(() => !placesChevron.collapsed);
241 yield checkBookmarksItemsChevronContextMenu();
243 yield overflowEverything();
244 checkOverflowing(kBookmarksItems);
246 yield stopOverflowing();
247 checkNotOverflowing(kBookmarksItems);
249 yield checkBookmarksItemsChevronContextMenu();
251 placesToolbarItems.style.removeProperty("max-width");
252 });
254 add_task(function* asyncCleanup() {
255 window.resizeTo(kOriginalWindowWidth, window.outerHeight);
256 yield resetCustomization();
257 });