diff --git a/README.md b/README.md
index bdced5c..7439921 100644
--- a/README.md
+++ b/README.md
@@ -184,6 +184,10 @@ jobs:
# none
list-tests: 'all'
+ # Show execution time for individual test cases
+ # When enabled, test case execution times will be displayed in parentheses next to test names
+ list-test-case-time: 'false'
+
# Limits number of created annotations with error message and stack trace captured during test execution.
# Must be less or equal to 50.
max-annotations: '10'
diff --git a/__tests__/__outputs__/jest-junit.md b/__tests__/__outputs__/jest-junit.md
index 951256f..40b701c 100644
--- a/__tests__/__outputs__/jest-junit.md
+++ b/__tests__/__outputs__/jest-junit.md
@@ -11,9 +11,9 @@
### ❌ __tests__\main.test.js
```
Test 1
- ✅ Passing test
+ ✅ Passing test (1ms)
Test 1 › Test 1.1
- ❌ Failing test
+ ❌ Failing test (2ms)
Error: expect(received).toBeTruthy()
❌ Exception in target unit
Error: Some error
@@ -23,7 +23,7 @@ Test 2
```
### ❌ __tests__\second.test.js
```
-❌ Timeout test
+❌ Timeout test (4ms)
: Timeout - Async callback was not invoked within the 1 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 1 ms timeout specified by jest.setTimeout.Error:
⚪ Skipped test
```
\ No newline at end of file
diff --git a/__tests__/jest-junit.test.ts b/__tests__/jest-junit.test.ts
index 912ebde..194856b 100644
--- a/__tests__/jest-junit.test.ts
+++ b/__tests__/jest-junit.test.ts
@@ -3,7 +3,7 @@ import * as path from 'path'
import {JestJunitParser} from '../src/parsers/jest-junit/jest-junit-parser'
import {ParseOptions} from '../src/test-parser'
-import {DEFAULT_OPTIONS, getReport} from '../src/report/get-report'
+import {DEFAULT_OPTIONS, getReport, ReportOptions} from '../src/report/get-report'
import {normalizeFilePath} from '../src/utils/path-utils'
describe('jest-junit tests', () => {
@@ -55,7 +55,12 @@ describe('jest-junit tests', () => {
const result = await parser.parse(filePath, fileContent)
expect(result).toMatchSnapshot()
- const report = getReport([result])
+ const reportOpts: ReportOptions = {
+ ...DEFAULT_OPTIONS,
+ listTestCaseTime: true
+ }
+
+ const report = getReport([result], reportOpts)
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
fs.writeFileSync(outputPath, report)
})
diff --git a/src/main.ts b/src/main.ts
index 9b24d38..842205b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -43,6 +43,7 @@ class TestReporter {
readonly reporter = core.getInput('reporter', {required: true})
readonly listSuites = core.getInput('list-suites', {required: true}) as 'all' | 'failed' | 'none'
readonly listTests = core.getInput('list-tests', {required: true}) as 'all' | 'failed' | 'none'
+ readonly listTestCaseTime = core.getInput('list-test-case-time', {required: false}) === 'true'
readonly maxAnnotations = parseInt(core.getInput('max-annotations', {required: true}))
readonly failOnError = core.getInput('fail-on-error', {required: true}) === 'true'
readonly failOnEmpty = core.getInput('fail-on-empty', {required: true}) === 'true'
@@ -174,7 +175,16 @@ class TestReporter {
}
}
- const {listSuites, listTests, onlySummary, useActionsSummary, badgeTitle, reportTitle, collapsed} = this
+ const {
+ listSuites,
+ listTests,
+ listTestCaseTime,
+ onlySummary,
+ useActionsSummary,
+ badgeTitle,
+ reportTitle,
+ collapsed
+ } = this
const passed = results.reduce((sum, tr) => sum + tr.passed, 0)
const failed = results.reduce((sum, tr) => sum + tr.failed, 0)
@@ -188,6 +198,7 @@ class TestReporter {
{
listSuites,
listTests,
+ listTestCaseTime,
baseUrl,
onlySummary,
useActionsSummary,
@@ -219,6 +230,7 @@ class TestReporter {
const summary = getReport(results, {
listSuites,
listTests,
+ listTestCaseTime,
baseUrl,
onlySummary,
useActionsSummary,
diff --git a/src/report/get-report.ts b/src/report/get-report.ts
index 02b9d49..2827bd5 100644
--- a/src/report/get-report.ts
+++ b/src/report/get-report.ts
@@ -11,6 +11,7 @@ const MAX_ACTIONS_SUMMARY_LENGTH = 1048576
export interface ReportOptions {
listSuites: 'all' | 'failed' | 'none'
listTests: 'all' | 'failed' | 'none'
+ listTestCaseTime: boolean
baseUrl: string
onlySummary: boolean
useActionsSummary: boolean
@@ -22,6 +23,7 @@ export interface ReportOptions {
export const DEFAULT_OPTIONS: ReportOptions = {
listSuites: 'all',
listTests: 'all',
+ listTestCaseTime: false,
baseUrl: '',
onlySummary: false,
useActionsSummary: true,
@@ -281,7 +283,8 @@ function getTestsReport(ts: TestSuiteResult, runIndex: number, suiteIndex: numbe
continue
}
const result = getResultIcon(tc.result)
- sections.push(`${space}${result} ${tc.name}`)
+ const time = options.listTestCaseTime && tc.time ? ` (${formatTime(tc.time)})` : ''
+ sections.push(`${space}${result} ${tc.name}${time}`)
if (tc.error) {
const lines = (tc.error.message ?? getFirstNonEmptyLine(tc.error.details)?.trim())
?.split(/\r?\n/g)