Skip to content

Commit ab510f5

Browse files
authored
feat(jest-config): openHandlesTimeout config option (#13875)
1 parent 39a0e05 commit ab510f5

File tree

16 files changed

+74
-12
lines changed

16 files changed

+74
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- `[jest-changed-files]` Support Sapling ([#13941](https://github.com/facebook/jest/pull/13941))
66
- `[jest-cli, jest-config, @jest/core, jest-haste-map, @jest/reporters, jest-runner, jest-runtime, @jest/types]` Add `workerThreads` configuration option to allow using [worker threads](https://nodejs.org/dist/latest/docs/api/worker_threads.html) for parallelization ([#13939](https://github.com/facebook/jest/pull/13939))
7+
- `[jest-config]` Add `openHandlesTimeout` option to configure possible open handles warning. ([#13875](https://github.com/facebook/jest/pull/13875))
78
- `[@jest/create-cache-key-function]` Allow passing `length` argument to `createCacheKey()` function and set its default value to `16` on Windows ([#13827](https://github.com/facebook/jest/pull/13827))
89
- `[jest-message-util]` Add support for [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) ([#13946](https://github.com/facebook/jest/pull/13946))
910
- `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937))

docs/CLI.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ Activates notifications for test results. Good for when you don't want your cons
310310

311311
Alias: `-o`. Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a git/hg repository at the moment and requires a static dependency graph (ie. no dynamic requires).
312312

313+
### `--openHandlesTimeout=<milliseconds>`
314+
315+
When `--detectOpenHandles` and `--forceExit` are _disabled_, Jest will print a warning if the process has not exited cleanly after this number of milliseconds. A value of `0` disables the warning. Defaults to `1000`.
316+
313317
### `--outputFile=<filename>`
314318

315319
Write test results to a file when the `--json` option is also specified. The returned JSON structure is documented in [testResultsProcessor](Configuration.md#testresultsprocessor-string).

docs/Configuration.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,12 @@ Specifies notification mode. Requires `notify: true`.
10781078
- `success-change`: send a notification when tests pass or once when it fails.
10791079
- `failure-change`: send a notification when tests fail or once when it passes.
10801080

1081+
### `openHandlesTimeout` \[number]
1082+
1083+
Default: `1000`
1084+
1085+
Print a warning indicating that there are probable open handles if Jest does not exit cleanly this number of milliseconds after it completes. Use `0` to disable the warning.
1086+
10811087
### `preset` \[string]
10821088

10831089
Default: `undefined`

e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ exports[`prints message about flag on forceExit 1`] = `"Force exiting Jest: Have
77
exports[`prints message about flag on slow tests 1`] = `
88
"Jest did not exit one second after the test run has completed.
99
10-
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with \`--detectOpenHandles\` to troubleshoot this issue."
10+
'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with \`--detectOpenHandles\` to troubleshoot this issue."
11+
`;
12+
13+
exports[`prints message about flag on slow tests with a custom timeout 1`] = `
14+
"Jest did not exit 0.5 seconds after the test run has completed.
15+
16+
'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with \`--detectOpenHandles\` to troubleshoot this issue."
1117
`;
1218

1319
exports[`prints out info about open handlers 1`] = `

e2e/__tests__/__snapshots__/showConfig.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
4444
],
4545
"moduleNameMapper": [],
4646
"modulePathIgnorePatterns": [],
47+
"openHandlesTimeout": 1000,
4748
"prettierPath": "prettier",
4849
"resetMocks": false,
4950
"resetModules": false,
@@ -121,6 +122,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
121122
"notifyMode": "failure-change",
122123
"onlyChanged": false,
123124
"onlyFailures": false,
125+
"openHandlesTimeout": 1000,
124126
"passWithNoTests": false,
125127
"projects": [],
126128
"rootDir": "<<REPLACED_ROOT_DIR>>",

e2e/__tests__/detectOpenHandles.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ it('prints message about flag on slow tests', async () => {
2929
expect(textAfterTest).toMatchSnapshot();
3030
});
3131

32+
it('prints message about flag on slow tests with a custom timeout', async () => {
33+
const run = runContinuous('detect-open-handles', [
34+
'outside',
35+
'--openHandlesTimeout=500',
36+
]);
37+
await run.waitUntil(({stderr}) =>
38+
stderr.includes('Jest did not exit 0.5 seconds'),
39+
);
40+
const {stderr} = await run.end();
41+
const textAfterTest = getTextAfterTest(stderr);
42+
43+
expect(textAfterTest).toMatchSnapshot();
44+
});
45+
3246
it('prints message about flag on forceExit', async () => {
3347
const run = runContinuous('detect-open-handles', ['outside', '--forceExit']);
3448
await run.waitUntil(({stderr}) => stderr.includes('Force exiting Jest'));

packages/jest-cli/src/args.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ export const options: {[key: string]: Options} = {
423423
description: 'Run tests that failed in the previous execution.',
424424
type: 'boolean',
425425
},
426+
openHandlesTimeout: {
427+
description:
428+
'Print a warning about probable open handles if Jest does not exit ' +
429+
'cleanly after this number of milliseconds. `0` to disable.',
430+
type: 'number',
431+
},
426432
outputFile: {
427433
description:
428434
'Write test results to a file when the --json option is ' +

packages/jest-cli/src/run.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,24 @@ const readResultsAndExit = (
132132
}
133133

134134
exit(code);
135-
} else if (!globalConfig.detectOpenHandles) {
135+
} else if (
136+
!globalConfig.detectOpenHandles &&
137+
globalConfig.openHandlesTimeout !== 0
138+
) {
139+
const timeout = globalConfig.openHandlesTimeout;
136140
setTimeout(() => {
137141
console.warn(
138142
chalk.yellow.bold(
139-
'Jest did not exit one second after the test run has completed.\n\n',
143+
`Jest did not exit ${
144+
timeout === 1000 ? 'one second' : `${timeout / 1000} seconds`
145+
} after the test run has completed.\n\n'`,
140146
) +
141147
chalk.yellow(
142148
'This usually means that there are asynchronous operations that ' +
143149
"weren't stopped in your tests. Consider running Jest with " +
144150
'`--detectOpenHandles` to troubleshoot this issue.',
145151
),
146152
);
147-
}, 1000).unref();
153+
}, timeout).unref();
148154
}
149155
};

packages/jest-config/src/Defaults.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const defaultOptions: Config.DefaultOptions = {
6060
noStackTrace: false,
6161
notify: false,
6262
notifyMode: 'failure-change',
63+
openHandlesTimeout: 1000,
6364
passWithNoTests: false,
6465
prettierPath: 'prettier',
6566
resetMocks: false,

packages/jest-config/src/ValidConfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export const initialOptions: Config.InitialOptions = {
116116
notifyMode: 'failure-change',
117117
onlyChanged: false,
118118
onlyFailures: false,
119+
openHandlesTimeout: 1000,
119120
passWithNoTests: false,
120121
preset: 'react-native',
121122
prettierPath: '<rootDir>/node_modules/prettier',
@@ -262,6 +263,7 @@ export const initialProjectOptions: Config.InitialProjectOptions = {
262263
},
263264
modulePathIgnorePatterns: ['<rootDir>/build/'],
264265
modulePaths: ['/shared/vendor/modules'],
266+
openHandlesTimeout: 1000,
265267
preset: 'react-native',
266268
prettierPath: '<rootDir>/node_modules/prettier',
267269
resetMocks: false,

0 commit comments

Comments
 (0)