Bug 1406028 - Migrate browser_webconsole_console_trace_duplicates.js to the new frontend r?jdescottes draft
authorMichael Ratcliffe <mratcliffe@mozilla.com>
Sat, 10 Feb 2018 16:41:50 +0000
changeset 753786 466a3c0401104770b472ac3ce0c11e98b9518d2d
parent 753522 a8e153c55eeee93a11e87d325fb20c644421036f
push id98682
push userbmo:mratcliffe@mozilla.com
push dateMon, 12 Feb 2018 13:04:51 +0000
reviewersjdescottes
bugs1406028
milestone60.0a1
Bug 1406028 - Migrate browser_webconsole_console_trace_duplicates.js to the new frontend r?jdescottes MozReview-Commit-ID: IUrs0HGCaHk
devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_trace_duplicates.js
devtools/client/webconsole/new-console-output/test/mochitest/test-bug_939783_console_trace_duplicates.html
devtools/client/webconsole/new-console-output/test/mochitest/test-console-trace-duplicates.html
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
@@ -18,17 +18,17 @@ support-files =
   test_console_csp_ignore_reflected_xss_message.html^headers^
   test_hpkp-invalid-headers.sjs
   test_hsts-invalid-headers.sjs
   test-autocomplete-in-stackframe.html
   test-batching.html
   test-bug_923281_console_log_filter.html
   test-bug_923281_test1.js
   test-bug_923281_test2.js
-  test-bug_939783_console_trace_duplicates.html
+  test-console-trace-duplicates.html
   test-bug-585956-console-trace.html
   test-bug-599725-response-headers.sjs
   test-bug-601177-log-levels.html
   test-bug-601177-log-levels.js
   test-bug-630733-response-redirect-headers.sjs
   test-bug-632275-getters.html
   test-bug-644419-log-limits.html
   test-bug-646025-console-file-location.html
@@ -247,16 +247,17 @@ tags = mcb
 [browser_webconsole_closure_inspection.js]
 skip-if = true # Bug 1405250
 [browser_webconsole_console_api_iframe.js]
 [browser_webconsole_console_dir.js]
 [browser_webconsole_console_dir_uninspectable.js]
 [browser_webconsole_console_group.js]
 [browser_webconsole_console_logging_workers_api.js]
 [browser_webconsole_console_table.js]
