diff --git a/CHANGELOG.md b/CHANGELOG.md index 746172c7f036..52ff51bd42d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - `[jest-core]` make `TestWatcher` extend `emittery` ([#10324](https://github.com/facebook/jest/pull/10324)) - `[jest-core]` Run failed tests interactively the same way we do with snapshots ([#10858](https://github.com/facebook/jest/pull/10858)) - `[jest-core]` more `TestSequencer` methods can be async ([#10980](https://github.com/facebook/jest/pull/10980)) +- `[jest-core]` Add support for `testSequencer` written in ESM ([#11207](https://github.com/facebook/jest/pull/11207)) - `[jest-environment-node]` Add AbortController to globals ([#11182](https://github.com/facebook/jest/pull/11182)) - `[@jest/fake-timers]` Update to `@sinonjs/fake-timers` to v7 ([#11198](https://github.com/facebook/jest/pull/11198)) - `[jest-haste-map]` Handle injected scm clocks ([#10966](https://github.com/facebook/jest/pull/10966)) diff --git a/e2e/__tests__/customEsmTestSequencers.test.ts b/e2e/__tests__/customEsmTestSequencers.test.ts new file mode 100644 index 000000000000..6fdadb280af8 --- /dev/null +++ b/e2e/__tests__/customEsmTestSequencers.test.ts @@ -0,0 +1,32 @@ +/** + * 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. + */ + +import * as path from 'path'; +import {onNodeVersions} from '@jest/test-utils'; +import {extractSummary} from '../Utils'; +import runJest from '../runJest'; +const dir = path.resolve(__dirname, '../custom-esm-test-sequencer'); + +onNodeVersions('^12.16.0 || >=13.7.0', () => { + test('run prioritySequence', () => { + const result = runJest(dir, ['-i'], { + nodeOptions: '--experimental-vm-modules --no-warnings', + }); + + expect(result.exitCode).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', + ]); + }); +}); diff --git a/e2e/custom-esm-test-sequencer/a.test.js b/e2e/custom-esm-test-sequencer/a.test.js new file mode 100644 index 000000000000..1187e8309f87 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/a.test.js @@ -0,0 +1,7 @@ +/** + * 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. + */ +test('a', () => {}); diff --git a/e2e/custom-esm-test-sequencer/b.test.js b/e2e/custom-esm-test-sequencer/b.test.js new file mode 100644 index 000000000000..04e77e777bb1 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/b.test.js @@ -0,0 +1,7 @@ +/** + * 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. + */ +test('b', () => {}); diff --git a/e2e/custom-esm-test-sequencer/c.test.js b/e2e/custom-esm-test-sequencer/c.test.js new file mode 100644 index 000000000000..332d8682ab00 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/c.test.js @@ -0,0 +1,7 @@ +/** + * 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. + */ +test('c', () => {}); diff --git a/e2e/custom-esm-test-sequencer/d.test.js b/e2e/custom-esm-test-sequencer/d.test.js new file mode 100644 index 000000000000..4102fe8c1925 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/d.test.js @@ -0,0 +1,7 @@ +/** + * 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. + */ +test('d', () => {}); diff --git a/e2e/custom-esm-test-sequencer/e.test.js b/e2e/custom-esm-test-sequencer/e.test.js new file mode 100644 index 000000000000..6b4bbf07b9b4 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/e.test.js @@ -0,0 +1,7 @@ +/** + * 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. + */ +test('e', () => {}); diff --git a/e2e/custom-esm-test-sequencer/package.json b/e2e/custom-esm-test-sequencer/package.json new file mode 100644 index 000000000000..4bc9288b13b7 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/package.json @@ -0,0 +1,8 @@ +{ + "type": "module", + "jest": { + "testEnvironment": "node", + "transform": {}, + "testSequencer": "/testSequencer.mjs" + } +} diff --git a/e2e/custom-esm-test-sequencer/testSequencer.mjs b/e2e/custom-esm-test-sequencer/testSequencer.mjs new file mode 100644 index 000000000000..f01adee77e64 --- /dev/null +++ b/e2e/custom-esm-test-sequencer/testSequencer.mjs @@ -0,0 +1,15 @@ +/** + * 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. + */ + +import Sequencer from '@jest/test-sequencer'; + +export default class CustomSequencer extends Sequencer.default { + sort(tests) { + const copyTests = Array.from(tests); + return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1)); + } +} diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index e54a2435a77e..008f102a4a4e 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -20,7 +20,7 @@ import type {Config} from '@jest/types'; import type {ChangedFiles, ChangedFilesPromise} from 'jest-changed-files'; import type {Test} from 'jest-runner'; import type {Context} from 'jest-runtime'; -import {interopRequireDefault, tryRealpath} from 'jest-util'; +import {requireOrImportModule, tryRealpath} from 'jest-util'; import {JestHook, JestHookEmitter} from 'jest-watcher'; import type FailedTestsCache from './FailedTestsCache'; import SearchSource from './SearchSource'; @@ -142,9 +142,9 @@ export default async function runJest({ failedTestsCache?: FailedTestsCache; filter?: Filter; }): Promise { - const Sequencer: typeof TestSequencer = interopRequireDefault( - require(globalConfig.testSequencer), - ).default; + const Sequencer: typeof TestSequencer = await requireOrImportModule( + globalConfig.testSequencer, + ); const sequencer = new Sequencer(); let allTests: Array = [];