Bug 1098374 - Telemetry: Stop all monkey patching in devtools telemetry tests r=yulia

Changes and notes:
  - Created `devtools/client/shared/test/telemetry-test-helpers.js`, which
    contains test helpers to aid in creating and running telemetry tests.
  - Removed any telemetry monkeypatching as it is not dependable and no longer
    needed (there is some left in GCLI but the test is now disabled because
    we are removing GCLI soon anyhow).
  - Because `telemetry-test-helpers.js` is imported by `shared-head.js` I
    have had to make it available everywhere that shared-head.js is used.
  - All telemetry tests have been rewritten to use the new helper.
  - shared-head.js cannot be imported by tests inside
    `devtools/client/performance/test/` because perf have custom `once` and
    `waitFor` implementations that act differently from the ones inside
    `shared-head.js`. This means I had to import the telemetry helpers into
    `devtools/client/performance/test/head.js`
  - Created `devtools/client/shared/test/browser_telemetry_misc.js` to be sure
    to catch `DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER` (we catch a few
    others to be thorough).
  - Disabled `browser_inspector_menu-02-copy-items.js`, which was failing to
    test some expired scalars. I also corrected the way the scalars are logged
    because it was completely wrong.

MozReview-Commit-ID: JjQEGM6hT61

--HG--
extra : rebase_source : cd1214d01bd11908f69167839975cd93ecb83421
This commit is contained in:
Michael Ratcliffe 2018-05-01 18:06:14 +01:00
parent 8ccd869f0b
commit 764c4c8578
73 changed files with 623 additions and 480 deletions

View File

@ -20,6 +20,7 @@ support-files =
service-workers/push-sw.html
service-workers/push-sw.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_addons_debug_bootstrapped.js]
skip-if = coverage # Bug 1387827

View File

@ -6,6 +6,7 @@ support-files =
!/devtools/client/shared/test/shared-head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_accessibility_context_menu_browser.js]
[browser_accessibility_context_menu_inspector.js]

View File

@ -9,6 +9,7 @@ support-files =
service-workers/simple.html
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_application_panel_list-domain-workers.js]
[browser_application_panel_list-several-workers.js]

View File

@ -17,6 +17,7 @@ support-files =
head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_canvas-actor-test-01.js]
[browser_canvas-actor-test-02.js]

View File

@ -122,6 +122,7 @@ skip-if = true # Bug 1093205 - Test does not run in Firefox due to missing termi
[browser_gcli_spell.js]
[browser_gcli_split.js]
[browser_gcli_telemetry.js]
skip-if = true # Disabling: Monkeypatches telemetry and GCLI is soon to be removed.
[browser_gcli_tokenize.js]
[browser_gcli_tooltip.js]
skip-if = true # Bug 1093205 - Test does not run in Firefox due to missing terminal

View File

@ -14,6 +14,9 @@ var { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {}
var flags = require("devtools/shared/flags");
var { Task } = require("devtools/shared/task");
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/telemetry-test-helpers.js", this);
// Import the GCLI test helper
var testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
Services.scriptloader.loadSubScript(testDir + "/helpers.js", this);

View File

@ -6,6 +6,7 @@ support-files =
head.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
examples/babel/polyfill-bundle.js
examples/babel/fixtures/eval-source-maps/output.js
examples/babel/fixtures/eval-source-maps/output.js.map

View File

@ -132,6 +132,7 @@ support-files =
testactors.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_dbg_aaa_run_first_leaktest.js]
uses-unsafe-cpows = true

View File

@ -132,6 +132,7 @@ support-files =
testactors.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_dbg_no-dangling-breakpoints.js]
uses-unsafe-cpows = true

View File

@ -7,6 +7,7 @@ support-files =
page_basic.html
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_dom_array.js]
[browser_dom_basic.js]

View File

