diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c699042c1f..f2dd803bd767 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[pretty-format]` Render custom displayName of memoized components - `[jest-validate]` Allow `maxWorkers` as part of the `jest.config.js` ([#8565](https://github.com/facebook/jest/pull/8565)) - `[jest-runtime]` Allow passing configuration objects to transformers ([#7288](https://github.com/facebook/jest/pull/7288)) +- `[@jest/core, @jest/test-sequencer]` Support async sort in custom `testSequencer` ([#8642](https://github.com/facebook/jest/pull/8642)) ### Fixes diff --git a/docs/Configuration.md b/docs/Configuration.md index ca1bb7dd3e5c..766ca3cf2b0e 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1039,11 +1039,11 @@ An example of such function can be found in our default [jasmine2 test runner pa Default: `@jest/test-sequencer` -This option allows you to use a custom sequencer instead of Jest's default. +This option allows you to use a custom sequencer instead of Jest's default. `sort` may optionally return a Promise. Example: -Sort test path alphabetically +Sort test path alphabetically. ```js const Sequencer = require('@jest/test-sequencer').default; diff --git a/e2e/__tests__/customTestSequencers.test.ts b/e2e/__tests__/customTestSequencers.test.ts index d9cb5f039db4..1f8ec40bb4b1 100644 --- a/e2e/__tests__/customTestSequencers.test.ts +++ b/e2e/__tests__/customTestSequencers.test.ts @@ -10,8 +10,43 @@ import runJest from '../runJest'; import {extractSummary} from '../Utils'; const dir = path.resolve(__dirname, '../custom-test-sequencer'); -test('run prioritySequence first', () => { - const result = runJest(dir, ['-i']); +test('run prioritySequence first sync', () => { + const result = runJest( + dir, + [ + '-i', + '--config', + JSON.stringify({ + testSequencer: '/testSequencer.js', + }), + ], + {}, + ); + expect(result.status).toBe(0); + const sequence = extractSummary(result.stderr) + .rest.replace(/PASS /g, '') + .split('\n'); + expect(sequence).toEqual([ + './a.test.js', + './b.test.js', + './c.test.js', + './d.test.js', + './e.test.js', + ]); +}); + +test('run prioritySequence first async', () => { + const result = runJest( + dir, + [ + '-i', + '--config', + JSON.stringify({ + testSequencer: '/testSequencerAsync.js', + }), + ], + {}, + ); expect(result.status).toBe(0); const sequence = extractSummary(result.stderr) .rest.replace(/PASS /g, '') diff --git a/e2e/custom-test-sequencer/package.json b/e2e/custom-test-sequencer/package.json index 80ef569e593c..148788b25446 100644 --- a/e2e/custom-test-sequencer/package.json +++ b/e2e/custom-test-sequencer/package.json @@ -1,6 +1,5 @@ { "jest": { - "testEnvironment": "node", - "testSequencer": "/testSequencer.js" + "testEnvironment": "node" } } diff --git a/e2e/custom-test-sequencer/testSequencerAsync.js b/e2e/custom-test-sequencer/testSequencerAsync.js new file mode 100644 index 000000000000..cf379c64752d --- /dev/null +++ b/e2e/custom-test-sequencer/testSequencerAsync.js @@ -0,0 +1,23 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const Sequencer = require('@jest/test-sequencer').default; + +class CustomSequencer extends Sequencer { + sort(tests) { + return new Promise(resolve => { + setTimeout(() => { + const copyTests = Array.from(tests); + resolve( + copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1)) + ); + }, 50); + }); + } +} + +module.exports = CustomSequencer; diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index b0906aeb616e..0d82b9aab33a 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -183,7 +183,7 @@ export default (async function runJest({ }), ); - allTests = sequencer.sort(allTests); + allTests = await sequencer.sort(allTests); if (globalConfig.listTests) { const testsPaths = Array.from(new Set(allTests.map(test => test.path)));