Bug 1381460 - Add telemetry search event for Activity Stream. r=Dexter data-r=bsmedberg draft
authorAndrei Oprea <andrei.br92@gmail.com>
Tue, 22 Aug 2017 15:35:52 +0200
changeset 651204 1f564dcb6194c93e8df21f9173327b2892cc8a21
parent 650424 eb72c8c077518c3fdc0dca5c0a14070bd25fe3cb
child 727622 cb182cc402748fc9c3f1e311599560f613b98898
push id75632
push userbmo:andrei.br92@gmail.com
push dateWed, 23 Aug 2017 10:43:41 +0000
reviewersDexter
bugs1381460
milestone57.0a1
Bug 1381460 - Add telemetry search event for Activity Stream. r=Dexter data-r=bsmedberg MozReview-Commit-ID: 2NdtjQ2Tsbo
browser/extensions/activity-stream/data/content/activity-stream.bundle.js
browser/modules/BrowserUsageTelemetry.jsm
browser/modules/test/browser/browser_UsageTelemetry_content.js
toolkit/components/telemetry/Events.yaml
toolkit/components/telemetry/Scalars.yaml
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -2077,22 +2077,17 @@ class Search extends React.Component {
       this.props.dispatch(ac.UserEvent({ event: "SEARCH" }));
     }
   }
   onClick(event) {
     this.controller.search(event);
   }
   onInputMount(input) {
     if (input) {
-      // The first "newtab" parameter here is called the "healthReportKey" and needs
-      // to be "newtab" so that BrowserUsageTelemetry.jsm knows to handle events with
-      // this name, and can add the appropriate telemetry probes for search. Without the
-      // correct name, certain tests like browser_UsageTelemetry_content.js will fail (See
-      // github ticket #2348 for more details)
-      this.controller = new ContentSearchUIController(input, input.parentNode, "newtab", "newtab");
+      this.controller = new ContentSearchUIController(input, input.parentNode, "activitystream", "newtab");
       addEventListener("ContentSearchClient", this);
     } else {
       this.controller = null;
       removeEventListener("ContentSearchClient", this);
     }
   }
 
   /*
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -40,16 +40,17 @@ const UNFILTERED_URI_COUNT_SCALAR_NAME =
 
 // A list of known search origins.
 const KNOWN_SEARCH_SOURCES = [
   "abouthome",
   "contextmenu",
   "newtab",
   "searchbar",
   "urlbar",
+  "activitystream"
 ];
 
 const KNOWN_ONEOFF_SOURCES = [
   "oneoff-urlbar",
   "oneoff-searchbar",
   "unknown", // Edge case: this is the searchbar (see bug 1195733 comment 7).
 ];
 
@@ -446,16 +447,19 @@ let BrowserUsageTelemetry = {
         this._handleSearchAndUrlbar(engine, source, details);
         break;
       case "abouthome":
         this._recordSearch(engine, "about_home", "enter");
         break;
       case "newtab":
         this._recordSearch(engine, "about_newtab", "enter");
         break;
+      case "activitystream":
+        this._recordSearch(engine, "activitystream", "enter");
+        break;
       case "contextmenu":
         this._recordSearch(engine, "contextmenu");
         break;
     }
   },
 
   /**
    * This function handles the "urlbar", "urlbar-oneoff", "searchbar" and
--- a/browser/modules/test/browser/browser_UsageTelemetry_content.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_content.js
@@ -1,13 +1,14 @@
 "use strict";
 
 const BASE_PROBE_NAME = "browser.engagement.navigation.";
 const SCALAR_CONTEXT_MENU = BASE_PROBE_NAME + "contextmenu";
 const SCALAR_ABOUT_NEWTAB = BASE_PROBE_NAME + "about_newtab";
+const SCALAR_ABOUT_ACTIVITYSTREAM = BASE_PROBE_NAME + "activitystream";
 
 add_task(async function setup() {
   // Create two new search engines. Mark one as the default engine, so
   // the test don't crash. We need to engines for this test as the searchbar
   // in content doesn't display the default search engine among the one-off engines.
   Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET",
                                        "http://example.com/?q={searchTerms}");
 
@@ -85,24 +86,35 @@ add_task(async function test_context_men
   checkEvents(events, [["navigation", "search", "contextmenu", null, {engine: "other-MozSearch"}]]);
 
   contextMenu.hidePopup();
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
   await BrowserTestUtils.removeTab(tab);
 });
 
 add_task(async function test_about_newtab() {
+  // Test newtab search event.
+  const ACTIVITY_STREAM_ENABLED = Services.prefs.getBoolPref("browser.newtabpage.activity-stream.enabled");
+  if (ACTIVITY_STREAM_ENABLED === true) {
+    Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
+  }
+
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let search_hist = getAndClearKeyedHistogram("SEARCH_COUNTS");
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
+  // browser.newtab.preload preloads a new tab before pref change actually happens.
+  // We need to throw away the first tab we open because it will not be up to date.
+  await BrowserTestUtils.removeTab(tab);
+  tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
     await ContentTaskUtils.waitForCondition(() => !content.document.hidden);
+    await ContentTaskUtils.waitForCondition(() => content.document.querySelector("#newtab-search-text"));
   });
 
   info("Trigger a simple serch, just text + enter.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   await typeInSearchField(tab.linkedBrowser, "test query", "newtab-search-text");
   await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser);
   await p;
 
@@ -115,10 +127,60 @@ add_task(async function test_about_newta
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, "other-MozSearch.newtab", 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "about_newtab", "enter", {engine: "other-MozSearch"}]]);
 
+  Services.prefs.clearUserPref("browser.newtabpage.activity-stream.enabled");
+
   await BrowserTestUtils.removeTab(tab);
 });
+
+add_task(async function test_about_newtab_activitystream() {
+  // Test activitystream search event.
+  const ACTIVITY_STREAM_ENABLED = Services.prefs.getBoolPref("browser.newtabpage.activity-stream.enabled");
+  if (ACTIVITY_STREAM_ENABLED === false) {
+    Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
+  }
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+  Services.telemetry.clearEvents();
+  let search_hist = getAndClearKeyedHistogram("SEARCH_COUNTS");
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
+  // browser.newtab.preload preloads a new tab before pref change actually happens.
+  // We need to throw away the first tab we open because it will not be up to date.
+  await BrowserTestUtils.removeTab(tab);
+  tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
+  await ContentTask.spawn(tab.linkedBrowser, null, async function() {
+    await ContentTaskUtils.waitForCondition(() => !content.document.hidden);
+  });
+
+  info("Trigger a simple serch, just text + enter.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  await ContentTask.spawn(tab.linkedBrowser, null, async function() {
+    await ContentTaskUtils.waitForCondition(() => content.document.querySelector("#newtab-search-text"));
+  });
+  await typeInSearchField(tab.linkedBrowser, "test query", "newtab-search-text");
+  await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser);
+  await p;
+
+  // Check if the scalars contain the expected values.
+  const scalars = getParentProcessScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true, false);
+  checkKeyedScalar(scalars, SCALAR_ABOUT_ACTIVITYSTREAM, "search_enter", 1);
+  Assert.equal(Object.keys(scalars[SCALAR_ABOUT_ACTIVITYSTREAM]).length, 1,
+    "This search must only increment one entry in the scalar.");
+
+  // Make sure SEARCH_COUNTS contains identical values.
+  checkKeyedHistogram(search_hist, "other-MozSearch.activitystream", 1);
+
+  // Also check events.
+  let events = Services.telemetry.snapshotEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
+  events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
+  checkEvents(events, [["navigation", "search", "activitystream", "enter", {engine: "other-MozSearch"}]]);
+
+  Services.prefs.clearUserPref("browser.newtabpage.activity-stream.enabled");
+
+  await BrowserTestUtils.removeTab(tab);
+});
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -1,12 +1,12 @@
 navigation:
   search:
     objects: ["about_home", "about_newtab", "contextmenu", "oneoff",
-              "suggestion", "alias", "enter", "searchbar", "urlbar"]
+              "suggestion", "alias", "enter", "searchbar", "urlbar", "activitystream"]
     release_channel_collection: opt-out
     record_in_processes: ["main"]
     description: >
       This is recorded on each search navigation.
       The value field records the action used to trigger the search:
         "enter", "oneoff", "suggestion", "alias", null (for contextmenu)
     bug_numbers: [1316281]
     notification_emails:
--- a/toolkit/components/telemetry/Scalars.yaml
+++ b/toolkit/components/telemetry/Scalars.yaml
@@ -243,16 +243,30 @@ browser.engagement.navigation:
     kind: uint
     keyed: true
     notification_emails:
       - bcolloran@mozilla.com
     release_channel_collection: opt-out
     record_in_processes:
       - 'main'
 
+  activitystream:
+    bug_numbers:
+      - 1381460
+    description: >
+      Count search events originating from Activity Stream. This is currently only tracking simple searches and saving them in the 'search_enter' key.
+    expires: never
+    kind: uint
+    keyed: true
+    notification_emails:
+      - aoprea@mozilla.com
+    release_channel_collection: opt-out
+    record_in_processes:
+      - 'main'
+
 # The following section contains the browser usage scalars.
 browser.usage:
   graphite:
     bug_numbers:
       - 1331915
     description: >
       The number of times a graphite2 font has been loaded.
     expires: "60"