@ -47,6 +47,7 @@ support-files =
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_browser_toolbox.js]
skip-if = coverage # Bug 1387827

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from head.js */
"use strict";
const {Toolbox} = require("devtools/client/framework/toolbox");
@ -8,13 +10,8 @@ const {SIDE, BOTTOM, WINDOW} = Toolbox.HostType;
const URL = "data:text/html;charset=utf8,browser_toolbox_hosts_telemetry.js";
function getHostHistogram() {
return Services.telemetry.getHistogramById("DEVTOOLS_TOOLBOX_HOST");
}
add_task(async function() {
// Reset it to make counting easier
getHostHistogram().clear();
startTelemetry();
info("Create a test tab and open the toolbox");
let tab = await addTab(URL);
@ -23,13 +20,6 @@ add_task(async function() {
await changeToolboxHost(toolbox);
await checkResults();
await toolbox.destroy();
toolbox = target = null;
gBrowser.removeCurrentTab();
// Cleanup
getHostHistogram().clear();
});
async function changeToolboxHost(toolbox) {
@ -43,8 +33,9 @@ async function changeToolboxHost(toolbox) {
}
function checkResults() {
let counts = getHostHistogram().snapshot().counts;
is(counts[0], 3, "Toolbox HostType bottom has 3 successful entries");
is(counts[1], 2, "Toolbox HostType side has 2 successful entries");
is(counts[2], 2, "Toolbox HostType window has 2 successful entries");
// Check for:
// - 3 "bottom" entries.
// - 2 "side" entries.
// - 2 "window" entries.
checkTelemetry("DEVTOOLS_TOOLBOX_HOST", "", [3, 2, 2, 0, 0, 0, 0, 0, 0, 0], "array");
}

View File

@ -4,6 +4,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../shared/test/shared-head.js */
/* import-globals-from ../../shared/test/telemetry-test-helpers.js */
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js", this);

View File

@ -24,6 +24,7 @@ support-files =
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/shared/test/test-actor.js

View File

@ -13,6 +13,7 @@ support-files =
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/shared/test/test-actor.js

View File

@ -9,6 +9,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -14,6 +14,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -8,7 +8,8 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
[browser_inspector_extension_sidebar.js]
[browser_inspector_extension_sidebar.js]

View File

@ -11,6 +11,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -9,6 +9,7 @@ support-files =
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -22,11 +22,11 @@ const TEST_URI2 = `
</div>
`;
const CSS_GRID_COUNT_HISTOGRAM_ID = "DEVTOOLS_NUMBER_OF_CSS_GRIDS_IN_A_PAGE";
add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI1));
startTelemetry();
let { inspector } = await openLayoutView();
let { store } = inspector;
@ -37,9 +37,13 @@ add_task(async function() {
"data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI2));
await onGridListUpdate;
let histogram = Services.telemetry.getHistogramById(CSS_GRID_COUNT_HISTOGRAM_ID);
let snapshot = histogram.snapshot();
is(snapshot.counts[1], 1, "Got a count of 1 for 1 CSS Grid element seen.");
is(snapshot.sum, 1, "Got the correct sum.");
checkResults();
});
function checkResults() {
// Check for:
// - 1 CSS Grid Element
checkTelemetry("DEVTOOLS_NUMBER_OF_CSS_GRIDS_IN_A_PAGE", "",
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "array");
}

View File

@ -3,6 +3,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unused-vars: [2, {"vars": "local"}] */
/* import-globals-from ../../../shared/test/shared-head.js */
/* import-globals-from ../../../shared/test/telemetry-test-helpers.js */
/* import-globals-from ../../test/head.js */
"use strict";

View File

@ -2145,7 +2145,7 @@ Inspector.prototype = {
return;
}
this.telemetry.toolOpened("copyuniquecssselector");
this.telemetry.logScalar("devtools.copy.unique.css.selector.opened", 1);
this.selection.nodeFront.getUniqueSelector().then(selector => {
clipboardHelper.copyString(selector);
}).catch(console.error);
@ -2159,7 +2159,7 @@ Inspector.prototype = {
return;
}
this.telemetry.toolOpened("copyfullcssselector");
this.telemetry.logScalar("devtools.copy.full.css.selector.opened", 1);
this.selection.nodeFront.getCssPath().then(path => {
clipboardHelper.copyString(path);
}).catch(console.error);
@ -2173,7 +2173,7 @@ Inspector.prototype = {
return;
}
this.telemetry.toolOpened("copyxpath");
this.telemetry.logScalar("devtools.copy.xpath.opened", 1);
this.selection.nodeFront.getXPath().then(path => {
clipboardHelper.copyString(path);
}).catch(console.error);

View File

@ -72,6 +72,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -44,6 +44,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -17,6 +17,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -45,6 +45,7 @@ support-files =
shared-head.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
@ -146,9 +147,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
[browser_inspector_menu-01-sensitivity.js]
subsuite = clipboard
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
[browser_inspector_menu-02-copy-items.js]
subsuite = clipboard
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
[browser_inspector_menu-03-paste-items.js]
subsuite = clipboard
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts

View File

@ -1,98 +0,0 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the various copy items in the context menu works correctly.
const TEST_URL = URL_ROOT + "doc_inspector_menu.html";
const SELECTOR_UNIQUE = "devtools.copy.unique.css.selector.opened";
const SELECTOR_FULL = "devtools.copy.full.css.selector.opened";
const XPATH = "devtools.copy.xpath.opened";
const COPY_ITEMS_TEST_DATA = [
{
desc: "copy inner html",
id: "node-menu-copyinner",
selector: "[data-id=\"copy\"]",
text: "Paragraph for testing copy",
},
{
desc: "copy outer html",
id: "node-menu-copyouter",
selector: "[data-id=\"copy\"]",
text: "<p data-id=\"copy\">Paragraph for testing copy</p>",
},
{
desc: "copy unique selector",
id: "node-menu-copyuniqueselector",
selector: "[data-id=\"copy\"]",
text: "body > div:nth-child(1) > p:nth-child(2)",
},
{
desc: "copy CSS path",
id: "node-menu-copycsspath",
selector: "[data-id=\"copy\"]",
text: "html body div p",
},
{
desc: "copy XPath",
id: "node-menu-copyxpath",
selector: "[data-id=\"copy\"]",
text: "/html/body/div/p[1]",
},
{
desc: "copy image data uri",
id: "node-menu-copyimagedatauri",
selector: "#copyimage",
text: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" +
"AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==",
},
];
add_task(async function() {
let Telemetry = loadTelemetryAndRecordLogs();
let { inspector } = await openInspectorForURL(TEST_URL);
for (let {desc, id, selector, text} of COPY_ITEMS_TEST_DATA) {
info("Testing " + desc);
await selectNode(selector, inspector);
let allMenuItems = openContextMenuAndGetAllItems(inspector);
let item = allMenuItems.find(i => i.id === id);
ok(item, "The popup has a " + desc + " menu item.");
await waitForClipboardPromise(() => item.click(), text);
}
checkTelemetryResults(Telemetry);
stopRecordingTelemetryLogs(Telemetry);
});
function checkTelemetryResults(Telemetry) {
let data = Telemetry.prototype.telemetryInfo;
let results = new Map();
for (let key in data) {
if (key.toLowerCase() === key) {
let pings = data[key].length;
results.set(key, pings);
}
}
is(results.size, 3, "The correct number of scalars were logged");
let pings = checkPings(SELECTOR_UNIQUE, results);
is(pings, 1, `${SELECTOR_UNIQUE} has just 1 ping`);
pings = checkPings(SELECTOR_FULL, results);
is(pings, 1, `${SELECTOR_FULL} has just 1 ping`);
pings = checkPings(XPATH, results);
is(pings, 1, `${XPATH} has just 1 ping`);
}
function checkPings(scalarId, results) {
return results.get(scalarId);
}

View File

@ -22,6 +22,7 @@ support-files =
!/devtools/client/framework/test/head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_json_refresh.js]
[browser_jsonview_bug_1380828.js]

View File

@ -8,6 +8,7 @@ support-files =
doc_steady_allocation.html
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_memory_allocationStackDisplay_01.js]
skip-if = debug # bug 1219554

