UNPKG

playwright-bdd

Version:
278 lines 12.9 kB
"use strict"; /** * Cucumber json reporter. * Based on: https://github.com/cucumber/cucumber-js/blob/main/src/formatter/json_formatter.ts * * Although json reporter is marked as deprecated in CucumberJS docs * (see https://github.com/cucumber/cucumber-js/blob/main/docs/formatters.md#json), * this decision was rolled back: * (see https://github.com/cucumber/json-formatter/issues/34). * * See also: separate tool to convert cucumber messages to cucumber json: * https://github.com/vrymar/cucumber-json-report-formatter/tree/master */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable max-lines, max-statements, max-nested-callbacks, visual/complexity, max-lines-per-function */ /* eslint-disable @typescript-eslint/no-explicit-any */ const messages = __importStar(require("@cucumber/messages")); const base_1 = __importDefault(require("./base")); const GherkinDocumentParser = __importStar(require("../../cucumber/formatter/GherkinDocumentParser")); const PickleParser = __importStar(require("../../cucumber/formatter/PickleParser")); const valueChecker_1 = require("../../cucumber/valueChecker"); const stepArguments_1 = require("../../cucumber/stepArguments"); const durationHelpers_1 = require("../../cucumber/formatter/durationHelpers"); // import { formatLocation } from '../../cucumber/formatter/locationHelpers'; const GherkinDocument_1 = require("./messagesBuilder/GherkinDocument"); const Projects_1 = require("./messagesBuilder/Projects"); const skip_1 = require("./attachments/skip"); const external_1 = require("./attachments/external"); const helpers_1 = require("./attachments/helpers"); const { getGherkinExampleRuleMap, getGherkinScenarioLocationMap, getGherkinStepMap, getGherkinScenarioMap, } = GherkinDocumentParser; const { getScenarioDescription, getPickleStepMap, getStepKeyword } = PickleParser; class JsonReporter extends base_1.default { // for now omit adding step definitions to json report // private supportCodeLibrary: Pick<ISupportCodeLibrary, 'stepDefinitions'> = { // stepDefinitions: [], // }; constructor(internalOptions, userOptions = {}) { super(internalOptions); this.userOptions = userOptions; this.setOutputStream(this.userOptions.outputFile); this.eventBroadcaster.on('envelope', (envelope) => { if ((0, valueChecker_1.doesHaveValue)(envelope.testRunFinished)) { this.onTestRunFinished(); } }); } convertNameToId(obj) { return obj.name.replace(/ /g, '-').toLowerCase(); } formatDataTable(dataTable) { return { rows: dataTable.rows.map((row) => ({ cells: row.cells.map((x) => x.value), })), }; } formatDocString(docString, gherkinStep) { return { content: docString.content, line: gherkinStep.docString?.location.line, }; } formatStepArgument(stepArgument, gherkinStep) { if ((0, valueChecker_1.doesNotHaveValue)(stepArgument)) { return []; } return [ (0, stepArguments_1.parseStepArgument)(stepArgument, { dataTable: (dataTable) => this.formatDataTable(dataTable), docString: (docString) => this.formatDocString(docString, gherkinStep), }), ]; } onTestRunFinished() { const groupedTestCaseAttempts = {}; this.eventDataCollector.getTestCaseAttempts().forEach((testCaseAttempt) => { if (!testCaseAttempt.willBeRetried) { const uri = testCaseAttempt.pickle.uri; if ((0, valueChecker_1.doesNotHaveValue)(groupedTestCaseAttempts[uri])) { groupedTestCaseAttempts[uri] = []; } groupedTestCaseAttempts[uri].push(testCaseAttempt); } }); const features = Object.keys(groupedTestCaseAttempts).map((uri) => { const group = groupedTestCaseAttempts[uri]; const { gherkinDocument } = group[0]; const gherkinStepMap = getGherkinStepMap(gherkinDocument); const gherkinScenarioMap = getGherkinScenarioMap(gherkinDocument); const gherkinExampleRuleMap = getGherkinExampleRuleMap(gherkinDocument); const gherkinScenarioLocationMap = getGherkinScenarioLocationMap(gherkinDocument); const elements = group.map((testCaseAttempt) => { const { pickle } = testCaseAttempt; const pickleStepMap = getPickleStepMap(pickle); let isBeforeHook = true; const steps = testCaseAttempt.testCase.testSteps.map((testStep) => { isBeforeHook = isBeforeHook && !(0, valueChecker_1.doesHaveValue)(testStep.pickleStepId); return this.getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments: testCaseAttempt.stepAttachments[testStep.id], testStepResult: testCaseAttempt.stepResults[testStep.id], }); }); return this.getScenarioData({ feature: gherkinDocument.feature, gherkinScenarioLocationMap, gherkinExampleRuleMap, gherkinScenarioMap, pickle, steps, }); }); return this.getFeatureData({ gherkinDocument, elements, }); }); this.outputStream.write(JSON.stringify(features, null, 2)); } getFeatureData({ gherkinDocument, elements }) { const meta = GherkinDocument_1.GherkinDocumentMessage.extractMeta(gherkinDocument); const feature = gherkinDocument.feature; const featureNameWithProject = (0, Projects_1.getFeatureNameWithProject)(meta.projectName, feature.name); return { description: feature.description, elements, id: this.convertNameToId({ name: featureNameWithProject }), line: feature.location.line, keyword: feature.keyword, name: this.userOptions.addProjectToFeatureName ? featureNameWithProject : feature.name, tags: this.getFeatureTags(feature), uri: meta.originalUri, metadata: this.getFeatureMetadata(gherkinDocument), }; } getFeatureMetadata(gherkinDocument) { if (!this.userOptions.addMetadata) return; const meta = GherkinDocument_1.GherkinDocumentMessage.extractMeta(gherkinDocument); const metadata = { Project: meta.projectName || '', Browser: meta.browserName || '', }; return this.userOptions.addMetadata === 'object' ? metadata : Object.keys(metadata).map((name) => ({ name, value: metadata[name] })); } getScenarioData({ feature, gherkinScenarioLocationMap, gherkinExampleRuleMap, gherkinScenarioMap, pickle, steps, }) { const description = getScenarioDescription({ pickle, gherkinScenarioMap, }); return { description, id: this.formatScenarioId({ feature, pickle, gherkinExampleRuleMap }), keyword: gherkinScenarioMap[pickle.astNodeIds[0]].keyword, line: gherkinScenarioLocationMap[pickle.astNodeIds[pickle.astNodeIds.length - 1]].line, name: pickle.name, steps, tags: this.getScenarioTags({ feature, pickle, gherkinScenarioMap }), type: 'scenario', }; } formatScenarioId({ feature, pickle, gherkinExampleRuleMap, }) { let parts; const rule = gherkinExampleRuleMap[pickle.astNodeIds[0]]; if ((0, valueChecker_1.doesHaveValue)(rule)) { parts = [feature, rule, pickle]; } else { parts = [feature, pickle]; } return parts.map((part) => this.convertNameToId(part)).join(';'); } getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments, testStepResult, }) { const data = {}; if ((0, valueChecker_1.doesHaveValue)(testStep.pickleStepId)) { const pickleStep = pickleStepMap[testStep.pickleStepId]; data.arguments = this.formatStepArgument(pickleStep.argument, gherkinStepMap[pickleStep.astNodeIds[0]]); data.keyword = getStepKeyword({ pickleStep, gherkinStepMap }); data.line = gherkinStepMap[pickleStep.astNodeIds[0]].location.line; data.name = pickleStep.text; } else { data.keyword = isBeforeHook ? 'Before' : 'After'; data.hidden = true; } // for now omit adding step definitions to json report // if (doesHaveValue(testStep.stepDefinitionIds) && testStep.stepDefinitionIds.length === 1) { // const stepDefinition = this.supportCodeLibrary.stepDefinitions.find( // (s) => s.id === testStep.stepDefinitionIds?.[0], // ); // if (doesHaveValue(stepDefinition)) { // data.match = { location: formatLocation(stepDefinition) }; // } // } const { message, status } = testStepResult; data.result = { status: messages.TestStepResultStatus[status].toLowerCase(), }; if ((0, valueChecker_1.doesHaveValue)(testStepResult.duration)) { data.result.duration = (0, durationHelpers_1.durationToNanoseconds)(testStepResult.duration); } if (status === messages.TestStepResultStatus.FAILED && (0, valueChecker_1.doesHaveValue)(message)) { data.result.error_message = message; } const allowedAttachments = this.getAllowedAttachments(testStepAttachments); if (allowedAttachments && allowedAttachments.length > 0) { data.embeddings = allowedAttachments.map((attachment) => { const embeddedAttachment = (0, external_1.toEmbeddedAttachment)(attachment); const data = (0, helpers_1.getAttachmentBodyAsBase64)(embeddedAttachment); const mime_type = embeddedAttachment.mediaType; return { data, mime_type }; }); } return data; } getFeatureTags(feature) { return feature.tags.map((tagData) => ({ name: tagData.name, line: tagData.location.line, })); } getScenarioTags({ feature, pickle, gherkinScenarioMap, }) { const scenario = gherkinScenarioMap[pickle.astNodeIds[0]]; return pickle.tags.map((tagData) => this.getScenarioTag(tagData, feature, scenario)); } getScenarioTag(tagData, feature, scenario) { const byAstNodeId = (tag) => tag.id === tagData.astNodeId; const flatten = (acc, val) => acc.concat(val); const tag = feature.tags.find(byAstNodeId) || scenario.tags.find(byAstNodeId) || scenario.examples .map((e) => e.tags) .reduce((acc, val) => flatten(acc, val), []) .find(byAstNodeId); return { name: tagData.name, line: tag?.location?.line, }; } getAllowedAttachments(testStepAttachments) { return testStepAttachments?.filter((attachment) => { return !(0, skip_1.shouldSkipAttachment)({ attachment }, this.userOptions.skipAttachments); }); } } exports.default = JsonReporter; //# sourceMappingURL=json.js.map