From 168433e37a5d0db7088a6c89bfa9664f1a691968 Mon Sep 17 00:00:00 2001 From: Vadimchesh Date: Wed, 20 Mar 2024 12:09:46 +0100 Subject: [PATCH 1/5] feat: add immediately option to jest.retryTimes (#14696) --- docs/JestObjectAPI.md | 10 ++++ .../__snapshots__/testRetries.test.ts.snap | 39 ++++++++++++++ e2e/__tests__/testRetries.test.ts | 20 ++++++++ .../__tests__/immediatelyRetry.test.js | 23 +++++++++ packages/jest-circus/src/run.ts | 51 +++++++++++++------ packages/jest-circus/src/types.ts | 1 + packages/jest-environment/src/index.ts | 9 +++- packages/jest-runtime/src/index.ts | 2 + 8 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 e2e/test-retries/__tests__/immediatelyRetry.test.js diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 82007ee41703..e231ad590f87 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -1139,6 +1139,16 @@ test('will fail', () => { }); ``` +`immediately` option is used to retry the failed test immediately. + +```js +jest.retryTimes(3, {immediately: true}); + +test('will fail', () => { + expect(true).toBe(false); +}); +``` + Returns the `jest` object for chaining. :::caution diff --git a/e2e/__tests__/__snapshots__/testRetries.test.ts.snap b/e2e/__tests__/__snapshots__/testRetries.test.ts.snap index 3317a40cbceb..8bb2d6a99725 100644 --- a/e2e/__tests__/__snapshots__/testRetries.test.ts.snap +++ b/e2e/__tests__/__snapshots__/testRetries.test.ts.snap @@ -1,5 +1,44 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Test Retries immediately retry after failed test 1`] = ` +"LOGGING RETRY ERRORS retryTimes set + RETRY 1 + + expect(received).toBeFalsy() + + Received: true + + 15 | expect(true).toBeTruthy(); + 16 | } else { + > 17 | expect(true).toBeFalsy(); + | ^ + 18 | } + 19 | }); + 20 | it('truthy test', () => { + + at Object.toBeFalsy (__tests__/immediatelyRetry.test.js:17:18) + + RETRY 2 + + expect(received).toBeFalsy() + + Received: true + + 15 | expect(true).toBeTruthy(); + 16 | } else { + > 17 | expect(true).toBeFalsy(); + | ^ + 18 | } + 19 | }); + 20 | it('truthy test', () => { + + at Object.toBeFalsy (__tests__/immediatelyRetry.test.js:17:18) + +PASS __tests__/immediatelyRetry.test.js + ✓ retryTimes set + ✓ truthy test" +`; + exports[`Test Retries logs error(s) before retry 1`] = ` "LOGGING RETRY ERRORS retryTimes set RETRY 1 diff --git a/e2e/__tests__/testRetries.test.ts b/e2e/__tests__/testRetries.test.ts index acb3ffc25f39..227c1ed6dd2f 100644 --- a/e2e/__tests__/testRetries.test.ts +++ b/e2e/__tests__/testRetries.test.ts @@ -60,6 +60,26 @@ describe('Test Retries', () => { expect(extractSummary(result.stderr).rest).toMatchSnapshot(); }); + it('immediately retry after failed test', () => { + const logMessage = `console.log + FIRST TRUTHY TEST + + at Object.log (__tests__/immediatelyRetry.test.js:14:13) + + console.log + SECOND TRUTHY TEST + + at Object.log (__tests__/immediatelyRetry.test.js:21:11)`; + + const result = runJest('test-retries', ['immediatelyRetry.test.js']); + const stdout = result.stdout.trim(); + expect(result.exitCode).toBe(0); + expect(result.failed).toBe(false); + expect(result.stderr).toContain(logErrorsBeforeRetryErrorMessage); + expect(stdout).toBe(logMessage); + expect(extractSummary(result.stderr).rest).toMatchSnapshot(); + }); + it('reporter shows more than 1 invocation if test is retried', () => { let jsonResult; diff --git a/e2e/test-retries/__tests__/immediatelyRetry.test.js b/e2e/test-retries/__tests__/immediatelyRetry.test.js new file mode 100644 index 000000000000..252d11d6b840 --- /dev/null +++ b/e2e/test-retries/__tests__/immediatelyRetry.test.js @@ -0,0 +1,23 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +jest.retryTimes(3, {immediately: true, logErrorsBeforeRetry: true}); +let i = 0; +it('retryTimes set', () => { + i++; + if (i === 3) { + console.log('FIRST TRUTHY TEST'); + expect(true).toBeTruthy(); + } else { + expect(true).toBeFalsy(); + } +}); +it('truthy test', () => { + console.log('SECOND TRUTHY TEST'); + expect(true).toBeTruthy(); +}); diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index 40f9695959ec..dec3af02d943 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -15,7 +15,7 @@ import shuffleArray, { rngBuilder, } from './shuffleArray'; import {dispatch, getState} from './state'; -import {RETRY_TIMES, WAIT_BEFORE_RETRY} from './types'; +import {IMMEDIATELY, RETRY_TIMES, WAIT_BEFORE_RETRY} from './types'; import { callAsyncCircusFn, getAllHooksForDescribe, @@ -78,11 +78,32 @@ const _runTestsForDescribeBlock = async ( (global as Global.Global)[WAIT_BEFORE_RETRY] as string, 10, ) || 0; + const retryImmediately: boolean = + // eslint-disable-next-line no-restricted-globals + ((global as Global.Global)[IMMEDIATELY] as any) || false; + const deferredRetryTests = []; if (rng) { describeBlock.children = shuffleArray(describeBlock.children, rng); } + + const rerunTest = async (test: Circus.TestEntry) => { + let numRetriesAvailable = retryTimes; + + while (numRetriesAvailable > 0 && test.errors.length > 0) { + // Clear errors so retries occur + await dispatch({name: 'test_retry', test}); + + if (waitBeforeRetry > 0) { + await new Promise(resolve => setTimeout(resolve, waitBeforeRetry)); + } + + await _runTest(test, isSkipped); + numRetriesAvailable--; + } + }; + for (const child of describeBlock.children) { switch (child.type) { case 'describeBlock': { @@ -91,12 +112,22 @@ const _runTestsForDescribeBlock = async ( } case 'test': { const hasErrorsBeforeTestRun = child.errors.length > 0; + const hasRetryTimes = retryTimes > 0; await _runTest(child, isSkipped); + //If immediate retry is set, we retry the test immediately after the first run if ( + retryImmediately && hasErrorsBeforeTestRun === false && - retryTimes > 0 && - child.errors.length > 0 + hasRetryTimes + ) { + await rerunTest(child); + } + + if ( + hasErrorsBeforeTestRun === false && + hasRetryTimes && + !retryImmediately ) { deferredRetryTests.push(child); } @@ -107,19 +138,7 @@ const _runTestsForDescribeBlock = async ( // Re-run failed tests n-times if configured for (const test of deferredRetryTests) { - let numRetriesAvailable = retryTimes; - - while (numRetriesAvailable > 0 && test.errors.length > 0) { - // Clear errors so retries occur - await dispatch({name: 'test_retry', test}); - - if (waitBeforeRetry > 0) { - await new Promise(resolve => setTimeout(resolve, waitBeforeRetry)); - } - - await _runTest(test, isSkipped); - numRetriesAvailable--; - } + await rerunTest(test); } if (!isSkipped) { diff --git a/packages/jest-circus/src/types.ts b/packages/jest-circus/src/types.ts index 0e64cf823033..a337543e1249 100644 --- a/packages/jest-circus/src/types.ts +++ b/packages/jest-circus/src/types.ts @@ -7,6 +7,7 @@ export const STATE_SYM = Symbol('JEST_STATE_SYMBOL'); export const RETRY_TIMES = Symbol.for('RETRY_TIMES'); +export const IMMEDIATELY = Symbol.for('IMMEDIATELY'); export const WAIT_BEFORE_RETRY = Symbol.for('WAIT_BEFORE_RETRY'); // To pass this value from Runtime object to state we need to use global[sym] export const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL'); diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index ad3e6c1be1ce..f3b2e648cec1 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -300,12 +300,19 @@ export interface Jest { * * `waitBeforeRetry` is the number of milliseconds to wait before retrying * + * `immediately` is the flag to retry the failed tests immediately after + * failure + * * @remarks * Only available with `jest-circus` runner. */ retryTimes( numRetries: number, - options?: {logErrorsBeforeRetry?: boolean; waitBeforeRetry?: number}, + options?: { + logErrorsBeforeRetry?: boolean; + waitBeforeRetry?: number; + immediately?: boolean; + }, ): Jest; /** * Exhausts tasks queued by `setImmediate()`. diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 1c004f26ca40..31e22b8e2507 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -123,6 +123,7 @@ type ResolveOptions = Parameters[1] & { const testTimeoutSymbol = Symbol.for('TEST_TIMEOUT_SYMBOL'); const retryTimesSymbol = Symbol.for('RETRY_TIMES'); const waitBeforeRetrySymbol = Symbol.for('WAIT_BEFORE_RETRY'); +const immediatelySybmbol = Symbol.for('IMMEDIATELY'); const logErrorsBeforeRetrySymbol = Symbol.for('LOG_ERRORS_BEFORE_RETRY'); const NODE_MODULES = `${path.sep}node_modules${path.sep}`; @@ -2292,6 +2293,7 @@ export default class Runtime { options?.logErrorsBeforeRetry; this._environment.global[waitBeforeRetrySymbol] = options?.waitBeforeRetry; + this._environment.global[immediatelySybmbol] = options?.immediately; return jestObject; }; From b58faf329e9500571419a5a7516af90839c281c4 Mon Sep 17 00:00:00 2001 From: Vadimchesh Date: Wed, 20 Mar 2024 13:38:00 +0100 Subject: [PATCH 2/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 179398c50251..2f665e34c04b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - `[jest-circus, jest-cli, jest-config]` Add `waitNextEventLoopTurnForUnhandledRejectionEvents` flag to minimise performance impact of correct detection of unhandled promise rejections introduced in [#14315](https://github.com/jestjs/jest/pull/14315) ([#14681](https://github.com/jestjs/jest/pull/14681)) - `[jest-circus]` Add a `waitBeforeRetry` option to `jest.retryTimes` ([#14738](https://github.com/jestjs/jest/pull/14738)) +- `[jest-circus]` Add a `immediately` option to `jest.retryTimes` ([#14696](https://github.com/jestjs/jest/pull/14696)) - `[jest-circus, jest-jasmine2]` Allow `setupFilesAfterEnv` to export an async function ([#10962](https://github.com/jestjs/jest/issues/10962)) - `[jest-config]` [**BREAKING**] Add `mts` and `cts` to default `moduleFileExtensions` config ([#14369](https://github.com/facebook/jest/pull/14369)) - `[jest-config]` [**BREAKING**] Update `testMatch` and `testRegex` default option for supporting `mjs`, `cjs`, `mts`, and `cts` ([#14584](https://github.com/jestjs/jest/pull/14584)) From 6cffa1bc73ed7eee1e3536d7d9ab1d78f892411b Mon Sep 17 00:00:00 2001 From: Vadimchesh Date: Wed, 20 Mar 2024 15:39:06 +0100 Subject: [PATCH 3/5] update api description, add type test --- docs/JestObjectAPI.md | 2 +- packages/jest-circus/src/run.ts | 1 + packages/jest-environment/src/index.ts | 2 +- packages/jest-types/__typetests__/jest.test.ts | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index e231ad590f87..7ab2b55efa45 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -1139,7 +1139,7 @@ test('will fail', () => { }); ``` -`immediately` option is used to retry the failed test immediately. +`immediately` option is used to retry the failed test immediately after the failure. If this option is not specified, the tests are retried after Jest is finished running all test in a file. ```js jest.retryTimes(3, {immediately: true}); diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index dec3af02d943..0081a64453f1 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -78,6 +78,7 @@ const _runTestsForDescribeBlock = async ( (global as Global.Global)[WAIT_BEFORE_RETRY] as string, 10, ) || 0; + const retryImmediately: boolean = // eslint-disable-next-line no-restricted-globals ((global as Global.Global)[IMMEDIATELY] as any) || false; diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index f3b2e648cec1..37c61495d1a4 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -309,9 +309,9 @@ export interface Jest { retryTimes( numRetries: number, options?: { + immediately?: boolean; logErrorsBeforeRetry?: boolean; waitBeforeRetry?: number; - immediately?: boolean; }, ): Jest; /** diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index bdd26ae82811..9c5530e1e3eb 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -667,6 +667,9 @@ expect(jest.retryTimes(3, {logErrorsBeforeRetry: 'all'})).type.toRaiseError(); expect(jest.retryTimes({logErrorsBeforeRetry: true})).type.toRaiseError(); expect(jest.retryTimes(3, {waitBeforeRetry: 1000})).type.toEqual(); expect(jest.retryTimes(3, {waitBeforeRetry: true})).type.toRaiseError(); +expect(jest.retryTimes(3, {immediately: true})).type.toEqual(); +expect(jest.retryTimes(3, {immediately: 'now'})).type.toRaiseError(); +expect(jest.retryTimes(3, {immediately: 1000})).type.toRaiseError(); expect(jest.retryTimes({logErrorsBeforeRetry: 'all'})).type.toRaiseError(); expect(jest.retryTimes()).type.toRaiseError(); From b4b398666cf50e6cd961e3c1db2a22f0c6780883 Mon Sep 17 00:00:00 2001 From: Vadimchesh Date: Wed, 20 Mar 2024 21:20:51 +0100 Subject: [PATCH 4/5] rename immedialety property to retryImmediately --- CHANGELOG.md | 2 +- docs/JestObjectAPI.md | 4 +- .../__snapshots__/testRetries.test.ts.snap | 78 +++++++++---------- e2e/__tests__/testRetries.test.ts | 8 +- ...Retry.test.js => retryImmediately.test.js} | 2 +- packages/jest-circus/src/run.ts | 4 +- packages/jest-circus/src/types.ts | 2 +- packages/jest-environment/src/index.ts | 4 +- packages/jest-runtime/src/index.ts | 5 +- .../jest-types/__typetests__/jest.test.ts | 8 +- 10 files changed, 60 insertions(+), 57 deletions(-) rename e2e/test-retries/__tests__/{immediatelyRetry.test.js => retryImmediately.test.js} (86%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f665e34c04b..0bc7e98bf629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - `[jest-circus, jest-cli, jest-config]` Add `waitNextEventLoopTurnForUnhandledRejectionEvents` flag to minimise performance impact of correct detection of unhandled promise rejections introduced in [#14315](https://github.com/jestjs/jest/pull/14315) ([#14681](https://github.com/jestjs/jest/pull/14681)) - `[jest-circus]` Add a `waitBeforeRetry` option to `jest.retryTimes` ([#14738](https://github.com/jestjs/jest/pull/14738)) -- `[jest-circus]` Add a `immediately` option to `jest.retryTimes` ([#14696](https://github.com/jestjs/jest/pull/14696)) +- `[jest-circus]` Add a `retryImmediately` option to `jest.retryTimes` ([#14696](https://github.com/jestjs/jest/pull/14696)) - `[jest-circus, jest-jasmine2]` Allow `setupFilesAfterEnv` to export an async function ([#10962](https://github.com/jestjs/jest/issues/10962)) - `[jest-config]` [**BREAKING**] Add `mts` and `cts` to default `moduleFileExtensions` config ([#14369](https://github.com/facebook/jest/pull/14369)) - `[jest-config]` [**BREAKING**] Update `testMatch` and `testRegex` default option for supporting `mjs`, `cjs`, `mts`, and `cts` ([#14584](https://github.com/jestjs/jest/pull/14584)) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 7ab2b55efa45..d7ac9f10f189 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -1139,10 +1139,10 @@ test('will fail', () => { }); ``` -`immediately` option is used to retry the failed test immediately after the failure. If this option is not specified, the tests are retried after Jest is finished running all test in a file. +`retryImmediately` option is used to retry the failed test immediately after the failure. If this option is not specified, the tests are retried after Jest is finished running all test in a file. ```js -jest.retryTimes(3, {immediately: true}); +jest.retryTimes(3, {retryImmediately: true}); test('will fail', () => { expect(true).toBe(false); diff --git a/e2e/__tests__/__snapshots__/testRetries.test.ts.snap b/e2e/__tests__/__snapshots__/testRetries.test.ts.snap index 8bb2d6a99725..ff71c0d297a7 100644 --- a/e2e/__tests__/__snapshots__/testRetries.test.ts.snap +++ b/e2e/__tests__/__snapshots__/testRetries.test.ts.snap @@ -1,44 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Test Retries immediately retry after failed test 1`] = ` -"LOGGING RETRY ERRORS retryTimes set - RETRY 1 - - expect(received).toBeFalsy() - - Received: true - - 15 | expect(true).toBeTruthy(); - 16 | } else { - > 17 | expect(true).toBeFalsy(); - | ^ - 18 | } - 19 | }); - 20 | it('truthy test', () => { - - at Object.toBeFalsy (__tests__/immediatelyRetry.test.js:17:18) - - RETRY 2 - - expect(received).toBeFalsy() - - Received: true - - 15 | expect(true).toBeTruthy(); - 16 | } else { - > 17 | expect(true).toBeFalsy(); - | ^ - 18 | } - 19 | }); - 20 | it('truthy test', () => { - - at Object.toBeFalsy (__tests__/immediatelyRetry.test.js:17:18) - -PASS __tests__/immediatelyRetry.test.js - ✓ retryTimes set - ✓ truthy test" -`; - exports[`Test Retries logs error(s) before retry 1`] = ` "LOGGING RETRY ERRORS retryTimes set RETRY 1 @@ -152,3 +113,42 @@ exports[`Test Retries wait before retry with fake timers 1`] = ` PASS __tests__/waitBeforeRetryFakeTimers.test.js ✓ retryTimes set with fake timers" `; + +exports[`Test Retries with flag retryImmediately retry immediately after failed test 1`] = ` +"LOGGING RETRY ERRORS retryTimes set + RETRY 1 + + expect(received).toBeFalsy() + + Received: true + + 15 | expect(true).toBeTruthy(); + 16 | } else { + > 17 | expect(true).toBeFalsy(); + | ^ + 18 | } + 19 | }); + 20 | it('truthy test', () => { + + at Object.toBeFalsy (__tests__/retryImmediately.test.js:17:18) + + RETRY 2 + + expect(received).toBeFalsy() + + Received: true + + 15 | expect(true).toBeTruthy(); + 16 | } else { + > 17 | expect(true).toBeFalsy(); + | ^ + 18 | } + 19 | }); + 20 | it('truthy test', () => { + + at Object.toBeFalsy (__tests__/retryImmediately.test.js:17:18) + +PASS __tests__/retryImmediately.test.js + ✓ retryTimes set + ✓ truthy test" +`; diff --git a/e2e/__tests__/testRetries.test.ts b/e2e/__tests__/testRetries.test.ts index 227c1ed6dd2f..4eac7e19be16 100644 --- a/e2e/__tests__/testRetries.test.ts +++ b/e2e/__tests__/testRetries.test.ts @@ -60,18 +60,18 @@ describe('Test Retries', () => { expect(extractSummary(result.stderr).rest).toMatchSnapshot(); }); - it('immediately retry after failed test', () => { + it('with flag retryImmediately retry immediately after failed test', () => { const logMessage = `console.log FIRST TRUTHY TEST - at Object.log (__tests__/immediatelyRetry.test.js:14:13) + at Object.log (__tests__/retryImmediately.test.js:14:13) console.log SECOND TRUTHY TEST - at Object.log (__tests__/immediatelyRetry.test.js:21:11)`; + at Object.log (__tests__/retryImmediately.test.js:21:11)`; - const result = runJest('test-retries', ['immediatelyRetry.test.js']); + const result = runJest('test-retries', ['retryImmediately.test.js']); const stdout = result.stdout.trim(); expect(result.exitCode).toBe(0); expect(result.failed).toBe(false); diff --git a/e2e/test-retries/__tests__/immediatelyRetry.test.js b/e2e/test-retries/__tests__/retryImmediately.test.js similarity index 86% rename from e2e/test-retries/__tests__/immediatelyRetry.test.js rename to e2e/test-retries/__tests__/retryImmediately.test.js index 252d11d6b840..26d3388ec200 100644 --- a/e2e/test-retries/__tests__/immediatelyRetry.test.js +++ b/e2e/test-retries/__tests__/retryImmediately.test.js @@ -6,7 +6,7 @@ */ 'use strict'; -jest.retryTimes(3, {immediately: true, logErrorsBeforeRetry: true}); +jest.retryTimes(3, {logErrorsBeforeRetry: true, retryImmediately: true}); let i = 0; it('retryTimes set', () => { i++; diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index 0081a64453f1..3d7dd89f95cf 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -15,7 +15,7 @@ import shuffleArray, { rngBuilder, } from './shuffleArray'; import {dispatch, getState} from './state'; -import {IMMEDIATELY, RETRY_TIMES, WAIT_BEFORE_RETRY} from './types'; +import {RETRY_IMMEDIATELY, RETRY_TIMES, WAIT_BEFORE_RETRY} from './types'; import { callAsyncCircusFn, getAllHooksForDescribe, @@ -81,7 +81,7 @@ const _runTestsForDescribeBlock = async ( const retryImmediately: boolean = // eslint-disable-next-line no-restricted-globals - ((global as Global.Global)[IMMEDIATELY] as any) || false; + ((global as Global.Global)[RETRY_IMMEDIATELY] as any) || false; const deferredRetryTests = []; diff --git a/packages/jest-circus/src/types.ts b/packages/jest-circus/src/types.ts index a337543e1249..4b2a6a7632e7 100644 --- a/packages/jest-circus/src/types.ts +++ b/packages/jest-circus/src/types.ts @@ -7,7 +7,7 @@ export const STATE_SYM = Symbol('JEST_STATE_SYMBOL'); export const RETRY_TIMES = Symbol.for('RETRY_TIMES'); -export const IMMEDIATELY = Symbol.for('IMMEDIATELY'); +export const RETRY_IMMEDIATELY = Symbol.for('RETRY_IMMEDIATELY'); export const WAIT_BEFORE_RETRY = Symbol.for('WAIT_BEFORE_RETRY'); // To pass this value from Runtime object to state we need to use global[sym] export const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL'); diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 37c61495d1a4..eed42adcffd7 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -300,7 +300,7 @@ export interface Jest { * * `waitBeforeRetry` is the number of milliseconds to wait before retrying * - * `immediately` is the flag to retry the failed tests immediately after + * `retryImmediately` is the flag to retry the failed test immediately after * failure * * @remarks @@ -309,8 +309,8 @@ export interface Jest { retryTimes( numRetries: number, options?: { - immediately?: boolean; logErrorsBeforeRetry?: boolean; + retryImmediately?: boolean; waitBeforeRetry?: number; }, ): Jest; diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 31e22b8e2507..551bce13a28b 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -123,7 +123,7 @@ type ResolveOptions = Parameters[1] & { const testTimeoutSymbol = Symbol.for('TEST_TIMEOUT_SYMBOL'); const retryTimesSymbol = Symbol.for('RETRY_TIMES'); const waitBeforeRetrySymbol = Symbol.for('WAIT_BEFORE_RETRY'); -const immediatelySybmbol = Symbol.for('IMMEDIATELY'); +const retryImmediatelySybmbol = Symbol.for('RETRY_IMMEDIATELY'); const logErrorsBeforeRetrySymbol = Symbol.for('LOG_ERRORS_BEFORE_RETRY'); const NODE_MODULES = `${path.sep}node_modules${path.sep}`; @@ -2293,7 +2293,8 @@ export default class Runtime { options?.logErrorsBeforeRetry; this._environment.global[waitBeforeRetrySymbol] = options?.waitBeforeRetry; - this._environment.global[immediatelySybmbol] = options?.immediately; + this._environment.global[retryImmediatelySybmbol] = + options?.retryImmediately; return jestObject; }; diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 9c5530e1e3eb..7de8bf5a323d 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -667,9 +667,11 @@ expect(jest.retryTimes(3, {logErrorsBeforeRetry: 'all'})).type.toRaiseError(); expect(jest.retryTimes({logErrorsBeforeRetry: true})).type.toRaiseError(); expect(jest.retryTimes(3, {waitBeforeRetry: 1000})).type.toEqual(); expect(jest.retryTimes(3, {waitBeforeRetry: true})).type.toRaiseError(); -expect(jest.retryTimes(3, {immediately: true})).type.toEqual(); -expect(jest.retryTimes(3, {immediately: 'now'})).type.toRaiseError(); -expect(jest.retryTimes(3, {immediately: 1000})).type.toRaiseError(); +expect(jest.retryTimes(3, {retryImmediately: true})).type.toEqual< + typeof jest +>(); +expect(jest.retryTimes(3, {retryImmediately: 'now'})).type.toRaiseError(); +expect(jest.retryTimes(3, {retryImmediately: 1000})).type.toRaiseError(); expect(jest.retryTimes({logErrorsBeforeRetry: 'all'})).type.toRaiseError(); expect(jest.retryTimes()).type.toRaiseError(); From 1870f9c394f35c1162f0dbd95f4beee031a433ac Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 26 Mar 2024 09:21:24 +0100 Subject: [PATCH 5/5] Apply suggestions from code review --- docs/JestObjectAPI.md | 2 +- packages/jest-circus/src/run.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index d7ac9f10f189..8b0e6ece428f 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -1139,7 +1139,7 @@ test('will fail', () => { }); ``` -`retryImmediately` option is used to retry the failed test immediately after the failure. If this option is not specified, the tests are retried after Jest is finished running all test in a file. +`retryImmediately` option is used to retry the failed test immediately after the failure. If this option is not specified, the tests are retried after Jest is finished running all other tests in the file. ```js jest.retryTimes(3, {retryImmediately: true}); diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index 3d7dd89f95cf..4f8ae2e6dcfb 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -116,7 +116,7 @@ const _runTestsForDescribeBlock = async ( const hasRetryTimes = retryTimes > 0; await _runTest(child, isSkipped); - //If immediate retry is set, we retry the test immediately after the first run + // If immediate retry is set, we retry the test immediately after the first run if ( retryImmediately && hasErrorsBeforeTestRun === false &&