1import * as common from '../common/index.mjs'; 2import * as fixtures from '../common/fixtures.mjs'; 3import * as snapshot from '../common/assertSnapshot.js'; 4import { describe, it } from 'node:test'; 5import { hostname } from 'node:os'; 6 7const skipForceColors = 8 process.config.variables.icu_gyp_path !== 'tools/icu/icu-generic.gyp' || 9 process.config.variables.node_shared_openssl; 10 11function replaceTestDuration(str) { 12 return str 13 .replaceAll(/duration_ms: [0-9.]+/g, 'duration_ms: *') 14 .replaceAll(/duration_ms [0-9.]+/g, 'duration_ms *'); 15} 16 17const color = '(\\[\\d+m)'; 18const stackTraceBasePath = new RegExp(`${color}\\(${process.cwd()}/?${color}(.*)${color}\\)`, 'g'); 19 20function replaceSpecDuration(str) { 21 return str 22 .replaceAll(/[0-9.]+ms/g, '*ms') 23 .replaceAll(/duration_ms [0-9.]+/g, 'duration_ms *') 24 .replace(stackTraceBasePath, '$3'); 25} 26 27function replaceJunitDuration(str) { 28 return str 29 .replaceAll(/time="[0-9.]+"/g, 'time="*"') 30 .replaceAll(/duration_ms [0-9.]+/g, 'duration_ms *') 31 .replaceAll(hostname(), 'HOSTNAME') 32 .replace(stackTraceBasePath, '$3'); 33} 34 35function removeWindowsPathEscaping(str) { 36 return common.isWindows ? str.replaceAll(/\\\\/g, '\\') : str; 37} 38 39function replaceTestLocationLine(str) { 40 return str.replaceAll(/(js:)(\d+)(:\d+)/g, '$1(LINE)$3'); 41} 42 43const defaultTransform = snapshot.transform( 44 snapshot.replaceWindowsLineEndings, 45 snapshot.replaceStackTrace, 46 removeWindowsPathEscaping, 47 snapshot.replaceFullPaths, 48 snapshot.replaceWindowsPaths, 49 replaceTestDuration, 50 replaceTestLocationLine, 51); 52const specTransform = snapshot.transform( 53 replaceSpecDuration, 54 snapshot.replaceWindowsLineEndings, 55 snapshot.replaceStackTrace, 56); 57const junitTransform = snapshot.transform( 58 replaceJunitDuration, 59 snapshot.replaceWindowsLineEndings, 60 snapshot.replaceStackTrace, 61); 62 63const tests = [ 64 { name: 'test-runner/output/abort.js' }, 65 { name: 'test-runner/output/abort_suite.js' }, 66 { name: 'test-runner/output/abort_hooks.js' }, 67 { name: 'test-runner/output/describe_it.js' }, 68 { name: 'test-runner/output/describe_nested.js' }, 69 { name: 'test-runner/output/hooks.js' }, 70 { name: 'test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js' }, 71 { name: 'test-runner/output/hooks-with-no-global-test.js' }, 72 { name: 'test-runner/output/before-and-after-each-too-many-listeners.js' }, 73 { name: 'test-runner/output/before-and-after-each-with-timeout-too-many-listeners.js' }, 74 { name: 'test-runner/output/global_after_should_fail_the_test.js' }, 75 { name: 'test-runner/output/no_refs.js' }, 76 { name: 'test-runner/output/no_tests.js' }, 77 { name: 'test-runner/output/only_tests.js' }, 78 { name: 'test-runner/output/dot_reporter.js' }, 79 { name: 'test-runner/output/junit_reporter.js', transform: junitTransform }, 80 { name: 'test-runner/output/spec_reporter_successful.js', transform: specTransform }, 81 { name: 'test-runner/output/spec_reporter.js', transform: specTransform }, 82 { name: 'test-runner/output/spec_reporter_cli.js', transform: specTransform }, 83 { name: 'test-runner/output/output.js' }, 84 { name: 'test-runner/output/output_cli.js' }, 85 { name: 'test-runner/output/name_pattern.js' }, 86 { name: 'test-runner/output/name_pattern_with_only.js' }, 87 { name: 'test-runner/output/unresolved_promise.js' }, 88 { name: 'test-runner/output/default_output.js', transform: specTransform, tty: true }, 89 { name: 'test-runner/output/arbitrary-output.js' }, 90 { name: 'test-runner/output/async-test-scheduling.mjs' }, 91 !skipForceColors ? { 92 name: 'test-runner/output/arbitrary-output-colored.js', 93 transform: snapshot.transform(specTransform, replaceTestDuration), tty: true 94 } : false, 95 { name: 'test-runner/output/dot_output_custom_columns.js', transform: specTransform, tty: true }, 96 { 97 name: 'test-runner/output/tap_escape.js', 98 transform: snapshot.transform( 99 snapshot.replaceWindowsLineEndings, 100 replaceTestDuration, 101 ), 102 }, 103 process.features.inspector ? { name: 'test-runner/output/coverage_failure.js' } : false, 104] 105.filter(Boolean) 106.map(({ name, tty, transform }) => ({ 107 name, 108 fn: common.mustCall(async () => { 109 await snapshot.spawnAndAssert(fixtures.path(name), transform ?? defaultTransform, { tty }); 110 }), 111})); 112 113describe('test runner output', { concurrency: true }, () => { 114 for (const { name, fn } of tests) { 115 it(name, fn); 116 } 117}); 118