1
0
Fork 0
mirror of https://github.com/dorny/test-reporter.git synced 2026-05-06 10:37:36 +02:00
This commit is contained in:
Jozef Izso 2026-04-25 12:16:23 +02:00 committed by GitHub
commit 237f6ed195
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 79 additions and 9 deletions

View file

@ -1,4 +1,5 @@
import {getBadge, DEFAULT_OPTIONS, ReportOptions} from '../../src/report/get-report.js'
import {DEFAULT_OPTIONS, getBadge, getReport, ReportOptions} from '../../src/report/get-report.js'
import {TestCaseResult, TestGroupResult, TestRunResult, TestSuiteResult} from '../../src/test-results.js'
describe('getBadge', () => {
describe('URI encoding with special characters', () => {
@ -131,3 +132,28 @@ describe('getBadge', () => {
})
})
})
describe('getReport', () => {
it('sorts suites by descending time when configured', () => {
const results = [
new TestRunResult('report.xml', [
createSuite('unit', 10),
createSuite('integration', 30),
createSuite('smoke', 20)
])
]
const report = getReport(results, {
...DEFAULT_OPTIONS,
sortSuites: 'time-desc',
listTests: 'none'
})
expect(report.indexOf('integration')).toBeLessThan(report.indexOf('smoke'))
expect(report.indexOf('smoke')).toBeLessThan(report.indexOf('unit'))
})
})
function createSuite(name: string, time: number): TestSuiteResult {
return new TestSuiteResult(name, [new TestGroupResult(name, [new TestCaseResult(`${name}-test`, 'success', time)])])
}

View file

@ -46,6 +46,13 @@ inputs:
- none
required: false
default: 'all'
sort-suites:
description: |
Sort order for test suites. Supported options:
- name: Sort alphabetically by name (default)
- time-desc: Sort by execution time, slowest first
required: false
default: 'name'
list-tests:
description: |
Limits which test cases are listed. Supported options:

21
dist/index.js generated vendored
View file

