Bug 1577074 - Instrument scripts executed from editor mode. r=rcaliman.

We add an extra "input" property that is filled with
either "inline" or "multiline" depending if the expression
was evaluated in regular webconsole layout or in editor mode.

The test that was checking the execute_js telemetry event is
modify to only check what it was created for (hitting enter
on incomplete expression adds new line), and a new test is
added to specifically check that the execute_js telemetry event
is recorded as we expect.

Differential Revision: https://phabricator.services.mozilla.com/D43738

--HG--
rename : devtools/client/webconsole/test/browser/browser_jsterm_multiline.js => devtools/client/webconsole/test/browser/browser_webconsole_telemetry_execute_js.js
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Chevobbe 2019-09-02 06:22:32 +00:00
Родитель 0f6c405c91
Коммит c93c7ac5af
6 изменённых файлов: 131 добавлений и 77 удалений

Просмотреть файл

@ -56,6 +56,7 @@ function eventTelemetryMiddleware(telemetry, sessionId, store) {
// toolbox session id.
telemetry.recordEvent("execute_js", "webconsole", null, {
lines: action.expression.split(/\n/).length,
input: state.ui.editor ? "multiline" : "inline",
session_id: sessionId,
});
}

Просмотреть файл

@ -471,6 +471,7 @@ skip-if = true # Bug 1572667
skip-if = true # Bug 1572667
[browser_webconsole_stubs_page_error.js]
skip-if = true # Bug 1572667
[browser_webconsole_telemetry_execute_js.js]
[browser_webconsole_telemetry_js_errors.js]
[browser_webconsole_telemetry_filters_changed.js]
[browser_webconsole_telemetry_persist_toggle_changed.js]

Просмотреть файл

@ -9,9 +9,7 @@
"use strict";
const TEST_URI =
"http://example.com/browser/devtools/client/webconsole/" +
"test/browser/test-console.html";
const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS;
"http://example.com/browser/devtools/client/webconsole/test/browser/test-console.html";
const SHOULD_ENTER_MULTILINE = [
{ input: "function foo() {" },
@ -42,47 +40,7 @@ const SHOULD_EXECUTE = [
{ input: "{2,}" },
];
const SINGLE_LINE_DATA = {
timestamp: null,
category: "devtools.main",
method: "execute_js",
object: "webconsole",
value: null,
extra: {
lines: "1",
},
};
const DATA = [
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
SINGLE_LINE_DATA,
{
timestamp: null,
category: "devtools.main",
method: "execute_js",
object: "webconsole",
value: null,
extra: {
lines: "3",
},
},
];
add_task(async function() {
// Let's reset the counts.
Services.telemetry.clearEvents();
// Ensure no events have been logged
const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
ok(!snapshot.parent, "No events have been logged for the main process");
const hud = await openNewTabAndConsole(TEST_URI);
for (const { input, shiftKey } of SHOULD_ENTER_MULTILINE) {
@ -97,43 +55,11 @@ add_task(async function() {
for (const { input, shiftKey } of SHOULD_EXECUTE) {
setInputValue(hud, input);
const onMessage = waitForMessage(hud, "", ".result");
EventUtils.synthesizeKey("VK_RETURN", { shiftKey });
await onMessage;
await waitFor(() => !getInputValue(hud));
is(getInputValue(hud), "", "Input is cleared");
}
await executeAndWaitForMessage(
hud,
"document.\nlocation.\nhref",
TEST_URI,
".result"
);
checkEventTelemetry();
});
function checkEventTelemetry() {
const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
const events = snapshot.parent.filter(
event =>
event[1] === "devtools.main" &&
event[2] === "execute_js" &&
event[3] === "webconsole" &&
event[4] === null
);
for (const i in DATA) {
const [timestamp, category, method, object, value, extra] = events[i];
const expected = DATA[i];
// ignore timestamp
ok(timestamp > 0, "timestamp is greater than 0");
is(category, expected.category, "category is correct");
is(method, expected.method, "method is correct");
is(object, expected.object, "object is correct");
is(value, expected.value, "value is correct");
is(extra.lines, expected.extra.lines, "lines is correct");
}
}

Просмотреть файл

@ -0,0 +1,97 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Tests that the console record the execute_js telemetry event with expected data
// when evaluating expressions.
"use strict";
const TEST_URI = `data:text/html,<meta charset=utf8>Test execute_js telemetry event`;
const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS;
add_task(async function() {
await pushPref("devtools.webconsole.features.editor", true);
// Let's reset the counts.
Services.telemetry.clearEvents();
// Ensure no events have been logged
const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
ok(!snapshot.parent, "No events have been logged for the main process");
const hud = await openNewTabAndConsole(TEST_URI);
info("Evaluate a single line");
await keyboardExecuteAndWaitForMessage(hud, `"single line"`, "", ".result");
info("Evaluate another single line");
await keyboardExecuteAndWaitForMessage(hud, `"single line 2"`, "", ".result");
info("Evaluate multiple lines");
await keyboardExecuteAndWaitForMessage(hud, `"n"\n.trim()`, "", ".result");
info("Switch to editor mode");
await toggleLayout(hud);
info("Evaluate a single line in editor mode");
await keyboardExecuteAndWaitForMessage(hud, `"single line 3"`, "", ".result");
info("Evaluate multiple lines in editor mode");
await keyboardExecuteAndWaitForMessage(
hud,
`"y"\n.trim()\n.trim()`,
"",
".result"
);
info("Evaluate multiple lines again in editor mode");
await keyboardExecuteAndWaitForMessage(hud, `"x"\n.trim()`, "", ".result");
checkEventTelemetry([
getTelemetryEventData({ lines: 1, input: "inline" }),
getTelemetryEventData({ lines: 1, input: "inline" }),
getTelemetryEventData({ lines: 2, input: "inline" }),
getTelemetryEventData({ lines: 1, input: "multiline" }),
getTelemetryEventData({ lines: 3, input: "multiline" }),
getTelemetryEventData({ lines: 2, input: "multiline" }),
]);
info("Switch back to inline mode");
await toggleLayout(hud);
});
function checkEventTelemetry(expectedData) {
const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
const events = snapshot.parent.filter(
event =>
event[1] === "devtools.main" &&
event[2] === "execute_js" &&
event[3] === "webconsole" &&
event[4] === null
);
for (const [i, expected] of expectedData.entries()) {
const [timestamp, category, method, object, value, extra] = events[i];
// ignore timestamp
ok(timestamp > 0, "timestamp is greater than 0");
is(category, expected.category, "'category' is correct");
is(method, expected.method, "'method' is correct");
is(object, expected.object, "'object' is correct");
is(value, expected.value, "'value' is correct");
is(extra.lines, expected.extra.lines, "'lines' is correct");
is(extra.input, expected.extra.input, "'input' is correct");
}
}
function getTelemetryEventData(extra) {
return {
timestamp: null,
category: "devtools.main",
method: "execute_js",
object: "webconsole",
value: null,
extra,
};
}

Просмотреть файл

@ -250,6 +250,34 @@ function executeAndWaitForMessage(
return onMessage;
}
/**
* Set the input value, simulates the right keyboard event to evaluate it, depending on
* if the console is in editor mode or not, and wait for a message with the expected text
* (and an optional selector) to be displayed in the output.
*
* @param {Object} hud : The webconsole.
* @param {String} input : The input expression to execute.
* @param {String} matchingText : A string that should match the message body content.
* @param {String} selector : A selector that should match the message node.
*/
function keyboardExecuteAndWaitForMessage(
hud,
input,
matchingText,
selector = ".message"
) {
setInputValue(hud, input);
const onMessage = waitForMessage(hud, matchingText, selector);
if (isEditorModeEnabled(hud)) {
EventUtils.synthesizeKey("KEY_Enter", {
[Services.appinfo.OS === "Darwin" ? "metaKey" : "ctrlKey"]: true,
});
} else {
EventUtils.synthesizeKey("VK_RETURN");
}
return onMessage;
}
/**
* Wait for a predicate to return a result.
*

Просмотреть файл

@ -1075,6 +1075,7 @@ devtools.main:
release_channel_collection: opt-out
expiry_version: never
extra_keys:
input: Indicates from which input the command was evaluated ("inline" for regular input, "multiline" for editor mode).
lines: The number of lines contained in the command.
session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
exit: