UNPKG

allure-cucumberjs

Version:

Allure Cucumber.JS integration

478 lines (475 loc) 21.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _cucumber = require("@cucumber/cucumber"); var _messages = require("@cucumber/messages"); var _nodePath = require("node:path"); var _allureJsCommons = require("allure-js-commons"); var _sdk = require("allure-js-commons/sdk"); var _reporter = require("allure-js-commons/sdk/reporter"); var _legacy = require("./legacy.js"); var _utils = require("./utils.js"); var _excluded = ["resultsDir", "links", "labels"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } class AllureCucumberReporter extends _cucumber.Formatter { constructor(options) { super(options); _defineProperty(this, "afterHooks", {}); _defineProperty(this, "beforeHooks", {}); _defineProperty(this, "linksConfigs", {}); _defineProperty(this, "labelsConfigs", []); _defineProperty(this, "allureRuntime", void 0); _defineProperty(this, "documentMap", new Map()); _defineProperty(this, "scenarioMap", new Map()); _defineProperty(this, "stepMap", new Map()); _defineProperty(this, "testStepMap", new Map()); _defineProperty(this, "pickleStepMap", new Map()); _defineProperty(this, "pickleMap", new Map()); _defineProperty(this, "testCaseMap", new Map()); _defineProperty(this, "testCaseStartedMap", new Map()); _defineProperty(this, "testResultUuids", new Map()); _defineProperty(this, "scopeUuids", new Map()); _defineProperty(this, "fixtureUuids", new Map()); var _ref = options.parsedArgvOptions, { resultsDir, links, labels } = _ref, rest = _objectWithoutProperties(_ref, _excluded); this.allureRuntime = new _reporter.ReporterRuntime(_objectSpread({ writer: (0, _reporter.createDefaultWriter)({ resultsDir }), links }, rest)); this.linksConfigs = links || {}; this.labelsConfigs = labels || []; options.eventBroadcaster.on("envelope", this.parseEnvelope.bind(this)); this.beforeHooks = options.supportCodeLibrary.beforeTestCaseHookDefinitions.reduce((acc, hook) => Object.assign(acc, { [hook.id]: hook }), {}); this.afterHooks = options.supportCodeLibrary.afterTestCaseHookDefinitions.reduce((acc, hook) => Object.assign(acc, { [hook.id]: hook }), {}); // set AllureCucumberWorld for single thread mode if (options.supportCodeLibrary.World === _cucumber.World) { // @ts-ignore // noinspection JSConstantReassignment options.supportCodeLibrary.World = _legacy.AllureCucumberWorld; } } get tagsIgnorePatterns() { var { labelsConfigs, linksConfigs } = this; var linkConfigEntries = Object.entries(linksConfigs).map(_ref2 => { var [, v] = _ref2; return v; }); return [...labelsConfigs, ...linkConfigEntries].flatMap(_ref3 => { var { pattern } = _ref3; return pattern; }); } parseEnvelope(envelope) { switch (true) { case !!envelope.gherkinDocument: this.onGherkinDocument(envelope.gherkinDocument); break; case !!envelope.pickle: this.onPickle(envelope.pickle); break; case !!envelope.testCase: this.onTestCase(envelope.testCase); break; case !!envelope.testCaseStarted: this.onTestCaseStarted(envelope.testCaseStarted); break; case !!envelope.testCaseFinished: this.onTestCaseFinished(envelope.testCaseFinished); break; case !!envelope.attachment: this.onAttachment(envelope.attachment); break; case !!envelope.testStepStarted: this.onTestStepStarted(envelope.testStepStarted); break; case !!envelope.testStepFinished: this.onTestStepFinished(envelope.testStepFinished); break; case !!envelope.testRunFinished: this.onTestRunFinished(); break; } } parseTagsLabels(tags) { var labels = []; if (this.labelsConfigs.length === 0) { return labels; } this.labelsConfigs.forEach(matcher => { var matchedTags = tags.filter(tag => matcher.pattern.some(pattern => pattern.test(tag.name))); var matchedLabels = matchedTags.map(tag => { var tagValue = tag.name.replace(/^@\S+:/, ""); return { name: matcher.name, value: tagValue }; }); labels.push(...matchedLabels); }); return labels; } parsePickleTags(tags) { return tags.filter(tag => !this.tagsIgnorePatterns.some(pattern => pattern.test(tag.name))).map(tag => ({ name: _allureJsCommons.LabelName.TAG, value: tag.name })); } parseTagsLinks(tags) { var tagKeyRe = /^@\S+=/; var links = []; if (Object.keys(this.linksConfigs).length === 0) { return links; } Object.entries(this.linksConfigs).forEach(_ref4 => { var [type, matcher] = _ref4; var matchedTags = tags.filter(tag => matcher.pattern.some(pattern => pattern.test(tag.name))); var matchedLinks = matchedTags.map(tag => { var tagValue = tag.name.replace(tagKeyRe, ""); return { url: (0, _reporter.applyLinkTemplate)(matcher.urlTemplate, tagValue) || tagValue, type }; }); links.push(...matchedLinks); }); return links; } parseStatus(stepResult) { var error = this.exceptionToError(stepResult.message, stepResult.exception); switch (stepResult.status) { case _messages.TestStepResultStatus.FAILED: return error ? (0, _sdk.getStatusFromError)(error) : _allureJsCommons.Status.FAILED; case _messages.TestStepResultStatus.PASSED: return _allureJsCommons.Status.PASSED; case _messages.TestStepResultStatus.SKIPPED: case _messages.TestStepResultStatus.PENDING: return _allureJsCommons.Status.SKIPPED; default: return undefined; } } onRule(data) { var _data$children; (_data$children = data.children) === null || _data$children === void 0 || _data$children.forEach(c => { if (c.scenario) { this.onScenario(c.scenario); } }); } onGherkinDocument(data) { var _data$feature; if (data.uri) { this.documentMap.set(data.uri, data); } (_data$feature = data.feature) === null || _data$feature === void 0 || (_data$feature = _data$feature.children) === null || _data$feature === void 0 || _data$feature.forEach(c => { if (c.rule) { this.onRule(c.rule); } else if (c.scenario) { this.onScenario(c.scenario); } }); } onScenario(data) { this.scenarioMap.set(data.id, data); data.steps.forEach(step => this.stepMap.set(step.id, step)); } onPickle(data) { this.pickleMap.set(data.id, data); data.steps.forEach(ps => this.pickleStepMap.set(ps.id, ps)); } onTestCase(data) { this.testCaseMap.set(data.id, data); data.testSteps.forEach(ts => this.testStepMap.set(ts.id, ts)); } onTestCaseStarted(data) { var _scenario$name, _doc$feature, _doc$feature2, _doc$feature3, _doc$feature4, _this = this; var testCase = this.testCaseMap.get(data.testCaseId); var pickle = this.pickleMap.get(testCase.pickleId); var doc = this.documentMap.get(pickle.uri); var [scenarioId, ...astIds] = pickle.astNodeIds; var scenario = this.scenarioMap.get(scenarioId); var posixPath = (0, _utils.getPosixPathRelativeToProjectRoot)(pickle); var fullName = "".concat(posixPath, "#").concat(pickle.name); var testCaseId = (0, _reporter.md5)("".concat(posixPath, "#").concat((_scenario$name = scenario === null || scenario === void 0 ? void 0 : scenario.name) !== null && _scenario$name !== void 0 ? _scenario$name : pickle.name)); var result = { name: pickle.name, description: ((scenario === null || scenario === void 0 ? void 0 : scenario.description) || (doc === null || doc === void 0 || (_doc$feature = doc.feature) === null || _doc$feature === void 0 ? void 0 : _doc$feature.description) || "").trim(), labels: [], links: [], start: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp), testCaseId, fullName }; result.labels.push(...(0, _reporter.getEnvironmentLabels)()); result.labels.push((0, _reporter.getLanguageLabel)(), (0, _reporter.getFrameworkLabel)("cucumberjs"), (0, _reporter.getPackageLabel)((0, _utils.getPathRelativeToProjectRoot)(pickle)), (0, _reporter.getHostLabel)(), (0, _reporter.getThreadLabel)(data.workerId)); if (doc !== null && doc !== void 0 && doc.feature) { result.labels.push({ name: _allureJsCommons.LabelName.FEATURE, value: doc.feature.name }); } var pickleLabels = this.parsePickleTags(pickle.tags || []); var featureLabels = this.parseTagsLabels((doc === null || doc === void 0 || (_doc$feature2 = doc.feature) === null || _doc$feature2 === void 0 ? void 0 : _doc$feature2.tags) || []); var featureLinks = this.parseTagsLinks((doc === null || doc === void 0 || (_doc$feature3 = doc.feature) === null || _doc$feature3 === void 0 ? void 0 : _doc$feature3.tags) || []); var scenarioLabels = this.parseTagsLabels((scenario === null || scenario === void 0 ? void 0 : scenario.tags) || []); var scenarioLinks = this.parseTagsLinks((scenario === null || scenario === void 0 ? void 0 : scenario.tags) || []); // remove feature file name from the title path result.titlePath = posixPath.split("/").slice(0, -1).concat([doc === null || doc === void 0 || (_doc$feature4 = doc.feature) === null || _doc$feature4 === void 0 ? void 0 : _doc$feature4.name].filter(Boolean)); result.labels.push(...featureLabels, ...scenarioLabels, ...pickleLabels); result.links.push(...featureLinks, ...scenarioLinks); var scopeUuid = this.allureRuntime.startScope(); this.scopeUuids.set(data.id, scopeUuid); var testUuid = this.allureRuntime.startTest(result, [scopeUuid]); this.testResultUuids.set(data.id, testUuid); this.testCaseStartedMap.set(data.id, data); if (!(scenario !== null && scenario !== void 0 && scenario.examples)) { return; } var _loop = function _loop() { var _example$tableHeader, _example$tableBody; var exampleName = example !== null && example !== void 0 && example.name ? "Examples: ".concat(example.name) : "Examples"; var parameterNames = example === null || example === void 0 || (_example$tableHeader = example.tableHeader) === null || _example$tableHeader === void 0 ? void 0 : _example$tableHeader.cells.map(cell => cell.value); var csvDataTableHeader = (parameterNames === null || parameterNames === void 0 ? void 0 : parameterNames.join(",")) || ""; var currentRow = example === null || example === void 0 || (_example$tableBody = example.tableBody) === null || _example$tableBody === void 0 ? void 0 : _example$tableBody.find(tb => astIds.includes(tb.id)); if (currentRow) { var parameters = currentRow.cells.map((cell, index) => { var paramName = parameterNames && parameterNames.length > index ? parameterNames[index] : "arg".concat(index); var paramValue = cell.value; return { name: paramName, value: paramValue }; }); _this.allureRuntime.updateTest(testUuid, tr => tr.parameters = [...tr.parameters, ...parameters]); } var csvDataTableBody = (example === null || example === void 0 ? void 0 : example.tableBody.map(row => row.cells.map(cell => cell.value).join(",")).join("\n")) || ""; if (!csvDataTableHeader && !csvDataTableBody) { return 1; // continue } var csvDataTable = "".concat(csvDataTableHeader, "\n").concat(csvDataTableBody, "\n"); _this.allureRuntime.writeAttachment(testUuid, null, exampleName, Buffer.from(csvDataTable, "utf-8"), { contentType: _allureJsCommons.ContentType.CSV, fileExtension: ".csv" }); }; for (var example of scenario.examples) { if (_loop()) continue; } } onTestCaseFinished(data) { var testUuid = this.testResultUuids.get(data.testCaseStartedId); if (!testUuid) { return; } this.allureRuntime.updateTest(testUuid, result => { var _step$status; var step = (0, _reporter.getWorstTestStepResult)(result.steps); result.status = (_step$status = step === null || step === void 0 ? void 0 : step.status) !== null && _step$status !== void 0 ? _step$status : _allureJsCommons.Status.PASSED; result.stage = _allureJsCommons.Stage.FINISHED; if (step) { if (step.status === undefined) { result.statusDetails = { message: "The test doesn't have an implementation." }; } else { result.statusDetails = _objectSpread(_objectSpread({}, result.statusDetails), step.statusDetails); } } }); this.allureRuntime.stopTest(testUuid, { stop: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp) }); this.allureRuntime.writeTest(testUuid); this.testResultUuids.delete(data.testCaseStartedId); var scopeUuid = this.scopeUuids.get(data.testCaseStartedId); if (scopeUuid) { this.allureRuntime.writeScope(scopeUuid); this.scopeUuids.delete(data.testCaseStartedId); } } onTestStepStarted(data) { var _stepPickle$argument; var testUuid = this.testResultUuids.get(data.testCaseStartedId); var step = this.testStepMap.get(data.testStepId); if (step.hookId) { var scopeUuid = this.scopeUuids.get(data.testCaseStartedId); if (!scopeUuid) { return; } var beforeHook = step.hookId && this.beforeHooks[step.hookId]; var afterHook = step.hookId && this.afterHooks[step.hookId]; var type = beforeHook ? "before" : afterHook ? "after" : undefined; if (!type) { return; } var name = beforeHook ? beforeHook.name : afterHook ? afterHook.name : "hook"; if (name === "ALLURE_FIXTURE_IGNORE") { return; } var fixtureUuid = this.allureRuntime.startFixture(scopeUuid, type, { name, stage: _allureJsCommons.Stage.RUNNING, start: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp) }); if (fixtureUuid) { this.fixtureUuids.set(data.testCaseStartedId, fixtureUuid); } return; } if (!step.pickleStepId) { return; } var stepPickle = this.pickleStepMap.get(step.pickleStepId); if (!stepPickle) { return; } var stepKeyword = stepPickle.astNodeIds.map(astNodeId => this.stepMap.get(astNodeId)).map(stepAstNode => stepAstNode === null || stepAstNode === void 0 ? void 0 : stepAstNode.keyword).find(keyword => keyword !== undefined) || ""; var stepUuid = this.allureRuntime.startStep(testUuid, undefined, _objectSpread(_objectSpread({}, (0, _reporter.createStepResult)()), {}, { name: "".concat(stepKeyword).concat(stepPickle.text), start: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp) })); if (!((_stepPickle$argument = stepPickle.argument) !== null && _stepPickle$argument !== void 0 && _stepPickle$argument.dataTable)) { return; } var csvDataTable = stepPickle.argument.dataTable.rows.reduce((acc, row) => "".concat(acc + row.cells.map(cell => cell.value).join(","), "\n"), ""); this.allureRuntime.writeAttachment(testUuid, stepUuid, "Data table", Buffer.from(csvDataTable, "utf-8"), { contentType: _allureJsCommons.ContentType.CSV, fileExtension: ".csv" }); } onTestStepFinished(data) { var step = this.testStepMap.get(data.testStepId); if (!step) { return; } var status = this.parseStatus(data.testStepResult); var stage = status !== _allureJsCommons.Status.SKIPPED ? _allureJsCommons.Stage.FINISHED : _allureJsCommons.Stage.PENDING; var error = this.exceptionToError(data.testStepResult.message, data.testStepResult.exception); if (step.hookId) { var fixtureUuid = this.fixtureUuids.get(data.testCaseStartedId); if (!fixtureUuid) { return; } this.allureRuntime.updateFixture(fixtureUuid, r => { r.stage = stage; r.status = status; if (error) { r.statusDetails = _objectSpread(_objectSpread({}, r.statusDetails), (0, _sdk.getMessageAndTraceFromError)(error)); } }); this.allureRuntime.stopFixture(fixtureUuid, { stop: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp) }); this.fixtureUuids.delete(data.testCaseStartedId); return; } var testUuid = this.testResultUuids.get(data.testCaseStartedId); var currentStep = this.allureRuntime.currentStep(testUuid); if (!currentStep) { return; } this.allureRuntime.updateStep(currentStep, r => { r.status = status; r.stage = stage; if (status === undefined) { r.statusDetails = { message: "The step doesn't have an implementation." }; return; } if (error) { r.statusDetails = _objectSpread(_objectSpread({}, r.statusDetails), (0, _sdk.getMessageAndTraceFromError)(error)); } }); this.allureRuntime.stopStep(currentStep, { stop: _messages.TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp) }); } onAttachment(message) { var _message$fileName; if (!message.testCaseStartedId) { return; } var fixtureUuid = this.fixtureUuids.get(message.testCaseStartedId); var testUuid = this.testResultUuids.get(message.testCaseStartedId); var rootUuid = fixtureUuid !== null && fixtureUuid !== void 0 ? fixtureUuid : testUuid; if (!rootUuid) { return; } if (message.mediaType === "application/vnd.allure.skipcucumber+json") { if (testUuid) { this.allureRuntime.updateTest(testUuid, result => { result.labels.push({ name: "ALLURE_TESTPLAN_SKIP", value: "true" }); }); } return; } if (message.mediaType === _reporter.ALLURE_RUNTIME_MESSAGE_CONTENT_TYPE) { var parsedMessage = JSON.parse(message.body); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument this.allureRuntime.applyRuntimeMessages(rootUuid, Array.isArray(parsedMessage) ? parsedMessage : [parsedMessage]); return; } var encoding = message.contentEncoding === _messages.AttachmentContentEncoding.BASE64 ? "base64" : "utf-8"; this.allureRuntime.applyRuntimeMessages(rootUuid, [{ type: "attachment_content", data: { name: (_message$fileName = message.fileName) !== null && _message$fileName !== void 0 ? _message$fileName : "Attachment", content: Buffer.from(message.body, encoding).toString("base64"), encoding: "base64", contentType: message.mediaType, fileExtension: message.fileName ? (0, _nodePath.extname)(message.fileName) : undefined, wrapInStep: true } }]); } onTestRunFinished() { this.allureRuntime.writeCategoriesDefinitions(); this.allureRuntime.writeEnvironmentInfo(); } exceptionToError(message, exception) { if (!exception) { return; } return { message: message !== null && message !== void 0 ? message : exception.message, stack: exception.stackTrace, name: exception.type }; } } exports.default = AllureCucumberReporter; module.exports = exports.default; //# sourceMappingURL=reporter.js.map