Bug 1094864 - Rewrite most of browser/components/places/tests/browser to use the newer async Places APIs. r=mak
authorMark Banner <standard8@mozilla.com>
Fri, 22 Sep 2017 14:01:53 +0100
changeset 382891 c2131082228a24d8ae74c12ac846e49ad950c169
parent 382890 b8d59e74c0bbffc3c7728b708ea77ecd1b7fa1c7
child 382892 6f9635999d2cf776afa2b1a67a8344e37e89c752
push id52036
push usermbanner@mozilla.com
push dateTue, 26 Sep 2017 08:49:33 +0000
treeherderautoland@c2131082228a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1094864
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1094864 - Rewrite most of browser/components/places/tests/browser to use the newer async Places APIs. r=mak MozReview-Commit-ID: 78NB6QgDohQ
browser/components/places/tests/browser/browser_bookmark_folder_moveability.js
browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js
browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js
browser/components/places/tests/browser/browser_library_openFlatContainer.js
browser/components/places/tests/browser/browser_library_open_leak.js
browser/components/places/tests/browser/browser_library_search.js
browser/components/places/tests/browser/browser_library_views_liveupdate.js
browser/components/places/tests/browser/browser_sidebarpanels_click.js
browser/components/places/tests/browser/browser_views_liveupdate.js
--- a/browser/components/places/tests/browser/browser_bookmark_folder_moveability.js
+++ b/browser/components/places/tests/browser/browser_bookmark_folder_moveability.js
@@ -1,168 +1,185 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* 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/. */
 
-function test() {
-  const IDX = PlacesUtils.bookmarks.DEFAULT_INDEX;
+"use strict";
+
+let rootFolder;
+let rootNode;
 
-  // setup
-  var rootId = PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId, "", IDX);
-  var rootNode = PlacesUtils.getFolderContents(rootId, false, true).root;
-  is(rootNode.childCount, 0, "confirm test root is empty");
-
-  var tests = [];
+add_task(async function setup() {
+  rootFolder = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    title: "",
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
+  });
 
-  // add a regular folder, should be moveable
-  tests.push({
-    populate() {
-      this.id =
-        PlacesUtils.bookmarks.createFolder(rootId, "", IDX);
-    },
-    validate() {
-      is(rootNode.childCount, 1,
-        "populate added data to the test root");
-      is(PlacesControllerDragHelper.canMoveNode(rootNode.getChild(0)),
-         true, "can move regular folder node");
-    }
+  let rootId = await PlacesUtils.promiseItemId(rootFolder.guid);
+  rootNode = PlacesUtils.getFolderContents(rootId, false, true).root;
+
+  Assert.equal(rootNode.childCount, 0, "confirm test root is empty");
+
+  registerCleanupFunction(async () => {
+    await PlacesUtils.bookmarks.eraseEverything();
+  });
+});
+
+add_task(async function test_regular_folder() {
+  let regularFolder = await PlacesUtils.bookmarks.insert({
+    parentGuid: rootFolder.guid,
+    title: "",
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
   });
 
-  // add a regular folder shortcut, should be moveable
-  tests.push({
-    populate() {
-      this.folderId =
-        PlacesUtils.bookmarks.createFolder(rootId, "foo", IDX);
-      this.shortcutId =
-        PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:folder=" + this.folderId), IDX, "bar");
-    },
-    validate() {
-      is(rootNode.childCount, 2,
-        "populated data to the test root");
+  Assert.equal(rootNode.childCount, 1,
+    "populate added data to the test root");
+  Assert.equal(PlacesControllerDragHelper.canMoveNode(rootNode.getChild(0)),
+     true, "can move regular folder node");
+
+  await PlacesUtils.bookmarks.remove(regularFolder);
+});
 
-      var folderNode = rootNode.getChild(0);
-      is(folderNode.type, 6, "node is folder");
-      is(this.folderId, folderNode.itemId, "folder id and folder node item id match");
+add_task(async function test_folder_shortcut() {
+  let regularFolder = await PlacesUtils.bookmarks.insert({
+    parentGuid: rootFolder.guid,
+    title: "",
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
+  });
+  let regularFolderId = await PlacesUtils.promiseItemId(regularFolder.guid);
 
-      var shortcutNode = rootNode.getChild(1);
-      is(shortcutNode.type, 9, "node is folder shortcut");
-      is(this.shortcutId, shortcutNode.itemId, "shortcut id and shortcut node item id match");
-
-      var concreteId = PlacesUtils.getConcreteItemId(shortcutNode);
-      is(concreteId, folderNode.itemId, "shortcut node id and concrete id match");
-
-      is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
-         true, "can move folder shortcut node");
-    }
+  let shortcut = await PlacesUtils.bookmarks.insert({
+    parentGuid: rootFolder.guid,
+    title: "bar",
+    url: `place:folder=${regularFolderId}`
   });
 
-  // add a regular query, should be moveable
-  tests.push({
-    populate() {
-      this.bookmarkId =
-        PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("http://foo.com"), IDX, "foo");
-      this.queryId =
-        PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:terms=foo"), IDX, "bar");
-    },
-    validate() {
-      is(rootNode.childCount, 2,
-        "populated data to the test root");
+  Assert.equal(rootNode.childCount, 2,
+    "populated data to the test root");
+
+  let folderNode = rootNode.getChild(0);
+  Assert.equal(folderNode.type, 6, "node is folder");
+  Assert.equal(regularFolder.guid, folderNode.bookmarkGuid, "folder guid and folder node item guid match");
+
+  let shortcutNode = rootNode.getChild(1);
+  Assert.equal(shortcutNode.type, 9, "node is folder shortcut");
+  Assert.equal(shortcut.guid, shortcutNode.bookmarkGuid, "shortcut guid and shortcut node item guid match");
+
+  let concreteId = PlacesUtils.getConcreteItemGuid(shortcutNode);
+  Assert.equal(concreteId, folderNode.bookmarkGuid, "shortcut node id and concrete id match");
 
-      var bmNode = rootNode.getChild(0);
-      is(bmNode.itemId, this.bookmarkId, "bookmark id and bookmark node item id match");
+  Assert.equal(PlacesControllerDragHelper.canMoveNode(shortcutNode), true,
+   "can move folder shortcut node");
+
+  await PlacesUtils.bookmarks.remove(shortcut);
+  await PlacesUtils.bookmarks.remove(regularFolder);
+});
 
-      var queryNode = rootNode.getChild(1);
-      is(queryNode.itemId, this.queryId, "query id and query node item id match");
+add_task(async function test_regular_query() {
+  let bookmark = await PlacesUtils.bookmarks.insert({
+    parentGuid: rootFolder.guid,
+    title: "",
+    url: "http://foo.com",
+  });
 
-      is(PlacesControllerDragHelper.canMoveNode(queryNode),
-         true, "can move query node");
-    }
+  let query = await PlacesUtils.bookmarks.insert({
+    parentGuid: rootFolder.guid,
+    title: "bar",
+    url: `place:terms=foo`
   });
 
-  // test that special folders cannot be moved
-  // test that special folders shortcuts can be moved
-  tests.push({
-    folders: [PlacesUtils.bookmarksMenuFolderId,
-              PlacesUtils.tagsFolderId, PlacesUtils.unfiledBookmarksFolderId,
-              PlacesUtils.toolbarFolderId],
-    shortcuts: {},
-    populate() {
-      for (var i = 0; i < this.folders.length; i++) {
-        var id = this.folders[i];
-        this.shortcuts[id] =
-          PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:folder=" + id), IDX, "");
-      }
-    },
-    validate() {
-      // test toolbar shortcut node
-      is(rootNode.childCount, this.folders.length,
-        "populated data to the test root");
+  Assert.equal(rootNode.childCount, 2,
+    "populated data to the test root");
+
+  let bmNode = rootNode.getChild(0);
+  Assert.equal(bmNode.bookmarkGuid, bookmark.guid, "bookmark guid and bookmark node item guid match");
+
+  let queryNode = rootNode.getChild(1);
+  Assert.equal(queryNode.bookmarkGuid, query.guid, "query guid and query node item guid match");
+
+  Assert.equal(PlacesControllerDragHelper.canMoveNode(queryNode),
+     true, "can move query node");
+
+  await PlacesUtils.bookmarks.remove(query);
+  await PlacesUtils.bookmarks.remove(bookmark);
+});
 
-      function getRootChildNode(aId) {
-        var node = PlacesUtils.getFolderContents(PlacesUtils.placesRootId, false, true).root;
-        for (var i = 0; i < node.childCount; i++) {
-          var child = node.getChild(i);
-          if (child.itemId == aId) {
-            node.containerOpen = false;
-            return child;
-          }
-        }
-        node.containerOpen = false;
-        ok(false, "Unable to find child node");
-        return null;
-      }
+add_task(async function test_special_folders() {
+  // Test that special folders and special folder shortcuts cannot be moved.
+  let folders = [
+    PlacesUtils.bookmarksMenuFolderId,
+    PlacesUtils.tagsFolderId,
+    PlacesUtils.unfiledBookmarksFolderId,
+    PlacesUtils.toolbarFolderId
+  ];
+
+  let children = folders.map(folderId => {
+    return {
+      title: "",
+      url: `place:folder=${folderId}`
+    };
+  });
 
-      for (var i = 0; i < this.folders.length; i++) {
-        var id = this.folders[i];
-
-        var node = getRootChildNode(id);
-        isnot(node, null, "Node found");
-        is(PlacesControllerDragHelper.canMoveNode(node),
-           false, "shouldn't be able to move special folder node");
+  let shortcuts = await PlacesUtils.bookmarks.insertTree({
+    guid: rootFolder.guid,
+    children
+  });
 
-        var shortcutId = this.shortcuts[id];
-        var shortcutNode = rootNode.getChild(i);
+  // test toolbar shortcut node
+  Assert.equal(rootNode.childCount, folders.length,
+    "populated data to the test root");
 
-        is(shortcutNode.itemId, shortcutId, "shortcut id and shortcut node item id match");
-
-        dump("can move shortcut node?\n");
-        is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
-           true, "should be able to move special folder shortcut node");
+  function getRootChildNode(aId) {
+    let node = PlacesUtils.getFolderContents(PlacesUtils.placesRootId, false, true).root;
+    for (let i = 0; i < node.childCount; i++) {
+      let child = node.getChild(i);
+      if (child.itemId == aId) {
+        node.containerOpen = false;
+        return child;
       }
     }
-  });
+    node.containerOpen = false;
+    ok(false, "Unable to find child node");
+    return null;
+  }
+
+  for (let i = 0; i < folders.length; i++) {
+    let id = folders[i];
 
-  // test that a tag container cannot be moved
-  tests.push({
-    populate() {
-      // tag a uri
-      this.uri = makeURI("http://foo.com");
-      PlacesUtils.tagging.tagURI(this.uri, ["bar"]);
-      registerCleanupFunction(() => PlacesUtils.tagging.untagURI(this.uri, ["bar"]));
-    },
-    validate() {
-      // get tag root
-      var query = PlacesUtils.history.getNewQuery();
-      var options = PlacesUtils.history.getNewQueryOptions();
-      options.resultType = Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY;
-      var tagsNode = PlacesUtils.history.executeQuery(query, options).root;
+    let node = getRootChildNode(id);
+    isnot(node, null, "Node found");
+    Assert.equal(PlacesControllerDragHelper.canMoveNode(node),
+       false, "shouldn't be able to move special folder node");
+
+    let shortcut = shortcuts[i];
+    let shortcutNode = rootNode.getChild(i);
+
+    Assert.equal(shortcutNode.bookmarkGuid, shortcut.guid,
+      "shortcut guid and shortcut node item guid match");
 
-      tagsNode.containerOpen = true;
-      is(tagsNode.childCount, 1, "has new tag");
+    Assert.equal(PlacesControllerDragHelper.canMoveNode(shortcutNode),
+       true, "should be able to move special folder shortcut node");
+  }
+});
 
-      var tagNode = tagsNode.getChild(0);
+add_task(async function test_tag_container() {
+  // tag a uri
+  this.uri = makeURI("http://foo.com");
+  PlacesUtils.tagging.tagURI(this.uri, ["bar"]);
+  registerCleanupFunction(() => PlacesUtils.tagging.untagURI(this.uri, ["bar"]));
 
-      is(PlacesControllerDragHelper.canMoveNode(tagNode),
-         false, "should not be able to move tag container node");
-      tagsNode.containerOpen = false;
-    }
-  });
+  // get tag root
+  let query = PlacesUtils.history.getNewQuery();
+  let options = PlacesUtils.history.getNewQueryOptions();
+  options.resultType = Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY;
+  let tagsNode = PlacesUtils.history.executeQuery(query, options).root;
 
-  tests.forEach(function(aTest) {
-    PlacesUtils.bookmarks.removeFolderChildren(rootId);
-    aTest.populate();
-    aTest.validate();
-  });
+  tagsNode.containerOpen = true;
+  Assert.equal(tagsNode.childCount, 1, "has new tag");
+
+  let tagNode = tagsNode.getChild(0);
 
-  rootNode.containerOpen = false;
-  PlacesUtils.bookmarks.removeItem(rootId);
-}
+  Assert.equal(PlacesControllerDragHelper.canMoveNode(tagNode),
+     false, "should not be able to move tag container node");
+  tagsNode.containerOpen = false;
+});
--- a/browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js
+++ b/browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js
@@ -19,61 +19,64 @@ var dragDirections = { LEFT: 0, UP: 1, R
  * @param aElement
  *        DOM node element we will drag
  * @param aExpectedDragData
  *        Array of flavors and values in the form:
  *        [ ["text/plain: sometext", "text/html: <b>sometext</b>"], [...] ]
  *        Pass an empty array to check that drag even has been canceled.
  * @param aDirection
  *        Direction for the dragging gesture, see dragDirections helper object.
+ * @return {Promise} Resolved once the drag gesture has been observed.
  */
-function synthesizeDragWithDirection(aElement, aExpectedDragData, aDirection, aCallback) {
-  // Dragstart listener function.
-  gBookmarksToolbar.addEventListener("dragstart", function listener(event) {
-    info("A dragstart event has been trapped.");
-    var dataTransfer = event.dataTransfer;
-    is(dataTransfer.mozItemCount, aExpectedDragData.length,
-       "Number of dragged items should be the same.");
+function synthesizeDragWithDirection(aElement, aExpectedDragData, aDirection) {
+  let promise = new Promise(resolve => {
+    // Dragstart listener function.
+    gBookmarksToolbar.addEventListener("dragstart", function listener(event) {
+      info("A dragstart event has been trapped.");
+      var dataTransfer = event.dataTransfer;
+      is(dataTransfer.mozItemCount, aExpectedDragData.length,
+         "Number of dragged items should be the same.");
 
-    for (var t = 0; t < dataTransfer.mozItemCount; t++) {
-      var types = dataTransfer.mozTypesAt(t);
-      var expecteditem = aExpectedDragData[t];
-      is(types.length, expecteditem.length,
-        "Number of flavors for item " + t + " should be the same.");
+      for (var t = 0; t < dataTransfer.mozItemCount; t++) {
+        var types = dataTransfer.mozTypesAt(t);
+        var expecteditem = aExpectedDragData[t];
+        is(types.length, expecteditem.length,
+          "Number of flavors for item " + t + " should be the same.");
 
-      for (var f = 0; f < types.length; f++) {
-        is(types[f], expecteditem[f].substring(0, types[f].length),
-           "Flavor " + types[f] + " for item " + t + " should be the same.");
-        is(dataTransfer.mozGetDataAt(types[f], t),
-           expecteditem[f].substring(types[f].length + 2),
-           "Contents for item " + t + " with flavor " + types[f] + " should be the same.");
+        for (var f = 0; f < types.length; f++) {
+          is(types[f], expecteditem[f].substring(0, types[f].length),
+             "Flavor " + types[f] + " for item " + t + " should be the same.");
+          is(dataTransfer.mozGetDataAt(types[f], t),
+             expecteditem[f].substring(types[f].length + 2),
+             "Contents for item " + t + " with flavor " + types[f] + " should be the same.");
+        }
       }
-    }
 
-    if (!aExpectedDragData.length)
-      ok(event.defaultPrevented, "Drag has been canceled.");
+      if (!aExpectedDragData.length)
+        ok(event.defaultPrevented, "Drag has been canceled.");
 
-    event.preventDefault();
-    event.stopPropagation();
+      event.preventDefault();
+      event.stopPropagation();
 
-    gBookmarksToolbar.removeEventListener("dragstart", listener);
+      gBookmarksToolbar.removeEventListener("dragstart", listener);
 
-    // This is likely to cause a click event, and, in case we are dragging a
-    // bookmark, an unwanted page visit.  Prevent the click event.
-    aElement.addEventListener("click", prevent);
-    EventUtils.synthesizeMouse(aElement,
-                               startingPoint.x + xIncrement * 9,
-                               startingPoint.y + yIncrement * 9,
-                               { type: "mouseup" });
-    aElement.removeEventListener("click", prevent);
+      // This is likely to cause a click event, and, in case we are dragging a
+      // bookmark, an unwanted page visit.  Prevent the click event.
+      aElement.addEventListener("click", prevent);
+      EventUtils.synthesizeMouse(aElement,
+                                 startingPoint.x + xIncrement * 9,
+                                 startingPoint.y + yIncrement * 9,
+                                 { type: "mouseup" });
+      aElement.removeEventListener("click", prevent);
 
-    // Cleanup eventually opened menus.
-    if (aElement.localName == "menu" && aElement.open)
-      aElement.open = false;
-    aCallback()
+      // Cleanup eventually opened menus.
+      if (aElement.localName == "menu" && aElement.open)
+        aElement.open = false;
+      resolve();
+    });
   });
 
   var prevent = function(aEvent) { aEvent.preventDefault(); }
 
   var xIncrement = 0;
   var yIncrement = 0;
 
   switch (aDirection) {
@@ -102,23 +105,25 @@ function synthesizeDragWithDirection(aEl
   EventUtils.synthesizeMouse(aElement,
                              startingPoint.x + xIncrement * 1,
                              startingPoint.y + yIncrement * 1,
                              { type: "mousemove" });
   EventUtils.synthesizeMouse(aElement,
                              startingPoint.x + xIncrement * 9,
                              startingPoint.y + yIncrement * 9,
                              { type: "mousemove" });
+
+  return promise;
 }
 
-function getToolbarNodeForItemId(aItemId) {
+function getToolbarNodeForItemId(itemGuid) {
   var children = document.getElementById("PlacesToolbarItems").childNodes;
   var node = null;
   for (var i = 0; i < children.length; i++) {
-    if (aItemId == children[i]._placesNode.itemId) {
+    if (itemGuid == children[i]._placesNode.bookmarkGuid) {
       node = children[i];
       break;
     }
   }
   return node;
 }
 
 function getExpectedDataForPlacesNode(aNode) {
@@ -132,116 +137,78 @@ function getExpectedDataForPlacesNode(aN
     var wrappedFlavor = aFlavor + ": " +
                         PlacesUtils.wrapNode(aNode, aFlavor);
     wrappedNode.push(wrappedFlavor);
   });
 
   return [wrappedNode];
 }
 
-var gTests = [
-
-// ------------------------------------------------------------------------------
-
-  {
-    desc: "Drag a folder on toolbar",
-    run() {
-      // Create a test folder to be dragged.
-      var folderId = PlacesUtils.bookmarks
-                                .createFolder(PlacesUtils.toolbarFolderId,
-                                              TEST_TITLE,
-                                              PlacesUtils.bookmarks.DEFAULT_INDEX);
-      var element = getToolbarNodeForItemId(folderId);
-      isnot(element, null, "Found node on toolbar");
-
-      isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
-      var expectedData = getExpectedDataForPlacesNode(element._placesNode);
-
-      info("Dragging left");
-      synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT,
-        function() {
-          info("Dragging right");
-          synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT,
-            function() {
-              info("Dragging up");
-              synthesizeDragWithDirection(element, expectedData, dragDirections.UP,
-                function() {
-                  info("Dragging down");
-                  synthesizeDragWithDirection(element, [], dragDirections.DOWN,
-                    function() {
-                      // Cleanup.
-                      PlacesUtils.bookmarks.removeItem(folderId);
-                      nextTest();
-                    });
-                });
-            });
-        });
-    }
-  },
-
-// ------------------------------------------------------------------------------
-
-  {
-    desc: "Drag a bookmark on toolbar",
-    run() {
-      // Create a test bookmark to be dragged.
-      var itemId = PlacesUtils.bookmarks
-                              .insertBookmark(PlacesUtils.toolbarFolderId,
-                                              PlacesUtils._uri(TEST_URL),
-                                              PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                              TEST_TITLE);
-      var element = getToolbarNodeForItemId(itemId);
-      isnot(element, null, "Found node on toolbar");
-
-      isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
-      var expectedData = getExpectedDataForPlacesNode(element._placesNode);
-
-      info("Dragging left");
-      synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT,
-        function() {
-          info("Dragging right");
-          synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT,
-            function() {
-              info("Dragging up");
-              synthesizeDragWithDirection(element, expectedData, dragDirections.UP,
-                function() {
-                  info("Dragging down");
-                  synthesizeDragWithDirection(element, expectedData, dragDirections.DOWN,
-                    function() {
-                      // Cleanup.
-                      PlacesUtils.bookmarks.removeItem(itemId);
-                      nextTest();
-                    });
-                });
-            });
-        });
-    }
-  },
-];
-
-function nextTest() {
-  if (gTests.length) {
-    var testCase = gTests.shift();
-    waitForFocus(function() {
-      info("Start of test: " + testCase.desc);
-      testCase.run();
-    });
-  } else if (wasCollapsed) {
-    // Collapse the personal toolbar if needed.
-    promiseSetToolbarVisibility(toolbar, false).then(finish);
-  } else {
-    finish();
-  }
-}
-
-var toolbar = document.getElementById("PersonalToolbar");
-var wasCollapsed = toolbar.collapsed;
-
-function test() {
-  waitForExplicitFinish();
+add_task(async function setup() {
+  var toolbar = document.getElementById("PersonalToolbar");
+  var wasCollapsed = toolbar.collapsed;
 
   // Uncollapse the personal toolbar if needed.
   if (wasCollapsed) {
-    promiseSetToolbarVisibility(toolbar, true).then(nextTest);
-  } else {
-    nextTest();
+    await promiseSetToolbarVisibility(toolbar, true);
   }
-}
+
+  registerCleanupFunction(async () => {
+    // Collapse the personal toolbar if needed.
+    await promiseSetToolbarVisibility(toolbar, false);
+  });
+});
+
+add_task(async function test_drag_folder_on_toolbar() {
+  let folder = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    title: TEST_TITLE,
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
+  });
+
+  var element = getToolbarNodeForItemId(folder.guid);
+  isnot(element, null, "Found node on toolbar");
+
+  isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
+  var expectedData = getExpectedDataForPlacesNode(element._placesNode);
+
+  info("Dragging left");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT);
+
+  info("Dragging right");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT);
+
+  info("Dragging up");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.UP);
+
+  info("Dragging down");
+  await synthesizeDragWithDirection(element, [], dragDirections.DOWN);
+
+  await PlacesUtils.bookmarks.remove(folder);
+});
+
+add_task(async function test_drag_bookmark_on_toolbar() {
+  var bookmark = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    title: TEST_TITLE,
+    url: TEST_URL,
+  });
+
+  var element = getToolbarNodeForItemId(bookmark.guid);
+  isnot(element, null, "Found node on toolbar");
+
+  isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
+  var expectedData = getExpectedDataForPlacesNode(element._placesNode);
+
+  info("Dragging left");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT);
+
+  info("Dragging right");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT);
+
+  info("Dragging up");
+  await synthesizeDragWithDirection(element, expectedData, dragDirections.UP);
+
+  info("Dragging down");
+  synthesizeDragWithDirection(element, expectedData, dragDirections.DOWN);
+
+  await PlacesUtils.bookmarks.remove(bookmark);
+});
--- a/browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js
@@ -1,41 +1,43 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-function test() {
-  waitForExplicitFinish();
-  openLibrary(onLibraryReady);
-}
-
-function onLibraryReady(aLibrary) {
+add_task(async function() {
   let hierarchy = [ "AllBookmarks", "BookmarksMenu" ];
 
-  let folder1 = PlacesUtils.bookmarks
-                           .createFolder(PlacesUtils.bookmarksMenuFolderId,
-                                         "Folder 1",
-                                         PlacesUtils.bookmarks.DEFAULT_INDEX);
-  hierarchy.push(folder1);
-  let folder2 = PlacesUtils.bookmarks
-                           .createFolder(folder1, "Folder 2",
-                                         PlacesUtils.bookmarks.DEFAULT_INDEX);
-  hierarchy.push(folder2);
-  let bookmark = PlacesUtils.bookmarks
-                            .insertBookmark(folder2, NetUtil.newURI("http://example.com/"),
-                                            PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                            "Bookmark");
-
-  registerCleanupFunction(function() {
-    PlacesUtils.bookmarks.removeItem(folder1);
-    aLibrary.close();
+  let items = await PlacesUtils.bookmarks.insertTree({
+    guid: PlacesUtils.bookmarks.menuGuid,
+    children: [{
+      title: "Folder 1",
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      children: [{
+        title: "Folder 2",
+        type: PlacesUtils.bookmarks.TYPE_FOLDER,
+        children: [{
+          title: "Bookmark",
+          url: "http://example.com",
+        }],
+      }],
+    }],
   });
 
-  aLibrary.PlacesOrganizer.selectLeftPaneContainerByHierarchy(hierarchy);
+  let folder1Id = await PlacesUtils.promiseItemId(items[0].guid);
+  let folder2Id = await PlacesUtils.promiseItemId(items[1].guid);
 
-  is(aLibrary.PlacesOrganizer._places.selectedNode.itemId, folder2,
-     "Found the expected left pane selected node");
+  hierarchy.push(folder1Id, folder2Id);
+
+  let library = await promiseLibrary();
 
-  is(aLibrary.ContentTree.view.view.nodeForTreeIndex(0).itemId, bookmark,
-     "Found the expected right pane contents");
+  registerCleanupFunction(async function() {
+    await PlacesUtils.bookmarks.remove(items[0]);
+    await promiseLibraryClosed(library)
+  });
+
+  library.PlacesOrganizer.selectLeftPaneContainerByHierarchy(hierarchy);
 
-  finish();
-}
+  Assert.equal(library.PlacesOrganizer._places.selectedNode.bookmarkGuid, items[1].guid,
+    "Found the expected left pane selected node");
+
+  Assert.equal(library.ContentTree.view.view.nodeForTreeIndex(0).bookmarkGuid, items[2].guid,
+    "Found the expected right pane contents");
+});
--- a/browser/components/places/tests/browser/browser_library_openFlatContainer.js
+++ b/browser/components/places/tests/browser/browser_library_openFlatContainer.js
@@ -3,40 +3,43 @@
  */
 
 /**
  * Test opening a flat container in the right pane even if its parent in the
  * left pane is closed.
  */
 
 add_task(async function() {
-  let folder = PlacesUtils.bookmarks
-                          .createFolder(PlacesUtils.unfiledBookmarksFolderId,
-                                        "Folder",
-                                        PlacesUtils.bookmarks.DEFAULT_INDEX);
-  let bookmark = PlacesUtils.bookmarks
-                            .insertBookmark(folder, NetUtil.newURI("http://example.com/"),
-                                            PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                            "Bookmark");
+  let bookmarks = await PlacesUtils.bookmarks.insertTree({
+    guid: PlacesUtils.bookmarks.unfiledGuid,
+    children: [{
+      title: "Folder",
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      children: [{
+        title: "Bookmark",
+        url: "http://example.com",
+      }],
+    }],
+  });
 
   let library = await promiseLibrary("AllBookmarks");
-  registerCleanupFunction(function() {
-    library.close();
-    PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
+  registerCleanupFunction(async function() {
+    await promiseLibraryClosed(library);
+    await PlacesUtils.bookmarks.eraseEverything();
   });
 
   // Select unfiled later, to ensure it's closed.
   library.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
   ok(!library.PlacesOrganizer._places.selectedNode.containerOpen,
      "Unfiled container is closed");
 
   let folderNode = library.ContentTree.view.view.nodeForTreeIndex(0);
-  is(folderNode.itemId, folder,
+  is(folderNode.bookmarkGuid, bookmarks[0].guid,
      "Found the expected folder in the right pane");
   // Select the folder node in the right pane.
   library.ContentTree.view.selectNode(folderNode);
 
   synthesizeClickOnSelectedTreeCell(library.ContentTree.view,
                                     { clickCount: 2 });
 
-  is(library.ContentTree.view.view.nodeForTreeIndex(0).itemId, bookmark,
+  is(library.ContentTree.view.view.nodeForTreeIndex(0).bookmarkGuid, bookmarks[1].guid,
      "Found the expected bookmark in the right pane");
 });
--- a/browser/components/places/tests/browser/browser_library_open_leak.js
+++ b/browser/components/places/tests/browser/browser_library_open_leak.js
@@ -8,16 +8,15 @@
  * Bug 474831
  * https://bugzilla.mozilla.org/show_bug.cgi?id=474831
  *
  * Tests for leaks caused by simply opening and closing the Places Library
  * window.  Opens the Places Library window, waits for it to load, closes it,
  * and finishes.
  */
 
-function test() {
-  waitForExplicitFinish();
-  openLibrary(function(win) {
-    ok(true, "Library has been correctly opened");
-    win.close();
-    finish();
-  });
-}
+add_task(async function test_open_and_close() {
+  let library = await promiseLibrary();
+
+  Assert.ok(true, "Library has been correctly opened");
+
+  await promiseLibraryClosed(library);
+});
--- a/browser/components/places/tests/browser/browser_library_search.js
+++ b/browser/components/places/tests/browser/browser_library_search.js
@@ -136,46 +136,37 @@ function search(aFolderId, aSearchStr, a
     is(query.searchTerms, aSearchStr,
        "Content tree's searchTerms should be text in search box");
   } else {
     is(query.hasSearchTerms, false,
        "Content tree's searchTerms should not exist after search reset");
   }
 }
 
-/**
- * test() contains window-launching boilerplate that calls this to really kick
- * things off.  Add functions to the testCases array, and this will call them.
- */
-function onLibraryAvailable() {
-  testCases.forEach(aTest => aTest());
-
-  gLibrary.close();
-  gLibrary = null;
-
-  // Cleanup.
-  PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
-  PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
-  PlacesTestUtils.clearHistory().then(finish);
-}
-
-function test() {
-  waitForExplicitFinish();
-
-  // Sanity:
-  ok(PlacesUtils, "PlacesUtils in context");
-
+add_task(async function test() {
   // Add visits, a bookmark and a tag.
-  PlacesTestUtils.addVisits(
+  await PlacesTestUtils.addVisits(
     [{ uri: PlacesUtils._uri(TEST_URL), visitDate: Date.now() * 1000,
        transition: PlacesUtils.history.TRANSITION_TYPED },
      { uri: PlacesUtils._uri(TEST_DOWNLOAD_URL), visitDate: Date.now() * 1000,
        transition: PlacesUtils.history.TRANSITION_DOWNLOAD }]
-    ).then(() => {
-      PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                           PlacesUtils._uri(TEST_URL),
-                                           PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                           "dummy");
-      PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
+    );
+
+  await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+    title: "dummy",
+    url: TEST_URL,
+  });
+
+  PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
 
-      gLibrary = openLibrary(onLibraryAvailable);
-    });
-}
+  gLibrary = await promiseLibrary();
+
+  testCases.forEach(aTest => aTest());
+
+  await promiseLibraryClosed(gLibrary);
+
+  // Cleanup.
+  PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
+
+  await PlacesUtils.bookmarks.eraseEverything();
+  await PlacesUtils.history.clear();
+});
--- a/browser/components/places/tests/browser/browser_library_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_library_views_liveupdate.js
@@ -1,208 +1,169 @@
 /* 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 Library Left pane view for liveupdate.
  */
 
-var gLibrary = null;
+let gLibrary = null;
+
+async function testInFolder(folderGuid, prefix) {
+  let addedBookmarks = [];
+  let item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}1`,
+    url: `http://${prefix}1.mozilla.org/`,
+  });
+  item.title = `${prefix}1_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
+
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}2`,
+    url: "place:",
+  });
+
+  item.title = `${prefix}2_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
 
-function test() {
-  waitForExplicitFinish();
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
+  });
+  addedBookmarks.push(item);
+
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}f`,
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
+  });
+
+  item.title = `${prefix}f_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
+
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: item.guid,
+    title: `${prefix}f1`,
+    url: `http://${prefix}f1.mozilla.org/`,
+  });
+  addedBookmarks.push(item);
+
+  item.index = 0;
+  await PlacesUtils.bookmarks.update(item);
+
+  return addedBookmarks;
+}
+
+add_task(async function test() {
   // This test takes quite some time, and timeouts frequently, so we require
   // more time to run.
   // See Bug 525610.
   requestLongerTimeout(2);
 
   // Open Library, we will check the left pane.
-  openLibrary(function(library) {
-    gLibrary = library;
-    startTest();
-  });
-}
+  gLibrary = await promiseLibrary();
 
-/**
- * Adds bookmarks observer, and executes a bunch of bookmarks operations.
- */
-function startTest() {
-  var bs = PlacesUtils.bookmarks;
   // Add observers.
-  bs.addObserver(bookmarksObserver);
+  PlacesUtils.bookmarks.addObserver(bookmarksObserver);
   PlacesUtils.annotations.addObserver(bookmarksObserver);
-  var addedBookmarks = [];
+  let addedBookmarks = [];
 
   // MENU
   ok(true, "*** Acting on menu bookmarks");
-  var id = bs.insertBookmark(bs.bookmarksMenuFolder,
-                             PlacesUtils._uri("http://bm1.mozilla.org/"),
-                             bs.DEFAULT_INDEX,
-                             "bm1");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(bs.bookmarksMenuFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "bm2");
-  bs.setItemTitle(id, "bm2_edited");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.bookmarksMenuFolder,
-                       "bmf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "bmf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://bmf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "bmf1");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.bookmarksMenuFolder, 0);
+  addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.menuGuid, "bm"));
 
   // TOOLBAR
   ok(true, "*** Acting on toolbar bookmarks");
-  id = bs.insertBookmark(bs.toolbarFolder,
-                         PlacesUtils._uri("http://tb1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "tb1");
-  bs.setItemTitle(id, "tb1_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(bs.toolbarFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "tb2");
-  bs.setItemTitle(id, "tb2_edited");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.toolbarFolder,
-                       "tbf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "tbf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://tbf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "bmf1");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.toolbarFolder, 0);
+  addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.toolbarGuid, "tb"));
 
   // UNSORTED
   ok(true, "*** Acting on unsorted bookmarks");
-  id = bs.insertBookmark(bs.unfiledBookmarksFolder,
-                         PlacesUtils._uri("http://ub1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "ub1");
-  bs.setItemTitle(id, "ub1_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(bs.unfiledBookmarksFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "ub2");
-  bs.setItemTitle(id, "ub2_edited");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.unfiledBookmarksFolder,
-                       "ubf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "ubf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://ubf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "ubf1");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
+  addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.unfiledGuid, "ub"));
 
   // Remove all added bookmarks.
-  addedBookmarks.forEach(function(aItem) {
+  for (let i = 0; i < addedBookmarks.length; i++) {
     // If we remove an item after its containing folder has been removed,
     // this will throw, but we can ignore that.
     try {
-      bs.removeItem(aItem);
+      await PlacesUtils.bookmarks.remove(addedBookmarks[i]);
     } catch (ex) {}
-  });
+  }
 
   // Remove observers.
-  bs.removeObserver(bookmarksObserver);
+  PlacesUtils.bookmarks.removeObserver(bookmarksObserver);
   PlacesUtils.annotations.removeObserver(bookmarksObserver);
-  finishTest();
-}
 
-/**
- * Restores browser state and calls finish.
- */
-function finishTest() {
-  // Close Library window.
-  gLibrary.close();
-  finish();
-}
+  await promiseLibraryClosed(gLibrary);
+});
 
 /**
  * The observer is where magic happens, for every change we do it will look for
  * nodes positions in the affected views.
  */
-var bookmarksObserver = {
+let bookmarksObserver = {
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsINavBookmarkObserver,
     Ci.nsIAnnotationObserver
   ]),
 
   // nsIAnnotationObserver
   onItemAnnotationSet() {},
   onItemAnnotationRemoved() {},
   onPageAnnotationSet() {},
   onPageAnnotationRemoved() {},
 
   // nsINavBookmarkObserver
   onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex, aItemType,
                                         aURI) {
-    var node = null;
-    var index = null;
+    let node = null;
+    let index = null;
     [node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
     // Left pane should not be updated for normal bookmarks or separators.
     switch (aItemType) {
       case PlacesUtils.bookmarks.TYPE_BOOKMARK:
-        var uriString = aURI.spec;
-        var isQuery = uriString.substr(0, 6) == "place:";
+        let uriString = aURI.spec;
+        let isQuery = uriString.substr(0, 6) == "place:";
         if (isQuery) {
           isnot(node, null, "Found new Places node in left pane");
           ok(index >= 0, "Node is at index " + index);
           break;
         }
         // Fallback to separator case if this is not a query.
       case PlacesUtils.bookmarks.TYPE_SEPARATOR:
         is(node, null, "New Places node not added in left pane");
         break;
       default:
         isnot(node, null, "Found new Places node in left pane");
         ok(index >= 0, "Node is at index " + index);
     }
   },
 
   onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
-    var node = null;
+    let node = null;
     [node, ] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
     is(node, null, "Places node not found in left pane");
   },
 
   onItemMoved(aItemId,
                         aOldFolderId, aOldIndex,
                         aNewFolderId, aNewIndex, aItemType) {
-    var node = null;
-    var index = null;
+    let node = null;
+    let index = null;
     [node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
     // Left pane should not be updated for normal bookmarks or separators.
     switch (aItemType) {
       case PlacesUtils.bookmarks.TYPE_BOOKMARK:
-        var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
-        var isQuery = uriString.substr(0, 6) == "place:";
+        let uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
+        let isQuery = uriString.substr(0, 6) == "place:";
         if (isQuery) {
           isnot(node, null, "Found new Places node in left pane");
           ok(index >= 0, "Node is at index " + index);
           break;
         }
         // Fallback to separator case if this is not a query.
       case PlacesUtils.bookmarks.TYPE_SEPARATOR:
         is(node, null, "New Places node not added in left pane");
@@ -247,50 +208,50 @@ var bookmarksObserver = {
 function getNodeForTreeItem(aItemId, aTree, aValidator) {
 
   function findNode(aContainerIndex) {
     if (aTree.view.isContainerEmpty(aContainerIndex))
       return [null, null, false];
 
     // The rowCount limit is just for sanity, but we will end looping when
     // we have checked the last child of this container or we have found node.
-    for (var i = aContainerIndex + 1; i < aTree.view.rowCount; i++) {
-      var node = aTree.view.nodeForTreeIndex(i);
+    for (let i = aContainerIndex + 1; i < aTree.view.rowCount; i++) {
+      let node = aTree.view.nodeForTreeIndex(i);
 
       if (node.itemId == aItemId) {
         // Minus one because we want relative index inside the container.
         let valid = aValidator ? aValidator(i) : true;
         return [node, i - aTree.view.getParentIndex(i) - 1, valid];
       }
 
       if (PlacesUtils.nodeIsFolder(node)) {
         // Open container.
         aTree.view.toggleOpenState(i);
         // Search inside it.
-        var foundNode = findNode(i);
+        let foundNode = findNode(i);
         // Close container.
         aTree.view.toggleOpenState(i);
         // Return node if found.
         if (foundNode[0] != null)
           return foundNode;
       }
 
       // We have finished walking this container.
       if (!aTree.view.hasNextSibling(aContainerIndex + 1, i))
         break;
     }
     return [null, null, false]
   }
 
   // Root node is hidden, so we need to manually walk the first level.
-  for (var i = 0; i < aTree.view.rowCount; i++) {
+  for (let i = 0; i < aTree.view.rowCount; i++) {
     // Open container.
     aTree.view.toggleOpenState(i);
     // Search inside it.
-    var foundNode = findNode(i);
+    let foundNode = findNode(i);
     // Close container.
     aTree.view.toggleOpenState(i);
     // Return node if found.
     if (foundNode[0] != null)
       return foundNode;
   }
   return [null, null, false];
 }
--- a/browser/components/places/tests/browser/browser_sidebarpanels_click.js
+++ b/browser/components/places/tests/browser/browser_sidebarpanels_click.js
@@ -1,155 +1,158 @@
 /* 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/. */
 
 // This test makes sure that the items in the bookmarks and history sidebar
 // panels are clickable in both LTR and RTL modes.
 
-function test() {
-  waitForExplicitFinish();
+var sidebar;
+
+add_task(async function test_sidebarpanels_click() {
   ignoreAllUncaughtExceptions();
 
   const BOOKMARKS_SIDEBAR_ID = "viewBookmarksSidebar";
   const BOOKMARKS_SIDEBAR_TREE_ID = "bookmarks-view";
   const HISTORY_SIDEBAR_ID = "viewHistorySidebar";
   const HISTORY_SIDEBAR_TREE_ID = "historyTree";
   const TEST_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser/sidebarpanels_click_test_page.html";
 
   // If a sidebar is already open, close it.
   if (!document.getElementById("sidebar-box").hidden) {
     ok(false, "Unexpected sidebar found - a previous test failed to cleanup correctly");
     SidebarUI.hide();
   }
 
-  let sidebar = document.getElementById("sidebar");
+  // Ensure history is clean before starting the test.
+  await PlacesUtils.history.clear();
+
+  sidebar = document.getElementById("sidebar");
   let tests = [];
-  let currentTest;
 
   tests.push({
-    _itemID: null,
-    init(aCallback) {
+    _bookmark: null,
+    async init() {
       // Add a bookmark to the Unfiled Bookmarks folder.
-      this._itemID = PlacesUtils.bookmarks.insertBookmark(
-        PlacesUtils.unfiledBookmarksFolderId, PlacesUtils._uri(TEST_URL),
-        PlacesUtils.bookmarks.DEFAULT_INDEX, "test"
-      );
-      aCallback();
+      this._bookmark = await PlacesUtils.bookmarks.insert({
+        parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+        title: "test",
+        url: TEST_URL,
+      });
+
     },
     prepare() {
     },
-    selectNode(tree) {
-      tree.selectItems([this._itemID]);
+    async selectNode(tree) {
+      let bookmarkId = await PlacesUtils.promiseItemId(this._bookmark.guid);
+      tree.selectItems([bookmarkId]);
     },
     cleanup(aCallback) {
-      PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
-      executeSoon(aCallback);
+      return PlacesUtils.bookmarks.remove(this._bookmark);
     },
     sidebarName: BOOKMARKS_SIDEBAR_ID,
     treeName: BOOKMARKS_SIDEBAR_TREE_ID,
     desc: "Bookmarks sidebar test"
   });
 
   tests.push({
-    init(aCallback) {
+    async init() {
       // Add a history entry.
       let uri = PlacesUtils._uri(TEST_URL);
-      PlacesTestUtils.addVisits({
+      await PlacesTestUtils.addVisits({
         uri, visitDate: Date.now() * 1000,
         transition: PlacesUtils.history.TRANSITION_TYPED
-      }).then(aCallback);
+      });
     },
     prepare() {
       sidebar.contentDocument.getElementById("byvisited").doCommand();
     },
     selectNode(tree) {
       tree.selectNode(tree.view.nodeForTreeIndex(0));
       is(tree.selectedNode.uri, TEST_URL, "The correct visit has been selected");
       is(tree.selectedNode.itemId, -1, "The selected node is not bookmarked");
     },
     cleanup(aCallback) {
-      PlacesTestUtils.clearHistory().then(aCallback);
+      return PlacesTestUtils.clearHistory();
     },
     sidebarName: HISTORY_SIDEBAR_ID,
     treeName: HISTORY_SIDEBAR_TREE_ID,
     desc: "History sidebar test"
   });
 
-  function testPlacesPanel(preFunc, postFunc) {
-    currentTest.init(function() {
-      SidebarUI.show(currentTest.sidebarName);
+  for (let test of tests) {
+    gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
+    await testPlacesPanel(test, () => {
+      changeSidebarDirection("ltr");
+      info("Running " + test.desc + " in LTR mode");
+    });
+
+    await testPlacesPanel(test, () => {
+      changeSidebarDirection("rtl");
+      info("Running " + test.desc + " in RTL mode");
     });
 
-    sidebar.addEventListener("load", function() {
-      executeSoon(function() {
-        currentTest.prepare();
-
-        if (preFunc)
-          preFunc();
-
-        function observer(aSubject, aTopic, aData) {
-          info("alert dialog observed as expected");
-          Services.obs.removeObserver(observer, "common-dialog-loaded");
-          Services.obs.removeObserver(observer, "tabmodal-dialog-loaded");
+    // Remove tabs created by sub-tests.
+    while (gBrowser.tabs.length > 1) {
+      gBrowser.removeTab(gBrowser.tabContainer.lastChild);
+    }
+  }
+});
 
-          aSubject.Dialog.ui.button0.click();
+async function testPlacesPanel(testInfo, preFunc) {
+  await testInfo.init();
 
-          executeSoon(function() {
-              SidebarUI.hide();
-              currentTest.cleanup(postFunc);
-            });
-        }
-        Services.obs.addObserver(observer, "common-dialog-loaded");
-        Services.obs.addObserver(observer, "tabmodal-dialog-loaded");
+  let promise = new Promise(resolve => {
+    sidebar.addEventListener("load", function() {
+      executeSoon(async function() {
+        testInfo.prepare();
 
-        let tree = sidebar.contentDocument.getElementById(currentTest.treeName);
+        preFunc();
+
+        let tree = sidebar.contentDocument.getElementById(testInfo.treeName);
 
         // Select the inserted places item.
-        currentTest.selectNode(tree);
+        await testInfo.selectNode(tree);
+
+        let promiseAlert = promiseAlertDialogObserved();
 
         synthesizeClickOnSelectedTreeCell(tree);
         // Now, wait for the observer to catch the alert dialog.
         // If something goes wrong, the test will time out at this stage.
         // Note that for the history sidebar, the URL itself is not opened,
         // and Places will show the load-js-data-url-error prompt as an alert
         // box, which means that the click actually worked, so it's good enough
         // for the purpose of this test.
+
+        await promiseAlert;
+
+        executeSoon(async function() {
+          SidebarUI.hide();
+          await testInfo.cleanup();
+          resolve();
+        });
       });
     }, {capture: true, once: true});
-  }
-
-  function changeSidebarDirection(aDirection) {
-    sidebar.contentDocument.documentElement.style.direction = aDirection;
-  }
+  });
 
-  function runNextTest() {
-    // Remove eventual tabs created by previous sub-tests.
-    while (gBrowser.tabs.length > 1) {
-      gBrowser.removeTab(gBrowser.tabContainer.lastChild);
-    }
+  SidebarUI.show(testInfo.sidebarName);
+
+  return promise;
+}
 
-    if (tests.length == 0) {
-      finish();
-    } else {
-      // Create a new tab and run the test.
-      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-      currentTest = tests.shift();
-      testPlacesPanel(function() {
-                        changeSidebarDirection("ltr");
-                        info("Running " + currentTest.desc + " in LTR mode");
-                      },
-                      function() {
-                        testPlacesPanel(function() {
-                          // Run the test in RTL mode.
-                          changeSidebarDirection("rtl");
-                          info("Running " + currentTest.desc + " in RTL mode");
-                        },
-                        function() {
-                          runNextTest();
-                        });
-                      });
+function promiseAlertDialogObserved() {
+  return new Promise(resolve => {
+    function observer(subject) {
+      info("alert dialog observed as expected");
+      Services.obs.removeObserver(observer, "common-dialog-loaded");
+      Services.obs.removeObserver(observer, "tabmodal-dialog-loaded");
+
+      subject.Dialog.ui.button0.click();
+      resolve();
     }
-  }
+    Services.obs.addObserver(observer, "common-dialog-loaded");
+    Services.obs.addObserver(observer, "tabmodal-dialog-loaded");
+  });
+}
 
-  // Ensure history is clean before starting the test.
-  PlacesTestUtils.clearHistory().then(runNextTest);
+function changeSidebarDirection(aDirection) {
+  sidebar.contentDocument.documentElement.style.direction = aDirection;
 }
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_views_liveupdate.js
@@ -4,182 +4,128 @@
 
 /**
  * Tests Places views (menu, toolbar, tree) for liveupdate.
  */
 
 var toolbar = document.getElementById("PersonalToolbar");
 var wasCollapsed = toolbar.collapsed;
 
-function test() {
-  waitForExplicitFinish();
-
-  // Uncollapse the personal toolbar if needed.
-  if (wasCollapsed) {
-    promiseSetToolbarVisibility(toolbar, true).then(openBookmarksSidebar);
-  } else {
-    openBookmarksSidebar();
-  }
-}
-
-function openBookmarksSidebar() {
-  // Open bookmarks menu.
-  var popup = document.getElementById("bookmarksMenuPopup");
-  ok(popup, "Menu popup element exists");
-  fakeOpenPopup(popup);
-
-  // Open bookmarks sidebar.
-  var sidebar = document.getElementById("sidebar");
-  sidebar.addEventListener("load", function() {
-    // Need to executeSoon since the tree is initialized on sidebar load.
-    executeSoon(startTest);
-  }, {capture: true, once: true});
-  SidebarUI.show("viewBookmarksSidebar");
-}
-
 /**
  * Simulates popup opening causing it to populate.
  * We cannot just use menu.open, since it would not work on Mac due to native menubar.
  */
 function fakeOpenPopup(aPopup) {
   var popupEvent = document.createEvent("MouseEvent");
   popupEvent.initMouseEvent("popupshowing", true, true, window, 0,
                             0, 0, 0, 0, false, false, false, false,
                             0, null);
   aPopup.dispatchEvent(popupEvent);
 }
 
-/**
- * Adds bookmarks observer, and executes a bunch of bookmarks operations.
- */
-function startTest() {
-  var bs = PlacesUtils.bookmarks;
-  // Add observers.
-  bs.addObserver(bookmarksObserver);
-  PlacesUtils.annotations.addObserver(bookmarksObserver);
-  var addedBookmarks = [];
-
-  // MENU
-  info("*** Acting on menu bookmarks");
-  var id = bs.insertBookmark(bs.bookmarksMenuFolder,
-                             PlacesUtils._uri("http://bm1.mozilla.org/"),
-                             bs.DEFAULT_INDEX,
-                             "bm1");
-  bs.setItemTitle(id, "bm1_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(bs.bookmarksMenuFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "bm2");
-  bs.setItemTitle(id, "");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.bookmarksMenuFolder,
-                       "bmf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "bmf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://bmf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "bmf1");
-  bs.setItemTitle(id, "bmf1_edited");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.bookmarksMenuFolder, 0);
+async function testInFolder(folderGuid, prefix) {
+  let addedBookmarks = [];
+  let item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}1`,
+    url: `http://${prefix}1.mozilla.org/`,
+  });
+  item.title = `${prefix}1_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
 
-  // TOOLBAR
-  info("*** Acting on toolbar bookmarks");
-  id = bs.insertBookmark(bs.toolbarFolder,
-                         PlacesUtils._uri("http://tb1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "tb1");
-  bs.setItemTitle(id, "tb1_edited");
-  addedBookmarks.push(id);
-  // Test live update of title.
-  bs.setItemTitle(id, "tb1_edited");
-  id = bs.insertBookmark(bs.toolbarFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "tb2");
-  bs.setItemTitle(id, "");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.toolbarFolder,
-                       "tbf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "tbf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://tbf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "tbf1");
-  bs.setItemTitle(id, "tbf1_edited");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.toolbarFolder, 0);
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}2`,
+    url: "place:",
+  });
+
+  item.title = `${prefix}2_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
 
-  // UNSORTED
-  info("*** Acting on unsorted bookmarks");
-  id = bs.insertBookmark(bs.unfiledBookmarksFolder,
-                         PlacesUtils._uri("http://ub1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "ub1");
-  bs.setItemTitle(id, "ub1_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(bs.unfiledBookmarksFolder,
-                         PlacesUtils._uri("place:"),
-                         bs.DEFAULT_INDEX,
-                         "ub2");
-  bs.setItemTitle(id, "ub2_edited");
-  addedBookmarks.push(id);
-  id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
-  addedBookmarks.push(id);
-  id = bs.createFolder(bs.unfiledBookmarksFolder,
-                       "ubf",
-                       bs.DEFAULT_INDEX);
-  bs.setItemTitle(id, "ubf_edited");
-  addedBookmarks.push(id);
-  id = bs.insertBookmark(id,
-                         PlacesUtils._uri("http://ubf1.mozilla.org/"),
-                         bs.DEFAULT_INDEX,
-                         "bubf1");
-  bs.setItemTitle(id, "bubf1_edited");
-  addedBookmarks.push(id);
-  bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
+  });
+  addedBookmarks.push(item);
 
-  // Remove all added bookmarks.
-  addedBookmarks.forEach(function(aItem) {
-    // If we remove an item after its containing folder has been removed,
-    // this will throw, but we can ignore that.
-    try {
-      bs.removeItem(aItem);
-    } catch (ex) {}
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: folderGuid,
+    title: `${prefix}f`,
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
   });
 
-  // Remove observers.
-  bs.removeObserver(bookmarksObserver);
-  PlacesUtils.annotations.removeObserver(bookmarksObserver);
-  finishTest();
+  item.title = `${prefix}f_edited`;
+  await PlacesUtils.bookmarks.update(item);
+  addedBookmarks.push(item);
+
+  item = await PlacesUtils.bookmarks.insert({
+    parentGuid: item.guid,
+    title: `${prefix}f1`,
+    url: `http://${prefix}f1.mozilla.org/`,
+  });
+  addedBookmarks.push(item);
+
+  item.index = 0;
+  item.parentGuid = folderGuid;
+  await PlacesUtils.bookmarks.update(item);
+
+  return addedBookmarks;
 }
 
-/**
- * Restores browser state and calls finish.
- */
-function finishTest() {
-  // Close bookmarks sidebar.
-  SidebarUI.hide();
+add_task(async function test() {
+  // Uncollapse the personal toolbar if needed.
+  if (wasCollapsed) {
+    await promiseSetToolbarVisibility(toolbar, true);
+  }
+
+  // Open bookmarks menu.
+  var popup = document.getElementById("bookmarksMenuPopup");
+  ok(popup, "Menu popup element exists");
+  fakeOpenPopup(popup);
+
+  // Open bookmarks sidebar.
+  await withSidebarTree("bookmarks", async () => {
+    // Add observers.
+    PlacesUtils.bookmarks.addObserver(bookmarksObserver);
+    PlacesUtils.annotations.addObserver(bookmarksObserver);
+    var addedBookmarks = [];
+
+    // MENU
+    info("*** Acting on menu bookmarks");
+    addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.menuGuid, "bm"));
+
+    // TOOLBAR
+    info("*** Acting on toolbar bookmarks");
+    addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.toolbarGuid, "tb"));
+
+    // UNSORTED
+    info("*** Acting on unsorted bookmarks");
+    addedBookmarks = addedBookmarks.concat(await testInFolder(PlacesUtils.bookmarks.unfiledGuid, "ub"));
+
+    // Remove all added bookmarks.
+    for (let bm of addedBookmarks) {
+      // If we remove an item after its containing folder has been removed,
+      // this will throw, but we can ignore that.
+      try {
+        await PlacesUtils.bookmarks.remove(bm);
+      } catch (ex) {}
+    }
+
+    // Remove observers.
+    PlacesUtils.bookmarks.removeObserver(bookmarksObserver);
+    PlacesUtils.annotations.removeObserver(bookmarksObserver);
+  });
 
   // Collapse the personal toolbar if needed.
   if (wasCollapsed) {
-    promiseSetToolbarVisibility(toolbar, false).then(finish);
-  } else {
-    finish();
+    await promiseSetToolbarVisibility(toolbar, false);
   }
-}
+});
 
 /**
  * The observer is where magic happens, for every change we do it will look for
  * nodes positions in the affected views.
  */
 var bookmarksObserver = {
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsINavBookmarkObserver,
@@ -202,24 +148,24 @@ var bookmarksObserver = {
     for (var i = 0; i < views.length; i++) {
       var [node, index] = searchItemInView(aItemId, views[i]);
       isnot(node, null, "Found new Places node in " + views[i]);
       is(index, aIndex, "Node is at index " + index);
     }
   },
 
   onItemRemoved: function PSB_onItemRemoved(aItemId, aFolderId, aIndex,
-                                            aItemType) {
+                                            aItemType, url, aGuid) {
     var views = getViewsForFolder(aFolderId);
     ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
     // Check that item has been removed.
     for (var i = 0; i < views.length; i++) {
       var node = null;
       [node, ] = searchItemInView(aItemId, views[i]);
-      is(node, null, "Places node not found in " + views[i]);
+      is(node, null, "Places node should not be found in " + views[i]);
     }
   },
 
   onItemMoved(aItemId,
                         aOldFolderId, aOldIndex,
                         aNewFolderId, aNewIndex,
                         aItemType) {
     var views = getViewsForFolder(aNewFolderId);