mirror of
https://github.com/dorny/test-reporter.git
synced 2026-02-04 05:27:55 +01:00
- Add a new listTestCaseTime flag, that optionally prints test times next to test names. This flag defaults to false, for backward compatibility. - Update get-report.ts to use this flag when generating a report. - Update existing tests to set ReportOptions listTestCaseTime: true to verify above feature. - Update README with documentation about this new flag. Note this feature was needed for individual test times under pytest, since the xml is generated with all tests under one test suite. https://github.com/dorny/test-reporter/issues/260
354 lines
13 KiB
TypeScript
354 lines
13 KiB
TypeScript
import * as fs from 'fs'
|
|
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, ReportOptions} from '../src/report/get-report'
|
|
import {normalizeFilePath} from '../src/utils/path-utils'
|
|
|
|
describe('jest-junit tests', () => {
|
|
it('produces empty test run result when there are no test cases in the testsuites element', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'empty', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result.tests).toBe(0)
|
|
expect(result.result).toBe('success')
|
|
})
|
|
|
|
it('produces empty test run result when there are no test cases in a nested testsuite element', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'empty', 'jest-junit-empty-testsuite.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result.tests).toBe(0)
|
|
expect(result.result).toBe('success')
|
|
})
|
|
|
|
it('report from ./reports/jest test results matches snapshot', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const outputPath = path.join(__dirname, '__outputs__', 'jest-junit.md')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: ['__tests__/main.test.js', '__tests__/second.test.js', 'lib/main.js']
|
|
//workDir: 'C:/Users/Michal/Workspace/dorny/test-check/reports/jest/'
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result).toMatchSnapshot()
|
|
|
|
const reportOpts: ReportOptions = {
|
|
...DEFAULT_OPTIONS,
|
|
listTestCaseTime: true
|
|
}
|
|
|
|
const report = getReport([result], reportOpts)
|
|
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
|
|
fs.writeFileSync(outputPath, report)
|
|
})
|
|
|
|
it('report from facebook/jest test results matches snapshot', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'external', 'jest', 'jest-test-results.xml')
|
|
const trackedFilesPath = path.join(__dirname, 'fixtures', 'external', 'jest', 'files.txt')
|
|
const outputPath = path.join(__dirname, '__outputs__', 'jest-test-results.md')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const trackedFiles = fs.readFileSync(trackedFilesPath, {encoding: 'utf8'}).split(/\n\r?/g)
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles
|
|
//workDir: '/home/dorny/dorny/jest/'
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result).toMatchSnapshot()
|
|
|
|
const report = getReport([result])
|
|
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
|
|
fs.writeFileSync(outputPath, report)
|
|
})
|
|
|
|
it('report from #235 testing react components named <ComponentName />', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'external', 'jest', 'jest-react-component-test-results.xml')
|
|
const trackedFilesPath = path.join(__dirname, 'fixtures', 'external', 'jest', 'files.txt')
|
|
const outputPath = path.join(__dirname, '__outputs__', 'jest-react-component-test-results.md')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const trackedFiles = fs.readFileSync(trackedFilesPath, {encoding: 'utf8'}).split(/\n\r?/g)
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles
|
|
//workDir: '/home/dorny/dorny/jest/'
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result).toMatchSnapshot()
|
|
|
|
const report = getReport([result])
|
|
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
|
|
fs.writeFileSync(outputPath, report)
|
|
})
|
|
|
|
it('parsing ESLint report without timing information works - PR #134', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit-eslint.xml')
|
|
const outputPath = path.join(__dirname, '__outputs__', 'jest-junit-eslint.md')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: ['test.js']
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result).toMatchSnapshot()
|
|
|
|
const report = getReport([result])
|
|
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
|
|
fs.writeFileSync(outputPath, report)
|
|
})
|
|
|
|
it('parsing junit report with message succeeds', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'junit-with-message.xml')
|
|
const outputPath = path.join(__dirname, '__outputs__', 'junit-with-message.md')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: ['test.js']
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
expect(result).toMatchSnapshot()
|
|
|
|
const report = getReport([result])
|
|
fs.mkdirSync(path.dirname(outputPath), {recursive: true})
|
|
fs.writeFileSync(outputPath, report)
|
|
})
|
|
|
|
it('report does not include a title by default', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const report = getReport([result])
|
|
// Report should have the badge as the first line
|
|
expect(report).toMatch(/^!\[Tests failed]/)
|
|
})
|
|
|
|
it.each([
|
|
['empty string', ''],
|
|
['space', ' '],
|
|
['tab', '\t'],
|
|
['newline', '\n']
|
|
])('report does not include a title when configured value is %s', async (_, reportTitle) => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
reportTitle
|
|
})
|
|
// Report should have the badge as the first line
|
|
expect(report).toMatch(/^!\[Tests failed]/)
|
|
})
|
|
|
|
it('report includes a custom report title', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
reportTitle: 'My Custom Title'
|
|
})
|
|
// Report should have the title as the first line
|
|
expect(report).toMatch(/^# My Custom Title\n/)
|
|
})
|
|
|
|
it('report can be collapsed when configured', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
collapsed: 'always'
|
|
})
|
|
// Report should include collapsible details
|
|
expect(report).toContain('<details><summary>Expand for details</summary>')
|
|
expect(report).toContain('</details>')
|
|
})
|
|
|
|
it('report is not collapsed when configured to never', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
collapsed: 'never'
|
|
})
|
|
// Report should not include collapsible details
|
|
expect(report).not.toContain('<details><summary>Expand for details</summary>')
|
|
expect(report).not.toContain('</details>')
|
|
})
|
|
|
|
it('report auto-collapses when all tests pass', async () => {
|
|
// Test with a fixture that has all passing tests (no failures)
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit-eslint.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
|
|
// Verify this fixture has no failures
|
|
expect(result.failed).toBe(0)
|
|
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
collapsed: 'auto'
|
|
})
|
|
|
|
// Should collapse when all tests pass
|
|
expect(report).toContain('<details><summary>Expand for details</summary>')
|
|
expect(report).toContain('</details>')
|
|
})
|
|
|
|
it('report does not auto-collapse when tests fail', async () => {
|
|
// Test with a fixture that has failing tests
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
|
|
// Verify this fixture has failures
|
|
expect(result.failed).toBeGreaterThan(0)
|
|
|
|
const report = getReport([result], {
|
|
...DEFAULT_OPTIONS,
|
|
collapsed: 'auto'
|
|
})
|
|
|
|
// Should not collapse when there are failures
|
|
expect(report).not.toContain('<details><summary>Expand for details</summary>')
|
|
expect(report).not.toContain('</details>')
|
|
})
|
|
|
|
it('report includes the short summary', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const shortSummary = '1 passed, 4 failed and 1 skipped'
|
|
const report = getReport([result], DEFAULT_OPTIONS, shortSummary)
|
|
// Report should have the title as the first line
|
|
expect(report).toMatch(/^## 1 passed, 4 failed and 1 skipped\n/)
|
|
})
|
|
|
|
it('report includes a custom report title and short summary', async () => {
|
|
const fixturePath = path.join(__dirname, 'fixtures', 'jest-junit.xml')
|
|
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
|
|
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
|
|
|
|
const opts: ParseOptions = {
|
|
parseErrors: true,
|
|
trackedFiles: []
|
|
}
|
|
|
|
const parser = new JestJunitParser(opts)
|
|
const result = await parser.parse(filePath, fileContent)
|
|
const shortSummary = '1 passed, 4 failed and 1 skipped'
|
|
const report = getReport(
|
|
[result],
|
|
{
|
|
...DEFAULT_OPTIONS,
|
|
reportTitle: 'My Custom Title'
|
|
},
|
|
shortSummary
|
|
)
|
|
// Report should have the title as the first line
|
|
expect(report).toMatch(/^# My Custom Title\n## 1 passed, 4 failed and 1 skipped\n/)
|
|
})
|
|
})
|