From 313a2747ff1c28e84c85fcbb84aae5db84c042ed Mon Sep 17 00:00:00 2001 From: mag123c Date: Sun, 18 Jan 2026 14:48:44 +0900 Subject: [PATCH 1/2] test_runner: print coverage and diagnostic info with dot reporter When using the dot reporter with coverage enabled, coverage threshold failures and coverage reports were not printed, only an exit code was returned. This made it impossible to know why the test run failed. This change adds handling for test:diagnostic and test:coverage events to the dot reporter, matching the behavior of the spec reporter. Fixes: https://github.com/nodejs/node/issues/60884 --- lib/internal/test_runner/reporter/dot.js | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/internal/test_runner/reporter/dot.js b/lib/internal/test_runner/reporter/dot.js index 45ff047bc4e5a0..1d73523f3c3e56 100644 --- a/lib/internal/test_runner/reporter/dot.js +++ b/lib/internal/test_runner/reporter/dot.js @@ -4,12 +4,19 @@ const { MathMax, } = primordials; const colors = require('internal/util/colors'); -const { formatTestReport } = require('internal/test_runner/reporter/utils'); +const { getCoverageReport } = require('internal/test_runner/utils'); +const { + formatTestReport, + reporterColorMap, + reporterUnicodeSymbolMap, +} = require('internal/test_runner/reporter/utils'); module.exports = async function* dot(source) { let count = 0; let columns = getLineLength(); const failedTests = []; + const diagnostics = []; + let coverage; for await (const { type, data } of source) { if (type === 'test:pass') { yield `${colors.green}.${colors.reset}`; @@ -25,8 +32,24 @@ module.exports = async function* dot(source) { columns = getLineLength(); count = 0; } + if (type === 'test:diagnostic' && data.level === 'error') { + ArrayPrototypePush(diagnostics, data); + } + if (type === 'test:coverage') { + coverage = data; + } } yield '\n'; + if (diagnostics.length > 0) { + for (const diagnostic of diagnostics) { + const color = reporterColorMap[diagnostic.level] || reporterColorMap['test:diagnostic']; + yield `${color}${reporterUnicodeSymbolMap['test:diagnostic']}${diagnostic.message}${colors.white}\n`; + } + if (coverage) { + yield getCoverageReport('', coverage.summary, + reporterUnicodeSymbolMap['test:coverage'], colors.blue, true); + } + } if (failedTests.length > 0) { yield `\n${colors.red}Failed tests:${colors.white}\n\n`; for (const test of failedTests) { From 402b748d411102924e8ed66150b1b41b52d27e71 Mon Sep 17 00:00:00 2001 From: mag123c Date: Tue, 20 Jan 2026 18:00:35 +0900 Subject: [PATCH 2/2] test: add dot reporter coverage threshold tests --- .../test-runner-coverage-thresholds.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/parallel/test-runner-coverage-thresholds.js b/test/parallel/test-runner-coverage-thresholds.js index e45e1191299ca7..2742464adf6437 100644 --- a/test/parallel/test-runner-coverage-thresholds.js +++ b/test/parallel/test-runner-coverage-thresholds.js @@ -170,4 +170,25 @@ for (const coverage of coverages) { assert.strictEqual(result.status, 1); assert(!findCoverageFileForPid(result.pid)); }); + + test(`test failing ${coverage.flag} with dot reporter`, () => { + const result = spawnSync(process.execPath, [ + '--test', + '--experimental-test-coverage', + '--test-coverage-exclude=!test/**', + `${coverage.flag}=99`, + '--test-reporter', 'dot', + fixture, + ]); + + const stdout = result.stdout.toString(); + assert.match( + stdout, + RegExp(`Error: ${coverage.actual.toFixed(2)}% ${coverage.name} coverage does not meet threshold of 99%`) + ); + assert.match(stdout, /start of coverage report/); + assert.match(stdout, /end of coverage report/); + assert.strictEqual(result.status, 1); + assert(!findCoverageFileForPid(result.pid)); + }); }