Bug 1308420 - Move nsBrowserGlue.js _handleURLBarTelemetry() into BrowserUsageTelemetry. r?mak draft
authorMark Banner <standard8@mozilla.com>
Wed, 07 Dec 2016 13:45:56 +0000
changeset 452810 59496a23ecec94353cdf5ee9e37c08cc6d8aa1a5
parent 451264 567894f026558e6dada617a3998f29aed06ac7d8
child 540314 06bb9d73cb927798514a4d11e31e8e5a5eda3c63
push id39503
push userbmo:standard8@mozilla.com
push dateThu, 22 Dec 2016 09:27:10 +0000
reviewersmak
bugs1308420
milestone53.0a1
Bug 1308420 - Move nsBrowserGlue.js _handleURLBarTelemetry() into BrowserUsageTelemetry. r?mak MozReview-Commit-ID: AYNeNyoCwoG
browser/components/nsBrowserGlue.js
browser/modules/BrowserUsageTelemetry.jsm
browser/modules/test/browser_UsageTelemetry_content.js
browser/modules/test/browser_UsageTelemetry_content_aboutHome.js
browser/modules/test/browser_UsageTelemetry_urlbar.js
browser/modules/test/head.js
toolkit/components/telemetry/Histograms.json
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -358,86 +358,25 @@ BrowserGlue.prototype = {
           for (let addon of addons) {
             if (addon.type != "experiment") {
               this._notifyUnsignedAddonsDisabled();
               break;
             }
           }
         });
         break;
-      case "autocomplete-did-enter-text":
-        this._handleURLBarTelemetry(subject.QueryInterface(Ci.nsIAutoCompleteInput));
-        break;
       case "test-initialize-sanitizer":
         this._sanitizer.onStartup();
         break;
       case AddonWatcher.TOPIC_SLOW_ADDON_DETECTED:
         this._notifySlowAddon(data);
         break;
     }
   },
 
-  _handleURLBarTelemetry(input) {
-    if (!input ||
-        input.id != "urlbar" ||
-        input.inPrivateContext ||
-        input.popup.selectedIndex < 0) {
-      return;
-    }
-    let controller =
-      input.popup.view.QueryInterface(Ci.nsIAutoCompleteController);
-    let idx = input.popup.selectedIndex;
-    let value = controller.getValueAt(idx);
-    let action = input._parseActionUrl(value);
-    let actionType;
-    if (action) {
-      actionType =
-        action.type == "searchengine" && action.params.searchSuggestion ?
-          "searchsuggestion" :
-        action.type;
-    }
-    if (!actionType) {
-      let styles = new Set(controller.getStyleAt(idx).split(/\s+/));
-      let style = ["autofill", "tag", "bookmark"].find(s => styles.has(s));
-      actionType = style || "history";
-    }
-
-    Services.telemetry
-            .getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX")
-            .add(idx);
-
-    // Ideally this would be a keyed histogram and we'd just add(actionType),
-    // but keyed histograms aren't currently shown on the telemetry dashboard
-    // (bug 1151756).
-    //
-    // You can add values but don't change any of the existing values.
-    // Otherwise you'll break our data.
-    let buckets = {
-      autofill: 0,
-      bookmark: 1,
-      history: 2,
-      keyword: 3,
-      searchengine: 4,
-      searchsuggestion: 5,
-      switchtab: 6,
-      tag: 7,
-      visiturl: 8,
-      remotetab: 9,
-      extension: 10,
-    };
-    if (actionType in buckets) {
-      Services.telemetry
-              .getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE")
-              .add(buckets[actionType]);
-    } else {
-      Cu.reportError("Unknown FX_URLBAR_SELECTED_RESULT_TYPE type: " +
-                     actionType);
-    }
-  },
-
   // initialization (called on application startup)
   _init: function BG__init() {
     let os = Services.obs;
     os.addObserver(this, "notifications-open-settings", false);
     os.addObserver(this, "prefservice:after-app-defaults", false);
     os.addObserver(this, "final-ui-startup", false);
     os.addObserver(this, "browser-delayed-startup-finished", false);
     os.addObserver(this, "sessionstore-windows-restored", false);
@@ -464,17 +403,16 @@ BrowserGlue.prototype = {
     os.addObserver(this, "profile-before-change", false);
     if (AppConstants.MOZ_TELEMETRY_REPORTING) {
       os.addObserver(this, "keyword-search", false);
     }
     os.addObserver(this, "browser-search-engine-modified", false);
     os.addObserver(this, "restart-in-safe-mode", false);
     os.addObserver(this, "flash-plugin-hang", false);
     os.addObserver(this, "xpi-signature-changed", false);
-    os.addObserver(this, "autocomplete-did-enter-text", false);
 
     if (AppConstants.NIGHTLY_BUILD) {
       os.addObserver(this, AddonWatcher.TOPIC_SLOW_ADDON_DETECTED, false);
     }
 
     this._flashHangCount = 0;
     this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
 
@@ -519,17 +457,16 @@ BrowserGlue.prototype = {
     os.removeObserver(this, "handle-xul-text-link");
     os.removeObserver(this, "profile-before-change");
     if (AppConstants.MOZ_TELEMETRY_REPORTING) {
       os.removeObserver(this, "keyword-search");
     }
     os.removeObserver(this, "browser-search-engine-modified");
     os.removeObserver(this, "flash-plugin-hang");
     os.removeObserver(this, "xpi-signature-changed");
-    os.removeObserver(this, "autocomplete-did-enter-text");
   },
 
   _onAppDefaults: function BG__onAppDefaults() {
     // apply distribution customizations (prefs)
     // other customizations are applied in _finalUIStartup()
     this._distributionCustomizer.applyPrefDefaults();
   },
 
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -1,16 +1,16 @@
 /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
 /* 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/. */
 
 "use strict";
 
-this.EXPORTED_SYMBOLS = ["BrowserUsageTelemetry"];
+this.EXPORTED_SYMBOLS = ["BrowserUsageTelemetry", "URLBAR_SELECTED_RESULT_TYPES"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
@@ -18,16 +18,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 // The upper bound for the count of the visited unique domain names.
 const MAX_UNIQUE_VISITED_DOMAINS = 100;
 
 // Observed topic names.
 const WINDOWS_RESTORED_TOPIC = "sessionstore-windows-restored";
 const TAB_RESTORING_TOPIC = "SSTabRestoring";
 const TELEMETRY_SUBSESSIONSPLIT_TOPIC = "internal-telemetry-after-subsession-split";
 const DOMWINDOW_OPENED_TOPIC = "domwindowopened";
+const AUTOCOMPLETE_ENTER_TEXT_TOPIC = "autocomplete-did-enter-text";
 
 // Probe names.
 const MAX_TAB_COUNT_SCALAR_NAME = "browser.engagement.max_concurrent_tab_count";
 const MAX_WINDOW_COUNT_SCALAR_NAME = "browser.engagement.max_concurrent_window_count";
 const TAB_OPEN_EVENT_COUNT_SCALAR_NAME = "browser.engagement.tab_open_event_count";
 const WINDOW_OPEN_EVENT_COUNT_SCALAR_NAME = "browser.engagement.window_open_event_count";
 const UNIQUE_DOMAINS_COUNT_SCALAR_NAME = "browser.engagement.unique_domains_count";
 const TOTAL_URI_COUNT_SCALAR_NAME = "browser.engagement.total_uri_count";
@@ -43,16 +44,34 @@ const KNOWN_SEARCH_SOURCES = [
 ];
 
 const KNOWN_ONEOFF_SOURCES = [
   "oneoff-urlbar",
   "oneoff-searchbar",
   "unknown", // Edge case: this is the searchbar (see bug 1195733 comment 7).
 ];
 
+/**
+ * The buckets used for logging telemetry to the FX_URLBAR_SELECTED_RESULT_TYPE
+ * histogram.
+ */
+const URLBAR_SELECTED_RESULT_TYPES = {
+  autofill: 0,
+  bookmark: 1,
+  history: 2,
+  keyword: 3,
+  searchengine: 4,
+  searchsuggestion: 5,
+  switchtab: 6,
+  tag: 7,
+  visiturl: 8,
+  remotetab: 9,
+  extension: 10,
+};
+
 function getOpenTabsAndWinsCounts() {
   let tabCount = 0;
   let winCount = 0;
 
   let browserEnum = Services.wm.getEnumerator("navigator:browser");
   while (browserEnum.hasMoreElements()) {
     let win = browserEnum.getNext();
     winCount++;
@@ -182,19 +201,92 @@ let URICountListener = {
   reset() {
     this._domainSet.clear();
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference]),
 };
 
+let urlbarListener = {
+  init() {
+    Services.obs.addObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC, true);
+  },
+
+  uninit() {
+    Services.obs.removeObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC, true);
+  },
+
+  observe(subject, topic, data) {
+    switch (topic) {
+      case AUTOCOMPLETE_ENTER_TEXT_TOPIC:
+        this._handleURLBarTelemetry(subject.QueryInterface(Ci.nsIAutoCompleteInput));
+        break;
+    }
+  },
+
+  /**
+   * Used to log telemetry when the user enters text in the urlbar.
+   *
+   * @param {nsIAutoCompleteInput} input  The autocomplete element where the
+   *                                      text was entered.
+   */
+  _handleURLBarTelemetry(input) {
+    if (!input ||
+        input.id != "urlbar" ||
+        input.inPrivateContext ||
+        input.popup.selectedIndex < 0) {
+      return;
+    }
+    let controller =
+      input.popup.view.QueryInterface(Ci.nsIAutoCompleteController);
+    let idx = input.popup.selectedIndex;
+    let value = controller.getValueAt(idx);
+    let action = input._parseActionUrl(value);
+    let actionType;
+    if (action) {
+      actionType =
+        action.type == "searchengine" && action.params.searchSuggestion ?
+          "searchsuggestion" :
+        action.type;
+    }
+    if (!actionType) {
+      let styles = new Set(controller.getStyleAt(idx).split(/\s+/));
+      let style = ["autofill", "tag", "bookmark"].find(s => styles.has(s));
+      actionType = style || "history";
+    }
+
+    Services.telemetry
+            .getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX")
+            .add(idx);
+
+    // Ideally this would be a keyed histogram and we'd just add(actionType),
+    // but keyed histograms aren't currently shown on the telemetry dashboard
+    // (bug 1151756).
+    //
+    // You can add values but don't change any of the existing values.
+    // Otherwise you'll break our data.
+    if (actionType in URLBAR_SELECTED_RESULT_TYPES) {
+      Services.telemetry
+              .getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE")
+              .add(URLBAR_SELECTED_RESULT_TYPES[actionType]);
+    } else {
+      Cu.reportError("Unknown FX_URLBAR_SELECTED_RESULT_TYPE type: " +
+                     actionType);
+    }
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+                                         Ci.nsISupportsWeakReference]),
+};
+
 let BrowserUsageTelemetry = {
   init() {
     Services.obs.addObserver(this, WINDOWS_RESTORED_TOPIC, false);
+    urlbarListener.init();
   },
 
   /**
    * Handle subsession splits in the parent process.
    */
   afterSubsessionSplit() {
     // Scalars just got cleared due to a subsession split. We need to set the maximum
     // concurrent tab and window counts so that they reflect the correct value for the
@@ -206,16 +298,17 @@ let BrowserUsageTelemetry = {
     // Reset the URI counter.
     URICountListener.reset();
   },
 
   uninit() {
     Services.obs.removeObserver(this, DOMWINDOW_OPENED_TOPIC, false);
     Services.obs.removeObserver(this, TELEMETRY_SUBSESSIONSPLIT_TOPIC, false);
     Services.obs.removeObserver(this, WINDOWS_RESTORED_TOPIC, false);
+    urlbarListener.uninit();
   },
 
   observe(subject, topic, data) {
     switch (topic) {
       case WINDOWS_RESTORED_TOPIC:
         this._setupAfterRestore();
         break;
       case DOMWINDOW_OPENED_TOPIC:
--- a/browser/modules/test/browser_UsageTelemetry_content.js
+++ b/browser/modules/test/browser_UsageTelemetry_content.js
@@ -28,16 +28,17 @@ add_task(function* setup() {
     ["toolkit.telemetry.enabled", true]  // And Extended Telemetry to be enabled.
   ]});
 
   // Make sure to restore the engine once we're done.
   registerCleanupFunction(function* () {
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engineDefault);
     Services.search.removeEngine(engineOneOff);
+    yield PlacesTestUtils.clearHistory();
   });
 });
 
 add_task(function* test_context_menu() {
   // Let's reset the Telemetry data.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let search_hist = getSearchCountsHistogram();
--- a/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js
+++ b/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js
@@ -30,16 +30,17 @@ add_task(function* setup() {
   // Enable Extended Telemetry.
   yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
 
   // Make sure to restore the engine once we're done.
   registerCleanupFunction(function* () {
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engineDefault);
     Services.search.removeEngine(engineOneOff);
+    yield PlacesTestUtils.clearHistory();
   });
 });
 
 add_task(function* test_abouthome_simpleQuery() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let search_hist = getSearchCountsHistogram();
--- a/browser/modules/test/browser_UsageTelemetry_urlbar.js
+++ b/browser/modules/test/browser_UsageTelemetry_urlbar.js
@@ -3,16 +3,31 @@
 const SCALAR_URLBAR = "browser.engagement.navigation.urlbar";
 
 // The preference to enable suggestions in the urlbar.
 const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
 // The name of the search engine used to generate suggestions.
 const SUGGESTION_ENGINE_NAME = "browser_UsageTelemetry usageTelemetrySearchSuggestions.xml";
 const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
 
+XPCOMUtils.defineLazyModuleGetter(this, "URLBAR_SELECTED_RESULT_TYPES",
+                                  "resource:///modules/BrowserUsageTelemetry.jsm");
+
+function checkHistogramResults(resultIndexes, expected, histogram) {
+  for (let i = 0; i < resultIndexes.counts.length; i++) {
+    if (i == expected) {
+      Assert.equal(resultIndexes.counts[i], 1,
+        `expected counts should match for ${histogram} index ${i}`);
+    } else {
+      Assert.equal(resultIndexes.counts[i], 0,
+        `unexpected counts should be zero for ${histogram} index ${i}`);
+    }
+  }
+}
+
 let searchInAwesomebar = Task.async(function* (inputText, win = window) {
   yield new Promise(r => waitForFocus(r, win));
   // Write the search query in the urlbar.
   win.gURLBar.focus();
   win.gURLBar.value = inputText;
   win.gURLBar.controller.startSearch(inputText);
   // Wait for the popup to show.
   yield BrowserTestUtils.waitForEvent(win.gURLBar.popup, "popupshown");
@@ -57,29 +72,40 @@ add_task(function* setup() {
   Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
 
   // Enable the urlbar one-off buttons.
   Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true);
 
   // Enable Extended Telemetry.
   yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
 
+  // Enable local telemetry recording for the duration of the tests.
+  let oldCanRecord = Services.telemetry.canRecordExtended;
+  Services.telemetry.canRecordExtended = true;
+
   // Make sure to restore the engine once we're done.
   registerCleanupFunction(function* () {
+    Services.telemetry.canRecordExtended = oldCanRecord;
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engine);
     Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF, true);
     Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
+    yield PlacesTestUtils.clearHistory();
   });
 });
 
 add_task(function* test_simpleQuery() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
+  let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
+  resultIndexHist.clear();
+  resultTypeHist.clear();
+
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Simulate entering a simple search.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("simple query");
   EventUtils.sendKey("return");
@@ -95,23 +121,37 @@ add_task(function* test_simpleQuery() {
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = events.filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "urlbar", "enter", {engine: "other-MozSearch"}]]);
 
+  // Check the histograms as well.
+  let resultIndexes = resultIndexHist.snapshot();
+  checkHistogramResults(resultIndexes, 0, "FX_URLBAR_SELECTED_RESULT_INDEX");
+
+  let resultTypes = resultTypeHist.snapshot();
+  checkHistogramResults(resultTypes,
+    URLBAR_SELECTED_RESULT_TYPES.searchengine,
+    "FX_URLBAR_SELECTED_RESULT_TYPE");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
 add_task(function* test_searchAlias() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
+  let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
+  resultIndexHist.clear();
+  resultTypeHist.clear();
+
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Search using a search alias.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("mozalias query");
   EventUtils.sendKey("return");
@@ -127,23 +167,37 @@ add_task(function* test_searchAlias() {
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = events.filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "urlbar", "alias", {engine: "other-MozSearch"}]]);
 
+  // Check the histograms as well.
+  let resultIndexes = resultIndexHist.snapshot();
+  checkHistogramResults(resultIndexes, 0, "FX_URLBAR_SELECTED_RESULT_INDEX");
+
+  let resultTypes = resultTypeHist.snapshot();
+  checkHistogramResults(resultTypes,
+    URLBAR_SELECTED_RESULT_TYPES.searchengine,
+    "FX_URLBAR_SELECTED_RESULT_TYPE");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
 add_task(function* test_oneOff() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
+  let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
+  resultIndexHist.clear();
+  resultTypeHist.clear();
+
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Perform a one-off search using the first engine.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("query");
 
@@ -162,23 +216,37 @@ add_task(function* test_oneOff() {
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = events.filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "urlbar", "oneoff", {engine: "other-MozSearch"}]]);
 
+  // Check the histograms as well.
+  let resultIndexes = resultIndexHist.snapshot();
+  checkHistogramResults(resultIndexes, 0, "FX_URLBAR_SELECTED_RESULT_INDEX");
+
+  let resultTypes = resultTypeHist.snapshot();
+  checkHistogramResults(resultTypes,
+    URLBAR_SELECTED_RESULT_TYPES.searchengine,
+    "FX_URLBAR_SELECTED_RESULT_TYPE");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
 add_task(function* test_suggestion() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
+  let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
+  resultIndexHist.clear();
+  resultTypeHist.clear();
+
   let search_hist = getSearchCountsHistogram();
 
   // Create an engine to generate search suggestions and add it as default
   // for this test.
   const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
   let suggestionEngine = yield new Promise((resolve, reject) => {
     Services.search.addEngine(url, null, "", false, {
       onSuccess(engine) { resolve(engine) },
@@ -209,12 +277,21 @@ add_task(function* test_suggestion() {
   let searchEngineId = 'other-' + suggestionEngine.name;
   checkKeyedHistogram(search_hist, searchEngineId + '.urlbar', 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = events.filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "urlbar", "suggestion", {engine: searchEngineId}]]);
 
+  // Check the histograms as well.
+  let resultIndexes = resultIndexHist.snapshot();
+  checkHistogramResults(resultIndexes, 3, "FX_URLBAR_SELECTED_RESULT_INDEX");
+
+  let resultTypes = resultTypeHist.snapshot();
+  checkHistogramResults(resultTypes,
+    URLBAR_SELECTED_RESULT_TYPES.searchsuggestion,
+    "FX_URLBAR_SELECTED_RESULT_TYPE");
+
   Services.search.currentEngine = previousEngine;
   Services.search.removeEngine(suggestionEngine);
   yield BrowserTestUtils.removeTab(tab);
 });
--- a/browser/modules/test/head.js
+++ b/browser/modules/test/head.js
@@ -1,10 +1,13 @@
 Cu.import("resource://gre/modules/Promise.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
+                                  "resource://testing-common/PlacesTestUtils.jsm");
+
 const SINGLE_TRY_TIMEOUT = 100;
 const NUMBER_OF_TRIES = 30;
 
 function waitForConditionPromise(condition, timeoutMsg, tryCount = NUMBER_OF_TRIES) {
   let defer = Promise.defer();
   let tries = 0;
   function checkCondition() {
     if (tries >= tryCount) {
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -5464,17 +5464,17 @@
     "description": "Firefox: The index of the selected result in the URL bar popup"
   },
   "FX_URLBAR_SELECTED_RESULT_TYPE": {
     "alert_emails": ["firefox-dev@mozilla.org"],
     "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 14,
     "bug_numbers": [775825],
-    "description": "Firefox: The type of the selected result in the URL bar popup. See nsBrowserGlue.js::_handleURLBarTelemetry for the result types."
+    "description": "Firefox: The type of the selected result in the URL bar popup. See BrowserUsageTelemetry.jsm:URLBAR_SELECTED_RESULT_TYPES for the result types."
   },
   "INNERWINDOWS_WITH_MUTATION_LISTENERS": {
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Deleted or to-be-reused innerwindow which has had mutation event listeners."
   },
   "CHARSET_OVERRIDE_SITUATION": {
     "expires_in_version": "never",