mirror of
https://github.com/dorny/test-reporter.git
synced 2025-12-16 06:17:10 +01:00
Improve logging and error handling
This commit is contained in:
parent
967dbab3c6
commit
1ab5efa052
7 changed files with 174 additions and 33 deletions
142
dist/index.js
generated
vendored
142
dist/index.js
generated
vendored
|
|
@ -75,11 +75,13 @@ async function main() {
|
||||||
const parser = getParser(reporter);
|
const parser = getParser(reporter);
|
||||||
const files = await getFiles(path);
|
const files = await getFiles(path);
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
core.setFailed(`No file matches path ${path}`);
|
core.setFailed(`No file matches path '${path}'`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
core.info(`Using test report parser '${reporter}'`);
|
||||||
const result = await parser(files, opts);
|
const result = await parser(files, opts);
|
||||||
const conclusion = result.success ? 'success' : 'failure';
|
const conclusion = result.success ? 'success' : 'failure';
|
||||||
|
core.info(`Creating check run '${name}' with conclusion '${conclusion}'`);
|
||||||
await octokit.checks.create({
|
await octokit.checks.create({
|
||||||
head_sha: sha,
|
head_sha: sha,
|
||||||
name,
|
name,
|
||||||
|
|
@ -90,7 +92,7 @@ async function main() {
|
||||||
});
|
});
|
||||||
core.setOutput('conclusion', conclusion);
|
core.setOutput('conclusion', conclusion);
|
||||||
if (failOnError && !result.success) {
|
if (failOnError && !result.success) {
|
||||||
core.setFailed(`Failed test has been found and 'fail-on-error' option is set to ${failOnError}.`);
|
core.setFailed(`Failed test has been found and 'fail-on-error' option is set to ${failOnError}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getParser(reporter) {
|
function getParser(reporter) {
|
||||||
|
|
@ -104,12 +106,13 @@ function getParser(reporter) {
|
||||||
case 'jest-junit':
|
case 'jest-junit':
|
||||||
return jest_junit_parser_1.parseJestJunit;
|
return jest_junit_parser_1.parseJestJunit;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Input parameter 'reporter' is set to invalid value '${reporter}'`);
|
throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function getFiles(pattern) {
|
async function getFiles(pattern) {
|
||||||
const paths = await fast_glob_1.default(pattern, { dot: true });
|
const paths = await fast_glob_1.default(pattern, { dot: true });
|
||||||
return Promise.all(paths.map(async (path) => {
|
return Promise.all(paths.map(async (path) => {
|
||||||
|
core.info(`Reading test report '${path}'`);
|
||||||
const content = await fs.promises.readFile(path, { encoding: 'utf8' });
|
const content = await fs.promises.readFile(path, { encoding: 'utf8' });
|
||||||
return { path, content };
|
return { path, content };
|
||||||
}));
|
}));
|
||||||
|
|
@ -125,11 +128,31 @@ run();
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.parseDartJson = void 0;
|
exports.parseDartJson = void 0;
|
||||||
|
const core = __importStar(__webpack_require__(2186));
|
||||||
const get_report_1 = __importDefault(__webpack_require__(3737));
|
const get_report_1 = __importDefault(__webpack_require__(3737));
|
||||||
const file_utils_1 = __webpack_require__(2711);
|
const file_utils_1 = __webpack_require__(2711);
|
||||||
const markdown_utils_1 = __webpack_require__(6482);
|
const markdown_utils_1 = __webpack_require__(6482);
|
||||||
|
|
@ -193,8 +216,22 @@ async function parseDartJson(files, options) {
|
||||||
}
|
}
|
||||||
exports.parseDartJson = parseDartJson;
|
exports.parseDartJson = parseDartJson;
|
||||||
function getTestRun(path, content) {
|
function getTestRun(path, content) {
|
||||||
const lines = content.split(/\n\r?/g).filter(line => line !== '');
|
core.info(`Parsing content of '${path}'`);
|
||||||
const events = lines.map(str => JSON.parse(str));
|
const lines = content.split(/\n\r?/g);
|
||||||
|
const events = lines
|
||||||
|
.map((str, i) => {
|
||||||
|
if (str.trim() === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JSON.parse(str);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
const col = e.columnNumber !== undefined ? `:${e.columnNumber}` : '';
|
||||||
|
new Error(`Invalid JSON at ${path}:${i + 1}${col}\n\n${e}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(evt => evt != null);
|
||||||
let success = false;
|
let success = false;
|
||||||
let totalTime = 0;
|
let totalTime = 0;
|
||||||
const suites = {};
|
const suites = {};
|
||||||
|
|
@ -356,11 +393,31 @@ exports.isDoneEvent = isDoneEvent;
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.exceptionThrowSource = exports.parseDotnetTrx = void 0;
|
exports.exceptionThrowSource = exports.parseDotnetTrx = void 0;
|
||||||
|
const core = __importStar(__webpack_require__(2186));
|
||||||
const xml2js_1 = __webpack_require__(6189);
|
const xml2js_1 = __webpack_require__(6189);
|
||||||
const file_utils_1 = __webpack_require__(2711);
|
const file_utils_1 = __webpack_require__(2711);
|
||||||
const xml_utils_1 = __webpack_require__(8653);
|
const xml_utils_1 = __webpack_require__(8653);
|
||||||
|
|
@ -395,7 +452,7 @@ async function parseDotnetTrx(files, options) {
|
||||||
const testRuns = [];
|
const testRuns = [];
|
||||||
const testClasses = [];
|
const testClasses = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const trx = await getTrxReport(file.content);
|
const trx = await getTrxReport(file);
|
||||||
const tc = getTestClasses(trx);
|
const tc = getTestClasses(trx);
|
||||||
const tr = getTestRunResult(file.path, trx, tc);
|
const tr = getTestRunResult(file.path, trx, tc);
|
||||||
testRuns.push(tr);
|
testRuns.push(tr);
|
||||||
|
|
@ -413,10 +470,16 @@ async function parseDotnetTrx(files, options) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.parseDotnetTrx = parseDotnetTrx;
|
exports.parseDotnetTrx = parseDotnetTrx;
|
||||||
async function getTrxReport(content) {
|
async function getTrxReport(file) {
|
||||||
return (await xml2js_1.parseStringPromise(content, {
|
core.info(`Parsing content of '${file.path}'`);
|
||||||
attrValueProcessors: [xml_utils_1.parseAttribute]
|
try {
|
||||||
}));
|
return (await xml2js_1.parseStringPromise(file.content, {
|
||||||
|
attrValueProcessors: [xml_utils_1.parseAttribute]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
throw new Error(`Invalid XML at ${file.path}\n\n${e}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function getTestRunResult(path, trx, testClasses) {
|
function getTestRunResult(path, trx, testClasses) {
|
||||||
const times = trx.TestRun.Times[0].$;
|
const times = trx.TestRun.Times[0].$;
|
||||||
|
|
@ -508,11 +571,31 @@ exports.exceptionThrowSource = exceptionThrowSource;
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.exceptionThrowSource = exports.parseJestJunit = void 0;
|
exports.exceptionThrowSource = exports.parseJestJunit = void 0;
|
||||||
|
const core = __importStar(__webpack_require__(2186));
|
||||||
const xml2js_1 = __webpack_require__(6189);
|
const xml2js_1 = __webpack_require__(6189);
|
||||||
const markdown_utils_1 = __webpack_require__(6482);
|
const markdown_utils_1 = __webpack_require__(6482);
|
||||||
const file_utils_1 = __webpack_require__(2711);
|
const file_utils_1 = __webpack_require__(2711);
|
||||||
|
|
@ -523,7 +606,7 @@ async function parseJestJunit(files, options) {
|
||||||
const junit = [];
|
const junit = [];
|
||||||
const testRuns = [];
|
const testRuns = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const ju = await getJunitReport(file.content);
|
const ju = await getJunitReport(file);
|
||||||
const tr = getTestRunResult(file.path, ju);
|
const tr = getTestRunResult(file.path, ju);
|
||||||
junit.push(ju);
|
junit.push(ju);
|
||||||
testRuns.push(tr);
|
testRuns.push(tr);
|
||||||
|
|
@ -540,10 +623,16 @@ async function parseJestJunit(files, options) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.parseJestJunit = parseJestJunit;
|
exports.parseJestJunit = parseJestJunit;
|
||||||
async function getJunitReport(content) {
|
async function getJunitReport(file) {
|
||||||
return (await xml2js_1.parseStringPromise(content, {
|
core.info(`Parsing content of '${file.path}'`);
|
||||||
attrValueProcessors: [xml_utils_1.parseAttribute]
|
try {
|
||||||
}));
|
return (await xml2js_1.parseStringPromise(file.content, {
|
||||||
|
attrValueProcessors: [xml_utils_1.parseAttribute]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
throw new Error(`Invalid XML at ${file.path}\n\n${e}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function getTestRunResult(path, junit) {
|
function getTestRunResult(path, junit) {
|
||||||
const suites = junit.testsuites.testsuite.map(ts => {
|
const suites = junit.testsuites.testsuite.map(ts => {
|
||||||
|
|
@ -633,11 +722,31 @@ exports.exceptionThrowSource = exceptionThrowSource;
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3737:
|
/***/ 3737:
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
const core = __importStar(__webpack_require__(2186));
|
||||||
const markdown_utils_1 = __webpack_require__(6482);
|
const markdown_utils_1 = __webpack_require__(6482);
|
||||||
const slugger_1 = __webpack_require__(3328);
|
const slugger_1 = __webpack_require__(3328);
|
||||||
function getReport(results) {
|
function getReport(results) {
|
||||||
|
|
@ -651,6 +760,7 @@ function getReport(results) {
|
||||||
}
|
}
|
||||||
exports.default = getReport;
|
exports.default = getReport;
|
||||||
function getRunSummary(tr) {
|
function getRunSummary(tr) {
|
||||||
|
core.info('Generating check run summary');
|
||||||
const time = `${(tr.time / 1000).toFixed(3)}s`;
|
const time = `${(tr.time / 1000).toFixed(3)}s`;
|
||||||
const headingLine1 = `### ${tr.path}`;
|
const headingLine1 = `### ${tr.path}`;
|
||||||
const headingLine2 = `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.skipped}** skipped and **${tr.failed}** failed.`;
|
const headingLine2 = `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.skipped}** skipped and **${tr.failed}** failed.`;
|
||||||
|
|
|
||||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
|
|
@ -50,13 +50,15 @@ async function main(): Promise<void> {
|
||||||
const files = await getFiles(path)
|
const files = await getFiles(path)
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
core.setFailed(`No file matches path ${path}`)
|
core.setFailed(`No file matches path '${path}'`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core.info(`Using test report parser '${reporter}'`)
|
||||||
const result = await parser(files, opts)
|
const result = await parser(files, opts)
|
||||||
const conclusion = result.success ? 'success' : 'failure'
|
const conclusion = result.success ? 'success' : 'failure'
|
||||||
|
|
||||||
|
core.info(`Creating check run '${name}' with conclusion '${conclusion}'`)
|
||||||
await octokit.checks.create({
|
await octokit.checks.create({
|
||||||
head_sha: sha,
|
head_sha: sha,
|
||||||
name,
|
name,
|
||||||
|
|
@ -68,7 +70,7 @@ async function main(): Promise<void> {
|
||||||
|
|
||||||
core.setOutput('conclusion', conclusion)
|
core.setOutput('conclusion', conclusion)
|
||||||
if (failOnError && !result.success) {
|
if (failOnError && !result.success) {
|
||||||
core.setFailed(`Failed test has been found and 'fail-on-error' option is set to ${failOnError}.`)
|
core.setFailed(`Failed test has been found and 'fail-on-error' option is set to ${failOnError}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +85,7 @@ function getParser(reporter: string): ParseTestResult {
|
||||||
case 'jest-junit':
|
case 'jest-junit':
|
||||||
return parseJestJunit
|
return parseJestJunit
|
||||||
default:
|
default:
|
||||||
throw new Error(`Input parameter 'reporter' is set to invalid value '${reporter}'`)
|
throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +93,7 @@ export async function getFiles(pattern: string): Promise<FileContent[]> {
|
||||||
const paths = await glob(pattern, {dot: true})
|
const paths = await glob(pattern, {dot: true})
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
paths.map(async path => {
|
paths.map(async path => {
|
||||||
|
core.info(`Reading test report '${path}'`)
|
||||||
const content = await fs.promises.readFile(path, {encoding: 'utf8'})
|
const content = await fs.promises.readFile(path, {encoding: 'utf8'})
|
||||||
return {path, content}
|
return {path, content}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
||||||
|
|
||||||
import getReport from '../../report/get-report'
|
import getReport from '../../report/get-report'
|
||||||
|
|
@ -85,8 +86,21 @@ export async function parseDartJson(files: FileContent[], options: ParseOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTestRun(path: string, content: string): TestRun {
|
function getTestRun(path: string, content: string): TestRun {
|
||||||
const lines = content.split(/\n\r?/g).filter(line => line !== '')
|
core.info(`Parsing content of '${path}'`)
|
||||||
const events = lines.map(str => JSON.parse(str)) as ReportEvent[]
|
const lines = content.split(/\n\r?/g)
|
||||||
|
const events = lines
|
||||||
|
.map((str, i) => {
|
||||||
|
if (str.trim() === '') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JSON.parse(str)
|
||||||
|
} catch (e) {
|
||||||
|
const col = e.columnNumber !== undefined ? `:${e.columnNumber}` : ''
|
||||||
|
new Error(`Invalid JSON at ${path}:${i + 1}${col}\n\n${e}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(evt => evt != null) as ReportEvent[]
|
||||||
|
|
||||||
let success = false
|
let success = false
|
||||||
let totalTime = 0
|
let totalTime = 0
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
import {ErrorInfo, Outcome, TestMethod, TrxReport} from './dotnet-trx-types'
|
import {ErrorInfo, Outcome, TestMethod, TrxReport} from './dotnet-trx-types'
|
||||||
|
|
||||||
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
||||||
|
|
@ -29,7 +30,7 @@ class Test {
|
||||||
readonly error?: ErrorInfo
|
readonly error?: ErrorInfo
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get result(): TestExecutionResult {
|
get result(): TestExecutionResult | undefined {
|
||||||
switch (this.outcome) {
|
switch (this.outcome) {
|
||||||
case 'Passed':
|
case 'Passed':
|
||||||
return 'success'
|
return 'success'
|
||||||
|
|
@ -46,7 +47,7 @@ export async function parseDotnetTrx(files: FileContent[], options: ParseOptions
|
||||||
const testClasses: TestClass[] = []
|
const testClasses: TestClass[] = []
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const trx = await getTrxReport(file.content)
|
const trx = await getTrxReport(file)
|
||||||
const tc = getTestClasses(trx)
|
const tc = getTestClasses(trx)
|
||||||
const tr = getTestRunResult(file.path, trx, tc)
|
const tr = getTestRunResult(file.path, trx, tc)
|
||||||
testRuns.push(tr)
|
testRuns.push(tr)
|
||||||
|
|
@ -66,10 +67,15 @@ export async function parseDotnetTrx(files: FileContent[], options: ParseOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTrxReport(content: string): Promise<TrxReport> {
|
async function getTrxReport(file: FileContent): Promise<TrxReport> {
|
||||||
return (await parseStringPromise(content, {
|
core.info(`Parsing content of '${file.path}'`)
|
||||||
attrValueProcessors: [parseAttribute]
|
try {
|
||||||
})) as TrxReport
|
return (await parseStringPromise(file.content, {
|
||||||
|
attrValueProcessors: [parseAttribute]
|
||||||
|
})) as TrxReport
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Invalid XML at ${file.path}\n\n${e}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTestRunResult(path: string, trx: TrxReport, testClasses: TestClass[]): TestRunResult {
|
function getTestRunResult(path: string, trx: TrxReport, testClasses: TestClass[]): TestRunResult {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
import {Annotation, FileContent, ParseOptions, TestResult} from '../parser-types'
|
||||||
import {parseStringPromise} from 'xml2js'
|
import {parseStringPromise} from 'xml2js'
|
||||||
|
|
||||||
|
|
@ -20,7 +21,7 @@ export async function parseJestJunit(files: FileContent[], options: ParseOptions
|
||||||
const testRuns: TestRunResult[] = []
|
const testRuns: TestRunResult[] = []
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const ju = await getJunitReport(file.content)
|
const ju = await getJunitReport(file)
|
||||||
const tr = getTestRunResult(file.path, ju)
|
const tr = getTestRunResult(file.path, ju)
|
||||||
junit.push(ju)
|
junit.push(ju)
|
||||||
testRuns.push(tr)
|
testRuns.push(tr)
|
||||||
|
|
@ -39,10 +40,15 @@ export async function parseJestJunit(files: FileContent[], options: ParseOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getJunitReport(content: string): Promise<JunitReport> {
|
async function getJunitReport(file: FileContent): Promise<JunitReport> {
|
||||||
return (await parseStringPromise(content, {
|
core.info(`Parsing content of '${file.path}'`)
|
||||||
attrValueProcessors: [parseAttribute]
|
try {
|
||||||
})) as JunitReport
|
return (await parseStringPromise(file.content, {
|
||||||
|
attrValueProcessors: [parseAttribute]
|
||||||
|
})) as JunitReport
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Invalid XML at ${file.path}\n\n${e}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTestRunResult(path: string, junit: JunitReport): TestRunResult {
|
function getTestRunResult(path: string, junit: JunitReport): TestRunResult {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
import {TestExecutionResult, TestRunResult, TestSuiteResult} from './test-results'
|
import {TestExecutionResult, TestRunResult, TestSuiteResult} from './test-results'
|
||||||
import {Align, Icon, link, table} from '../utils/markdown-utils'
|
import {Align, Icon, link, table} from '../utils/markdown-utils'
|
||||||
import {slug} from '../utils/slugger'
|
import {slug} from '../utils/slugger'
|
||||||
|
|
@ -14,6 +15,7 @@ export default function getReport(results: TestRunResult[]): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRunSummary(tr: TestRunResult): string {
|
function getRunSummary(tr: TestRunResult): string {
|
||||||
|
core.info('Generating check run summary')
|
||||||
const time = `${(tr.time / 1000).toFixed(3)}s`
|
const time = `${(tr.time / 1000).toFixed(3)}s`
|
||||||
const headingLine1 = `### ${tr.path}`
|
const headingLine1 = `### ${tr.path}`
|
||||||
const headingLine2 = `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.skipped}** skipped and **${tr.failed}** failed.`
|
const headingLine2 = `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.skipped}** skipped and **${tr.failed}** failed.`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue