diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f79ba66b72..10f2f668712b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixes - `[expect]` Allow again `expect.Matchers` generic with single value ([#11986](https://github.com/facebook/jest/pull/11986)) +- `[jest-circus, jest-jasmine2]` Avoid false concurrent test failures due to unhandled promise rejections ([#11987](https://github.com/facebook/jest/pull/11987)) - `[jest-config]` Add missing `slash` dependency to `package.json` ([#12080](https://github.com/facebook/jest/pull/12080)) - `[jest-core]` Incorrect detection of open ZLIB handles ([#12022](https://github.com/facebook/jest/pull/12022)) - `[jest-diff]` Break dependency cycle ([#10818](https://github.com/facebook/jest/pull/10818)) diff --git a/e2e/__tests__/jasmineAsync.test.ts b/e2e/__tests__/jasmineAsync.test.ts index 3006a04b3810..8b6cfb93ec1c 100644 --- a/e2e/__tests__/jasmineAsync.test.ts +++ b/e2e/__tests__/jasmineAsync.test.ts @@ -168,4 +168,13 @@ describe('async jasmine', () => { expect(result.exitCode).toBe(0); }); + + it('works when another test fails while one is running', () => { + const {json} = runWithJson('jasmine-async', [ + 'concurrent-parallel-failure.test.js', + ]); + expect(json.numTotalTests).toBe(2); + expect(json.numPassedTests).toBe(1); + expect(json.numFailedTests).toBe(1); + }); }); diff --git a/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js b/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js new file mode 100644 index 000000000000..e4869be91465 --- /dev/null +++ b/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js @@ -0,0 +1,16 @@ +/** + * 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. + */ + +'use strict'; + +it.concurrent('Good Test', async () => { + await new Promise(r => setTimeout(r, 100)); +}); + +it.concurrent('Bad Test', async () => { + expect('a').toBe('b'); +}); diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index d7487477e31d..43bf59f1af4e 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -93,6 +93,9 @@ export const initialize = async ({ // that will result in this test to be skipped, so we'll be executing the promise function anyway, // even if it ends up being skipped. const promise = mutex(() => testFn()); + // Avoid triggering the uncaught promise rejection handler in case the test errors before + // being awaited on. + promise.catch(() => {}); globalsObject.test(testName, () => promise, timeout); }; diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 6a31a66c32b7..84836e81dba4 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -215,6 +215,9 @@ function makeConcurrent( } catch (error: unknown) { promise = Promise.reject(error); } + // Avoid triggering the uncaught promise rejection handler in case the test errors before + // being awaited on. + promise.catch(() => {}); return spec; };