diff --git a/CHANGELOG.md b/CHANGELOG.md index b357758570eb..f7200de0f981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - `[@jest/core]` Group together open handles with the same stack trace ([#13417](https://github.com/jestjs/jest/pull/13417), & [#14789](https://github.com/jestjs/jest/pull/14789)) - `[@jest/core]` Add `perfStats` to surface test setup overhead ([#14622](https://github.com/jestjs/jest/pull/14622)) - `[@jest/core]` [**BREAKING**] Changed `--filter` to accept an object with shape `{ filtered: Array }` to match [documentation](https://jestjs.io/docs/cli#--filterfile) ([#13319](https://github.com/jestjs/jest/pull/13319)) +- `[@jest/core]` Support `--outputFile` option for [listTests](https://jestjs.io/docs/cli#--listtests) ([#14944](https://github.com/facebook/jest/pull/14944)) - `[@jest/core, @jest/test-sequencer]` [**BREAKING**] Exposes `globalConfig` & `contexts` to `TestSequencer` ([#14535](https://github.com/jestjs/jest/pull/14535), & [#14543](https://github.com/jestjs/jest/pull/14543)) - `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM to v22 ([#13825](https://github.com/jestjs/jest/pull/13825)) - `[@jest/environment-jsdom-abstract]` Introduce new package which abstracts over the `jsdom` environment, allowing usage of custom versions of JSDOM ([#14717](https://github.com/jestjs/jest/pull/14717)) diff --git a/e2e/__tests__/__snapshots__/listTests.test.ts.snap b/e2e/__tests__/__snapshots__/listTests.test.ts.snap index 519ed836efdb..1440d531b30a 100644 --- a/e2e/__tests__/__snapshots__/listTests.test.ts.snap +++ b/e2e/__tests__/__snapshots__/listTests.test.ts.snap @@ -1,5 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`--listTests flag --outputFile flag causes tests to be saved in the file as JSON 1`] = `"["/MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/dummy.test.js","/MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/other.test.js"]"`; + +exports[`--listTests flag --outputFile flag causes tests to be saved in the file in different lines 1`] = ` +"/MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/dummy.test.js +/MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/other.test.js" +`; + exports[`--listTests flag causes tests to be printed in different lines 1`] = ` "/MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/dummy.test.js /MOCK_ABSOLUTE_PATH/e2e/list-tests/__tests__/other.test.js" diff --git a/e2e/__tests__/listTests.test.ts b/e2e/__tests__/listTests.test.ts index 811527848d4d..4e08588cd96e 100644 --- a/e2e/__tests__/listTests.test.ts +++ b/e2e/__tests__/listTests.test.ts @@ -6,6 +6,7 @@ */ import * as path from 'path'; +import * as fs from 'graceful-fs'; import runJest from '../runJest'; const testRootDir = path.resolve(__dirname, '..', '..'); @@ -36,4 +37,51 @@ describe('--listTests flag', () => { JSON.stringify(JSON.parse(stdout).map(normalizePaths).sort()), ).toMatchSnapshot(); }); + + describe('--outputFile flag', () => { + const outputFilePath = path.resolve('.', 'test-lists.json'); + afterAll(() => { + fs.unlinkSync(outputFilePath); + }); + it('causes tests to be saved in the file as JSON', () => { + const {exitCode, stdout} = runJest('list-tests', [ + '--listTests', + '--json', + '--outputFile', + outputFilePath, + ]); + + expect(exitCode).toBe(0); + expect(stdout).toBe(''); + + const outputFileExists = fs.existsSync(outputFilePath); + expect(outputFileExists).toBe(true); + + const outputFileContent = fs.readFileSync(outputFilePath, 'utf8'); + expect(() => JSON.parse(outputFileContent)).not.toThrow(); + expect( + JSON.stringify( + JSON.parse(outputFileContent).map(normalizePaths).sort(), + ), + ).toMatchSnapshot(); + }); + it('causes tests to be saved in the file in different lines', () => { + const {exitCode, stdout} = runJest('list-tests', [ + '--listTests', + '--outputFile', + outputFilePath, + ]); + + expect(exitCode).toBe(0); + expect(stdout).toBe(''); + + const outputFileExists = fs.existsSync(outputFilePath); + expect(outputFileExists).toBe(true); + + const outputFileContent = fs.readFileSync(outputFilePath, 'utf8'); + expect( + normalizePaths(outputFileContent).split('\n').sort().join('\n'), + ).toMatchSnapshot(); + }); + }); }); diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index 565cec8fc7f2..f1bdee4d3e02 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -214,15 +214,19 @@ export default async function runJest({ if (globalConfig.listTests) { const testsPaths = [...new Set(allTests.map(test => test.path))]; - /* eslint-disable no-console */ - if (globalConfig.json) { - console.log(JSON.stringify(testsPaths)); + const testsListOutput = globalConfig.json + ? JSON.stringify(testsPaths) + : testsPaths.join('\n'); + + if (globalConfig.outputFile) { + const outputFile = path.resolve(process.cwd(), globalConfig.outputFile); + fs.writeFileSync(outputFile, testsListOutput, 'utf8'); } else { - console.log(testsPaths.join('\n')); + // eslint-disable-next-line no-console + console.log(testsListOutput); } - /* eslint-enable */ - onComplete && onComplete(makeEmptyAggregatedTestResult()); + onComplete(makeEmptyAggregatedTestResult()); return; }