Bug 1500147 - Part 2: Record LWT telemetry in customize mode r=rpl
authorMark Striemer <mstriemer@mozilla.com>
Thu, 07 Feb 2019 16:42:04 +0000
changeset 458273 0a5e45e5783401a625ea582968567be21b1b978c
parent 458272 dec5ea7cb93f0cbd9db782d5b70db44651e88056
child 458274 286129ec63de146b55a3ef0292c6a927a0f4f698
push id35522
push usernbeleuzu@mozilla.com
push dateSat, 09 Feb 2019 03:34:29 +0000
treeherdermozilla-central@4e56ef85817a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrpl
bugs1500147
milestone67.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 1500147 - Part 2: Record LWT telemetry in customize mode r=rpl Differential Revision: https://phabricator.services.mozilla.com/D18002
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/test/browser.ini
browser/components/customizableui/test/browser_lwt_telemetry.js
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -23,16 +23,18 @@ const kDownloadAutoHidePref = "browser.d
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {CustomizableUI} = ChromeUtils.import("resource:///modules/CustomizableUI.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyGlobalGetters(this, ["CSS"]);
 
+ChromeUtils.defineModuleGetter(this, "AMTelemetry",
+                               "resource://gre/modules/AddonManager.jsm");
 ChromeUtils.defineModuleGetter(this, "DragPositionManager",
                                "resource:///modules/DragPositionManager.jsm");
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "LightweightThemeManager",
                                "resource://gre/modules/LightweightThemeManager.jsm");
 ChromeUtils.defineModuleGetter(this, "SessionStore",
                                "resource:///modules/sessionstore/SessionStore.jsm");
@@ -1200,21 +1202,23 @@ CustomizeMode.prototype = {
       this._unwrapItemsInArea(aContainer);
       this._removeDragHandlers(aContainer);
       this.areas.delete(aContainer);
     }
   },
 
   openAddonsManagerThemes(aEvent) {
     aEvent.target.parentNode.parentNode.hidePopup();
+    AMTelemetry.recordLinkEvent({object: "customize", value: "manageThemes"});
     this.window.BrowserOpenAddonsMgr("addons://list/theme");
   },
 
   getMoreThemes(aEvent) {
     aEvent.target.parentNode.parentNode.hidePopup();
+    AMTelemetry.recordLinkEvent({object: "customize", value: "getThemes"});
     let getMoreURL = Services.urlFormatter.formatURLPref("lightweightThemes.getMoreURL");
     this.window.openTrustedLinkIn(getMoreURL, "tab");
   },
 
   updateUIDensity(mode) {
     this.window.gUIDensity.update(mode);
   },
 
