Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jest-circus): add onTestCaseStart hook Reporter #14174

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- `[jest-cli]` Include type definitions to generated config files ([#14078](https://github.com/facebook/jest/pull/14078))
- `[jest-snapshot]` Support arrays as property matchers ([#14025](https://github.com/facebook/jest/pull/14025))
- `[jest-core, jest-circus, jest-reporter, jest-runner]` Added support for reporting about start individual test cases using jest-circus ([#14174](https://github.com/jestjs/jest/pull/14174))

### Fixes

Expand Down
Expand Up @@ -14,3 +14,12 @@ exports[`Custom Reporters Integration on jest-circus push test case results for
"onTestCaseResult: sample, status: todo, numExpectations: 0
onTestFileResult testCaseResult 0: sample, status: todo, numExpectations: 0"
`;

exports[`Custom Reporters Integration on jest-circus push test case start 1`] = `
"onTestCaseStart: test 1, mode: undefined, ancestorTitles: Custom Reporters
onTestCaseStart: test 2, mode: undefined, ancestorTitles: Custom Reporters"
`;

exports[`Custom Reporters Integration on jest-circus doesn't push test case start for skip tests 1`] = `""`;

exports[`Custom Reporters Integration on jest-circus doesn't push test case start for todo tests 1`] = `""`;
36 changes: 36 additions & 0 deletions e2e/__tests__/customReportersOnCircus.test.ts
Expand Up @@ -54,4 +54,40 @@ describe('Custom Reporters Integration on jest-circus', () => {

expect(stdout).toMatchSnapshot();
});

test('push test case start', () => {
const {stdout} = runJest('custom-reporters', [
'--config',
JSON.stringify({
reporters: ['default', '<rootDir>/reporters/TestCaseStartReporter.js'],
}),
'just2Tests.test.js',
]);

expect(stdout).toMatchSnapshot();
});

test("doesn't push test case start for todo tests", () => {
const {stdout} = runJest('custom-reporters', [
'--config',
JSON.stringify({
reporters: ['default', '<rootDir>/reporters/TestCaseStartReporter.js'],
}),
'todo.test.js',
]);

expect(stdout).toMatchSnapshot();
});

test("doesn't push test case start for skip tests", () => {
const {stdout} = runJest('custom-reporters', [
'--config',
JSON.stringify({
reporters: ['default', '<rootDir>/reporters/TestCaseStartReporter.js'],
}),
'skip.test.js',
]);

expect(stdout).toMatchSnapshot();
});
});
2 changes: 2 additions & 0 deletions e2e/__tests__/testEnvironmentCircus.test.ts
Expand Up @@ -23,6 +23,7 @@ it('calls testEnvironment handleTestEvent', () => {
"run_start",
"run_describe_start",
"test_start: test name here",
"test_started: test name here",
"hook_start",
"hook_success: test name here",
"hook_start",
Expand All @@ -31,6 +32,7 @@ it('calls testEnvironment handleTestEvent', () => {
"test_fn_success: test name here",
"test_done: test name here",
"test_start: second test name here",
"test_started: second test name here",
"hook_start",
"hook_success: second test name here",
"hook_start",
Expand Down
2 changes: 2 additions & 0 deletions e2e/__tests__/testEnvironmentCircusAsync.test.ts
Expand Up @@ -36,6 +36,7 @@ it('calls asynchronous handleTestEvent in testEnvironment', () => {
"run_describe_start",
"run_describe_start",
"test_start: passing test",
"test_started: passing test",
"hook_start: beforeEach",
"hook_success: beforeEach",
"hook_start: beforeEach",
Expand All @@ -46,6 +47,7 @@ it('calls asynchronous handleTestEvent in testEnvironment', () => {
"hook_failure: afterEach",
"test_done: passing test",
"test_start: failing test",
"test_started: failing test",
"hook_start: beforeEach",
"hook_success: beforeEach",
"hook_start: beforeEach",
Expand Down
19 changes: 19 additions & 0 deletions e2e/custom-reporters/__tests__/just2Tests.test.js
@@ -0,0 +1,19 @@
/**
* 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';

describe('Custom Reporters', () => {
it('test 1', () => {
expect(true).toBeTruthy();
});

it('test 2', () => {
expect(true).toBeTruthy();
});
});
13 changes: 13 additions & 0 deletions e2e/custom-reporters/__tests__/skip.test.js
@@ -0,0 +1,13 @@
/**
* 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';

describe('Custom Reporters', () => {
it.skip('sample', () => {});
});
26 changes: 26 additions & 0 deletions e2e/custom-reporters/reporters/TestCaseStartReporter.js
@@ -0,0 +1,26 @@
/**
* 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';

/**
* @class
* @implements {import('@jest/reporters').Reporter}
*/
class TestCaseStartReporter {
onTestCaseStart(test, testCaseStartInfo) {
const mode =
testCaseStartInfo.mode != null ? testCaseStartInfo.mode : 'undefined';
console.log(
`onTestCaseStart: ${testCaseStartInfo.title}, ` +
`mode: ${mode}, ` +
`ancestorTitles: ${testCaseStartInfo.ancestorTitles.join('.')}`,
);
}
}

module.exports = TestCaseStartReporter;
1 change: 1 addition & 0 deletions packages/jest-circus/src/__mocks__/testEventHandler.ts
Expand Up @@ -20,6 +20,7 @@ const testEventHandler: Circus.EventHandler = (event, state) => {
break;
}
case 'test_start':
case 'test_started':
case 'test_retry':
case 'test_done': {
console.log(`${event.name}:`, event.test.name);
Expand Down
Expand Up @@ -54,6 +54,7 @@ hook_start: beforeAll
hook_success: beforeAll
run_describe_start: child describe
test_start: my test
test_started: my test
hook_start: beforeEach
> beforeEach
hook_success: beforeEach
Expand Down Expand Up @@ -132,24 +133,29 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
test_fn_start: one
test_fn_success: one
test_done: one
test_start: two
test_started: two
test_fn_start: two
test_fn_success: two
test_done: two
run_describe_start: 2nd level describe
test_start: 2nd level test
test_started: 2nd level test
test_fn_start: 2nd level test
test_fn_success: 2nd level test
test_done: 2nd level test
run_describe_start: 3rd level describe
test_start: 3rd level test
test_started: 3rd level test
test_fn_start: 3rd level test
test_fn_success: 3rd level test
test_done: 3rd level test
test_start: 3rd level test#2
test_started: 3rd level test#2
test_fn_start: 3rd level test#2
test_fn_success: 3rd level test#2
test_done: 3rd level test#2
Expand All @@ -162,6 +168,7 @@ hook_success: afterAll
run_describe_finish: describe
run_describe_start: 2nd describe
test_start: 2nd describe test
test_started: 2nd describe test
test_fn_start: 2nd describe test
test_fn_success: 2nd describe test
test_done: 2nd describe test
Expand Down
Expand Up @@ -11,6 +11,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
Expand All @@ -19,6 +20,7 @@ hook_start: afterEach
hook_failure: afterEach
test_done: one
test_start: two
test_started: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
Expand All @@ -41,6 +43,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describer
test_start: One
test_started: One
test_fn_start: One
test_fn_success: One
test_done: One
Expand All @@ -62,6 +65,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
Expand All @@ -70,6 +74,7 @@ hook_start: afterEach
hook_success: afterEach
test_done: one
test_start: two
test_started: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
Expand Down
Expand Up @@ -17,6 +17,7 @@ hook_start: beforeAll
> beforeAll 1
hook_success: beforeAll
test_start: test 1
test_started: test 1
test_fn_start: test 1
> test 1
test_fn_success: test 1
Expand All @@ -26,11 +27,13 @@ hook_start: beforeAll
> beforeAll 2
hook_success: beforeAll
test_start: test 2
test_started: test 2
test_fn_start: test 2
> test 2
test_fn_success: test 2
test_done: test 2
test_start: test 3
test_started: test 3
test_fn_start: test 3
> test 3
test_fn_success: test 3
Expand Down Expand Up @@ -65,13 +68,15 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
hook_start: beforeEach
> describe beforeEach
hook_success: beforeEach
test_fn_start: one
test_fn_success: one
test_done: one
test_start: two
test_started: two
hook_start: beforeEach
> describe beforeEach
hook_success: beforeEach
Expand All @@ -80,6 +85,7 @@ test_fn_success: two
test_done: two
run_describe_start: 2nd level describe
test_start: 2nd level test
test_started: 2nd level test
hook_start: beforeEach
> describe beforeEach
hook_success: beforeEach
Expand All @@ -91,6 +97,7 @@ test_fn_success: 2nd level test
test_done: 2nd level test
run_describe_start: 3rd level describe
test_start: 3rd level test
test_started: 3rd level test
hook_start: beforeEach
> describe beforeEach
hook_success: beforeEach
Expand All @@ -101,6 +108,7 @@ test_fn_start: 3rd level test
test_fn_success: 3rd level test
test_done: 3rd level test
test_start: 3rd level test#2
test_started: 3rd level test#2
hook_start: beforeEach
> describe beforeEach
hook_success: beforeEach
Expand All @@ -115,6 +123,7 @@ run_describe_finish: 2nd level describe
run_describe_finish: describe
run_describe_start: 2nd describe
test_start: 2nd describe test
test_started: 2nd describe test
hook_start: beforeEach
> 2nd describe beforeEach that throws
hook_failure: beforeEach
Expand All @@ -140,6 +149,7 @@ run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe 1
run_describe_start: 2nd level describe
test_start: test
test_started: test
hook_start: beforeEach
before each 1
hook_success: beforeEach
Expand Down
Expand Up @@ -11,6 +11,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
Expand All @@ -19,6 +20,7 @@ hook_start: afterEach
hook_failure: afterEach
test_done: one
test_start: two
test_started: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
Expand All @@ -41,6 +43,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describer
test_start: One
test_started: One
test_fn_start: One
test_fn_success: One
test_done: One
Expand All @@ -62,6 +65,7 @@ run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_started: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
Expand All @@ -70,6 +74,7 @@ hook_start: afterEach
hook_success: afterEach
test_done: one
test_start: two
test_started: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-circus/src/run.ts
Expand Up @@ -166,6 +166,8 @@ const _runTest = async (
return;
}

await dispatch({name: 'test_started', test});

const {afterEach, beforeEach} = getEachHooksForTest(test);

for (const hook of beforeEach) {
Expand Down
11 changes: 10 additions & 1 deletion packages/jest-circus/src/testCaseReportHandler.ts
Expand Up @@ -7,12 +7,21 @@

import type {TestFileEvent} from '@jest/test-result';
import type {Circus} from '@jest/types';
import {makeSingleTestResult, parseSingleTestResult} from './utils';
import {
createTestCaseStartInfo,
makeSingleTestResult,
parseSingleTestResult,
} from './utils';

const testCaseReportHandler =
(testPath: string, sendMessageToJest: TestFileEvent) =>
(event: Circus.Event): void => {
switch (event.name) {
case 'test_started': {
const testCaseStartInfo = createTestCaseStartInfo(event.test);
sendMessageToJest('test-case-start', [testPath, testCaseStartInfo]);
break;
}
case 'test_todo':
case 'test_done': {
const testResult = makeSingleTestResult(event.test);
Expand Down