From 82569a272a2ef65ef1238208a7a0c72140e5e6a2 Mon Sep 17 00:00:00 2001 From: Pietro Marchini Date: Wed, 23 Oct 2024 08:51:50 +0200 Subject: [PATCH] lib: ensure FORCE_COLOR forces color output in non-TTY environments PR-URL: https://github.com/nodejs/node/pull/55404 Reviewed-By: Luigi Pinca Reviewed-By: Jake Yuesong Li Reviewed-By: Matteo Collina Reviewed-By: Chemi Atlow Reviewed-By: Moshe Atlow Reviewed-By: James M Snell --- lib/internal/util/colors.js | 22 +++++------ .../output/assertion-color-tty.mjs | 6 +++ .../output/assertion-color-tty.snapshot | 37 +++++++++++++++++++ .../output/non-tty-forced-color-output.js | 6 +++ .../non-tty-forced-color-output.snapshot | 9 +++++ test/parallel/test-runner-output.mjs | 10 +++++ 6 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 test/fixtures/test-runner/output/assertion-color-tty.mjs create mode 100644 test/fixtures/test-runner/output/assertion-color-tty.snapshot create mode 100644 test/fixtures/test-runner/output/non-tty-forced-color-output.js create mode 100644 test/fixtures/test-runner/output/non-tty-forced-color-output.snapshot diff --git a/lib/internal/util/colors.js b/lib/internal/util/colors.js index 054f9c4b4090d8..812048c923bee7 100644 --- a/lib/internal/util/colors.js +++ b/lib/internal/util/colors.js @@ -24,18 +24,16 @@ module.exports = { stream.getColorDepth() > 2 : true); }, refresh() { - if (process.stderr.isTTY) { - const hasColors = module.exports.shouldColorize(process.stderr); - module.exports.blue = hasColors ? '\u001b[34m' : ''; - module.exports.green = hasColors ? '\u001b[32m' : ''; - module.exports.white = hasColors ? '\u001b[39m' : ''; - module.exports.yellow = hasColors ? '\u001b[33m' : ''; - module.exports.red = hasColors ? '\u001b[31m' : ''; - module.exports.gray = hasColors ? '\u001b[90m' : ''; - module.exports.clear = hasColors ? '\u001bc' : ''; - module.exports.reset = hasColors ? '\u001b[0m' : ''; - module.exports.hasColors = hasColors; - } + const hasColors = module.exports.shouldColorize(process.stderr); + module.exports.blue = hasColors ? '\u001b[34m' : ''; + module.exports.green = hasColors ? '\u001b[32m' : ''; + module.exports.white = hasColors ? '\u001b[39m' : ''; + module.exports.yellow = hasColors ? '\u001b[33m' : ''; + module.exports.red = hasColors ? '\u001b[31m' : ''; + module.exports.gray = hasColors ? '\u001b[90m' : ''; + module.exports.clear = hasColors ? '\u001bc' : ''; + module.exports.reset = hasColors ? '\u001b[0m' : ''; + module.exports.hasColors = hasColors; }, }; diff --git a/test/fixtures/test-runner/output/assertion-color-tty.mjs b/test/fixtures/test-runner/output/assertion-color-tty.mjs new file mode 100644 index 00000000000000..28845882c10002 --- /dev/null +++ b/test/fixtures/test-runner/output/assertion-color-tty.mjs @@ -0,0 +1,6 @@ +import assert from 'node:assert/strict' +import { test } from 'node:test' + +test('failing assertion', () => { + assert.strictEqual('!Hello World', 'Hello World!') +}) diff --git a/test/fixtures/test-runner/output/assertion-color-tty.snapshot b/test/fixtures/test-runner/output/assertion-color-tty.snapshot new file mode 100644 index 00000000000000..2909d909351743 --- /dev/null +++ b/test/fixtures/test-runner/output/assertion-color-tty.snapshot @@ -0,0 +1,37 @@ +[31m✖ failing assertion [90m(*ms)[39m[39m + [AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + [32mactual[39m [31mexpected[39m + + [39m'[39m[32m![39m[39mH[39m[39me[39m[39ml[39m[39ml[39m[39mo[39m[39m [39m[39mW[39m[39mo[39m[39mr[39m[39ml[39m[39md[39m[31m![39m[39m'[39m + ] { + generatedMessage: [33mtrue[39m, + code: [32m'ERR_ASSERTION'[39m, + actual: [32m'!Hello World'[39m, + expected: [32m'Hello World!'[39m, + operator: [32m'strictEqual'[39m + } + +[34mℹ tests 1[39m +[34mℹ suites 0[39m +[34mℹ pass 0[39m +[34mℹ fail 1[39m +[34mℹ cancelled 0[39m +[34mℹ skipped 0[39m +[34mℹ todo 0[39m +[34mℹ duration_ms *[39m + +[31m✖ failing tests:[39m + +* +[31m✖ failing assertion [90m(*ms)[39m[39m + [AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + [32mactual[39m [31mexpected[39m + + [39m'[39m[32m![39m[39mH[39m[39me[39m[39ml[39m[39ml[39m[39mo[39m[39m [39m[39mW[39m[39mo[39m[39mr[39m[39ml[39m[39md[39m[31m![39m[39m'[39m + ] { + generatedMessage: [33mtrue[39m, + code: [32m'ERR_ASSERTION'[39m, + actual: [32m'!Hello World'[39m, + expected: [32m'Hello World!'[39m, + operator: [32m'strictEqual'[39m + } diff --git a/test/fixtures/test-runner/output/non-tty-forced-color-output.js b/test/fixtures/test-runner/output/non-tty-forced-color-output.js new file mode 100644 index 00000000000000..4d3c9de969a13f --- /dev/null +++ b/test/fixtures/test-runner/output/non-tty-forced-color-output.js @@ -0,0 +1,6 @@ +'use strict'; + +process.env.FORCE_COLOR = 1; + +const test = require('node:test'); +test('passing test', () => {}); diff --git a/test/fixtures/test-runner/output/non-tty-forced-color-output.snapshot b/test/fixtures/test-runner/output/non-tty-forced-color-output.snapshot new file mode 100644 index 00000000000000..3d1f593832fe77 --- /dev/null +++ b/test/fixtures/test-runner/output/non-tty-forced-color-output.snapshot @@ -0,0 +1,9 @@ +✔ passing test (*ms) +ℹ tests 1 +ℹ suites 0 +ℹ pass 1 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms * diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index 17bb5f1ce7a175..0996d4d88dbc60 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -203,6 +203,16 @@ const tests = [ name: 'test-runner/output/arbitrary-output.js', flags: ['--test-reporter=tap'], }, + { + name: 'test-runner/output/non-tty-forced-color-output.js', + transform: specTransform, + }, + canColorize ? { + name: 'test-runner/output/assertion-color-tty.mjs', + flags: ['--test', '--stack-trace-limit=0'], + transform: specTransform, + tty: true, + } : false, { name: 'test-runner/output/async-test-scheduling.mjs', flags: ['--test-reporter=tap'],