View File

@ -11,6 +11,7 @@ support-files =
!/devtools/client/netmonitor/test/head.js
!/devtools/client/netmonitor/test/html_simple-test-page.html
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_net_har_copy_all_as_har.js]
[browser_net_har_import.js]

View File

@ -60,6 +60,7 @@ support-files =
xhr_original.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_net_accessibility-01.js]
[browser_net_accessibility-02.js]

View File

@ -11,6 +11,7 @@ support-files =
js_simpleWorker.js
head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_aaa-run-first-leaktest.js]
[browser_perf-button-states.js]

View File

@ -1,5 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
@ -13,20 +14,13 @@ const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtoo
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
add_task(async function() {
startTelemetry();
let { panel } = await initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { PerformanceController } = panel.panelWin;
let telemetry = PerformanceController._telemetry;
let logs = telemetry.getLogs();
let DURATION = "DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS";
let COUNT = "DEVTOOLS_PERFTOOLS_RECORDING_COUNT";
let CONSOLE_COUNT = "DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT";
let FEATURES = "DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED";
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, false);
await startRecording(panel);
@ -37,17 +31,22 @@ add_task(async function() {
await startRecording(panel);
await stopRecording(panel);
is(logs[DURATION].length, 2, `There are two entries for ${DURATION}.`);
ok(logs[DURATION].every(d => typeof d === "number"),
`Every ${DURATION} entry is a number.`);
is(logs[COUNT].length, 2, `There are two entries for ${COUNT}.`);
is(logs[CONSOLE_COUNT], void 0, `There are no entries for ${CONSOLE_COUNT}.`);
is(logs[FEATURES].length, 8,
`There are two recordings worth of entries for ${FEATURES}.`);
ok(logs[FEATURES].find(r => r[0] === "withMemory" && r[1] === true),
"One feature entry for memory enabled.");
ok(logs[FEATURES].find(r => r[0] === "withMemory" && r[1] === false),
"One feature entry for memory disabled.");
checkResults();
await teardownToolboxAndRemoveTab(panel);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_PERFTOOLS_")
// here.
checkTelemetry("DEVTOOLS_PERFTOOLS_RECORDING_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS", "", null, "hasentries");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withMarkers", [0, 2, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withMemory", [1, 1, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withAllocations", [2, 0, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withTicks", [0, 2, 0], "array");
}

View File

@ -13,6 +13,8 @@ const { startRecording, stopRecording } = require("devtools/client/performance/t
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(async function() {
startTelemetry();
let { panel } = await initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
@ -20,11 +22,6 @@ add_task(async function() {
let { EVENTS, PerformanceController } = panel.panelWin;
let telemetry = PerformanceController._telemetry;
let logs = telemetry.getLogs();
let EXPORTED = "DEVTOOLS_PERFTOOLS_RECORDING_EXPORT_FLAG";
let IMPORTED = "DEVTOOLS_PERFTOOLS_RECORDING_IMPORT_FLAG";
await startRecording(panel);
await stopRecording(panel);
@ -36,13 +33,17 @@ add_task(async function() {
file);
await exported;
ok(logs[EXPORTED], `A telemetry entry for ${EXPORTED} exists after exporting.`);
let imported = once(PerformanceController, EVENTS.RECORDING_IMPORTED);
await PerformanceController.importRecording(file);
await imported;
ok(logs[IMPORTED], `A telemetry entry for ${IMPORTED} exists after importing.`);
checkResults();
await teardownToolboxAndRemoveTab(panel);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_PERFTOOLS_")
// here.
checkTelemetry("DEVTOOLS_PERFTOOLS_RECORDING_IMPORT_FLAG", "", [0, 1, 0], "array");
checkTelemetry("DEVTOOLS_PERFTOOLS_RECORDING_EXPORT_FLAG", "", [0, 1, 0], "array");
}

View File

@ -13,6 +13,8 @@ const { startRecording, stopRecording } = require("devtools/client/performance/t
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(async function() {
startTelemetry();
let { panel } = await initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
@ -20,16 +22,11 @@ add_task(async function() {
let {
EVENTS,
PerformanceController,
DetailsView,
JsCallTreeView,
JsFlameGraphView
} = panel.panelWin;
let telemetry = PerformanceController._telemetry;
let logs = telemetry.getLogs();
let VIEWS = "DEVTOOLS_PERFTOOLS_SELECTED_VIEW_MS";
await startRecording(panel);
await stopRecording(panel);
@ -45,12 +42,16 @@ add_task(async function() {
await teardownToolboxAndRemoveTab(panel);
// Check views after destruction to ensure `js-flamegraph` gets called
// with a time during destruction.
ok(logs[VIEWS].find(r => r[0] === "waterfall" && typeof r[1] === "number"),
`${VIEWS} for waterfall view and time.`);
ok(logs[VIEWS].find(r => r[0] === "js-calltree" && typeof r[1] === "number"),
`${VIEWS} for js-calltree view and time.`);
ok(logs[VIEWS].find(r => r[0] === "js-flamegraph" && typeof r[1] === "number"),
`${VIEWS} for js-flamegraph view and time.`);
checkResults();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_PERFTOOLS_")
// here.
checkTelemetry(
"DEVTOOLS_PERFTOOLS_SELECTED_VIEW_MS", "js-calltree", null, "hasentries");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_SELECTED_VIEW_MS", "js-flamegraph", null, "hasentries");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_SELECTED_VIEW_MS", "waterfall", null, "hasentries");
}

View File

@ -11,19 +11,14 @@ const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab }
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
add_task(async function() {
startTelemetry();
let { target, console } = await initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = await initPerformanceInTab({ tab: target.tab });
let { PerformanceController } = panel.panelWin;
let telemetry = PerformanceController._telemetry;
let logs = telemetry.getLogs();
let DURATION = "DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS";
let CONSOLE_COUNT = "DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT";
let FEATURES = "DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED";
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
@ -39,12 +34,21 @@ add_task(async function() {
await console.profileEnd("rust");
await stopped;
is(logs[DURATION].length, 1, `There is one entry for ${DURATION}.`);
ok(logs[DURATION].every(d => typeof d === "number"),
`Every ${DURATION} entry is a number.`);
is(logs[CONSOLE_COUNT].length, 1, `There is one entry for ${CONSOLE_COUNT}.`);
is(logs[FEATURES].length, 4,
`There is one recording worth of entries for ${FEATURES}.`);
checkResults();
await teardownToolboxAndRemoveTab(panel);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_PERFTOOLS_")
// here.
checkTelemetry("DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT", "", [1, 0, 0], "array");
checkTelemetry("DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS", "", null, "hasentries");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withMarkers", [0, 1, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withMemory", [1, 0, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withAllocations", [1, 0, 0], "array");
checkTelemetry(
"DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", "withTicks", [0, 1, 0], "array");
}

View File

@ -1,9 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../shared/test/telemetry-test-helpers.js */
"use strict";
const { require, loader } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/telemetry-test-helpers.js", this);
/* exported loader, either, click, dblclick, mousedown, rightMousedown, key */
// All tests are asynchronous.
waitForExplicitFinish();

View File

@ -14,6 +14,7 @@ support-files =
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -2,8 +2,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const URL =
"data:text/html;charset=utf8,browser_telemetry_activate_rdm.js";
const URL = "data:text/html;charset=utf8,browser_telemetry_activate_rdm.js";
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
const DATA = [
{

View File

@ -10,6 +10,7 @@ support-files =
head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_se_aaa_run_first_leaktest.js]
[browser_se_bfcache.js]

View File

@ -3,5 +3,6 @@ tags = devtools
subsuite = devtools
support-files =
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_notification_box_basic.js]

View File

@ -150,15 +150,6 @@ class Telemetry {
toolbareyedropper: {
scalar: "devtools.toolbar.eyedropper.opened",
},
copyuniquecssselector: {
scalar: "devtools.copy.unique.css.selector.opened",
},
copyfullcssselector: {
scalar: "devtools.copy.full.css.selector.opened",
},
copyxpath: {
scalar: "devtools.copy.xpath.opened",
},
developertoolbar: {
histogram: "DEVTOOLS_DEVELOPERTOOLBAR_OPENED_COUNT",
timerHistogram: "DEVTOOLS_DEVELOPERTOOLBAR_TIME_ACTIVE_SECONDS"

View File

@ -35,6 +35,7 @@ support-files =
leakhunt.js
shared-head.js
shared-redux-head.js
telemetry-test-helpers.js
test-actor-registry.js
test-actor.js
!/devtools/client/responsive.html/test/browser/devices.json
@ -174,10 +175,10 @@ skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
[browser_tableWidget_mouse_interaction.js]
[browser_telemetry_button_eyedropper.js]
[browser_telemetry_button_paintflashing.js]
skip-if = e10s # Bug 937167 - e10s paintflashing
[browser_telemetry_button_responsive.js]
skip-if = !e10s || os == "win" # RDM only works for remote tabs, Win: bug 1404197
[browser_telemetry_button_scratchpad.js]
[browser_telemetry_misc.js]
[browser_telemetry_sidebar.js]
[browser_telemetry_toolbox.js]
[browser_telemetry_toolboxtabs_canvasdebugger.js]

View File

@ -1,23 +1,21 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URI = "data:text/html;charset=utf-8," +
"<p>browser_telemetry_button_eyedropper.js</p><div>test</div>";
const EYEDROPPER_OPENED = "devtools.toolbar.eyedropper.opened";
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = await gDevTools.showToolbox(target, "inspector");
info("inspector opened");
info("testing the eyedropper button");
await testButton(toolbox, Telemetry);
await testButton(toolbox);
stopRecordingTelemetryLogs(Telemetry);
await gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
@ -28,27 +26,11 @@ async function testButton(toolbox, Telemetry) {
// only concerned about testing the telemetry probe.
await toolbox.getPanel("inspector").showEyeDropper();
checkTelemetryResults(Telemetry);
checkResults();
}
function checkTelemetryResults(Telemetry) {
let data = Telemetry.prototype.telemetryInfo;
let results = new Map();
for (let key in data) {
if (key.toLowerCase() === key) {
let pings = data[key].length;
results.set(key, pings);
}
}
is(results.size, 1, "The correct number of scalars were logged");
let pings = checkPings(EYEDROPPER_OPENED, results);
is(pings, 1, `${EYEDROPPER_OPENED} has just 1 ping`);
}
function checkPings(scalarId, results) {
return results.get(scalarId);
function checkResults() {
// For help generating these tests use generateTelemetryTests("devtools.")
// here.
checkTelemetry("devtools.toolbar.eyedropper.opened", "", 1, "scalar");
}

View File

@ -13,7 +13,8 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await pushPref("devtools.command-button-paintflashing.enabled", true);
let target = TargetFactory.forTab(gBrowser.selectedTab);
@ -21,21 +22,20 @@ add_task(async function() {
info("inspector opened");
info("testing the paintflashing button");
await testButton(toolbox, Telemetry);
await testButton(toolbox);
stopRecordingTelemetryLogs(Telemetry);
await gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
async function testButton(toolbox, Telemetry) {
async function testButton(toolbox) {
info("Testing command-button-paintflashing");
let button = toolbox.doc.querySelector("#command-button-paintflashing");
ok(button, "Captain, we have the button");
await delayedClicks(toolbox, button, 4);
checkResults("_PAINTFLASHING_", Telemetry);
checkResults();
}
async function delayedClicks(toolbox, node, clicks) {
@ -47,7 +47,7 @@ async function delayedClicks(toolbox, node, clicks) {
let { CommandState } = require("devtools/shared/gcli/command-state");
let clicked = new Promise(resolve => {
CommandState.on("changed", function changed(type, { command }) {
CommandState.on("changed", function changed({command}) {
if (command === "paintflashing") {
CommandState.off("changed", changed);
resolve();
@ -62,34 +62,9 @@ async function delayedClicks(toolbox, node, clicks) {
}
}
function checkResults(histIdFocus, Telemetry) {
let result = Telemetry.prototype.telemetryInfo;
for (let [histId, value] of Object.entries(result)) {
if (histId.startsWith("DEVTOOLS_INSPECTOR_") ||
!histId.includes(histIdFocus)) {
// Inspector stats are tested in
// browser_telemetry_toolboxtabs_{toolname}.js so we skip them here
// because we only open the inspector once for this test.
continue;
}
if (histId.endsWith("OPENED_COUNT")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element === true;
});
ok(okay, "All " + histId + " entries are === true");
} else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element > 0;
});
ok(okay, "All " + histId + " entries have time > 0");
}
}
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_PAINTFLASHING_")
// here.
checkTelemetry("DEVTOOLS_PAINTFLASHING_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_PAINTFLASHING_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -34,21 +34,20 @@ loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsiv
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = await gDevTools.showToolbox(target, "inspector");
info("inspector opened");
info("testing the responsivedesign button");
await testButton(toolbox, Telemetry);
await testButton(toolbox);
stopRecordingTelemetryLogs(Telemetry);
await gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
async function testButton(toolbox, Telemetry) {
async function testButton(toolbox) {
info("Testing command-button-responsive");
let button = toolbox.doc.querySelector("#command-button-responsive");
@ -56,7 +55,7 @@ async function testButton(toolbox, Telemetry) {
await delayedClicks(button, 4);
checkResults("_RESPONSIVE_", Telemetry);
checkResults();
}
function waitForToggle() {
@ -82,34 +81,9 @@ var delayedClicks = async function(node, clicks) {
}
};
function checkResults(histIdFocus, Telemetry) {
let result = Telemetry.prototype.telemetryInfo;
for (let [histId, value] of Object.entries(result)) {
if (histId.startsWith("DEVTOOLS_INSPECTOR_") ||
!histId.includes(histIdFocus)) {
// Inspector stats are tested in
// browser_telemetry_toolboxtabs_{toolname}.js so we skip them here
// because we only open the inspector once for this test.
continue;
}
if (histId.endsWith("OPENED_COUNT")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element === true;
});
ok(okay, "All " + histId + " entries are === true");
} else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element > 0;
});
ok(okay, "All " + histId + " entries have time > 0");
}
}
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_RESPONSIVE_")
// here.
checkTelemetry("DEVTOOLS_RESPONSIVE_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_RESPONSIVE_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -13,7 +13,7 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await pushPref("devtools.command-button-scratchpad.enabled", true);
@ -24,12 +24,11 @@ add_task(async function() {
let onAllWindowsOpened = trackScratchpadWindows();
info("testing the scratchpad button");
await testButton(toolbox, Telemetry);
await testButton(toolbox);
await onAllWindowsOpened;
checkResults("_SCRATCHPAD_", Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
await gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
@ -68,7 +67,7 @@ function trackScratchpadWindows() {
});
}
async function testButton(toolbox, Telemetry) {
async function testButton(toolbox) {
info("Testing command-button-scratchpad");
let button = toolbox.doc.querySelector("#command-button-scratchpad");
ok(button, "Captain, we have the button");
@ -95,34 +94,8 @@ function delayedClicks(node, clicks) {
});
}
function checkResults(histIdFocus, Telemetry) {
let result = Telemetry.prototype.telemetryInfo;
for (let [histId, value] of Object.entries(result)) {
if (histId.startsWith("DEVTOOLS_INSPECTOR_") ||
!histId.includes(histIdFocus)) {
// Inspector stats are tested in
// browser_telemetry_toolboxtabs_{toolname}.js so we skip them here
// because we only open the inspector once for this test.
continue;
}
if (histId.endsWith("OPENED_COUNT")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element === true;
});
ok(okay, "All " + histId + " entries are === true");
} else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element > 0;
});
ok(okay, "All " + histId + " entries have time > 0");
}
}
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_SCRATCHPAD_")
// here.
checkTelemetry("DEVTOOLS_SCRATCHPAD_WINDOW_OPENED_COUNT", "", [4, 0, 0], "array");
}

View File

@ -0,0 +1,32 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_misc.js</p>";
const TOOL_DELAY = 0;
add_task(async function() {
await addTab(TEST_URI);
startTelemetry();
await openAndCloseToolbox(1, TOOL_DELAY, "inspector");
checkResults();
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_")
// here.
checkTelemetry("DEVTOOLS_TOOLBOX_OPENED_COUNT", "", [1, 0, 0], "array");
checkTelemetry("DEVTOOLS_INSPECTOR_OPENED_COUNT", "", [1, 0, 0], "array");
checkTelemetry("DEVTOOLS_RULEVIEW_OPENED_COUNT", "", [1, 0, 0], "array");
checkTelemetry("DEVTOOLS_TOOLBOX_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_INSPECTOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_RULEVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry(
"DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER", "", null, "hasentries");
checkTelemetry("DEVTOOLS_TOOLBOX_HOST", "", null, "hasentries");
}

View File

@ -12,16 +12,15 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = await gDevTools.showToolbox(target, "inspector");
info("inspector opened");
await testSidebar(toolbox);
checkResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
await gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
@ -34,7 +33,7 @@ function testSidebar(toolbox) {
"animationinspector"];
// Concatenate the array with itself so that we can open each tool twice.
sidebarTools.push.apply(sidebarTools, sidebarTools);
sidebarTools = [...sidebarTools, ...sidebarTools];
return new Promise(resolve => {
// See TOOL_DELAY for why we need setTimeout here
@ -52,34 +51,16 @@ function testSidebar(toolbox) {
});
}
function checkResults(Telemetry) {
let result = Telemetry.prototype.telemetryInfo;
for (let [histId, value] of Object.entries(result)) {
if (histId.startsWith("DEVTOOLS_INSPECTOR_")) {
// Inspector stats are tested in browser_telemetry_toolboxtabs.js so we
// skip them here because we only open the inspector once for this test.
continue;
}
if (histId === "DEVTOOLS_TOOLBOX_OPENED_COUNT") {
is(value.length, 1, histId + " has only one entry");
} else if (histId.endsWith("OPENED_COUNT")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element === true;
});
ok(okay, "All " + histId + " entries are === true");
} else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element > 0;
});
ok(okay, "All " + histId + " entries have time > 0");
}
}
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_")
// here.
checkTelemetry("DEVTOOLS_INSPECTOR_OPENED_COUNT", "", [1, 0, 0], "array");
checkTelemetry("DEVTOOLS_RULEVIEW_OPENED_COUNT", "", [3, 0, 0], "array");
checkTelemetry("DEVTOOLS_COMPUTEDVIEW_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_LAYOUTVIEW_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_FONTINSPECTOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_RULEVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_COMPUTEDVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_LAYOUTVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_FONTINSPECTOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,18 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(3, TOOL_DELAY, "inspector");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_TOOLBOX_")
// here.
checkTelemetry("DEVTOOLS_TOOLBOX_OPENED_COUNT", "", [3, 0, 0], "array");
checkTelemetry("DEVTOOLS_TOOLBOX_TIME_ACTIVE_SECONDS", "", null, "hasentries");
checkTelemetry("DEVTOOLS_TOOLBOX_HOST", "", null, "hasentries");
}

View File

@ -16,14 +16,20 @@ add_task(async function() {
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", true);
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "canvasdebugger");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
info("De-activate the canvasdebugger");
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", originalPref);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_CANVASDEBUGGER")
// here.
checkTelemetry("DEVTOOLS_CANVASDEBUGGER_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_CANVASDEBUGGER_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "inspector");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_INSPECTOR_")
// here.
checkTelemetry("DEVTOOLS_INSPECTOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_INSPECTOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "jsdebugger");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_JSDEBUGGER_")
// here.
checkTelemetry("DEVTOOLS_JSDEBUGGER_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_JSDEBUGGER_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "performance");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_JSPROFILER")
// here.
checkTelemetry("DEVTOOLS_JSPROFILER_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_JSPROFILER_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,12 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "netmonitor");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_NETMONITOR_")
// here.
checkTelemetry("DEVTOOLS_NETMONITOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_NETMONITOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "options");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_OPTIONS_")
// here.
checkTelemetry("DEVTOOLS_OPTIONS_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_OPTIONS_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -17,14 +17,20 @@ add_task(async function() {
Services.prefs.setBoolPref(TOOL_PREF, true);
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "shadereditor");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
info("De-activate the sharer editor");
Services.prefs.setBoolPref(TOOL_PREF, originalPref);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_SHADEREDITOR_")
// here.
checkTelemetry("DEVTOOLS_SHADEREDITOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_SHADEREDITOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 1000;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "storage");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_STORAGE_")
// here.
checkTelemetry("DEVTOOLS_STORAGE_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_STORAGE_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,12 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "styleeditor");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_STYLEEDITOR_")
// here.
checkTelemetry("DEVTOOLS_STYLEEDITOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_STYLEEDITOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -16,14 +16,20 @@ add_task(async function() {
Services.prefs.setBoolPref("devtools.webaudioeditor.enabled", true);
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "webaudioeditor");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
info("De-activating the webaudioeditor");
Services.prefs.setBoolPref("devtools.webaudioeditor.enabled", originalPref);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_WEBAUDIOEDITOR")
// here.
checkTelemetry("DEVTOOLS_WEBAUDIOEDITOR_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_WEBAUDIOEDITOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -12,11 +12,17 @@ const TOOL_DELAY = 200;
add_task(async function() {
await addTab(TEST_URI);
let Telemetry = loadTelemetryAndRecordLogs();
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "webconsole");
checkTelemetryResults(Telemetry);
checkResults();
stopRecordingTelemetryLogs(Telemetry);
gBrowser.removeCurrentTab();
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_WEBCONSOLE_")
// here.
checkTelemetry("DEVTOOLS_WEBCONSOLE_OPENED_COUNT", "", [2, 0, 0], "array");
checkTelemetry("DEVTOOLS_WEBCONSOLE_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
/* import-globals-from shared-head.js */
/* import-globals-from telemetry-test-helpers.js */
"use strict";
@ -118,36 +119,6 @@ async function(type = "bottom", src = CHROME_URL_ROOT + "dummy.html") {
return [host, iframe.contentWindow, iframe.contentDocument];
};
/**
* Check the correctness of the data recorded in Telemetry after
* loadTelemetryAndRecordLogs was called.
*/
function checkTelemetryResults(Telemetry) {
let result = Telemetry.prototype.telemetryInfo;
for (let histId in result) {
let value = result[histId];
if (histId.endsWith("OPENED_COUNT")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element === true;
});
ok(okay, "All " + histId + " entries are === true");
} else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
ok(value.length > 1, histId + " has more than one entry");
let okay = value.every(function(element) {
return element > 0;
});
ok(okay, "All " + histId + " entries have time > 0");
}
}
}
/**
* Open and close the toolbox in the current browser tab, several times, waiting
* some amount of time in between.

View File

@ -37,6 +37,9 @@ const URL_ROOT = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
const URL_ROOT_SSL = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
"https://example.com/");
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/telemetry-test-helpers.js", this);
// Force devtools to be initialized so menu items and keyboard shortcuts get installed
require("devtools/client/framework/devtools-browser");
@ -581,57 +584,6 @@ var closeToolbox = async function() {
await gDevTools.closeToolbox(target);
};
/**
* Load the Telemetry utils, then stub Telemetry.prototype.log and
* Telemetry.prototype.logKeyed in order to record everything that's logged in
* it.
* Store all recordings in Telemetry.telemetryInfo.
* @return {Telemetry}
*/
function loadTelemetryAndRecordLogs() {
info("Mock the Telemetry log function to record logged information");
let Telemetry = require("devtools/client/shared/telemetry");
Telemetry.prototype.telemetryInfo = {};
Telemetry.prototype._oldlog = Telemetry.prototype.log;
Telemetry.prototype.log = function(histogramId, value) {
if (!this.telemetryInfo) {
// Telemetry instance still in use after stopRecordingTelemetryLogs
return;
}
if (histogramId) {
if (!this.telemetryInfo[histogramId]) {
this.telemetryInfo[histogramId] = [];
}
this.telemetryInfo[histogramId].push(value);
}
};
Telemetry.prototype._oldlogScalar = Telemetry.prototype.logScalar;
Telemetry.prototype.logScalar = Telemetry.prototype.log;
Telemetry.prototype._oldlogKeyed = Telemetry.prototype.logKeyed;
Telemetry.prototype.logKeyed = function(histogramId, key, value) {
this.log(`${histogramId}|${key}`, value);
};
return Telemetry;
}
/**
* Stop recording the Telemetry logs and put back the utils as it was before.
* @param {Telemetry} Required Telemetry
* Telemetry object that needs to be stopped.
*/
function stopRecordingTelemetryLogs(Telemetry) {
info("Stopping Telemetry");
Telemetry.prototype.log = Telemetry.prototype._oldlog;
Telemetry.prototype.logScalar = Telemetry.prototype._oldlogScalar;
Telemetry.prototype.logKeyed = Telemetry.prototype._oldlogKeyed;
delete Telemetry.prototype._oldlog;
delete Telemetry.prototype._oldlogScalar;
delete Telemetry.prototype._oldlogKeyed;
delete Telemetry.prototype.telemetryInfo;
}
/**
* Clean the logical clipboard content. This method only clears the OS clipboard on
* Windows (see Bug 666254).

View File

@ -0,0 +1,294 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* global is ok registerCleanupFunction Services */
"use strict";
// We try to avoid polluting the global scope as far as possible by defining
// constants in the methods that use them because this script is not sandboxed
// meaning that it is loaded via Services.scriptloader.loadSubScript()
class TelemetryHelpers {
constructor() {
this.oldCanRecord = Services.telemetry.canRecordExtended;
this.generateTelemetryTests = this.generateTelemetryTests.bind(this);
registerCleanupFunction(this.stopTelemetry.bind(this));
}
/**
* Allow collection of extended telemetry data.
*/
startTelemetry() {
Services.telemetry.canRecordExtended = true;
}
/**
* Clear all telemetry types.
*/
stopTelemetry() {
this.clearToolsOpenedPref();
Services.telemetry.canRecordExtended = this.oldCanRecord;
// Clear histograms, scalars and Telemetry Events.
this.clearHistograms(Services.telemetry.snapshotHistograms);
this.clearHistograms(Services.telemetry.snapshotKeyedHistograms);
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
}
/**
* Clears both OPTIN and OPTOUT versions of Telemetry Histograms.
*
* @param {Function} snapshotFunc
* The function used to take the snapshot. This can be one of the
* following:
* - Services.telemetry.snapshotHistograms
* - Services.telemetry.snapshotKeyedHistograms
*
* `snapshotFunc(OPTIN, true, true)` should clear the histograms but this
* only deletes seemingly random histograms, hence this method.
*/
clearHistograms(snapshotFunc) {
// Although most of our Telemetry probes are OPTOUT, OPTIN includes all OPTIN
// *and* OPTOUT data.
const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN;
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
const tel = Services.telemetry;
for (let optInOut of [OPTIN, OPTOUT]) {
const snapshot = snapshotFunc(optInOut, true, false).parent;
const histKeys = Object.keys(snapshot);
for (let getHistogram of [tel.getHistogramById, tel.getKeyedHistogramById]) {
for (let key of histKeys) {
try {
getHistogram(key).clear();
} catch (e) {
// Some histograms may have already been cleaned up by the system so we
// swallow the "histogram does not exist" error silently here.
}
}
}
}
}
/**
* Clears the pref that is used to log telemetry data once per browser version.
*/
clearToolsOpenedPref() {
const TOOLS_OPENED_PREF = "devtools.telemetry.tools.opened.version";
Services.prefs.clearUserPref(TOOLS_OPENED_PREF);
}
/**
* Check the value of a given telemetry histogram.
*
* @param {String} histId
* Histogram id
* @param {String} key
* Keyed histogram key
* @param {Array|Number} expected
* Expected value
* @param {String} checkType
* "array" (default) - Check that an array matches the histogram data.
* "hasentries" - For non-enumerated linear and exponential
* histograms. This checks for at least one entry.
* "scalar" - Telemetry type is a scalar.
* "keyedscalar" - Telemetry type is a keyed scalar.
*/
checkTelemetry(histId, key, expected, checkType) {
// Although most of our Telemetry probes are OPTOUT, OPTIN includes all OPTIN
// *and* OPTOUT data.
const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN;
let actual;
let msg;
if (checkType === "array" || checkType === "hasentries") {
if (key) {
const keyedHistogram =
Services.telemetry.getKeyedHistogramById(histId).snapshot();
const result = keyedHistogram[key];
if (result) {
actual = result.counts;
} else {
ok(false, `${histId}[${key}] exists`);
return;
}
} else {
actual = Services.telemetry.getHistogramById(histId).snapshot().counts;
}
}
switch (checkType) {
case "array":
msg = key ? `${histId}["${key}"] correct.` : `${histId} correct.`;
is(JSON.stringify(actual), JSON.stringify(expected), msg);
break;
case "hasentries":
let hasEntry = actual.some(num => num > 0);
if (key) {
ok(hasEntry, `${histId}["${key}"] has at least one entry.`);
} else {
ok(hasEntry, `${histId} has at least one entry.`);
}
break;
case "scalar":
const scalars =
Services.telemetry.snapshotScalars(OPTIN, false).parent;
is(scalars[histId], expected, `${histId} correct`);
break;
case "keyedscalar":
const keyedScalars =
Services.telemetry.snapshotKeyedScalars(OPTIN, false).parent;
const value = keyedScalars[histId][key];
msg = key ? `${histId}["${key}"] correct.` : `${histId} correct.`;
is(value, expected, msg);
break;
}
}
/**
* Generate telemetry tests. You should call generateTelemetryTests("DEVTOOLS_")
* from your result checking code in telemetry tests. It logs checkTelemetry
* calls for all changed telemetry values.
*
* @param {String} prefix
* Optionally limits results to histogram ids starting with prefix.
*/
generateTelemetryTests(prefix = "") {
// Although most of our Telemetry probes are OPTOUT, OPTIN includes all OPTIN
// *and* OPTOUT data.
const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN;
// Get all histograms and scalars
const histograms =
Services.telemetry.snapshotHistograms(OPTIN, true, false).parent;
const keyedHistograms =
Services.telemetry.snapshotKeyedHistograms(OPTIN, true, false).parent;
const scalars =
Services.telemetry.snapshotScalars(OPTIN, false).parent;
const keyedScalars =
Services.telemetry.snapshotKeyedScalars(OPTIN, false).parent;
const allHistograms = Object.assign({},
histograms,
keyedHistograms,
scalars,
keyedScalars);
// Get all keys
const histIds = Object.keys(allHistograms)
.filter(histId => histId.startsWith(prefix));
dump("=".repeat(80) + "\n");
for (let histId of histIds) {
let snapshot = allHistograms[histId];
if (histId === histId.toLowerCase()) {
if (typeof snapshot === "object") {
// Keyed Scalar
const keys = Object.keys(snapshot);
for (let key of keys) {
const value = snapshot[key];
dump(`checkTelemetry("${histId}", "${key}", ${value}, "keyedscalar");\n`);
}
} else {
// Scalar
dump(`checkTelemetry("${histId}", "", ${snapshot}, "scalar");\n`);
}
} else if (typeof snapshot.histogram_type !== "undefined" &&
typeof snapshot.counts !== "undefined") {
// Histogram
const actual = snapshot.counts;
this.displayDataFromHistogramSnapshot(snapshot, "", histId, actual);
} else {
// Keyed Histogram
const keys = Object.keys(snapshot);
for (let key of keys) {
const value = snapshot[key];
const actual = value.counts;
this.displayDataFromHistogramSnapshot(value, key, histId, actual);
}
}
}
dump("=".repeat(80) + "\n");
}
/**
* Generates the inner contents of a test's checkTelemetry() method.
*
* @param {HistogramSnapshot} snapshot
* A snapshot of a telemetry chart obtained via snapshotHistograms or
* similar.
* @param {String} key
* Only used for keyed histograms. This is the key we are interested in
* checking.
* @param {String} histId
* The histogram ID.
* @param {Array|String|Boolean} actual
* The value of the histogram data.
*/
displayDataFromHistogramSnapshot(snapshot, key, histId, actual) {
key = key ? `"${key}"` : `""`;
switch (snapshot.histogram_type) {
case Services.telemetry.HISTOGRAM_EXPONENTIAL:
case Services.telemetry.HISTOGRAM_LINEAR:
let total = 0;
for (let val of actual) {
total += val;
}
if (histId.endsWith("_ENUMERATED")) {
if (total > 0) {
actual = actual.toSource();
dump(`checkTelemetry("${histId}", ${key}, ${actual}, "array");\n`);
}
return;
}
dump(`checkTelemetry("${histId}", ${key}, null, "hasentries");\n`);
break;
case Services.telemetry.HISTOGRAM_BOOLEAN:
actual = actual.toSource();
if (actual !== "[0, 0, 0]") {
dump(`checkTelemetry("${histId}", ${key}, ${actual}, "array");\n`);
}
break;
case Services.telemetry.HISTOGRAM_FLAG:
actual = actual.toSource();
if (actual !== "[1, 0, 0]") {
dump(`checkTelemetry("${histId}", ${key}, ${actual}, "array");\n`);
}
break;
case Services.telemetry.HISTOGRAM_COUNT:
actual = actual.toSource();
dump(`checkTelemetry("${histId}", ${key}, ${actual}, "array");\n`);
break;
}
}
}
// "exports"... because this is a helper and not imported via require we need to
// expose the three main methods that should be used by tests. The reason this
// is not imported via require is because it needs access to test methods
// (is, ok etc).
/* eslint-disable no-unused-vars */
const telemetryHelpers = new TelemetryHelpers();
const generateTelemetryTests = telemetryHelpers.generateTelemetryTests;
const checkTelemetry = telemetryHelpers.checkTelemetry;
const startTelemetry = telemetryHelpers.startTelemetry;
/* eslint-enable no-unused-vars */

View File

@ -25,6 +25,7 @@ support-files =
cm_mode_ruby.js
cm_script_injection_test.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_editor_autocomplete_basic.js]
[browser_editor_autocomplete_events.js]

View File

@ -25,6 +25,7 @@ support-files =
storage-updates.html
head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_storage_basic.js]
[browser_storage_basic_usercontextid_1.js]

View File

@ -67,6 +67,7 @@ support-files =
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/responsive.html/test/browser/devices.json
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/shared/test/test-actor.js

View File

@ -20,6 +20,7 @@ support-files =
head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_audionode-actor-get-param-flags.js]
[browser_audionode-actor-get-params-01.js]

View File

@ -4,6 +4,7 @@ subsuite = devtools
support-files =
head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
../stubs/*
test-console-api.html
test-css-message.html

View File

@ -156,6 +156,7 @@ support-files =
!/devtools/client/netmonitor/test/sjs_cors-test-server.sjs
!/image/test/mochitest/blue.png
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js

View File

@ -26,6 +26,7 @@ support-files =
timeline-iframe-parent.html
storage-helpers.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/server/tests/mochitest/hello-actor.js
[browser_accessibility_node.js]

View File

@ -3,6 +3,7 @@ tags = devtools
subsuite = devtools
support-files =
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
../../../server/tests/browser/head.js
[browser_async_storage.js]