summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js308
1 files changed, 308 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js b/browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js
new file mode 100644
index 0000000000..2fffd00e6e
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_telemetry.js
@@ -0,0 +1,308 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+const TIMING_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_OPEN_MS";
+const TIMING_HISTOGRAM_KEYED = "WEBEXT_BROWSERACTION_POPUP_OPEN_MS_BY_ADDONID";
+const RESULT_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT";
+const RESULT_HISTOGRAM_KEYED =
+ "WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT_BY_ADDONID";
+
+const EXTENSION_ID1 = "@test-extension1";
+const EXTENSION_ID2 = "@test-extension2";
+
+// Keep this in sync with the order in Histograms.json for
+// WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT
+const CATEGORIES = ["popupShown", "clearAfterHover", "clearAfterMousedown"];
+
+/**
+ * Takes a Telemetry histogram snapshot and makes sure
+ * that the index for that value (as defined by CATEGORIES)
+ * has a count of 1, and that it's the only value that
+ * has been incremented.
+ *
+ * @param {object} snapshot
+ * The Telemetry histogram snapshot to examine.
+ * @param {string} category
+ * The category in CATEGORIES whose index we expect to have
+ * been set to 1.
+ */
+function assertOnlyOneTypeSet(snapshot, category) {
+ let categoryIndex = CATEGORIES.indexOf(category);
+ Assert.equal(
+ snapshot.values[categoryIndex],
+ 1,
+ `Should have seen the ${category} count increment.`
+ );
+ // Use Array.prototype.reduce to sum up all of the
+ // snapshot.count entries
+ Assert.equal(
+ Object.values(snapshot.values).reduce((a, b) => a + b, 0),
+ 1,
+ "Should only be 1 collected value."
+ );
+}
+
+add_task(async function testBrowserActionTelemetryTiming() {
+ let extensionOptions = {
+ manifest: {
+ browser_action: {
+ default_popup: "popup.html",
+ default_area: "navbar",
+ browser_style: true,
+ },
+ },
+
+ files: {
+ "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><div></div></body></html>`,
+ },
+ };
+ let extension1 = ExtensionTestUtils.loadExtension({
+ ...extensionOptions,
+ manifest: {
+ ...extensionOptions.manifest,
+ browser_specific_settings: {
+ gecko: { id: EXTENSION_ID1 },
+ },
+ },
+ });
+ let extension2 = ExtensionTestUtils.loadExtension({
+ ...extensionOptions,
+ manifest: {
+ ...extensionOptions.manifest,
+ browser_specific_settings: {
+ gecko: { id: EXTENSION_ID2 },
+ },
+ },
+ });
+
+ let histogram = Services.telemetry.getHistogramById(TIMING_HISTOGRAM);
+ let histogramKeyed = Services.telemetry.getKeyedHistogramById(
+ TIMING_HISTOGRAM_KEYED
+ );
+
+ histogram.clear();
+ histogramKeyed.clear();
+
+ is(
+ histogram.snapshot().sum,
+ 0,
+ `No data recorded for histogram: ${TIMING_HISTOGRAM}.`
+ );
+ is(
+ Object.keys(histogramKeyed).length,
+ 0,
+ `No data recorded for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+
+ await extension1.startup();
+ await extension2.startup();
+
+ is(
+ histogram.snapshot().sum,
+ 0,
+ `No data recorded for histogram after startup: ${TIMING_HISTOGRAM}.`
+ );
+ is(
+ Object.keys(histogramKeyed).length,
+ 0,
+ `No data recorded for histogram after startup: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+
+ clickBrowserAction(extension1);
+ await awaitExtensionPanel(extension1);
+ let sumOld = histogram.snapshot().sum;
+ ok(
+ sumOld > 0,
+ `Data recorded for first extension for histogram: ${TIMING_HISTOGRAM}.`
+ );
+
+ let oldKeyedSnapshot = histogramKeyed.snapshot();
+ Assert.deepEqual(
+ Object.keys(oldKeyedSnapshot),
+ [EXTENSION_ID1],
+ `Data recorded for first extension for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ ok(
+ oldKeyedSnapshot[EXTENSION_ID1].sum > 0,
+ `Data recorded for first extension for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+
+ await closeBrowserAction(extension1);
+
+ clickBrowserAction(extension2);
+ await awaitExtensionPanel(extension2);
+ let sumNew = histogram.snapshot().sum;
+ ok(
+ sumNew > sumOld,
+ `Data recorded for second extension for histogram: ${TIMING_HISTOGRAM}.`
+ );
+ sumOld = sumNew;
+
+ let newKeyedSnapshot = histogramKeyed.snapshot();
+ Assert.deepEqual(
+ Object.keys(newKeyedSnapshot).sort(),
+ [EXTENSION_ID1, EXTENSION_ID2],
+ `Data recorded for second extension for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ ok(
+ newKeyedSnapshot[EXTENSION_ID2].sum > 0,
+ `Data recorded for second extension for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ is(
+ newKeyedSnapshot[EXTENSION_ID1].sum,
+ oldKeyedSnapshot[EXTENSION_ID1].sum,
+ `Data recorded for first extension should not change for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ oldKeyedSnapshot = newKeyedSnapshot;
+
+ await closeBrowserAction(extension2);
+
+ clickBrowserAction(extension2);
+ await awaitExtensionPanel(extension2);
+ sumNew = histogram.snapshot().sum;
+ ok(
+ sumNew > sumOld,
+ `Data recorded for second opening of popup for histogram: ${TIMING_HISTOGRAM}.`
+ );
+ sumOld = sumNew;
+
+ newKeyedSnapshot = histogramKeyed.snapshot();
+ ok(
+ newKeyedSnapshot[EXTENSION_ID2].sum > oldKeyedSnapshot[EXTENSION_ID2].sum,
+ `Data recorded for second opening of popup for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ is(
+ newKeyedSnapshot[EXTENSION_ID1].sum,
+ oldKeyedSnapshot[EXTENSION_ID1].sum,
+ `Data recorded for first extension should not change for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ oldKeyedSnapshot = newKeyedSnapshot;
+
+ await closeBrowserAction(extension2);
+
+ clickBrowserAction(extension1);
+ await awaitExtensionPanel(extension1);
+ sumNew = histogram.snapshot().sum;
+ ok(
+ sumNew > sumOld,
+ `Data recorded for second opening of popup for histogram: ${TIMING_HISTOGRAM}.`
+ );
+
+ newKeyedSnapshot = histogramKeyed.snapshot();
+ ok(
+ newKeyedSnapshot[EXTENSION_ID1].sum > oldKeyedSnapshot[EXTENSION_ID1].sum,
+ `Data recorded for second opening of popup for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+ is(
+ newKeyedSnapshot[EXTENSION_ID2].sum,
+ oldKeyedSnapshot[EXTENSION_ID2].sum,
+ `Data recorded for second extension should not change for histogram: ${TIMING_HISTOGRAM_KEYED}.`
+ );
+
+ await closeBrowserAction(extension1);
+
+ await extension1.unload();
+ await extension2.unload();
+});
+
+add_task(async function testBrowserActionTelemetryResults() {
+ let extensionOptions = {
+ manifest: {
+ browser_specific_settings: {
+ gecko: { id: EXTENSION_ID1 },
+ },
+ browser_action: {
+ default_popup: "popup.html",
+ default_area: "navbar",
+ browser_style: true,
+ },
+ },
+
+ files: {
+ "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><div></div></body></html>`,
+ },
+ };
+ let extension = ExtensionTestUtils.loadExtension(extensionOptions);
+
+ let histogram = Services.telemetry.getHistogramById(RESULT_HISTOGRAM);
+ let histogramKeyed = Services.telemetry.getKeyedHistogramById(
+ RESULT_HISTOGRAM_KEYED
+ );
+
+ histogram.clear();
+ histogramKeyed.clear();
+
+ is(
+ histogram.snapshot().sum,
+ 0,
+ `No data recorded for histogram: ${RESULT_HISTOGRAM}.`
+ );
+ is(
+ Object.keys(histogramKeyed).length,
+ 0,
+ `No data recorded for histogram: ${RESULT_HISTOGRAM_KEYED}.`
+ );
+
+ await extension.startup();
+
+ // Make sure the mouse isn't hovering over the browserAction widget to start.
+ EventUtils.synthesizeMouseAtCenter(
+ gURLBar.textbox,
+ { type: "mouseover" },
+ window
+ );
+
+ let widget = getBrowserActionWidget(extension).forWindow(window);
+
+ // Hover the mouse over the browserAction widget and then move it away.
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mouseover", button: 0 },
+ window
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mouseout", button: 0 },
+ window
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ document.documentElement,
+ { type: "mousemove" },
+ window
+ );
+
+ assertOnlyOneTypeSet(histogram.snapshot(), "clearAfterHover");
+
+ let keyedSnapshot = histogramKeyed.snapshot();
+ Assert.deepEqual(
+ Object.keys(keyedSnapshot),
+ [EXTENSION_ID1],
+ `Data recorded for histogram: ${RESULT_HISTOGRAM_KEYED}.`
+ );
+ assertOnlyOneTypeSet(keyedSnapshot[EXTENSION_ID1], "clearAfterHover");
+
+ histogram.clear();
+ histogramKeyed.clear();
+
+ // TODO: Create a test for cancel after mousedown.
+ // This is tricky because calling mouseout after mousedown causes a
+ // "Hover" event to be added to the queue in ext-browserAction.js.
+
+ clickBrowserAction(extension);
+ await awaitExtensionPanel(extension);
+
+ assertOnlyOneTypeSet(histogram.snapshot(), "popupShown");
+
+ keyedSnapshot = histogramKeyed.snapshot();
+ Assert.deepEqual(
+ Object.keys(keyedSnapshot),
+ [EXTENSION_ID1],
+ `Data recorded for histogram: ${RESULT_HISTOGRAM_KEYED}.`
+ );
+ assertOnlyOneTypeSet(keyedSnapshot[EXTENSION_ID1], "popupShown");
+
+ await closeBrowserAction(extension);
+
+ await extension.unload();
+});