mirror of
https://github.com/dorny/test-reporter.git
synced 2025-12-16 14:27:10 +01:00
Persist test summary on disk
This commit is contained in:
parent
c9b3d0e2bd
commit
83b7f42d2d
19 changed files with 1284 additions and 3655 deletions
72
src/main.ts
72
src/main.ts
|
|
@ -1,5 +1,6 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import * as fs from 'fs'
|
||||
import {GitHub} from '@actions/github/lib/utils'
|
||||
|
||||
import {ArtifactProvider} from './input-providers/artifact-provider'
|
||||
|
|
@ -7,7 +8,6 @@ import {LocalFileProvider} from './input-providers/local-file-provider'
|
|||
import {FileContent} from './input-providers/input-provider'
|
||||
import {ParseOptions, TestParser} from './test-parser'
|
||||
import {TestRunResult} from './test-results'
|
||||
import {getAnnotations} from './report/get-annotations'
|
||||
import {getReport} from './report/get-report'
|
||||
|
||||
import {DartJsonParser} from './parsers/dart-json/dart-json-parser'
|
||||
|
|
@ -18,7 +18,6 @@ import {MochaJsonParser} from './parsers/mocha-json/mocha-json-parser'
|
|||
|
||||
import {normalizeDirPath, normalizeFilePath} from './utils/path-utils'
|
||||
import {getCheckRunContext} from './utils/github-utils'
|
||||
import {Icon} from './utils/markdown-utils'
|
||||
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
|
|
@ -154,45 +153,50 @@ class TestReporter {
|
|||
results.push(tr)
|
||||
}
|
||||
|
||||
core.info(`Creating check run ${name}`)
|
||||
const createResp = await this.octokit.rest.checks.create({
|
||||
head_sha: this.context.sha,
|
||||
name,
|
||||
status: 'in_progress',
|
||||
output: {
|
||||
title: name,
|
||||
summary: ''
|
||||
},
|
||||
...github.context.repo
|
||||
})
|
||||
// core.info(`Creating check run ${name}`)
|
||||
// const createResp = await this.octokit.checks.create({
|
||||
// head_sha: this.context.sha,
|
||||
// name,
|
||||
// status: 'in_progress',
|
||||
// output: {
|
||||
// title: name,
|
||||
// summary: ''
|
||||
// },
|
||||
// ...github.context.repo
|
||||
// })
|
||||
|
||||
core.info('Creating report summary')
|
||||
const {listSuites, listTests, onlySummary} = this
|
||||
const baseUrl = createResp.data.html_url as string
|
||||
const baseUrl = ''
|
||||
const summary = getReport(results, {listSuites, listTests, baseUrl, onlySummary})
|
||||
core.info('Summary content:')
|
||||
core.info(summary)
|
||||
await fs.promises.writeFile(this.path.replace('*.trx', 'test-summary.md'), summary)
|
||||
core.info('File content:')
|
||||
core.info(fs.readFileSync(this.path.replace('*.trx', 'test-summary.md'), 'utf8'))
|
||||
|
||||
core.info('Creating annotations')
|
||||
const annotations = getAnnotations(results, this.maxAnnotations)
|
||||
// core.info('Creating annotations')
|
||||
// const annotations = getAnnotations(results, this.maxAnnotations)
|
||||
|
||||
const isFailed = results.some(tr => tr.result === 'failed')
|
||||
const conclusion = isFailed ? 'failure' : 'success'
|
||||
const icon = isFailed ? Icon.fail : Icon.success
|
||||
// const isFailed = results.some(tr => tr.result === 'failed')
|
||||
// const conclusion = isFailed ? 'failure' : 'success'
|
||||
// const icon = isFailed ? Icon.fail : Icon.success
|
||||
|
||||
core.info(`Updating check run conclusion (${conclusion}) and output`)
|
||||
const resp = await this.octokit.rest.checks.update({
|
||||
check_run_id: createResp.data.id,
|
||||
conclusion,
|
||||
status: 'completed',
|
||||
output: {
|
||||
title: `${name} ${icon}`,
|
||||
summary,
|
||||
annotations
|
||||
},
|
||||
...github.context.repo
|
||||
})
|
||||
core.info(`Check run create response: ${resp.status}`)
|
||||
core.info(`Check run URL: ${resp.data.url}`)
|
||||
core.info(`Check run HTML: ${resp.data.html_url}`)
|
||||
// core.info(`Updating check run conclusion (${conclusion}) and output`)
|
||||
// const resp = await this.octokit.checks.update({
|
||||
// check_run_id: createResp.data.id,
|
||||
// conclusion,
|
||||
// status: 'completed',
|
||||
// output: {
|
||||
// title: `${name} ${icon}`,
|
||||
// summary,
|
||||
// annotations
|
||||
// },
|
||||
// ...github.context.repo
|
||||
// })
|
||||
// core.info(`Check run create response: ${resp.status}`)
|
||||
// core.info(`Check run URL: ${resp.data.url}`)
|
||||
// core.info(`Check run HTML: ${resp.data.html_url}`)
|
||||
|
||||
return results
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ import {
|
|||
} from '../../test-results'
|
||||
|
||||
class TestClass {
|
||||
constructor(readonly name: string) {}
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly assemblyName: string
|
||||
) {}
|
||||
readonly tests: Test[] = []
|
||||
}
|
||||
|
||||
|
|
@ -81,9 +84,12 @@ export class DotnetTrxParser implements TestParser {
|
|||
const testClasses: {[name: string]: TestClass} = {}
|
||||
for (const r of unitTestsResults) {
|
||||
const className = r.test.TestMethod[0].$.className
|
||||
const codeBase = r.test.TestMethod[0].$.codeBase
|
||||
const pathSegments = codeBase.replace(/\\/g, '/').split('/')
|
||||
const assemblyName = pathSegments[pathSegments.length - 1].replace('.dll', '')
|
||||
let tc = testClasses[className]
|
||||
if (tc === undefined) {
|
||||
tc = new TestClass(className)
|
||||
tc = new TestClass(className, assemblyName)
|
||||
testClasses[tc.name] = tc
|
||||
}
|
||||
const error = this.getErrorInfo(r.result)
|
||||
|
|
@ -117,6 +123,10 @@ export class DotnetTrxParser implements TestParser {
|
|||
return new TestSuiteResult(testClass.name, [group])
|
||||
})
|
||||
|
||||
if (testClasses.length > 0) {
|
||||
return new TestRunResult(testClasses[0].assemblyName, suites, totalTime)
|
||||
}
|
||||
|
||||
return new TestRunResult(path, suites, totalTime)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export interface UnitTest {
|
|||
|
||||
export interface TestMethod {
|
||||
$: {
|
||||
codeBase: string
|
||||
className: string
|
||||
name: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,16 +136,16 @@ function getTestRunsReport(testRuns: TestRunResult[], options: ReportOptions): s
|
|||
const sections: string[] = []
|
||||
|
||||
if (testRuns.length > 1 || options.onlySummary) {
|
||||
const tableData = testRuns.map((tr, runIndex) => {
|
||||
const time = formatTime(tr.time)
|
||||
const name = tr.path
|
||||
const addr = options.baseUrl + makeRunSlug(runIndex).link
|
||||
const nameLink = link(name, addr)
|
||||
const passed = tr.passed > 0 ? `${tr.passed}${Icon.success}` : ''
|
||||
const failed = tr.failed > 0 ? `${tr.failed}${Icon.fail}` : ''
|
||||
const skipped = tr.skipped > 0 ? `${tr.skipped}${Icon.skip}` : ''
|
||||
return [nameLink, passed, failed, skipped, time]
|
||||
})
|
||||
const tableData = testRuns
|
||||
.filter(tr => tr.passed > 0 || tr.failed > 0 || tr.skipped > 0)
|
||||
.map(tr => {
|
||||
const time = formatTime(tr.time)
|
||||
const name = tr.path
|
||||
const passed = tr.passed > 0 ? `${tr.passed}${Icon.success}` : ''
|
||||
const failed = tr.failed > 0 ? `${tr.failed}${Icon.fail}` : ''
|
||||
const skipped = tr.skipped > 0 ? `${tr.skipped}${Icon.skip}` : ''
|
||||
return [name, passed, failed, skipped, time]
|
||||
})
|
||||
|
||||
const resultsTable = table(
|
||||
['Report', 'Passed', 'Failed', 'Skipped', 'Time'],
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ export enum Align {
|
|||
}
|
||||
|
||||
export const Icon = {
|
||||
skip: '✖️', // ':heavy_multiplication_x:'
|
||||
success: '✔️', // ':heavy_check_mark:'
|
||||
fail: '❌' // ':x:'
|
||||
skip: ':no_entry_sign:',
|
||||
success: ':white_check_mark:',
|
||||
fail: ':x:'
|
||||
}
|
||||
|
||||
export function link(title: string, address: string): string {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue