summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js')
-rw-r--r--devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js b/devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js
new file mode 100644
index 0000000000..2bd1149a49
--- /dev/null
+++ b/devtools/client/webconsole/test/browser/browser_jsterm_trace_command.js
@@ -0,0 +1,217 @@
+/* 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 the Javascript Tracing feature via the Web Console :trace command.
+
+"use strict";
+
+const TEST_URI = `data:text/html;charset=utf-8,<!DOCTYPE html>
+<body>
+ <div>
+ <h1>Testing trace command</h1>
+ <script>
+ function main() {}
+ function someNoise() {}
+ </script>
+ </div>
+ <div><p></p></div>
+</body>`;
+
+add_task(async function testBasicRecord() {
+ await pushPref("devtools.debugger.features.javascript-tracing", true);
+
+ const hud = await openNewTabAndConsole(TEST_URI);
+ ok(hud, "web console opened");
+
+ info("Test unsupported param error message");
+ let msg = await evaluateExpressionInConsole(
+ hud,
+ ":trace --unsupported-param",
+ "console-api"
+ );
+ is(
+ msg.textContent.trim(),
+ ":trace command doesn't support 'unsupported-param' argument."
+ );
+
+ info("Test the help argument");
+ msg = await evaluateExpressionInConsole(hud, ":trace --help", "console-api");
+ ok(msg.textContent.includes("Toggles the JavaScript tracer"));
+
+ info("Test toggling the tracer ON");
+ // Pass `console-api` specific classname as the command results don't log anything.
+ // Instead a JSTRACER_STATE resource logs a console-api message.
+ msg = await evaluateExpressionInConsole(
+ hud,
+ ":trace --logMethod console --prefix foo --values --on-next-interaction",
+ "console-api"
+ );
+ is(
+ msg.textContent.trim(),
+ "Waiting for next user interaction before tracing (next mousedown or keydown event)"
+ );
+
+ info("Trigger some code before the user interaction");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.someNoise();
+ });
+
+ info("Simulate a user interaction by trigerring a key event on the page");
+ await BrowserTestUtils.synthesizeKey("a", {}, gBrowser.selectedBrowser);
+
+ info("Trigger some code to log some traces");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.main("arg", 2);
+ });
+
+ info("Ensure a message notified about the tracer actual start");
+ await waitFor(
+ () => !!findConsoleAPIMessage(hud, `Started tracing to Web Console`)
+ );
+
+ // Assert that we also see the custom prefix, as well as function arguments
+ await waitFor(
+ () =>
+ !!findTracerMessages(hud, `foo: ⟶ interpreter λ main("arg", 2)`).length
+ );
+ is(
+ findTracerMessages(hud, `someNoise`).length,
+ 0,
+ "The code running before the key press should not be traced"
+ );
+
+ // But now that the tracer is active, we will be able to log this call to someNoise
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.someNoise();
+ });
+ await waitFor(
+ () => !!findTracerMessages(hud, `foo: ⟶ interpreter λ someNoise()`).length
+ );
+
+ info("Test toggling the tracer OFF");
+ msg = await evaluateExpressionInConsole(hud, ":trace", "console-api");
+ is(msg.textContent.trim(), "Stopped tracing");
+
+ info("Clear past traces");
+ hud.ui.clearOutput();
+ await waitFor(
+ () => !findTracerMessages(hud, `foo: ⟶ interpreter λ main("arg", 2)`).length
+ );
+ ok("Console was cleared");
+
+ info("Trigger some code again");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.main();
+ });
+
+ // Let some time for traces to appear
+ await wait(1000);
+
+ ok(
+ !findTracerMessages(hud, `foo: ⟶ interpreter λ main("arg", 2)`).length,
+ "We really stopped recording traces, and no trace appear in the console"
+ );
+});
+
+add_task(async function testLimitedRecord() {
+ await pushPref("devtools.debugger.features.javascript-tracing", true);
+
+ const jsCode = `function foo1() {foo2()}; function foo2() {foo3()}; function foo3() {}; function bar() {}`;
+ const hud = await openNewTabAndConsole(
+ "data:text/html," + encodeURIComponent(`<script>${jsCode}</script>`)
+ );
+ ok(hud, "web console opened");
+
+ info("Test toggling the tracer ON");
+ // Pass `console-api` specific classname as the command results aren't logged as "result".
+ // Instead the frontend log a message as a console API message.
+ await evaluateExpressionInConsole(
+ hud,
+ ":trace --logMethod console --max-depth 1",
+ "console-api"
+ );
+
+ info("Execute some code trigerring the tracer");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.foo1();
+ });
+
+ await waitFor(() => !!findTracerMessages(hud, `λ foo1`).length);
+ ok(true, "foo1 trace was printed to console");
+
+ is(
+ findTracerMessages(hud, `λ foo2`).length,
+ 0,
+ "We only see the first function thanks to the depth limit"
+ );
+
+ info("Test toggling the tracer OFF");
+ await evaluateExpressionInConsole(hud, ":trace", "console-api");
+
+ info("Clear past traces");
+ hud.ui.clearOutput();
+ await waitFor(() => !findTracerMessages(hud, `λ foo1`).length);
+ ok("Console was cleared");
+
+ info("Re-enable the tracing, but with a max record limit");
+ await evaluateExpressionInConsole(
+ hud,
+ ":trace --logMethod console --max-records 1",
+ "console-api"
+ );
+
+ info("Trigger some code again");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.foo1();
+ content.wrappedJSObject.bar();
+ });
+
+ await waitFor(() => !!findTracerMessages(hud, `λ foo3`).length);
+ await waitFor(() => !!findConsoleAPIMessage(hud, `Stopped tracing`));
+ is(
+ findTracerMessages(hud, `λ foo1`).length,
+ 1,
+ "Found the whole depth for the first event loop 1/3"
+ );
+ is(
+ findTracerMessages(hud, `λ foo2`).length,
+ 1,
+ "Found the whole depth for the first event loop 2/3"
+ );
+ is(
+ findTracerMessages(hud, `λ foo3`).length,
+ 1,
+ "Found the whole depth for the first event loop 3/3"
+ );
+ is(
+ findTracerMessages(hud, `λ bar`).length,
+ 0,
+ "But the second event loop was ignored"
+ );
+ ok(
+ !!findConsoleAPIMessage(
+ hud,
+ `Stopped tracing (reason: max-records)`,
+ ".console-api"
+ ),
+ "And the tracer was automatically stopped"
+ );
+
+ info("Enable tracing one last time without any restriction");
+ await evaluateExpressionInConsole(
+ hud,
+ ":trace --logMethod console",
+ "console-api"
+ );
+ info("Trigger various code again");
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ content.wrappedJSObject.foo1();
+ content.wrappedJSObject.bar();
+ });
+ await waitFor(() => !!findTracerMessages(hud, `λ foo1`).length);
+ await waitFor(() => !!findTracerMessages(hud, `λ foo2`).length);
+ await waitFor(() => !!findTracerMessages(hud, `λ foo3`).length);
+ await waitFor(() => !!findTracerMessages(hud, `λ bar`).length);
+ ok(true, "All traces were printed to console");
+});