@ -56954,6 +56954,7 @@ const DEFAULT_OPTIONS = {
listSuites: 'all',
listTests: 'all',
slugPrefix: '',
sortSuites: 'name',
baseUrl: '',
onlySummary: false,
useActionsSummary: true,
@ -56962,7 +56963,7 @@ const DEFAULT_OPTIONS = {
collapsed: 'auto'
};
function getReport(results, options = DEFAULT_OPTIONS, shortSummary = '') {
applySort(results);
applySort(results, options);
const opts = { ...options };
let lines = renderReport(results, opts, shortSummary);
let report = lines.join('\n');
@ -57010,10 +57011,15 @@ function trimReport(lines, options) {
reportLines.push(errorMsg);
return reportLines.join('\n');
}
function applySort(results) {
function applySort(results, options) {
results.sort((a, b) => a.path.localeCompare(b.path, DEFAULT_LOCALE));
for (const res of results) {
res.suites.sort((a, b) => a.name.localeCompare(b.name, DEFAULT_LOCALE));
if (options.sortSuites === 'time-desc') {
res.suites.sort((a, b) => b.time - a.time);
}
else {
res.suites.sort((a, b) => a.name.localeCompare(b.name, DEFAULT_LOCALE));
}
}
}
function getByteLength(text) {
@ -58948,6 +58954,7 @@ class TestReporter {
pathReplaceBackslashes = getInput('path-replace-backslashes', { required: false }) === 'true';
reporter = getInput('reporter', { required: true });
listSuites = getInput('list-suites', { required: true });
sortSuites = getInput('sort-suites', { required: false });
listTests = getInput('list-tests', { required: true });
maxAnnotations = parseInt(getInput('max-annotations', { required: true }));
failOnError = getInput('fail-on-error', { required: true }) === 'true';
@ -58968,6 +58975,10 @@ class TestReporter {
setFailed(`Input parameter 'list-suites' has invalid value`);
return;
}
if (this.sortSuites !== 'name' && this.sortSuites !== 'time-desc') {
setFailed(`Input parameter 'sort-suites' has invalid value`);
return;
}
if (this.listTests !== 'all' && this.listTests !== 'failed' && this.listTests !== 'none') {
setFailed(`Input parameter 'list-tests' has invalid value`);
return;
@ -59056,7 +59067,7 @@ class TestReporter {
throw error;
}
}
const { listSuites, listTests, slugPrefix, onlySummary, useActionsSummary, badgeTitle, reportTitle, collapsed } = this;
const { listSuites, sortSuites, listTests, slugPrefix, 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);
const skipped = results.reduce((sum, tr) => sum + tr.skipped, 0);
@ -59065,6 +59076,7 @@ class TestReporter {
if (this.useActionsSummary) {
const summary = getReport(results, {
listSuites,
sortSuites,
listTests,
slugPrefix,
baseUrl,
@ -59094,6 +59106,7 @@ class TestReporter {
baseUrl = createResp.data.html_url;
const summary = getReport(results, {
listSuites,
sortSuites,
listTests,
slugPrefix,
baseUrl,

View file

@ -43,6 +43,7 @@ class TestReporter {
readonly pathReplaceBackslashes = core.getInput('path-replace-backslashes', {required: false}) === 'true'
readonly reporter = core.getInput('reporter', {required: true})
readonly listSuites = core.getInput('list-suites', {required: true}) as 'all' | 'failed' | 'none'
readonly sortSuites = core.getInput('sort-suites', {required: false}) as 'name' | 'time-desc'
readonly listTests = core.getInput('list-tests', {required: true}) as 'all' | 'failed' | 'none'
readonly maxAnnotations = parseInt(core.getInput('max-annotations', {required: true}))
readonly failOnError = core.getInput('fail-on-error', {required: true}) === 'true'
@ -66,6 +67,11 @@ class TestReporter {
return
}
if (this.sortSuites !== 'name' && this.sortSuites !== 'time-desc') {
core.setFailed(`Input parameter 'sort-suites' has invalid value`)
return
}
if (this.listTests !== 'all' && this.listTests !== 'failed' && this.listTests !== 'none') {
core.setFailed(`Input parameter 'list-tests' has invalid value`)
return
@ -177,7 +183,17 @@ class TestReporter {
}
}
const {listSuites, listTests, slugPrefix, onlySummary, useActionsSummary, badgeTitle, reportTitle, collapsed} = this
const {
listSuites,
sortSuites,
listTests,
slugPrefix,
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)
@ -190,6 +206,7 @@ class TestReporter {
results,
{
listSuites,
sortSuites,
listTests,
slugPrefix,
baseUrl,
@ -222,6 +239,7 @@ class TestReporter {
baseUrl = createResp.data.html_url as string
const summary = getReport(results, {
listSuites,
sortSuites,
listTests,
slugPrefix,
baseUrl,

View file

@ -12,6 +12,7 @@ export interface ReportOptions {
listSuites: 'all' | 'failed' | 'none'
listTests: 'all' | 'failed' | 'none'
slugPrefix: string
sortSuites: 'name' | 'time-desc'
baseUrl: string
onlySummary: boolean
useActionsSummary: boolean
@ -24,6 +25,7 @@ export const DEFAULT_OPTIONS: ReportOptions = {
listSuites: 'all',
listTests: 'all',
slugPrefix: '',
sortSuites: 'name',
baseUrl: '',
onlySummary: false,
useActionsSummary: true,
@ -37,7 +39,7 @@ export function getReport(
options: ReportOptions = DEFAULT_OPTIONS,
shortSummary = ''
): string {
applySort(results)
applySort(results, options)
const opts = {...options}
let lines = renderReport(results, opts, shortSummary)
@ -96,10 +98,14 @@ function trimReport(lines: string[], options: ReportOptions): string {
return reportLines.join('\n')
}
function applySort(results: TestRunResult[]): void {
function applySort(results: TestRunResult[], options: ReportOptions): void {
results.sort((a, b) => a.path.localeCompare(b.path, DEFAULT_LOCALE))
for (const res of results) {
res.suites.sort((a, b) => a.name.localeCompare(b.name, DEFAULT_LOCALE))
if (options.sortSuites === 'time-desc') {
res.suites.sort((a, b) => b.time - a.time)
} else {
res.suites.sort((a, b) => a.name.localeCompare(b.name, DEFAULT_LOCALE))
}
}
}