diff --git a/CHANGELOG.md b/CHANGELOG.md index c6699df1d4b9..1eac9b5c8646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - `[expect]` Improve report when matcher fails, part 15 ([#8281](https://github.com/facebook/jest/pull/8281)) +- `[jest-circus]` Allow Circus `addEventHandler` and `getState` to be used externally ([#8307](https://github.com/facebook/jest/pull/8307)) - `[jest-cli]` Update `--forceExit` and "did not exit for one second" message colors ([#8329](https://github.com/facebook/jest/pull/8329)) - `[expect]` Improve report when matcher fails, part 16 ([#8306](https://github.com/facebook/jest/pull/8306)) - `[jest-runner]` Pass docblock pragmas to TestEnvironment constructor ([#8320](https://github.com/facebook/jest/pull/8320)) diff --git a/packages/jest-circus/README.md b/packages/jest-circus/README.md index af963748aa87..d9de8fb2258a 100644 --- a/packages/jest-circus/README.md +++ b/packages/jest-circus/README.md @@ -9,6 +9,38 @@ Circus is a flux-based test runner for Jest that is fast, easy to maintain, and simple to extend. +## API + +Circus exposes a public API for interacting with the flux store via imports from `jest-circus`. See the [type definitions](https://github.com/facebook/jest/blob/master/packages/jest-circus/src/types.ts) for more information on the events and state data currently available. + +Mutating event or state data is currently unsupported and may cause unexpected behavior or break in a future release without warning. + +New events, event data, and/or state data will not be considered a breaking change and may be added in any minor release. + +### addEventHandler + +`addEventHandler` can be used to listen for parts of the test lifecycle. + +```js +import {addEventHandler} from 'jest-circus'; + +addEventHandler((event, state) => { + if (event.name === 'test_start') { + // Handle event. + } +}); +``` + +### getState + +`getState` returns the current state. + +```js +import {getState} from 'jest-circus'; + +const state = getState(); +``` + ## Installation Install `jest-circus` using yarn: diff --git a/packages/jest-circus/src/__mocks__/testUtils.ts b/packages/jest-circus/src/__mocks__/testUtils.ts index 1353fcd09fda..78f284d4ca00 100644 --- a/packages/jest-circus/src/__mocks__/testUtils.ts +++ b/packages/jest-circus/src/__mocks__/testUtils.ts @@ -13,7 +13,7 @@ import crypto from 'crypto'; import {sync as spawnSync, ExecaReturns} from 'execa'; import {skipSuiteOnWindows} from '@jest/test-utils'; -const CIRCUS_PATH = require.resolve('../../build'); +const CIRCUS_PATH = require.resolve('../../build/'); const CIRCUS_RUN_PATH = require.resolve('../../build/run'); const CIRCUS_STATE_PATH = require.resolve('../../build/state'); const TEST_EVENT_HANDLER_PATH = require.resolve('./testEventHandler'); @@ -36,6 +36,7 @@ export const runTest = (source: string) => { const content = ` require('${BABEL_REGISTER_PATH}')({extensions: [".js", ".ts"]}); const circus = require('${CIRCUS_PATH}'); + global.it = circus.it; global.test = circus.test; global.describe = circus.describe; global.beforeEach = circus.beforeEach; @@ -55,35 +56,23 @@ export const runTest = (source: string) => { `; fs.writeFileSync(tmpFilename, content); - const result = spawnSync('node', [tmpFilename], { - cwd: process.cwd(), - }) as Result; - // For compat with cross-spawn - result.status = result.code; + // Normalize for compat with cross-spawn + let result: Result; - if (result.status !== 0) { - const message = ` - STDOUT: ${result.stdout && result.stdout.toString()} - STDERR: ${result.stderr && result.stderr.toString()} - STATUS: ${result.status} - ERROR: ${String(result.error)} - `; - throw new Error(message); + try { + result = spawnSync('node', [tmpFilename], { + cwd: process.cwd(), + }) as Result; + } catch (err) { + result = err; } - result.stdout = String(result.stdout); - result.stderr = String(result.stderr); - fs.unlinkSync(tmpFilename); - if (result.stderr) { - throw new Error( - ` - Unexpected stderr: - ${result.stderr} - `, - ); - } - return result; + return { + status: result.code, + stderr: String(result.stderr), + stdout: String(result.stdout), + }; }; diff --git a/packages/jest-circus/src/__tests__/__snapshots__/hooks.test.ts.snap b/packages/jest-circus/src/__tests__/__snapshots__/hooks.test.ts.snap index 465511f31286..e6f9a1294fa4 100644 --- a/packages/jest-circus/src/__tests__/__snapshots__/hooks.test.ts.snap +++ b/packages/jest-circus/src/__tests__/__snapshots__/hooks.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`beforeAll is exectued correctly 1`] = ` +exports[`beforeAll is executed correctly 1`] = ` "start_describe_definition: describe 1 add_hook: beforeAll add_test: test 1 diff --git a/packages/jest-circus/src/__tests__/circusItTestError.test.ts b/packages/jest-circus/src/__tests__/circusItTestError.test.ts index a267f511e836..c0b46f9ec919 100644 --- a/packages/jest-circus/src/__tests__/circusItTestError.test.ts +++ b/packages/jest-circus/src/__tests__/circusItTestError.test.ts @@ -5,75 +5,34 @@ * LICENSE file in the root directory of this source tree. */ -import {Global} from '@jest/types'; +import {runTest} from '../__mocks__/testUtils'; -let circusIt: Global.It; -let circusTest: Global.It; - -// using jest-jasmine2's 'it' to test jest-circus's 'it'. Had to differentiate -// the two with this alias. - -const aliasCircusIt = () => { - const {it, test} = require('../'); - circusIt = it; - circusTest = test; -}; - -aliasCircusIt(); - -describe('test/it error throwing', () => { - it(`it doesn't throw an error with valid arguments`, () => { - expect(() => { - circusIt('test1', () => {}); - }).not.toThrowError(); +describe('error throwing', () => { + test(`doesn't throw an error with valid arguments`, () => { + expect(runTest(`test('test1', () => {});`).stderr).toEqual(''); }); - it(`it throws error with missing callback function`, () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusIt('test2'); - }).toThrowError( + + test(`throws error with missing callback function`, () => { + expect(runTest(`test('test2');`).stderr).toContain( 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.', ); }); - it(`it throws an error when first argument isn't a string`, () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusIt(() => {}); - }).toThrowError('Invalid first argument, () => {}. It must be a string.'); - }); - it('it throws an error when callback function is not a function', () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusIt('test4', 'test4b'); - }).toThrowError( - 'Invalid second argument, test4b. It must be a callback function.', + + test(`throws an error when first argument isn't a string`, () => { + expect(runTest(`test(() => {});`).stderr).toContain( + 'Invalid first argument, () => {}. It must be a string.', ); }); - it(`test doesn't throw an error with valid arguments`, () => { - expect(() => { - circusTest('test5', () => {}); - }).not.toThrowError(); - }); - it(`test throws error with missing callback function`, () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusTest('test6'); - }).toThrowError( - 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.', + + test(`throws an error when callback function is not a function`, () => { + expect(runTest(`test('test4', 'test4b');`).stderr).toContain( + 'Invalid second argument, test4b. It must be a callback function.', ); }); - it(`test throws an error when first argument isn't a string`, () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusTest(() => {}); - }).toThrowError('Invalid first argument, () => {}. It must be a string.'); - }); - it('test throws an error when callback function is not a function', () => { - expect(() => { - // @ts-ignore: Easy, we're testing runtime errors here - circusTest('test8', 'test8b'); - }).toThrowError( - 'Invalid second argument, test8b. It must be a callback function.', + + test(`doesn't throw an error with valid arguments`, () => { + expect(runTest(`test('test4', 'test4b');`).stderr).toContain( + 'Invalid second argument, test4b. It must be a callback function.', ); }); }); diff --git a/packages/jest-circus/src/__tests__/hooks.test.ts b/packages/jest-circus/src/__tests__/hooks.test.ts index 02b54ae8e515..72cdfc37202b 100644 --- a/packages/jest-circus/src/__tests__/hooks.test.ts +++ b/packages/jest-circus/src/__tests__/hooks.test.ts @@ -56,7 +56,7 @@ test('multiple before each hooks in one describe are executed in the right order expect(stdout).toMatchSnapshot(); }); -test('beforeAll is exectued correctly', () => { +test('beforeAll is executed correctly', () => { const {stdout} = runTest(` describe('describe 1', () => { beforeAll(() => console.log('> beforeAll 1')); diff --git a/packages/jest-circus/src/globals.ts b/packages/jest-circus/src/globals.ts new file mode 100644 index 000000000000..c760680cf88f --- /dev/null +++ b/packages/jest-circus/src/globals.ts @@ -0,0 +1,196 @@ +/** + * 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 chalk from 'chalk'; +import {bind as bindEach} from 'jest-each'; +import {formatExecError} from 'jest-message-util'; +import {ErrorWithStack, isPromise} from 'jest-util'; +import {Global} from '@jest/types'; +import { + BlockFn, + HookFn, + HookType, + TestFn, + BlockMode, + BlockName, + TestName, + TestMode, +} from './types'; +import {dispatch} from './state'; + +type THook = (fn: HookFn, timeout?: number) => void; +type DescribeFn = (blockName: BlockName, blockFn: BlockFn) => void; + +export const describe = (() => { + const describe = (blockName: BlockName, blockFn: BlockFn) => + _dispatchDescribe(blockFn, blockName, describe); + const only = (blockName: BlockName, blockFn: BlockFn) => + _dispatchDescribe(blockFn, blockName, only, 'only'); + const skip = (blockName: BlockName, blockFn: BlockFn) => + _dispatchDescribe(blockFn, blockName, skip, 'skip'); + + describe.each = bindEach(describe, false); + + only.each = bindEach(only, false); + skip.each = bindEach(skip, false); + + describe.only = only; + describe.skip = skip; + + return describe; +})(); + +const _dispatchDescribe = ( + blockFn: BlockFn, + blockName: BlockName, + describeFn: DescribeFn, + mode?: BlockMode, +) => { + const asyncError = new ErrorWithStack(undefined, describeFn); + if (blockFn === undefined) { + asyncError.message = `Missing second argument. It must be a callback function.`; + throw asyncError; + } + if (typeof blockFn !== 'function') { + asyncError.message = `Invalid second argument, ${blockFn}. It must be a callback function.`; + throw asyncError; + } + dispatch({ + asyncError, + blockName, + mode, + name: 'start_describe_definition', + }); + const describeReturn = blockFn(); + + // TODO throw in Jest 25 + if (isPromise(describeReturn)) { + console.log( + formatExecError( + new ErrorWithStack( + chalk.yellow( + 'Returning a Promise from "describe" is not supported. Tests must be defined synchronously.\n' + + 'Returning a value from "describe" will fail the test in a future version of Jest.', + ), + describeFn, + ), + {rootDir: '', testMatch: []}, + {noStackTrace: false}, + ), + ); + } else if (describeReturn !== undefined) { + console.log( + formatExecError( + new ErrorWithStack( + chalk.yellow( + 'A "describe" callback must not return a value.\n' + + 'Returning a value from "describe" will fail the test in a future version of Jest.', + ), + describeFn, + ), + {rootDir: '', testMatch: []}, + {noStackTrace: false}, + ), + ); + } + + dispatch({blockName, mode, name: 'finish_describe_definition'}); +}; + +const _addHook = ( + fn: HookFn, + hookType: HookType, + hookFn: THook, + timeout?: number, +) => { + const asyncError = new ErrorWithStack(undefined, hookFn); + + if (typeof fn !== 'function') { + asyncError.message = + 'Invalid first argument. It must be a callback function.'; + + throw asyncError; + } + + dispatch({asyncError, fn, hookType, name: 'add_hook', timeout}); +}; + +// Hooks have to pass themselves to the HOF in order for us to trim stack traces. +export const beforeEach: THook = (fn, timeout) => + _addHook(fn, 'beforeEach', beforeEach, timeout); +export const beforeAll: THook = (fn, timeout) => + _addHook(fn, 'beforeAll', beforeAll, timeout); +export const afterEach: THook = (fn, timeout) => + _addHook(fn, 'afterEach', afterEach, timeout); +export const afterAll: THook = (fn, timeout) => + _addHook(fn, 'afterAll', afterAll, timeout); + +export const test: Global.It = (() => { + const test = (testName: TestName, fn: TestFn, timeout?: number): void => + _addTest(testName, undefined, fn, test, timeout); + const skip = (testName: TestName, fn?: TestFn, timeout?: number): void => + _addTest(testName, 'skip', fn, skip, timeout); + const only = (testName: TestName, fn: TestFn, timeout?: number): void => + _addTest(testName, 'only', fn, test.only, timeout); + + test.todo = (testName: TestName, ...rest: Array): void => { + if (rest.length > 0 || typeof testName !== 'string') { + throw new ErrorWithStack( + 'Todo must be called with only a description.', + test.todo, + ); + } + return _addTest(testName, 'todo', () => {}, test.todo); + }; + + const _addTest = ( + testName: TestName, + mode: TestMode, + fn: TestFn | undefined, + testFn: (testName: TestName, fn: TestFn, timeout?: number) => void, + timeout?: number, + ) => { + const asyncError = new ErrorWithStack(undefined, testFn); + + if (typeof testName !== 'string') { + asyncError.message = `Invalid first argument, ${testName}. It must be a string.`; + + throw asyncError; + } + if (fn === undefined) { + asyncError.message = + 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.'; + + throw asyncError; + } + if (typeof fn !== 'function') { + asyncError.message = `Invalid second argument, ${fn}. It must be a callback function.`; + + throw asyncError; + } + + return dispatch({ + asyncError, + fn, + mode, + name: 'add_test', + testName, + timeout, + }); + }; + + test.each = bindEach(test); + only.each = bindEach(only); + skip.each = bindEach(skip); + + test.only = only; + test.skip = skip; + + return test; +})(); + +export const it: Global.It = test; diff --git a/packages/jest-circus/src/index.ts b/packages/jest-circus/src/index.ts index b7e93f3da0f4..54ea0e8797c5 100644 --- a/packages/jest-circus/src/index.ts +++ b/packages/jest-circus/src/index.ts @@ -1,206 +1,18 @@ -/** - * 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. - */ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -import chalk from 'chalk'; -import {bind as bindEach} from 'jest-each'; -import {formatExecError} from 'jest-message-util'; -import {ErrorWithStack, isPromise} from 'jest-util'; -import {Global} from '@jest/types'; -import { - BlockFn, - HookFn, - HookType, - TestFn, - BlockMode, - BlockName, - TestName, - TestMode, -} from './types'; -import {dispatch} from './state'; +import * as globals from './globals'; -type THook = (fn: HookFn, timeout?: number) => void; -type DescribeFn = (blockName: BlockName, blockFn: BlockFn) => void; - -const describe = (() => { - const describe = (blockName: BlockName, blockFn: BlockFn) => - _dispatchDescribe(blockFn, blockName, describe); - const only = (blockName: BlockName, blockFn: BlockFn) => - _dispatchDescribe(blockFn, blockName, only, 'only'); - const skip = (blockName: BlockName, blockFn: BlockFn) => - _dispatchDescribe(blockFn, blockName, skip, 'skip'); - - describe.each = bindEach(describe, false); - - only.each = bindEach(only, false); - skip.each = bindEach(skip, false); - - describe.only = only; - describe.skip = skip; - - return describe; -})(); - -const _dispatchDescribe = ( - blockFn: BlockFn, - blockName: BlockName, - describeFn: DescribeFn, - mode?: BlockMode, -) => { - const asyncError = new ErrorWithStack(undefined, describeFn); - if (blockFn === undefined) { - asyncError.message = `Missing second argument. It must be a callback function.`; - throw asyncError; - } - if (typeof blockFn !== 'function') { - asyncError.message = `Invalid second argument, ${blockFn}. It must be a callback function.`; - throw asyncError; - } - dispatch({ - asyncError, - blockName, - mode, - name: 'start_describe_definition', - }); - const describeReturn = blockFn(); - - // TODO throw in Jest 25 - if (isPromise(describeReturn)) { - console.log( - formatExecError( - new ErrorWithStack( - chalk.yellow( - 'Returning a Promise from "describe" is not supported. Tests must be defined synchronously.\n' + - 'Returning a value from "describe" will fail the test in a future version of Jest.', - ), - describeFn, - ), - {rootDir: '', testMatch: []}, - {noStackTrace: false}, - ), - ); - } else if (describeReturn !== undefined) { - console.log( - formatExecError( - new ErrorWithStack( - chalk.yellow( - 'A "describe" callback must not return a value.\n' + - 'Returning a value from "describe" will fail the test in a future version of Jest.', - ), - describeFn, - ), - {rootDir: '', testMatch: []}, - {noStackTrace: false}, - ), - ); - } - - dispatch({blockName, mode, name: 'finish_describe_definition'}); -}; - -const _addHook = ( - fn: HookFn, - hookType: HookType, - hookFn: THook, - timeout?: number, -) => { - const asyncError = new ErrorWithStack(undefined, hookFn); - - if (typeof fn !== 'function') { - asyncError.message = - 'Invalid first argument. It must be a callback function.'; - - throw asyncError; - } - - dispatch({asyncError, fn, hookType, name: 'add_hook', timeout}); -}; - -// Hooks have to pass themselves to the HOF in order for us to trim stack traces. -const beforeEach: THook = (fn, timeout) => - _addHook(fn, 'beforeEach', beforeEach, timeout); -const beforeAll: THook = (fn, timeout) => - _addHook(fn, 'beforeAll', beforeAll, timeout); -const afterEach: THook = (fn, timeout) => - _addHook(fn, 'afterEach', afterEach, timeout); -const afterAll: THook = (fn, timeout) => - _addHook(fn, 'afterAll', afterAll, timeout); - -const test: Global.It = (() => { - const test = (testName: TestName, fn: TestFn, timeout?: number): void => - _addTest(testName, undefined, fn, test, timeout); - const skip = (testName: TestName, fn?: TestFn, timeout?: number): void => - _addTest(testName, 'skip', fn, skip, timeout); - const only = (testName: TestName, fn: TestFn, timeout?: number): void => - _addTest(testName, 'only', fn, test.only, timeout); - - test.todo = (testName: TestName, ...rest: Array): void => { - if (rest.length > 0 || typeof testName !== 'string') { - throw new ErrorWithStack( - 'Todo must be called with only a description.', - test.todo, - ); - } - return _addTest(testName, 'todo', () => {}, test.todo); - }; - - const _addTest = ( - testName: TestName, - mode: TestMode, - fn: TestFn | undefined, - testFn: (testName: TestName, fn: TestFn, timeout?: number) => void, - timeout?: number, - ) => { - const asyncError = new ErrorWithStack(undefined, testFn); - - if (typeof testName !== 'string') { - asyncError.message = `Invalid first argument, ${testName}. It must be a string.`; - - throw asyncError; - } - if (fn === undefined) { - asyncError.message = - 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.'; - - throw asyncError; - } - if (typeof fn !== 'function') { - asyncError.message = `Invalid second argument, ${fn}. It must be a callback function.`; - - throw asyncError; - } - - return dispatch({ - asyncError, - fn, - mode, - name: 'add_test', - testName, - timeout, - }); - }; - - test.each = bindEach(test); - only.each = bindEach(only); - skip.each = bindEach(skip); - - test.only = only; - test.skip = skip; - - return test; -})(); - -const it: Global.It = test; - -export = { +export {addEventHandler, getState} from './state'; +export {EventHandler, Event, State} from './types'; +export { afterAll, afterEach, beforeAll, beforeEach, describe, - it, test, -}; + it, +} from './globals'; + +// To avoid breaking change. Remove in Jest 25: +export default globals; 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 40f93dbf3c0b..31bc706da85d 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -18,7 +18,7 @@ import throat from 'throat'; import {addEventHandler, dispatch, ROOT_DESCRIBE_BLOCK_NAME} from '../state'; import {getTestID} from '../utils'; import run from '../run'; -import globals from '..'; +import * as globals from '../globals'; import {Event, RunResult, TestEntry} from '../types'; type Process = NodeJS.Process; diff --git a/packages/jest-circus/src/state.ts b/packages/jest-circus/src/state.ts index 8f684d254d16..e4527a93b43c 100644 --- a/packages/jest-circus/src/state.ts +++ b/packages/jest-circus/src/state.ts @@ -5,44 +5,55 @@ * LICENSE file in the root directory of this source tree. */ -import {Event, State, EventHandler, STATE_SYM} from './types'; +import { + Event, + State, + EventHandler, + STATE_SYMBOL, + JEST_EVENT_HANDLERS_SYMBOL, +} from './types'; import {makeDescribe} from './utils'; import eventHandler from './eventHandler'; import formatNodeAssertErrors from './formatNodeAssertErrors'; -const eventHandlers: Array = [ - eventHandler, - formatNodeAssertErrors, -]; - export const ROOT_DESCRIBE_BLOCK_NAME = 'ROOT_DESCRIBE_BLOCK'; -const ROOT_DESCRIBE_BLOCK = makeDescribe(ROOT_DESCRIBE_BLOCK_NAME); -const INITIAL_STATE: State = { - currentDescribeBlock: ROOT_DESCRIBE_BLOCK, - currentlyRunningTest: null, - expand: undefined, - hasFocusedTests: false, // whether .only has been used on any test/describe - includeTestLocationInResult: false, - parentProcess: null, - rootDescribeBlock: ROOT_DESCRIBE_BLOCK, - testNamePattern: null, - testTimeout: 5000, - unhandledErrors: [], +const getEventHandlers = () => { + if (!global[JEST_EVENT_HANDLERS_SYMBOL]) { + global[JEST_EVENT_HANDLERS_SYMBOL] = [eventHandler, formatNodeAssertErrors]; + } + return global[JEST_EVENT_HANDLERS_SYMBOL]; }; -global[STATE_SYM] = INITIAL_STATE; +export const getState = (): State => { + if (!global[STATE_SYMBOL]) { + const ROOT_DESCRIBE_BLOCK = makeDescribe(ROOT_DESCRIBE_BLOCK_NAME); + global[STATE_SYMBOL] = { + currentDescribeBlock: ROOT_DESCRIBE_BLOCK, + currentlyRunningTest: null, + expand: undefined, + hasFocusedTests: false, // whether .only has been used on any test/describe + includeTestLocationInResult: false, + parentProcess: null, + rootDescribeBlock: ROOT_DESCRIBE_BLOCK, + testNamePattern: null, + testTimeout: 5000, + unhandledErrors: [], + } as State; + } + + return global[STATE_SYMBOL]; +}; -export const getState = (): State => global[STATE_SYM]; -export const setState = (state: State): State => (global[STATE_SYM] = state); +export const setState = (state: State): State => (global[STATE_SYMBOL] = state); export const dispatch = (event: Event): void => { - for (const handler of eventHandlers) { + for (const handler of getEventHandlers()) { handler(event, getState()); } }; export const addEventHandler = (handler: EventHandler): void => { - eventHandlers.push(handler); + getEventHandlers().push(handler); }; diff --git a/packages/jest-circus/src/types.ts b/packages/jest-circus/src/types.ts index 87bf25bce902..9adcadaf4578 100644 --- a/packages/jest-circus/src/types.ts +++ b/packages/jest-circus/src/types.ts @@ -220,9 +220,12 @@ export type TestEntry = { timeout: number | undefined | null; }; -export const STATE_SYM = (Symbol( +export const STATE_SYMBOL = (Symbol.for( 'JEST_STATE_SYMBOL', -) as unknown) as 'STATE_SYM_SYMBOL'; +) as unknown) as 'JEST_STATE_SYMBOL'; +export const JEST_EVENT_HANDLERS_SYMBOL = (Symbol.for( + 'JEST_EVENT_HANDLERS', +) as unknown) as 'JEST_EVENT_HANDLERS'; export const RETRY_TIMES = (Symbol.for( 'RETRY_TIMES', ) as unknown) as 'RETRY_TIMES_SYMBOL'; @@ -234,7 +237,8 @@ export const TEST_TIMEOUT_SYMBOL = (Symbol.for( declare global { module NodeJS { interface Global { - STATE_SYM_SYMBOL: State; + JEST_STATE_SYMBOL: State; + JEST_EVENT_HANDLERS: Array; RETRY_TIMES_SYMBOL: string; TEST_TIMEOUT_SYMBOL: number; expect: typeof expect;