tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 3bd1ed791f21b30d106fb279a7591915e1a6ec77
parent b4c9cec229cf75138d7cedd7c37db4872c077d7b
Author: Florian Quèze <florian@queze.net>
Date:   Thu,  8 Jan 2026 16:52:42 +0000

Bug 2008920 - Make browser chrome mochitests log the task name as the subtest and log the assertion failure stacks in the stack field of structured messages, r=ahal.

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

Diffstat:
Mtesting/mochitest/browser-harness.xhtml | 20+++++++++++++-------
Mtesting/mochitest/browser-test.js | 33+++++++++++++++++++++++++++------
2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/testing/mochitest/browser-harness.xhtml b/testing/mochitest/browser-harness.xhtml @@ -146,11 +146,21 @@ return; } + // Use task name as subtest if available + let subtest = this.scope?.SimpleTest?._currentTaskName || null; + + // Combine assertion name with exception details if present + let message = result.name; + if (result.msg) { + message += " - " + result.msg; + } + this.dumper.structuredLogger.testStatus(this.path, - result.name, + subtest, result.status, result.expected, - result.msg); + message, + result.stack || null); let markerName = "TEST-"; if (result.pass) { markerName += result.todo ? "KNOWN-FAIL" : "PASS"; @@ -158,11 +168,7 @@ else { markerName += "UNEXPECTED-" + result.status; } - let markerText = result.name; - if (result.msg) { - markerText += " - " + result.msg; - } - ChromeUtils.addProfilerMarker(markerName, {category: "Test"}, markerText); + ChromeUtils.addProfilerMarker(markerName, {category: "Test"}, message); }, setDuration: function setDuration(duration) { diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js @@ -1284,6 +1284,8 @@ Tester.prototype = { let desc = isSetup ? "setup" : "test"; currentScope.SimpleTest.info(`Entering ${desc} ${task.name}`); let startTimestamp = ChromeUtils.now(); + currentScope.SimpleTest._currentTaskName = task.name; + let controller = new AbortController(); currentScope.__signal = controller.signal; if (isSetup) { @@ -1312,7 +1314,7 @@ Tester.prototype = { } currentTest.addResult( new testResult({ - name: `Uncaught exception in ${desc} ${task.name}`, + name: `Uncaught exception in ${desc}`, pass: currentScope.SimpleTest.isExpectingUncaughtException(), ex, stack: typeof ex == "object" && "stack" in ex ? ex.stack : null, @@ -1328,9 +1330,10 @@ Tester.prototype = { ChromeUtils.addProfilerMarker( isSetup ? "setup-task" : "task", { category: "Test", startTime: startTimestamp }, - task.name.replace(/^bound /, "") || undefined + task.name || undefined ); currentScope.SimpleTest.info(`Leaving ${desc} ${task.name}`); + currentScope.SimpleTest._currentTaskName = null; }, async _runTaskBasedTest(currentTest) { @@ -1704,8 +1707,23 @@ function testResult({ name, pass, todo, ex, stack, allowFailure }) { if (ex) { if (typeof ex == "object" && "fileName" in ex) { - // we have an exception - print filename and linenumber information - this.msg += "at " + ex.fileName + ":" + ex.lineNumber + " - "; + // Only add "at fileName:lineNumber" if stack doesn't start with same location + let stackMatchesExLocation = false; + + if (stack instanceof Ci.nsIStackFrame) { + stackMatchesExLocation = + stack.filename == ex.fileName && stack.lineNumber == ex.lineNumber; + } else if (typeof stack === "string") { + // For string stacks, format is: functionName@fileName:lineNumber:columnNumber + // Check if first line contains fileName:lineNumber + let firstLine = stack.split("\n")[0]; + let expectedLocation = ex.fileName + ":" + ex.lineNumber; + stackMatchesExLocation = firstLine.includes(expectedLocation); + } + + if (!stackMatchesExLocation) { + this.msg += "at " + ex.fileName + ":" + ex.lineNumber + " - "; + } } if ( @@ -1722,8 +1740,8 @@ function testResult({ name, pass, todo, ex, stack, allowFailure }) { } } + // Store stack separately instead of appending to msg if (stack) { - this.msg += "\nStack trace:\n"; let normalized; if (stack instanceof Ci.nsIStackFrame) { let frames = []; @@ -1739,7 +1757,7 @@ function testResult({ name, pass, todo, ex, stack, allowFailure }) { } else { normalized = "" + stack; } - this.msg += normalized; + this.stack = normalized; } if (gConfig.debugOnFailure) { @@ -1997,7 +2015,10 @@ function testScope(aTester, aTest, expected) { } function decorateTaskFn(fn) { + let originalName = fn.name; fn = fn.bind(this); + // Restore original name to avoid "bound " prefix in task name + Object.defineProperty(fn, "name", { value: originalName }); fn.skip = (val = true) => (fn.__skipMe = val); fn.only = () => (this.__runOnlyThisTask = fn); return fn;