+[browser_webconsole_console_trace_duplicates.js]
 [browser_webconsole_context_menu_copy_entire_message.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_webconsole_context_menu_copy_link_location.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_webconsole_context_menu_copy_object.js]
 subsuite = clipboard
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_trace_duplicates.js
@@ -0,0 +1,171 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ /* import-globals-from head.js */
+
+"use strict";
+
+const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
+                  "new-console-output/test/mochitest/" +
+                  "test-console-trace-duplicates.html";
+
+add_task(async function testTraceMessages() {
+  let hud = await openNewTabAndConsole(TEST_URI);
+
+  // NB: Now that stack frames include a column number multiple invocations
+  //     on the same line are considered unique. ie:
+  //       |foo(); foo();|
+  //     will generate two distinct trace entries.
+  let message = await waitFor(() => findMessage(hud, "foo1"));
+  let stackInfo = getStackInfo(message);
+
+  checkStackInfo(stackInfo, {
+    variable: "console.trace()",
+    repeats: 3,
+    filename: "test-console-trace-duplicates.html",
+    line: 23,
+    column: 3,
+    stack: [{
+      functionName: "foo3",
+      filename: TEST_URI,
+      line: 23,
+      column: 3
+    }, {
+      functionName: "foo2",
+      filename: TEST_URI,
+      line: 19,
+      column: 3
+    }, {
+      functionName: "foo1",
+      filename: TEST_URI,
+      line: 11,
+      column: 3
+    }, {
+      functionName: "<anonymous>",
+      filename: TEST_URI,
+      line: 26,
+      column: 1
+    }]
+  });
+});
+
+/**
+ * Get stack info from a message node. This is a companion to checkStackInfo().
+ *
+ * @param {MessageNode}
+ *        The message from which the stack info will be returned.
+ * @returns {Object}
+ *          An object in the following format:
+ *            {
+ *              variable: "console.trace()",
+ *              repeats: 3
+ *              filename: "some-filename.html"
+ *              line: 23
+ *              column: 3
+ *              stack: [
+ *                {
+ *                  "functionName": "foo3",
+ *                  "filename": "http://example.com/some-filename.html",
+ *                  "line":"23",
+ *                  "column":"3"
+ *                },
+ *                ...
+ *              ]
+ *            }
+ */
+function getStackInfo(message) {
+  let lineNode = message.querySelector(".frame-link-line");
+  let lc = getLineAndColumn(lineNode);
+  let result = {
+    variable: message.querySelector(".cm-variable").textContent,
+    repeats: message.querySelector(".message-repeats").textContent,
+    filename: message.querySelector(".frame-link-filename").textContent,
+    line: lc.line,
+    column: lc.column,
+    stack: []
+  };
+
+  let stack = message.querySelector(".stack-trace");
+  if (stack) {
+    let filenameNodes = stack.querySelectorAll(".frame-link-filename");
+    let lineNodes = stack.querySelectorAll(".frame-link-line");
+    let funcNodes = stack.querySelectorAll(".frame-link-function-display-name");
+
+    for (let i = 0; i < filenameNodes.length; i++) {
+      let filename = filenameNodes[i].textContent;
+      let functionName = funcNodes[i].textContent;
+      let { line, column } = getLineAndColumn(lineNodes[i]);
+
+      result.stack.push({
+        functionName,
+        filename,
+        line: line,
+        column: column
+      });
+    }
+  }
+
+  return result;
+}
+
+/**
+ * Check stack info returned by getStackInfo().
+ *
+ * @param {Object} stackInfo
+ *        A stackInfo object returned by getStackInfo().
+ * @param {Object} expected
+ *        An object in the same format as the expected stackInfo object.
+ */
+function checkStackInfo(stackInfo, expected) {
+  is(stackInfo.variable, expected.variable, `"$(expected.variable}" command logged`);
+  is(stackInfo.repeats, expected.repeats, "expected number of repeats are displayed");
+  is(stackInfo.filename, expected.filename, "expected filename is displayed");
+  is(stackInfo.line, expected.line, "expected line is displayed");
+  is(stackInfo.column, expected.column, "expected column is displayed");
+
+  ok(stackInfo.stack.length > 0, "a stack is displayed");
+  is(stackInfo.stack.length, expected.stack.length, "the stack is the expected length");
+
+  for (let i = 0; i < stackInfo.stack.length; i++) {
+    let actual = stackInfo.stack[i];
+    let stackExpected = expected.stack[i];
+
+    is(actual.functionName, stackExpected.functionName,
+      `expected function name is displayed for index ${i}`);
+    is(actual.filename, stackExpected.filename,
+      `expected filename is displayed for index ${i}`);
+    is(actual.line, stackExpected.line,
+      `expected line is displayed for index ${i}`);
+    is(actual.column, stackExpected.column,
+      `expected column is displayed for index ${i}`);
+  }
+}
+
+/**
+ * Splits the line and column info from the node containing the line and column
+ * to be split e.g. ':10:15'.
+ *
+ * @param {HTMLNode} node
+ *        The HTML node containing the line and column to be split.
+ */
+function getLineAndColumn(node) {
+  let lineAndColumn = node.textContent;
+  let line = 0;
+  let column = 0;
+
+  // LineAndColumn should look something like ":10:15"
+  if (lineAndColumn.startsWith(":")) {
+    // Trim the first colon leaving e.g. "10:15"
+    lineAndColumn = lineAndColumn.substr(1);
+
+    // Split "10:15" into line and column variables.
+    [ line, column ] = lineAndColumn.split(":");
+  }
+
+  return {
+    line: line * 1,
+    column: column * 1
+  };
+}
deleted file mode 100644
--- a/devtools/client/webconsole/new-console-output/test/mochitest/test-bug_939783_console_trace_duplicates.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>Web Console test for bug 939783 - different console.trace() calls
-      wrongly filtered as duplicates</title>
-    <!-- Any copyright is dedicated to the Public Domain.
-         http://creativecommons.org/publicdomain/zero/1.0/ -->
-<script type="application/javascript">
-function foo1() {
-  foo2();
-}
-
-function foo1b() {
-  foo2();
-}
-
-function foo2() {
-  foo3();
-}
-
-function foo3() {
-  console.trace();
-}
-
-foo1(); foo1();
-foo1b();
-
-</script>
-  </head>
-  <body>
-    <p>Web Console test for bug 939783 - different console.trace() calls
-      wrongly filtered as duplicates</p>
-  </body>
-</html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-trace-duplicates.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Web Console test for checking that different console.trace() calls
+      are not wrongly filtered as duplicates</title>
+    <!-- Any copyright is dedicated to the Public Domain.
+         http://creativecommons.org/publicdomain/zero/1.0/ -->
+<script type="application/javascript">
+function foo1() {
+  foo2();
+}
+
+function foo1b() {
+  foo2();
+}
+
+function foo2() {
+  foo3();
+}
+
+function foo3() {
+  console.trace();
+}
+
+foo1(); foo1();
+foo1b();
+
+</script>
+  </head>
+  <body>
+    <p>Web Console test for bug 939783 - different console.trace() calls
+      wrongly filtered as duplicates</p>
+  </body>
+</html>