@@ -1382,16 +1386,21 @@ CustomizeMode.prototype = {
     for (let theme of themes) {
       let button = buildToolbarButton(theme);
       button.addEventListener("command", () => {
         if ("userDisabled" in button.theme)
           button.theme.userDisabled = false;
         else
           LightweightThemeManager.currentTheme = button.theme;
         onThemeSelected(panel);
+        AMTelemetry.recordActionEvent({
+          object: "customize",
+          action: "enable",
+          extra: {type: "theme", addonId: theme.id},
+        });
       });
       panel.insertBefore(button, recommendedLabel);
     }
 
     function panelMouseOut(e) {
       // mouseout events bubble, so we get mouseout events for the buttons
       // in the panel. Here, we only care when the mouse actually leaves
       // the panel. For some reason event.target might not be the panel
@@ -1424,16 +1433,23 @@ CustomizeMode.prototype = {
       }
       let button = buildToolbarButton(theme);
       button.addEventListener("command", () => {
         LightweightThemeManager.setLocalTheme(button.theme);
         recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.theme.id; });
         lwthemePrefs.setStringPref("recommendedThemes",
                                    JSON.stringify(recommendedThemes));
         onThemeSelected(panel);
+        let addonId = `${button.theme.id}@personas.mozilla.org`;
+        AMTelemetry.recordActionEvent({
+          object: "customize",
+          action: "enable",
+          value: "recommended",
+          extra: {type: "theme", addonId},
+        });
       });
       panel.insertBefore(button, footer);
     }
     let hideRecommendedLabel = (footer.previousElementSibling == recommendedLabel);
     recommendedLabel.hidden = hideRecommendedLabel;
   },
 
   _clearLWThemesMenu(panel) {
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -174,12 +174,13 @@ subsuite = clipboard
 [browser_open_from_popup.js]
 [browser_PanelMultiView_focus.js]
 [browser_sidebar_toggle.js]
 skip-if = verify
 [browser_tabbar_big_widgets.js]
 [browser_remote_tabs_button.js]
 skip-if = (verify && debug && (os == 'linux' || os == 'mac'))
 [browser_widget_animation.js]
+[browser_lwt_telemetry.js]
 
 # Unit tests for the PanelMultiView module. These are independent from
 # CustomizableUI, but are located here together with the module they're testing.
 [browser_PanelMultiView.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/test/browser_lwt_telemetry.js
@@ -0,0 +1,95 @@
+"use strict";
+
+add_task(function clearTelemetry() {
+  Services.telemetry.clearEvents();
+});
+
+add_task(async function testCustomize() {
+  let getMoreURL = "about:blank#getMoreThemes";
+
+  // Reset the theme prefs to ensure they haven't been messed with.
+  Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
+  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
+  await SpecialPowers.pushPrefEnv({set: [
+    ["lightweightThemes.getMoreURL", getMoreURL],
+  ]});
+
+  await startCustomizing();
+
+  // Open the panel to populate the recommended themes.
+  let themePanel = document.getElementById("customization-lwtheme-menu");
+  themePanel.openPopup();
+  await BrowserTestUtils.waitForPopupEvent(themePanel, "shown");
+
+  // Install a recommended theme.
+  let recommendedLabel = document.getElementById("customization-lwtheme-menu-recommended");
+  let themeButton = recommendedLabel.nextElementSibling;
+  let themeId = `${themeButton.theme.id}@personas.mozilla.org`;
+  let themeChanged = TestUtils.topicObserved("lightweight-theme-changed");
+  themeButton.click();
+
+  // Wait for the theme to change and the popup to close.
+  await themeChanged;
+  await BrowserTestUtils.waitForPopupEvent(themePanel, "hidden");
+
+  // Switch back to the default theme.
+  let installedThemes = document.querySelectorAll(".customization-lwtheme-menu-theme");
+  let defaultId = "default-theme@mozilla.org";
+  let defaultThemeIndex = Array.from(installedThemes).findIndex(btn => btn.theme.id == defaultId);
+  let defaultThemeButton = installedThemes[defaultThemeIndex];
+  themeChanged = TestUtils.topicObserved("lightweight-theme-changed");
+  defaultThemeButton.click();
+
+  // Wait for the theme to change back to default.
+  await themeChanged;
+
+  // Find the footer buttons to test.
+  let footerRow = document.getElementById("customization-lwtheme-menu-footer");
+  let [manageButton, getMoreButton] = footerRow.childNodes;
+
+  // Check the manage button, it should open about:addons.
+  let waitForNewTab = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
+  manageButton.click();
+  let addonsTab = await waitForNewTab;
+
+  is(gBrowser.currentURI.spec, "about:addons", "Manage opened about:addons");
+  BrowserTestUtils.removeTab(addonsTab);
+
+  // Check the get more button, we mocked it to open getMoreURL.
+  waitForNewTab = BrowserTestUtils.waitForNewTab(gBrowser, getMoreURL);
+  getMoreButton.click();
+  addonsTab = await waitForNewTab;
+
+  is(gBrowser.currentURI.spec, getMoreURL, "Get more opened AMO");
+  BrowserTestUtils.removeTab(addonsTab);
+
+  let snapshot = Services.telemetry.snapshotEvents(
+    Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true);
+
+  // Make sure we got some data.
+  ok(snapshot.parent && snapshot.parent.length > 0, "Got parent telemetry events in the snapshot");
+
+  // Only look at the related events after stripping the timestamp and category.
+  let relatedEvents = snapshot.parent
+    .filter(([timestamp, category, method, object]) =>
+      category == "addonsManager" && object == "customize")
+    .map(relatedEvent => relatedEvent.slice(2, 6));
+
+  // Events are now [method, object, value, extra] as expected.
+  Assert.deepEqual(relatedEvents, [
+    ["action", "customize", "recommended", {action: "enable", addonId: themeId, type: "theme"}],
+    ["action", "customize", null, {action: "enable", addonId: defaultId, type: "theme"}],
+    ["link", "customize", "manageThemes"],
+    ["link", "customize", "getThemes"],
+  ], "The events are recorded correctly");
+
+  // Reset the theme prefs to leave them in a clean state.
+  Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
+  Services.prefs.clearUserPref("lightweightThemes.usedThemes");
+
+  // Wait for customize mode to be re-entered now that the customize tab is
+  // active. This is needed for endCustomizing() to work properly.
+  await TestUtils.waitForCondition(
+    () => document.documentElement.getAttribute("customizing") == "true");
+  await endCustomizing();
+});