jest-allure2-adapter
Version:
Allure 2 Adapter for jest
418 lines (415 loc) • 16.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AllureReporter = void 0;
const allure_js_commons_1 = require("allure-js-commons");
const test_suite_props_1 = require("./test-suite-props");
const allure_current_1 = require("./allure-current");
const utils_1 = require("./utils");
const dateNow = Date.now;
const stripAnsi = require('strip-ansi');
var SpecStatus;
(function (SpecStatus) {
SpecStatus["PASSED"] = "passed";
SpecStatus["FAILED"] = "failed";
SpecStatus["BROKEN"] = "broken";
SpecStatus["PENDING"] = "pending";
SpecStatus["DISABLED"] = "disabled";
SpecStatus["EXCLUDED"] = "excluded";
SpecStatus["TODO"] = "todo";
})(SpecStatus || (SpecStatus = {}));
class AllureReporter extends allure_js_commons_1.Allure {
constructor(config) {
var _a;
super(new allure_js_commons_1.AllureRuntime({ resultsDir: (_a = config === null || config === void 0 ? void 0 : config.resultsDir) !== null && _a !== void 0 ? _a : 'allure-results' }));
this.config = config;
this.runningTest = null;
this.runningGroup = null;
this.groupNameStack = [];
this.stepStack = [];
this.currentStepStatus = null;
this.storyProps = new test_suite_props_1.TestSuiteProps();
this.featureProps = new test_suite_props_1.TestSuiteProps();
this.frameworkProps = new test_suite_props_1.TestSuiteProps();
this.languageProps = new test_suite_props_1.TestSuiteProps();
this.hostProps = new test_suite_props_1.TestSuiteProps();
this.environmentInfo = {};
this.test_ = new allure_current_1.AllureCurrent(this.runtime, () => this.currentTest);
this.executable = new allure_current_1.AllureCurrent(this.runtime, () => this.currentExecutable);
}
get test() {
return this.test_;
}
get isTestActive() {
return this.runningTest !== null;
}
get currentTest() {
if (this.runningTest === null) {
throw new Error('No active test');
}
return this.runningTest;
}
get currentExecutable() {
var _a;
return (_a = this.currentStep) !== null && _a !== void 0 ? _a : this.currentTest;
}
get currentGroup() {
if (this.runningGroup === null) {
throw new Error('No active group');
}
return this.runningGroup;
}
get currentStep() {
if (this.stepStack.length > 0) {
return this.stepStack[this.stepStack.length - 1];
}
return null;
}
startGroup(name) {
// todo check currentgroup.startgroup
// todo check empty name
this.runningGroup = this.runtime.startGroup(name);
const group = { name: name, uuid: this.runningGroup.uuid, children: [] };
if (this.groupNameStack.length > 0) {
this.groupNameStack[this.groupNameStack.length - 1].children.push(this.runningGroup.uuid);
}
this.groupNameStack.push(group);
}
// todo decorators
startTest(spec, start) {
this.runningTest = this.currentGroup.startTest(spec.description, start || dateNow());
this.runningTest.fullName = spec.fullName;
this.executable.initDescription();
// Capture Jest worker thread for timeline report
if (process.env.JEST_WORKER_ID) {
this.currentTest.addLabel(allure_js_commons_1.LabelName.THREAD, `${('0' + Number(process.env.JEST_WORKER_ID)).slice(-2)}`);
}
this.framework('jest');
this.language('typescript/javascript');
const os = require('os');
const hostname = os.hostname();
this.host(hostname);
this.applyGroupping();
}
startStep(name, start) {
var _a;
const allureStep = this.currentExecutable.startStep((((_a = this.config) === null || _a === void 0 ? void 0 : _a.stepTimestamp) ? utils_1.dateStr() + ' | ' : '') + name, start || dateNow());
this.stepStack.push(allureStep);
return allureStep;
}
stepStatus(status, details) {
if (this.currentStep) {
this.currentStepStatus = { status: status, details: details };
}
}
endStep(status, stage, details, end) {
var _a;
const step = this.stepStack.pop();
if (!step) {
console.log('No step started');
return;
}
step.stage = stage !== null && stage !== void 0 ? stage : allure_js_commons_1.Stage.FINISHED;
if (status) {
step.status = status;
}
if ((details === null || details === void 0 ? void 0 : details.message) || (details === null || details === void 0 ? void 0 : details.trace)) {
step.statusDetails = {
message: details.message,
trace: details.trace,
};
}
if (details && ((_a = this.config) === null || _a === void 0 ? void 0 : _a.addStepStatusDetailsAttachment)) {
// todo: status details does not work in report, workaround below
const type = allure_js_commons_1.ContentType.JSON;
const file = this.getAttachFile(details, type);
step.addAttachment('StatusDetails_' + utils_1.dateStr(true), type, file);
}
step.endStep(end || dateNow());
this.currentStepStatus = null;
}
setHistoryId(uid) {
const getUuid = require('uuid-by-string');
this.currentTest.historyId = getUuid(uid);
}
setFullName(fullName) {
this.currentTest.fullName = fullName;
}
endTest(spec, stop) {
var _a;
this.endSteps();
if (spec.status === SpecStatus.PASSED) {
this.currentTest.status = allure_js_commons_1.Status.PASSED;
this.currentTest.stage = allure_js_commons_1.Stage.FINISHED;
}
if (spec.status === SpecStatus.BROKEN) {
this.currentTest.status = allure_js_commons_1.Status.BROKEN;
this.currentTest.stage = allure_js_commons_1.Stage.FINISHED;
}
if (spec.status === SpecStatus.FAILED) {
this.currentTest.status = allure_js_commons_1.Status.FAILED;
this.currentTest.stage = allure_js_commons_1.Stage.FINISHED;
}
if (spec.status === SpecStatus.PENDING ||
spec.status === SpecStatus.DISABLED ||
spec.status === SpecStatus.EXCLUDED ||
spec.status === SpecStatus.TODO) {
this.currentTest.status = allure_js_commons_1.Status.SKIPPED;
this.currentTest.stage = allure_js_commons_1.Stage.PENDING;
this.currentTest.detailsMessage = spec.pendingReason || 'Suite disabled';
}
// Capture exceptions
const exceptionInfo = this.findMessageAboutThrow(spec.failedExpectations) ||
this.findAnyError(spec.failedExpectations);
if (exceptionInfo !== null && typeof exceptionInfo.message === 'string') {
let { message } = exceptionInfo;
message = stripAnsi(message);
this.currentTest.detailsMessage = message;
if (exceptionInfo.stack && typeof exceptionInfo.stack === 'string') {
let { stack } = exceptionInfo;
stack = stripAnsi(stack, 0);
stack = stack.replace(message, '');
this.currentTest.detailsTrace = stack;
}
}
this.featureProps.apply((a) => super.feature(a));
this.storyProps.apply((a) => super.story(a));
this.frameworkProps.apply((a) => super.label(allure_js_commons_1.LabelName.FRAMEWORK, a));
this.languageProps.apply((a) => super.label(allure_js_commons_1.LabelName.LANGUAGE, a));
this.hostProps.apply((a) => super.label(allure_js_commons_1.LabelName.HOST, a));
this.applyDescription();
if (((_a = this.config) === null || _a === void 0 ? void 0 : _a.autoHistoryId) !== false) {
this.setHistoryId(spec.fullName);
}
this.currentTest.endTest(stop || dateNow());
}
endGroup() {
if (!this.currentGroup) {
throw new Error('No runningGroup');
}
const g = this.groupNameStack.pop();
if (g) {
this.runtime.writeGroup({
name: g.name,
uuid: g.uuid,
befores: [],
afters: [],
children: g.children,
});
}
this.currentGroup.endGroup();
}
writeCategories(categories) {
super.writeCategoriesDefinitions(categories);
}
step(name, body, start, ...args) {
var _a, _b, _c, _d, _e, _f;
const allureStep = this.startStep(name, start || dateNow());
let result;
if (!body) {
this.endStep(allure_js_commons_1.Status.PASSED);
return;
}
try {
result = allureStep.wrap(body)(args);
}
catch (error) {
this.endStep((_b = (_a = this.currentStepStatus) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : allure_js_commons_1.Status.FAILED, undefined, (_c = this.currentStepStatus) === null || _c === void 0 ? void 0 : _c.details);
throw error;
}
if (allure_js_commons_1.isPromise(result)) {
const promise = result;
return promise
.then((a) => {
var _a, _b, _c;
this.endStep((_b = (_a = this.currentStepStatus) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : allure_js_commons_1.Status.PASSED, undefined, (_c = this.currentStepStatus) === null || _c === void 0 ? void 0 : _c.details);
return a;
})
.catch((error) => {
var _a, _b, _c;
console.log('Result fail: isPromise');
this.endStep((_b = (_a = this.currentStepStatus) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : allure_js_commons_1.Status.FAILED, undefined, (_c = this.currentStepStatus) === null || _c === void 0 ? void 0 : _c.details);
throw error;
});
}
else {
this.endStep((_e = (_d = this.currentStepStatus) === null || _d === void 0 ? void 0 : _d.status) !== null && _e !== void 0 ? _e : allure_js_commons_1.Status.PASSED, undefined, (_f = this.currentStepStatus) === null || _f === void 0 ? void 0 : _f.details);
return result;
}
}
addEnvironment(name, value) {
this.environmentInfo[name] = value;
super.writeEnvironmentInfo(this.environmentInfo);
return this;
}
logStep(name, status, attachments) {
// console.log('AllureImpl status:', status);
/*const wrappedStep = this.startStep(name);
if (attachments) {
for (const {name, content, type} of attachments) {
this.attachment(name, content, type);
}
}
wrappedStep.logStep(status);
wrappedStep.endStep();*/
}
attachment(name, content, type = allure_js_commons_1.ContentType.JSON) {
return this.executable.attachment(name, content, type);
}
addParameter(name, value) {
this.executable.addParameter(name, value);
return this;
}
addParameters(...params) {
this.executable.addParameters(...params);
return this;
}
// for test
addPackage(value) {
this.currentTest.addLabel(allure_js_commons_1.LabelName.PACKAGE, value);
return this;
}
addLink(options) {
var _a;
this.currentTest.addLink(options.url, (_a = options.name) !== null && _a !== void 0 ? _a : options.url, options.type);
return this;
}
addIssue(options) {
var _a, _b, _c, _d;
if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.issueLink) && !options.url) {
throw new Error('Specify url or issueLink in config');
}
const link = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.issueLink) && !options.url
? (_c = this.config) === null || _c === void 0 ? void 0 : _c.issueLink(options.id) : `${options.url}${options.id}`;
this.issue((_d = options.name) !== null && _d !== void 0 ? _d : options.id, link);
return this;
}
addTms(options) {
var _a, _b, _c, _d;
if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.tmsLink) && !options.url) {
throw new Error('Specify url or tmsLink in config');
}
const link = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.tmsLink) && !options.url
? (_c = this.config) === null || _c === void 0 ? void 0 : _c.tmsLink(options.id) : `${options.url}${options.id}`;
this.tms((_d = options.name) !== null && _d !== void 0 ? _d : options.id, link);
return this;
}
addLabel(name, value) {
this.currentTest.addLabel(name, value);
return this;
}
addDescription(description) {
this.test.addDescription(description);
}
description(description) {
this.executable.description(description);
return this;
}
descriptionHtml(description) {
this.executable.descriptionHtml(description);
return this;
}
feature(feature) {
return this.featureStoryForSuite(this.featureProps, feature, 'FEATURE');
}
story(story) {
return this.featureStoryForSuite(this.storyProps, story, 'STORY');
}
tag(tag) {
super.tag(tag);
}
owner(owner) {
super.owner(owner);
}
lead(lead) {
super.label(allure_js_commons_1.LabelName.LEAD, lead);
}
framework(framework) {
this.frameworkProps.testProp = framework;
}
language(language) {
this.languageProps.testProp = language;
}
as_id(id) {
super.label(allure_js_commons_1.LabelName.AS_ID, id);
}
host(host) {
this.hostProps.testProp = host;
}
testClass(testClass) {
super.label(allure_js_commons_1.LabelName.TEST_CLASS, testClass);
}
testMethod(testMethod) {
super.label(allure_js_commons_1.LabelName.TEST_METHOD, testMethod);
}
severity(severity) {
super.severity(severity);
}
endSteps() {
while (this.currentStep !== null) {
this.endStep(allure_js_commons_1.Status.BROKEN);
}
}
applyGroupping() {
var _a;
const replaceDot = (name) => {
// todo regexp with \s
if (name.substr(0, 1) === '.') {
return name.substr(1, name.length - 1);
}
if (name.substr(name.length - 1) === '.') {
return name.substr(0, name.length - 1);
}
return name;
};
if (this.groupNameStack.length > 0 && ((_a = this.runningTest) === null || _a === void 0 ? void 0 : _a.uuid)) {
this.groupNameStack[this.groupNameStack.length - 1].children.push(this.runningTest.uuid);
}
const groups = this.groupNameStack.map((p) => replaceDot(p.name));
this.addPackage(groups.join('.'));
if (groups.length > 0) {
this.parentSuite(groups[0]);
}
if (groups.length > 1) {
this.suite(groups[1]);
}
if (groups.length > 2) {
this.subSuite(groups[2]);
}
}
applyDescription() {
const testDesc = this.test.getDescription();
if (testDesc.length) {
this.test.applyDescription();
}
}
findMessageAboutThrow(expectations) {
for (const expectation of expectations || []) {
if (expectation.matcherName === '') {
return expectation;
}
}
return null;
}
findAnyError(expectations) {
expectations = expectations || [];
if (expectations.length > 0) {
return expectations[0];
}
return null;
}
getAttachFile(content, type) {
return this.runtime.writeAttachment(utils_1.getContent(content, type), type);
}
featureStoryForSuite(prop, value, type) {
if (this.runningTest) {
prop.testProp = value;
return this;
}
if (prop.suiteProp) {
throw new Error(type + ' for suite can be set only once');
}
prop.suiteProp = value;
return this;
}
}
exports.AllureReporter = AllureReporter;