Bug 1392081 - Mochitest browser test for bookmarks toolbar overflow. r=gijs draft
authorMarco Bonardo <mbonardo@mozilla.com>
Mon, 28 Aug 2017 14:43:59 +0200
changeset 660629 683f2a78f3759e154ded86dab28a2dffadc75490
parent 660622 b52c9c4d62fb13f10b9ced2a18937c6f5907898c
child 660630 490b5bf65edffa7bfb4a714c3e8035c843d46aa2
push id78485
push usermak77@bonardo.net
push dateThu, 07 Sep 2017 09:11:04 +0000
reviewersgijs
bugs1392081
milestone57.0a1
Bug 1392081 - Mochitest browser test for bookmarks toolbar overflow. r=gijs MozReview-Commit-ID: DwDZl2AELXC
browser/components/places/content/browserPlacesViews.js
browser/components/places/tests/browser/browser.ini
browser/components/places/tests/browser/browser_toolbar_overflow.js
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -1273,16 +1273,18 @@ PlacesToolbar.prototype = {
         child.style.visibility = "visible";
       }
     }
 
     // We rebuild the chevron on popupShowing, so if it is open
     // we must update it.
     if (this._chevron.open)
       this._updateChevronPopupNodesVisibility();
+    let event = new CustomEvent("BookmarksToolbarVisibilityUpdated", {bubbles: true});
+    this._viewElt.dispatchEvent(event);
   },
 
   nodeInserted:
   function PT_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aParentPlacesNode);
     if (parentElt == this._rootElt) { // Node is on the toolbar.
       let children = this._rootElt.childNodes;
       // Nothing to do if it's a never-visible node, but note it's possible
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -51,16 +51,17 @@ subsuite = clipboard
 [browser_library_views_liveupdate.js]
 [browser_markPageAsFollowedLink.js]
 [browser_paste_into_tags.js]
 subsuite = clipboard
 [browser_sidebarpanels_click.js]
 skip-if = true # temporarily disabled for breaking the treeview - bug 658744
 [browser_sort_in_library.js]
 [browser_toolbar_drop_text.js]
+[browser_toolbar_overflow.js]
 [browser_toolbarbutton_menu_context.js]
 [browser_views_iconsupdate.js]
 support-files =
   favicon-normal16.png
 [browser_views_liveupdate.js]
 [browser_bookmark_all_tabs.js]
 support-files =
   bookmark_dummy_1.html
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_toolbar_overflow.js
@@ -0,0 +1,182 @@
+/* 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/. */
+
+/**
+ * Tests the bookmarks toolbar overflow.
+ */
+
+var gToolbar = document.getElementById("PersonalToolbar");
+var gToolbarContent = document.getElementById("PlacesToolbarItems");
+var gChevron = document.getElementById("PlacesChevron");
+
+const BOOKMARKS_COUNT = 250;
+
+add_task(async function setup() {
+  await PlacesUtils.bookmarks.eraseEverything();
+
+  // Add bookmarks.
+  await PlacesUtils.bookmarks.insertTree({
+    guid: PlacesUtils.bookmarks.toolbarGuid,
+    children: Array(BOOKMARKS_COUNT).fill("")
+                                    .map((_, i) => ({ url: `http://test.places.${i}/`}))
+  });
+
+  // Uncollapse the personal toolbar if needed.
+  let wasCollapsed = gToolbar.collapsed;
+  Assert.ok(wasCollapsed, "The toolbar is collapsed by default");
+  if (wasCollapsed) {
+    let promiseReady = BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated");
+    await promiseSetToolbarVisibility(gToolbar, true);
+    await promiseReady;
+  }
+  registerCleanupFunction(async () => {
+    if (wasCollapsed) {
+      await promiseSetToolbarVisibility(gToolbar, false);
+    }
+    await PlacesUtils.bookmarks.eraseEverything();
+  });
+});
+
+add_task(async function() {
+  // Check that the overflow chevron is visible.
+  Assert.ok(!gChevron.collapsed, "The overflow chevron should be visible");
+  Assert.ok(gToolbarContent.childNodes.length < BOOKMARKS_COUNT,
+            "Not all the nodes should be built by default");
+  let visibleNodes = [];
+  for (let node of gToolbarContent.childNodes) {
+    if (node.style.visibility == "visible")
+      visibleNodes.push(node);
+  }
+  Assert.ok(visibleNodes.length < gToolbarContent.childNodes.length,
+            "The number of visible nodes should be smaller than the number of built nodes");
+
+  await test_index("Node at the last visible index", visibleNodes.length - 1, "visible");
+  await test_index("Node at the first invisible index", visibleNodes.length, "hidden");
+  await test_index("First non-built node", gToolbarContent.childNodes.length, undefined);
+  await test_index("Later non-built node", gToolbarContent.childNodes.length + 1, undefined);
+
+  await test_move_index("Move node from last visible to first hidden",
+                        visibleNodes.length - 1, visibleNodes.length,
+                        "visible", "hidden");
+  await test_move_index("Move node from fist visible to last built",
+                        0, gToolbarContent.childNodes.length - 1,
+                        "visible", "hidden");
+  await test_move_index("Move node from fist visible to first non built",
+                        0, gToolbarContent.childNodes.length,
+                        "visible", undefined);
+});
+
+async function test_index(desc, index, expected) {
+  info(desc);
+  let children = gToolbarContent.childNodes;
+  let originalLen = children.length;
+  let nodeExisted = children.length > index;
+  let previousNodeIsVisible = nodeExisted &&
+                              children[index - 1].style.visibility == "visible";
+  let promiseUpdateVisibility = expected == "visible" || previousNodeIsVisible
+    ? BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated")
+    : Promise.resolve();
+  let bm = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "http://test.places.added/",
+    index
+  });
+  Assert.equal(bm.index, index, "Sanity check the bookmark index");
+  await promiseUpdateVisibility;
+
+  if (!expected) {
+    Assert.ok(children.length <= index,
+              "The new node should not have been added");
+  } else {
+    Assert.equal(children[index]._placesNode.bookmarkGuid, bm.guid,
+                 "Found the added bookmark at the expected position");
+    Assert.equal(children[index].style.visibility, expected,
+                 `The bookmark node should be ${expected}`);
+  }
+  Assert.equal(children.length, originalLen,
+               "Number of built nodes should stay the same");
+
+  info("Remove the node");
+  promiseUpdateVisibility = expected == "visible"
+    ? BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated")
+    : Promise.resolve();
+  await PlacesUtils.bookmarks.remove(bm);
+  await promiseUpdateVisibility;
+
+  if (expected && nodeExisted) {
+    Assert.equal(children[index]._placesNode.uri,
+                `http://test.places.${index}/`,
+                "Found the previous bookmark at the expected position");
+    Assert.equal(children[index].style.visibility, expected,
+                 `The bookmark node should be ${expected}`);
+  }
+  Assert.equal(children.length, originalLen,
+               "Number of built nodes should stay the same");
+}
+
+async function test_move_index(desc, fromIndex, toIndex, original, expected) {
+  info(desc);
+  let children = gToolbarContent.childNodes;
+  let originalLen = children.length;
+  let movedGuid = children[fromIndex]._placesNode.bookmarkGuid;
+  let existingGuid = children[toIndex] ?
+    children[toIndex]._placesNode.bookmarkGuid : null;
+  let existingIndex = fromIndex < toIndex ? toIndex - 1 : toIndex + 1;
+
+  Assert.equal(children[fromIndex].style.visibility, original,
+               `The bookmark node should be ${original}`);
+  let promiseUpdateVisibility = original == "visible" || expected == "visible"
+    ? BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated")
+    : Promise.resolve();
+  await PlacesUtils.bookmarks.update({
+    guid: movedGuid,
+    index: toIndex
+  });
+  await promiseUpdateVisibility;
+
+  if (!expected) {
+    Assert.ok(children.length <= toIndex,
+              "Node in the new position is not expected");
+    Assert.ok(children[originalLen - 1],
+              "We should keep number of built nodes consistent");
+  } else {
+    Assert.equal(children[toIndex]._placesNode.bookmarkGuid, movedGuid,
+                 "Found the moved bookmark at the expected position");
+    Assert.equal(children[toIndex].style.visibility, expected,
+                 `The destination bookmark node should be ${expected}`);
+  }
+  Assert.equal(children[fromIndex].style.visibility, original,
+               `The origin bookmark node should be ${original}`);
+  if (existingGuid) {
+    Assert.equal(children[existingIndex]._placesNode.bookmarkGuid, existingGuid,
+                 "Found the pushed away bookmark at the expected position");
+  }
+  Assert.equal(children.length, originalLen,
+               "Number of built nodes should stay the same");
+
+  info("Moving back the node");
+  promiseUpdateVisibility = original == "visible" || expected == "visible"
+    ? BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated")
+    : Promise.resolve();
+  await PlacesUtils.bookmarks.update({
+    guid: movedGuid,
+    index: fromIndex
+  });
+  await promiseUpdateVisibility;
+
+  Assert.equal(children[fromIndex]._placesNode.bookmarkGuid, movedGuid,
+               "Found the moved bookmark at the expected position");
+  if (expected) {
+    Assert.equal(children[toIndex].style.visibility, expected,
+                 `The bookmark node should be ${expected}`);
+  }
+  Assert.equal(children[fromIndex].style.visibility, original,
+               `The bookmark node should be ${original}`);
+  if (existingGuid) {
+    Assert.equal(children[toIndex]._placesNode.bookmarkGuid, existingGuid,
+                 "Found the pushed away bookmark at the expected position");
+  }
+  Assert.equal(children.length, originalLen,
+               "Number of built nodes should stay the same");
+}