Skip to content

Commit 04eb1f8

Browse files
MoLowdanielleadams
authored andcommitted
test_runner: pass FORCE_COLOR to child process
PR-URL: #48057 Backport-PR-URL: #48684 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent c46b31f commit 04eb1f8

File tree

7 files changed

+69
-4
lines changed

7 files changed

+69
-4
lines changed

lib/internal/test_runner/harness.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ function setup(root) {
177177
topLevel: 0,
178178
suites: 0,
179179
},
180+
shouldColorizeTestFiles: false,
180181
};
181182
root.startTime = hrtime();
182183
return root;

lib/internal/test_runner/runner.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) {
351351
stdio.push('ipc');
352352
env.WATCH_REPORT_DEPENDENCIES = '1';
353353
}
354+
if (root.harness.shouldColorizeTestFiles) {
355+
env.FORCE_COLOR = '1';
356+
}
354357

355358
const child = spawn(process.execPath, args, { signal: t.signal, encoding: 'utf8', env, stdio });
356359
if (watchMode) {

lib/internal/test_runner/utils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const { createWriteStream } = require('fs');
1717
const { pathToFileURL } = require('internal/url');
1818
const { createDeferredPromise } = require('internal/util');
1919
const { getOptionValue } = require('internal/options');
20-
const { green, red, white } = require('internal/util/colors');
20+
const { green, red, white, shouldColorize } = require('internal/util/colors');
2121

2222
const {
2323
codes: {
@@ -116,9 +116,10 @@ function tryBuiltinReporter(name) {
116116
return require(builtinPath);
117117
}
118118

119-
async function getReportersMap(reporters, destinations) {
119+
async function getReportersMap(reporters, destinations, rootTest) {
120120
return SafePromiseAllReturnArrayLike(reporters, async (name, i) => {
121121
const destination = kBuiltinDestinations.get(destinations[i]) ?? createWriteStream(destinations[i]);
122+
rootTest.harness.shouldColorizeTestFiles ||= shouldColorize(destination);
122123

123124
// Load the test reporter passed to --test-reporter
124125
let reporter = tryBuiltinReporter(name);
@@ -155,7 +156,7 @@ async function getReportersMap(reporters, destinations) {
155156

156157
async function setupTestReporters(rootTest) {
157158
const { reporters, destinations } = parseCommandLine();
158-
const reportersMap = await getReportersMap(reporters, destinations);
159+
const reportersMap = await getReportersMap(reporters, destinations, rootTest);
159160
for (let i = 0; i < reportersMap.length; i++) {
160161
const { reporter, destination } = reportersMap[i];
161162
compose(rootTest.reporter, reporter).pipe(destination);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
const test = require('node:test');
4+
console.log({ foo: 'bar' });
5+
test('passing test', () => {
6+
console.log(1);
7+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
const common = require('../../../common');
3+
const { once } = require('node:events');
4+
const { spawn } = require('node:child_process');
5+
const fixtures = require('../../../common/fixtures');
6+
7+
(async function run() {
8+
const test = fixtures.path('test-runner/output/arbitrary-output-colored-1.js');
9+
await once(spawn(process.execPath, ['--test', test], { stdio: 'inherit', env: { FORCE_COLOR: 1 } }), 'exit');
10+
await once(spawn(process.execPath, ['--test', '--test-reporter', 'tap', test], { stdio: 'inherit', env: { FORCE_COLOR: 1 } }), 'exit');
11+
})().then(common.mustCall());
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{ foo: [32m'bar'[39m }
2+
3+
[33m1[39m
4+
5+
[32m✔ passing test [90m(*ms)[39m[39m
6+
[34mℹ tests 1[39m
7+
[34mℹ suites 0[39m
8+
[34mℹ pass 1[39m
9+
[34mℹ fail 0[39m
10+
[34mℹ cancelled 0[39m
11+
[34mℹ skipped 0[39m
12+
[34mℹ todo 0[39m
13+
[34mℹ duration_ms *[39m
14+
TAP version 13
15+
# { foo: [32m'bar'[39m }
16+
#
17+
# [33m1[39m
18+
#
19+
# Subtest: passing test
20+
ok 1 - passing test
21+
---
22+
duration_ms: *
23+
...
24+
1..1
25+
# tests 1
26+
# suites 0
27+
# pass 1
28+
# fail 0
29+
# cancelled 0
30+
# skipped 0
31+
# todo 0
32+
# duration_ms *

test/parallel/test-runner-output.mjs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import * as fixtures from '../common/fixtures.mjs';
33
import * as snapshot from '../common/assertSnapshot.js';
44
import { describe, it } from 'node:test';
55

6+
const skipForceColors =
7+
process.config.variables.icu_gyp_path !== 'tools/icu/icu-generic.gyp' ||
8+
process.config.variables.node_shared_openssl;
9+
610
function replaceTestDuration(str) {
711
return str
812
.replaceAll(/duration_ms: 0(\r?\n)/g, 'duration_ms: ZERO$1')
@@ -46,8 +50,14 @@ const tests = [
4650
{ name: 'test-runner/output/unresolved_promise.js' },
4751
{ name: 'test-runner/output/default_output.js', transform: specTransform, tty: true },
4852
{ name: 'test-runner/output/arbitrary-output.js' },
53+
!skipForceColors ? {
54+
name: 'test-runner/output/arbitrary-output-colored.js',
55+
transform: snapshot.transform(specTransform, replaceTestDuration), tty: true
56+
} : false,
4957
{ name: 'test-runner/output/dot_output_custom_columns.js', transform: specTransform, tty: true },
50-
].map(({ name, tty, transform }) => ({
58+
]
59+
.filter(Boolean)
60+
.map(({ name, tty, transform }) => ({
5161
name,
5262
fn: common.mustCall(async () => {
5363
await snapshot.spawnAndAssert(fixtures.path(name), transform ?? defaultTransform, { tty });

0 commit comments

Comments
 (0)