2021-02-21 11:53:02 +00:00
|
|
|
import * as core from '@actions/core';
|
|
|
|
|
import { RunMeta, TestMeta } from './ts/meta.ts';
|
|
|
|
|
|
|
|
|
|
class ReportConverter {
|
|
|
|
|
static convertReport(filename, report) {
|
2021-02-21 12:46:22 +00:00
|
|
|
core.info(`Start analyzing report: ${filename}`);
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(JSON.stringify(report));
|
2021-02-21 11:53:02 +00:00
|
|
|
const run = report['test-run'];
|
|
|
|
|
const meta = new RunMeta(filename);
|
|
|
|
|
|
2021-02-22 01:03:06 +00:00
|
|
|
meta.total = Number(run._attributes.total);
|
|
|
|
|
meta.failed = Number(run._attributes.failed);
|
|
|
|
|
meta.skipped = Number(run._attributes.skipped);
|
|
|
|
|
meta.passed = Number(run._attributes.passed);
|
|
|
|
|
meta.duration = Number(run._attributes.duration);
|
2021-02-21 11:53:02 +00:00
|
|
|
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`test-suite length ${run['test-suite'].length} and value ${run['test-suite']}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
meta.addTests(ReportConverter.convertSuite(run['test-suite']));
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`meta length ${meta.suites.length}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
|
|
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-21 13:42:17 +00:00
|
|
|
static convertSuite(suites) {
|
2021-02-21 11:53:02 +00:00
|
|
|
if (Array.isArray(suites)) {
|
2021-02-22 17:17:24 +00:00
|
|
|
const innerResult = [];
|
2021-02-21 14:37:47 +00:00
|
|
|
suites.forEach(suite => {
|
2021-02-23 01:03:43 +00:00
|
|
|
innerResult.push(ReportConverter.convertSuite(suite));
|
2021-02-21 11:53:02 +00:00
|
|
|
});
|
2021-02-23 04:20:24 +00:00
|
|
|
core.debug(`suite innerResult length ${innerResult.length}`);
|
2021-02-22 17:17:24 +00:00
|
|
|
return innerResult;
|
2021-02-21 11:53:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`Analyze suite ${suites._attributes.type} / ${suites._attributes.fullname}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
const result = [];
|
|
|
|
|
const innerSuite = suites['test-suite'];
|
|
|
|
|
if (innerSuite) {
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`pushing suite ${innerSuite._attributes.id}`);
|
2021-02-22 16:57:08 +00:00
|
|
|
result.push(...ReportConverter.convertSuite(innerSuite));
|
2021-02-23 00:39:02 +00:00
|
|
|
core.debug(`suite ${innerSuite._attributes.id} pushed result to length ${result.length}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tests = suites['test-case'];
|
|
|
|
|
if (tests) {
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`tests length ${tests.length}`);
|
2021-02-22 01:03:06 +00:00
|
|
|
result.push(...ReportConverter.convertTests(suites._attributes.fullname, tests));
|
2021-02-23 00:39:02 +00:00
|
|
|
core.debug(`tests pushed result to length ${result.length}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-23 04:20:24 +00:00
|
|
|
core.debug(`suite result length ${result.length}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-21 13:42:17 +00:00
|
|
|
static convertTests(suite, tests) {
|
2021-02-21 11:53:02 +00:00
|
|
|
if (Array.isArray(tests)) {
|
|
|
|
|
const result = [];
|
2021-02-21 14:37:47 +00:00
|
|
|
tests.forEach(test => {
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`pushing test ${test._attributes.name}`);
|
2021-02-23 01:03:43 +00:00
|
|
|
result.push(ReportConverter.convertTestCase(suite, test));
|
|
|
|
|
core.debug(`test ${test._attributes.name} pushed result to length ${result.length}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
});
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-21 13:42:17 +00:00
|
|
|
return [ReportConverter.convertTestCase(suite, tests)];
|
2021-02-21 11:53:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-21 13:42:17 +00:00
|
|
|
static convertTestCase(suite, testCase) {
|
2021-02-22 01:03:06 +00:00
|
|
|
const { name, fullname, result, failure, duration } = testCase._attributes;
|
2021-02-21 11:53:02 +00:00
|
|
|
const meta = new TestMeta(suite, name);
|
|
|
|
|
meta.result = result;
|
|
|
|
|
meta.duration = Number(duration);
|
|
|
|
|
|
|
|
|
|
if (!failure) {
|
2021-02-22 23:19:20 +00:00
|
|
|
core.debug(`Skip test ${fullname} without failure data`);
|
2021-02-21 11:53:02 +00:00
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core.debug(`Convert data for test ${fullname}`);
|
|
|
|
|
if (failure['stack-trace'] === undefined) {
|
2021-02-21 12:46:22 +00:00
|
|
|
core.warning(`No stack trace for test case: ${fullname}`);
|
2021-02-21 11:53:02 +00:00
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const trace = failure['stack-trace'].cdata;
|
2021-02-21 13:42:17 +00:00
|
|
|
const point = ReportConverter.findAnnotationPoint(trace);
|
2021-02-21 11:53:02 +00:00
|
|
|
if (point === undefined) {
|
|
|
|
|
core.warning('Not able to find entry point for failed test! Test trace:');
|
|
|
|
|
core.warning(trace);
|
|
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
meta.annotation = {
|
|
|
|
|
path: point.path,
|
|
|
|
|
start_line: point.line,
|
|
|
|
|
end_line: point.line,
|
|
|
|
|
annotation_level: 'failure',
|
|
|
|
|
title: fullname,
|
2021-02-22 16:57:08 +00:00
|
|
|
message: failure.message._cdata,
|
2021-02-21 11:53:02 +00:00
|
|
|
raw_details: trace,
|
|
|
|
|
};
|
|
|
|
|
core.info(`- ${meta.annotation.path}:${meta.annotation.start_line} - ${meta.annotation.title}`);
|
|
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static findAnnotationPoint(trace) {
|
|
|
|
|
const match = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
|
|
|
|
|
return {
|
|
|
|
|
path: match.groups.path,
|
|
|
|
|
line: Number(match.groups.line),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default ReportConverter;
|