Backed out changeset 1ac7fce0b369 (bug 1406860) for failing xpcshell tests, e.g. toolkit/components/places/tests/unit/test_000_frecency.js. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Wed, 11 Oct 2017 18:25:57 +0200
changeset 679105 f1fb2969c2b3f1f4a0f8a4be8dbe06fd0b6ec01f
parent 679104 888796477f5516ec5a6bbc59f19a6c3d4191a72a
child 679106 455609e45fe7b0e59bcb874e86a3a88c002c0968
push id84141
push userbmo:schien@mozilla.com
push dateThu, 12 Oct 2017 11:13:04 +0000
reviewersbackout
bugs1406860
milestone58.0a1
backs out1ac7fce0b369889c60010e66085d2bf0eb8bc250
Backed out changeset 1ac7fce0b369 (bug 1406860) for failing xpcshell tests, e.g. toolkit/components/places/tests/unit/test_000_frecency.js. r=backout
browser/base/content/test/urlbar/browser_action_keyword_override.js
browser/base/content/test/urlbar/browser_action_searchengine.js
browser/base/content/test/urlbar/browser_action_searchengine_alias.js
browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js
browser/base/content/test/urlbar/browser_autocomplete_autoselect.js
browser/base/content/test/urlbar/browser_autocomplete_cursor.js
browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js
browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
browser/base/content/test/urlbar/browser_autocomplete_no_title.js
browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js
browser/base/content/test/urlbar/browser_search_favicon.js
browser/base/content/test/urlbar/browser_urlbarSearchSuggestions_opt-out.js
browser/base/content/test/urlbar/browser_urlbar_remove_match.js
browser/base/content/test/urlbar/browser_urlbar_search_no_speculative_connect_with_client_cert.js
browser/base/content/test/urlbar/head.js
browser/components/extensions/test/browser/browser-common.ini
browser/components/extensions/test/browser/browser_ext_omnibox.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
testing/modules/TestUtils.jsm
toolkit/components/places/tests/PlacesTestUtils.jsm
--- a/browser/base/content/test/urlbar/browser_action_keyword_override.js
+++ b/browser/base/content/test/urlbar/browser_action_keyword_override.js
@@ -5,17 +5,17 @@ add_task(async function() {
   await PlacesUtils.keywords.insert({ keyword: "keyword",
                                       url: "http://example.com/?q=%s" })
 
   registerCleanupFunction(async function() {
     await PlacesUtils.bookmarks.remove(bm);
   });
 
   await promiseAutocompleteResultPopup("keyword search");
-  let result = await waitForAutocompleteResultAt(0);
+  let result = gURLBar.popup.richlistbox.children[0];
 
   info("Before override");
   let titleHbox = result._titleText.parentNode.parentNode;
   ok(titleHbox.classList.contains("ac-title"), "Title hbox element sanity check");
   is_element_visible(titleHbox, "Title element should be visible");
 
   let urlHbox = result._urlText.parentNode.parentNode;
   ok(urlHbox.classList.contains("ac-url"), "URL hbox element sanity check");
--- a/browser/base/content/test/urlbar/browser_action_searchengine.js
+++ b/browser/base/content/test/urlbar/browser_action_searchengine.js
@@ -1,38 +1,35 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
 add_task(async function() {
   Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
                                        "http://example.com/?q={searchTerms}");
   let engine = Services.search.getEngineByName("MozSearch");
   let originalEngine = Services.search.currentEngine;
   Services.search.currentEngine = engine;
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
 
-  registerCleanupFunction(async function() {
+  registerCleanupFunction(() => {
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engine);
+
     try {
-      await BrowserTestUtils.removeTab(tab);
+      gBrowser.removeTab(tab);
     } catch (ex) { /* tab may have already been closed in case of failure */ }
-    await PlacesUtils.history.clear();
+
+    return PlacesTestUtils.clearHistory();
   });
 
   await promiseAutocompleteResultPopup("open a search");
-  let result = await waitForAutocompleteResultAt(0);
+  let result = gURLBar.popup.richlistbox.firstChild;
+
   isnot(result, null, "Should have a result");
   is(result.getAttribute("url"),
      `moz-action:searchengine,{"engineName":"MozSearch","input":"open%20a%20search","searchQuery":"open%20a%20search"}`,
      "Result should be a moz-action: for the correct search engine");
   is(result.hasAttribute("image"), false, "Result shouldn't have an image attribute");
 
   let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   result.click();
   await tabPromise;
 
   is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search", "Correct URL should be loaded");
-
-  gURLBar.popup.hidePopup();
-  await promisePopupHidden(gURLBar.popup);
 });
--- a/browser/base/content/test/urlbar/browser_action_searchengine_alias.js
+++ b/browser/base/content/test/urlbar/browser_action_searchengine_alias.js
@@ -1,37 +1,34 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
 add_task(async function() {
   let iconURI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC";
   Services.search.addEngineWithDetails("MozSearch", iconURI, "moz", "", "GET",
                                        "http://example.com/?q={searchTerms}");
   let engine = Services.search.getEngineByName("MozSearch");
   let originalEngine = Services.search.currentEngine;
   Services.search.currentEngine = engine;
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
 
-  registerCleanupFunction(async function() {
+  registerCleanupFunction(() => {
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engine);
+
     try {
-      await BrowserTestUtils.removeTab(tab);
+      gBrowser.removeTab(tab);
     } catch (ex) { /* tab may have already been closed in case of failure */ }
-    await PlacesUtils.history.clear();
+
+    return PlacesTestUtils.clearHistory();
   });
 
   await promiseAutocompleteResultPopup("moz open a search");
-  let result = await waitForAutocompleteResultAt(0);
+
+  let result = gURLBar.popup.richlistbox.children[0];
   ok(result.hasAttribute("image"), "Result should have an image attribute");
   ok(result.getAttribute("image") === engine.iconURI.spec,
      "Image attribute should have the search engine's icon");
 
   let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   EventUtils.synthesizeKey("VK_RETURN", { });
   await tabPromise;
 
   is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search");
-
-  gURLBar.popup.hidePopup();
-  await promisePopupHidden(gURLBar.popup);
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js
@@ -4,17 +4,19 @@
 const SUGGEST_ALL_PREF = "browser.search.suggest.enabled";
 const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
 const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
 
 add_task(async function switchToTab() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about");
 
   await promiseAutocompleteResultPopup("% about");
-  let result = await waitForAutocompleteResultAt(1);
+
+  ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results");
+  let result = gURLBar.popup.richlistbox.children[1];
   is(result.getAttribute("type"), "switchtab", "Expect right type attribute");
   is(result.label, "about:about about:about Tab", "Result a11y label should be: <title> <url> Tab");
 
   gURLBar.popup.hidePopup();
   await promisePopupHidden(gURLBar.popup);
   gBrowser.removeTab(tab);
 });
 
@@ -27,17 +29,16 @@ add_task(async function searchSuggestion
   Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
   registerCleanupFunction(function() {
     Services.search.currentEngine = oldCurrentEngine;
     Services.prefs.clearUserPref(SUGGEST_ALL_PREF);
     Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, suggestionsEnabled);
   });
 
   await promiseAutocompleteResultPopup("foo");
-  await waitForAutocompleteResultAt(2);
   // Don't assume that the search doesn't match history or bookmarks left around
   // by earlier tests.
   Assert.ok(gURLBar.popup.richlistbox.children.length >= 3,
             "Should get at least heuristic result + two search suggestions");
   // The first expected search is the search term itself since the heuristic
   // result will come before the search suggestions.
   let expectedSearches = [
     "foo",
@@ -48,11 +49,10 @@ add_task(async function searchSuggestion
     if (child.getAttribute("type").split(/\s+/).indexOf("searchengine") >= 0) {
       Assert.ok(expectedSearches.length > 0);
       let suggestion = expectedSearches.shift();
       Assert.equal(child.label, suggestion + " browser_searchSuggestionEngine searchSuggestionEngine.xml Search",
                    "Result label should be: <search term> <engine name> Search");
     }
   }
   Assert.ok(expectedSearches.length == 0);
-  gURLBar.popup.hidePopup();
-  await promisePopupHidden(gURLBar.popup);
+  gURLBar.closePopup();
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js
@@ -1,11 +1,8 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
 const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
 
 function repeat(limit, func) {
   for (let i = 0; i < limit; i++) {
     func(i);
   }
 }
 
@@ -25,34 +22,33 @@ function is_selected_one_off(index) {
   // This is true because although both the listbox and the one-offs can have
   // selections, the test doesn't check that.
   is(gURLBar.popup.richlistbox.selectedIndex, -1,
      "A one-off is selected, so the listbox should not have a selection");
 }
 
 add_task(async function() {
   let maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
+
   Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true);
-  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
   registerCleanupFunction(async function() {
     await PlacesTestUtils.clearHistory();
     Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
-    await BrowserTestUtils.removeTab(tab);
   });
 
   let visits = [];
   repeat(maxResults, i => {
     visits.push({
       uri: makeURI("http://example.com/autocomplete/?" + i),
     });
   });
   await PlacesTestUtils.addVisits(visits);
 
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
   await promiseAutocompleteResultPopup("example.com/autocomplete");
-  await waitForAutocompleteResultAt(maxResults - 1);
 
   let popup = gURLBar.popup;
   let results = popup.richlistbox.children;
   is(results.length, maxResults,
      "Should get maxResults=" + maxResults + " results");
   is_selected(0);
 
   info("Key Down to select the next item");
@@ -87,9 +83,10 @@ add_task(async function() {
   is_selected(0);
 
   info("Page Up again will wrap around to the end of the list");
   EventUtils.synthesizeKey("VK_PAGE_UP", {})
   is_selected(maxResults - 1);
 
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   await promisePopupHidden(gURLBar.popup);
+  gBrowser.removeTab(tab);
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
@@ -1,20 +1,17 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
 add_task(async function() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
   await promiseAutocompleteResultPopup("www.mozilla.org");
 
   gURLBar.selectTextRange(4, 4);
 
   is(gURLBar.popup.state, "open", "Popup should be open");
   is(gURLBar.popup.richlistbox.selectedIndex, 0, "Should have selected something");
 
   EventUtils.synthesizeKey("VK_RIGHT", {});
   await promisePopupHidden(gURLBar.popup);
 
   is(gURLBar.selectionStart, 5, "Should have moved the cursor");
   is(gURLBar.selectionEnd, 5, "And not selected anything");
 
-  await BrowserTestUtils.removeTab(tab);
+  gBrowser.removeTab(tab);
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js
@@ -1,24 +1,24 @@
 add_task(async function() {
-  await PlacesUtils.history.clear();
+  await PlacesTestUtils.clearHistory();
 
   await PlacesTestUtils.addVisits([
     { uri: makeURI("http://example.com/foo") },
     { uri: makeURI("http://example.com/foo/bar") },
   ]);
 
-  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
   registerCleanupFunction(async function() {
-    await BrowserTestUtils.removeTab(tab);
-    await PlacesUtils.history.clear();
+    await PlacesTestUtils.clearHistory();
   });
 
+  gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
+  gURLBar.focus();
+
   await promiseAutocompleteResultPopup("http://example.com");
-  await waitForAutocompleteResultAt(1);
 
   let popup = gURLBar.popup;
   let list = popup.richlistbox;
   let initialIndex = list.selectedIndex;
 
   info("Key Down to select the next item.");
   EventUtils.synthesizeKey("VK_DOWN", {});
 
@@ -39,9 +39,10 @@ add_task(async function() {
 
   info("Press return to load edited URL.");
   EventUtils.synthesizeKey("VK_RETURN", {});
   await Promise.all([
     promisePopupHidden(gURLBar.popup),
     docLoad,
   ]);
 
+  gBrowser.removeTab(gBrowser.selectedTab);
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
@@ -1,17 +1,15 @@
 // The order of these tests matters!
 
 add_task(async function setup() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
-  let bm = await PlacesUtils.bookmarks.insert({
-    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-    url: "http://example.com/?q=%s",
-    title: "test"
-  });
+  let bm = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+                                                url: "http://example.com/?q=%s",
+                                                title: "test" });
   registerCleanupFunction(async function() {
     await PlacesUtils.bookmarks.remove(bm);
     await BrowserTestUtils.removeTab(tab);
   });
   await PlacesUtils.keywords.insert({ keyword: "keyword",
                                       url: "http://example.com/?q=%s" });
   // Needs at least one success.
   ok(true, "Setup complete");
--- a/browser/base/content/test/urlbar/browser_autocomplete_no_title.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_no_title.js
@@ -1,17 +1,15 @@
 add_task(async function() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-  await PlacesUtils.history.clear();
-  const uri = "http://bug1060642.example.com/beards/are/pretty/great";
-  await PlacesTestUtils.addVisits([{ uri, title: "" }]);
-  registerCleanupFunction(async function() {
-    await PlacesUtils.history.clear();
-    await BrowserTestUtils.removeTab(tab);
-  });
+
+  let uri = NetUtil.newURI("http://bug1060642.example.com/beards/are/pretty/great");
+  await PlacesTestUtils.addVisits([{uri, title: ""}]);
 
   await promiseAutocompleteResultPopup("bug1060642");
-  let result = await waitForAutocompleteResultAt(1);
+  ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results");
+  let result = gURLBar.popup.richlistbox.children[1];
   is(result._titleText.textContent, "bug1060642.example.com", "Result title should be as expected");
 
   gURLBar.popup.hidePopup();
   await promisePopupHidden(gURLBar.popup);
+  gBrowser.removeTab(tab);
 });
--- a/browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js
@@ -1,22 +1,21 @@
 add_task(async function() {
-  registerCleanupFunction(async function() {
-    await PlacesUtils.bookmarks.eraseEverything();
+  registerCleanupFunction(() => {
+    PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
   });
 
   async function addTagItem(tagName) {
-    let url = `http://example.com/this/is/tagged/${tagName}`;
-    await PlacesUtils.bookmarks.insert({
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      url,
-      title: `test ${tagName}`
-    });
-    PlacesUtils.tagging.tagURI(Services.io.newURI(url), [tagName]);
-    await PlacesTestUtils.addVisits({uri: url, title: `Test page with tag ${tagName}`});
+    let uri = NetUtil.newURI(`http://example.com/this/is/tagged/${tagName}`);
+    PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
+                                         uri,
+                                         PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                         `test ${tagName}`);
+    PlacesUtils.tagging.tagURI(uri, [tagName]);
+    await PlacesTestUtils.addVisits([{uri, title: `Test page with tag ${tagName}`}]);
   }
 
   // We use different tags for each part of the test, as otherwise the
   // autocomplete code tries to be smart by using the previously cached element
   // without updating it (since all parameters it knows about are the same).
 
   let testcases = [{
     description: "Test with suggest.bookmark=true",
@@ -79,17 +78,17 @@ add_task(async function() {
     info(`Test case: ${testcase.description}`);
 
     await addTagItem(testcase.tagName);
     for (let prefName of Object.keys(testcase.prefs)) {
       Services.prefs.setBoolPref(`browser.urlbar.${prefName}`, testcase.prefs[prefName]);
     }
 
     await promiseAutocompleteResultPopup(testcase.input);
-    let result = await waitForAutocompleteResultAt(1);
+    let result = gURLBar.popup.richlistbox.children[1];
     ok(result && !result.collasped, "Should have result");
 
     is(result.getAttribute("type"), testcase.expected.type, "Result should have expected type");
 
     let typeIconStyle = window.getComputedStyle(result._typeIcon);
     let imageURL = typeIconStyle.listStyleImage;
     if (testcase.expected.typeImageVisible) {
       ok(/^url\(.+\)$/.test(imageURL), "Type image should be visible");
--- a/browser/base/content/test/urlbar/browser_search_favicon.js
+++ b/browser/base/content/test/urlbar/browser_search_favicon.js
@@ -25,17 +25,18 @@ add_task(async function() {
   let uri = NetUtil.newURI("http://s.example.com/search?q=foo&client=1");
   await PlacesTestUtils.addVisits({ uri, title: "Foo - SearchEngine Search" });
 
   await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
 
   // The first autocomplete result has the action searchengine, while
   // the second result is the "search favicon" element.
   await promiseAutocompleteResultPopup("foo");
-  let result = await waitForAutocompleteResultAt(1);
+  let result = gURLBar.popup.richlistbox.children[1];
+
   isnot(result, null, "Expect a search result");
   is(result.getAttribute("type"), "searchengine", "Expect correct `type` attribute");
 
   let titleHbox = result._titleText.parentNode.parentNode;
   ok(titleHbox.classList.contains("ac-title"), "Title hbox sanity check");
   is_element_visible(titleHbox, "Title element should be visible");
 
   let urlHbox = result._urlText.parentNode.parentNode;
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions_opt-out.js
+++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions_opt-out.js
@@ -67,22 +67,21 @@ add_task(async function focus() {
 
 add_task(async function click_on_focused() {
   // Even if the location bar is already focused, we should still show the popup
   // and the notification on click.
   setupVisibleHint();
   gURLBar.blur();
   // Won't show the hint since it's not user initiated.
   gURLBar.focus();
-  await new Promise(resolve => setTimeout(resolve, 1000));
+  await new Promise(resolve => setTimeout(resolve, 500));
   Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
-  Assert.ok(gURLBar.focused, "The input field should be focused");
 
   let popupPromise = promisePopupShown(gURLBar.popup);
-  EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {});
+  EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { button: 0, type: "mousedown" });
   await popupPromise;
 
   Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
   assertVisible(true);
   assertFooterVisible(false);
   Assert.equal(gURLBar.popup._matchCount, 0, "popup should have no results");
   gURLBar.blur();
   Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
--- a/browser/base/content/test/urlbar/browser_urlbar_remove_match.js
+++ b/browser/base/content/test/urlbar/browser_urlbar_remove_match.js
@@ -7,21 +7,21 @@ add_task(async function test_remove_hist
   await PlacesTestUtils.addVisits(TEST_URL);
 
   registerCleanupFunction(async function() {
     await PlacesUtils.history.clear();
   });
 
   let promiseVisitRemoved = PlacesTestUtils.waitForNotification(
     "onDeleteURI", uri => uri.spec == TEST_URL, "history");
-
   await promiseAutocompleteResultPopup("remove.me/from_urlbar");
-  let result = await waitForAutocompleteResultAt(1);
-  Assert.equal(result.getAttribute("ac-value"), TEST_URL, "Found the expected result");
-
+  await BrowserTestUtils.waitForCondition(
+    () => gURLBar.popup.richlistbox.children.length > 1 &&
+          gURLBar.popup.richlistbox.children[1].getAttribute("ac-value") == TEST_URL,
+    "Waiting for the result to appear");
   EventUtils.synthesizeKey("VK_DOWN", {});
   Assert.equal(gURLBar.popup.richlistbox.selectedIndex, 1);
   let options = AppConstants.platform == "macosx" ? { shiftKey: true } : {};
   EventUtils.synthesizeKey("VK_DELETE", options);
   await promiseVisitRemoved;
   await BrowserTestUtils.waitForCondition(
     () => !gURLBar.popup.richlistbox.children.some(c => !c.collapsed && c.getAttribute("ac-value") == TEST_URL),
     "Waiting for the result to disappear");
--- a/browser/base/content/test/urlbar/browser_urlbar_search_no_speculative_connect_with_client_cert.js
+++ b/browser/base/content/test/urlbar/browser_urlbar_search_no_speculative_connect_with_client_cert.js
@@ -145,27 +145,29 @@ add_task(async function setup() {
 add_task(async function popup_mousedown_no_client_cert_dialog_until_navigate_test() {
   const test = {
     // To not trigger autofill, search keyword starts from the second character.
     search: host.substr(1, 4),
     completeValue: uri
   };
   info(`Searching for '${test.search}'`);
   await promiseAutocompleteResultPopup(test.search, window, true);
-  await waitForAutocompleteResultAt(1);
   let controller = gURLBar.popup.input.controller;
   // The first item should be 'Search with ...' thus we want the second.
   let value = controller.getFinalCompleteValueAt(1);
   info(`The value of the second item is ${value}`);
   is(value, test.completeValue, "The second item has the url we visited.");
 
-  let listitem = await waitForAutocompleteResultAt(1);
-  Assert.ok(is_visible(listitem), "The node is there.");
+  await BrowserTestUtils.waitForCondition(() => {
+    return !!gURLBar.popup.richlistbox.childNodes[1] &&
+           is_visible(gURLBar.popup.richlistbox.childNodes[1]);
+  }, "the node is there.");
 
   expectingChooseCertificate = false;
+  let listitem = gURLBar.popup.richlistbox.childNodes[1];
   EventUtils.synthesizeMouseAtCenter(listitem, {type: "mousedown"}, window);
   is(gURLBar.popup.richlistbox.selectedIndex, 1, "The second item is selected");
 
   // We shouldn't have triggered a speculative connection, because a client
   // certificate is installed.
   SimpleTest.requestFlakyTimeout("Wait for UI");
   await new Promise(resolve => setTimeout(resolve, 200));
 
--- a/browser/base/content/test/urlbar/head.js
+++ b/browser/base/content/test/urlbar/head.js
@@ -308,17 +308,8 @@ function promisePageActionViewChildrenVi
 function promiseSpeculativeConnection(httpserver) {
   return BrowserTestUtils.waitForCondition(() => {
     if (httpserver) {
       return httpserver.connectionNumber == 1;
     }
     return false;
   }, "Waiting for connection setup");
 }
-
-async function waitForAutocompleteResultAt(index) {
-  let searchString = gURLBar.controller.searchString;
-  await BrowserTestUtils.waitForCondition(
-    () => gURLBar.popup.richlistbox.children.length > index &&
-          gURLBar.popup.richlistbox.children[index].getAttribute("ac-text") == searchString,
-    `Waiting for the autocomplete result for "${searchString}" at [${index}] to appear`);
-  return gURLBar.popup.richlistbox.children[index];
-}
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -85,16 +85,17 @@ skip-if = (os == 'win' && !debug) # bug 
 [browser_ext_geckoProfiler_symbolicate.js]
 [browser_ext_getViews.js]
 [browser_ext_identity_indication.js]
 [browser_ext_incognito_views.js]
 [browser_ext_incognito_popup.js]
 [browser_ext_lastError.js]
 [browser_ext_menus.js]
 [browser_ext_omnibox.js]
+skip-if = debug || asan # Bug 1354681
 [browser_ext_openPanel.js]
 [browser_ext_optionsPage_browser_style.js]
 [browser_ext_optionsPage_modals.js]
 [browser_ext_optionsPage_privileges.js]
 [browser_ext_pageAction_context.js]
 [browser_ext_pageAction_contextMenu.js]
 [browser_ext_pageAction_popup.js]
 [browser_ext_pageAction_popup_resize.js]
--- a/browser/components/extensions/test/browser/browser_ext_omnibox.js
+++ b/browser/components/extensions/test/browser/browser_ext_omnibox.js
@@ -89,20 +89,18 @@ add_task(async function() {
     gURLBar.value = keyword;
     EventUtils.synthesizeKey(" ", {});
     await expectEvent("on-input-started-fired");
     EventUtils.synthesizeKey("t", {});
     await expectEvent("on-input-changed-fired", {text: "t"});
     // Wait for the autocomplete search. Note that we cannot wait for the search
     // to be complete, since the add-on doesn't communicate when it's done, so
     // just check matches count.
-    await BrowserTestUtils.waitForCondition(
-      () => gURLBar.controller.matchCount >= 2 &&
-            gURLBar.popup.richlistbox.children[1].getAttribute("ac-text") == gURLBar.controller.searchString,
-      "waiting urlbar search to complete");
+    await BrowserTestUtils.waitForCondition(() => gURLBar.controller.matchCount >= 2,
+                                            "waiting urlbar search to complete");
     return "t";
   }
 
   async function testInputEvents() {
     gURLBar.focus();
 
     // Start an input session by typing in <keyword><space>.
     for (let letter of keyword) {
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -15,16 +15,17 @@ this.EXPORTED_SYMBOLS = [
   "BrowserTestUtils",
 ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://testing-common/TestUtils.jsm");
 Cu.import("resource://testing-common/ContentTask.jsm");
 
 Cc["@mozilla.org/globalmessagemanager;1"]
   .getService(Ci.nsIMessageListenerManager)
   .loadFrameScript(
     "chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js", true);
 
@@ -1305,18 +1306,63 @@ this.BrowserTestUtils = {
         mm.removeMessageListener("Test:SynthesizeCompositionChangeDone", compMsg);
         resolve();
       });
 
       mm.sendAsyncMessage("Test:SynthesizeCompositionChange", { event, seq });
     });
   },
 
-  // TODO: Fix consumers and remove me.
-  waitForCondition: TestUtils.waitForCondition,
+  /**
+   * Will poll a condition function until it returns true.
+   *
+   * @param condition
+   *        A condition function that must return true or false. If the
+   *        condition ever throws, this is also treated as a false. The
+   *        function can be a generator.
+   * @param interval
+   *        The time interval to poll the condition function. Defaults
+   *        to 100ms.
+   * @param attempts
+   *        The number of times to poll before giving up and rejecting
+   *        if the condition has not yet returned true. Defaults to 50
+   *        (~5 seconds for 100ms intervals)
+   * @return Promise
+   *        Resolves when condition is true.
+   *        Rejects if timeout is exceeded or condition ever throws.
+   */
+  waitForCondition(condition, msg, interval=100, maxTries=50) {
+    return new Promise((resolve, reject) => {
+      let tries = 0;
+      let intervalID = setInterval(async function() {
+        if (tries >= maxTries) {
+          clearInterval(intervalID);
+          msg += ` - timed out after ${maxTries} tries.`;
+          reject(msg);
+          return;
+        }
+
+        let conditionPassed = false;
+        try {
+          conditionPassed = await condition();
+        } catch(e) {
+          msg += ` - threw exception: ${e}`;
+          clearInterval(intervalID);
+          reject(msg);
+          return;
+        }
+
+        if (conditionPassed) {
+          clearInterval(intervalID);
+          resolve();
+        }
+        tries++;
+      }, interval);
+    });
+  },
 
   /**
    * Waits for a <xul:notification> with a particular value to appear
    * for the <xul:notificationbox> of the passed in browser.
    *
    * @param tabbrowser (<xul:tabbrowser>)
    *        The gBrowser that hosts the browser that should show
    *        the notification. For most tests, this will probably be
--- a/testing/modules/TestUtils.jsm
+++ b/testing/modules/TestUtils.jsm
@@ -16,17 +16,16 @@
 this.EXPORTED_SYMBOLS = [
   "TestUtils",
 ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Timer.jsm");
 
 this.TestUtils = {
   executeSoon(callbackFn) {
     Services.tm.dispatchToMainThread(callbackFn);
   },
 
   /**
    * Waits for the specified topic to be observed.
@@ -79,58 +78,10 @@ this.TestUtils = {
     let canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
     let ctx = canvas.getContext("2d");
     let ratio = win.devicePixelRatio;
     canvas.width = width * ratio;
     canvas.height = height * ratio;
     ctx.scale(ratio, ratio);
     ctx.drawWindow(win, left, top, width, height, "#fff");
     return canvas.toDataURL();
-  },
-
-    /**
-   * Will poll a condition function until it returns true.
-   *
-   * @param condition
-   *        A condition function that must return true or false. If the
-   *        condition ever throws, this is also treated as a false. The
-   *        function can be a generator.
-   * @param interval
-   *        The time interval to poll the condition function. Defaults
-   *        to 100ms.
-   * @param attempts
-   *        The number of times to poll before giving up and rejecting
-   *        if the condition has not yet returned true. Defaults to 50
-   *        (~5 seconds for 100ms intervals)
-   * @return Promise
-   *        Resolves when condition is true.
-   *        Rejects if timeout is exceeded or condition ever throws.
-   */
-  waitForCondition(condition, msg, interval = 100, maxTries = 50) {
-    return new Promise((resolve, reject) => {
-      let tries = 0;
-      let intervalID = setInterval(async function() {
-        if (tries >= maxTries) {
-          clearInterval(intervalID);
-          msg += ` - timed out after ${maxTries} tries.`;
-          reject(msg);
-          return;
-        }
-
-        let conditionPassed = false;
-        try {
-          conditionPassed = await condition();
-        } catch (e) {
-          msg += ` - threw exception: ${e}`;
-          clearInterval(intervalID);
-          reject(msg);
-          return;
-        }
-
-        if (conditionPassed) {
-          clearInterval(intervalID);
-          resolve();
-        }
-        tries++;
-      }, interval);
-    });
-  },
+  }
 };
--- a/toolkit/components/places/tests/PlacesTestUtils.jsm
+++ b/toolkit/components/places/tests/PlacesTestUtils.jsm
@@ -7,18 +7,18 @@ this.EXPORTED_SYMBOLS = [
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.importGlobalProperties(["URL"]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "TestUtils",
-                                  "resource://testing-common/TestUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+                                  "resource://gre/modules/NetUtil.jsm");
 
 this.PlacesTestUtils = Object.freeze({
   /**
    * Asynchronously adds visits to a page.
    *
    * @param aPlaceInfo
    *        Can be an nsIURI, in such a case a single LINK visit will be added.
    *        Otherwise can be an object describing the visit to add, or an array
@@ -50,19 +50,19 @@ this.PlacesTestUtils = Object.freeze({
       throw new Error("Unsupported type passed to addVisits");
     }
 
     // Create a PageInfo for each entry.
     for (let place of places) {
       let info = {url: place.uri};
       info.title = (typeof place.title === "string") ? place.title : "test visit for " + info.url.spec ;
       if (typeof place.referrer == "string") {
-        place.referrer = Services.io.newURI(place.referrer);
+        place.referrer = NetUtil.newURI(place.referrer);
       } else if (place.referrer && place.referrer instanceof URL) {
-        place.referrer = Services.io.newURI(place.referrer.href);
+        place.referrer = NetUtil.newURI(place.referrer.href);
       }
       let visitDate = place.visitDate;
       if (visitDate) {
         if (visitDate.constructor.name != "Date") {
           // visitDate should be in microseconds. It's easy to do the wrong thing
           // and pass milliseconds to updatePlaces, so we lazily check for that.
           // While it's not easily distinguishable, since both are integers, we
           // can check if the value is very far in the past, and assume it's
@@ -77,21 +77,17 @@ this.PlacesTestUtils = Object.freeze({
       }
       info.visits = [{
         transition: place.transition,
         date: visitDate,
         referrer: place.referrer
       }];
       infos.push(info);
     }
-    await PlacesUtils.history.insertMany(infos);
-    await TestUtils.waitForCondition(
-      () => PlacesUtils.history.fetch(infos[infos.length - 1].url),
-      "Ensure history has been updated and is visible to read-only connections"
-    );
+    return PlacesUtils.history.insertMany(infos);
   },
 
    /*
     * Add Favicons
     *
     * @param {Map} faviconURLs  keys are page URLs, values are their
     *                           associated favicon URLs.
     */
@@ -103,18 +99,18 @@ this.PlacesTestUtils = Object.freeze({
     if (!faviconURLs) {
       throw new Error("No favicon URLs were provided");
     }
     for (let [key, val] of faviconURLs) {
       if (!val) {
         throw new Error("URL does not exist");
       }
       faviconPromises.push(new Promise((resolve, reject) => {
-        let uri = Services.io.newURI(key);
-        let faviconURI = Services.io.newURI(val);
+        let uri = NetUtil.newURI(key);
+        let faviconURI = NetUtil.newURI(val);
         try {
           PlacesUtils.favicons.setAndFetchFaviconForPage(
             uri,
             faviconURI,
             false,
             PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
             resolve,
             Services.scriptSecurityManager.getSystemPrincipal());