UNPKG

@mmisty/cypress-allure-adapter

Version:

cypress allure adapter to generate allure results during tests execution (Allure TestOps compatible)

256 lines (255 loc) 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleCyLogEvents = void 0; const helper_1 = require("./helper"); const common_1 = require("../common"); const command_names_1 = require("../common/command-names"); const request_events_1 = require("./request-events"); const custom_commands_handling_1 = require("../setup/custom-commands-handling"); const group_handling_1 = require("./group-handling"); const requests_handler_1 = require("./requests-handler"); const dbg = 'cypress-allure:cy-events'; const UNCAUGHT_EXCEPTION_NAME = 'uncaught exception'; const UNCAUGHT_EXCEPTION_STATUS = 'broken'; const failedStatus = 'failed'; const passedStatus = 'passed'; const brokenStatus = 'broken'; const swapDoSyncCommand = () => { Cypress.on('command:enqueued', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const queue = () => cy.queue; // swap if next chainer is 'should' // should be done for all child commands ? const swapCmd = () => { const custId = queue().queueables.findIndex((t, i) => { var _a; return i >= queue().index && ((_a = t.attributes) === null || _a === void 0 ? void 0 : _a.name) === 'doSyncCommand'; }); const next = custId + 1; if (queue().queueables.length > next && ['assertion'].includes(queue().queueables[next].attributes.type)) { (0, common_1.swapItems)(queue().queueables, custId, next); swapCmd(); } }; swapCmd(); }); }; const handleCyLogEvents = (runner, events, config) => { const debug = (0, helper_1.logClient)(dbg); const { ignoreCommands, wrapCustomCommands, allureLogCyCommands, spyOnRequests } = config; const customCommands = []; const groups = new group_handling_1.Groups(events); const customCommandsHandler = new custom_commands_handling_1.CustomCommandsHandler(events, ignoreCommands, wrapCustomCommands); const requests = []; groups.handleGroupsEvents(); swapDoSyncCommand(); (0, request_events_1.logRequestEvents)(requests, events); const allureAttachRequests = Cypress.env('allureAttachRequests') ? `${Cypress.env('allureAttachRequests')}` === 'true' : false; const allureCompactAttachmentsRequests = Cypress.env('allureCompactAttachments') ? `${Cypress.env('allureCompactAttachments')}` === 'true' : true; const isLogCommand = (isLog, name) => { return isLog && !(0, command_names_1.ignoreAllCommands)(ignoreCommands).includes(name) && !Object.keys(Cypress.Allure).includes(name); }; if (allureLogCyCommands()) { customCommandsHandler.wrap(); // customCommandsHandler.wrapGroupedCommands(); } // should be beforeEach (not before) to get env variable value from test config beforeEach(`${common_1.packageLog}`, () => { // this way can save bodies for intercepted requests var _a; const requestsToSpy = (_a = spyOnRequests === null || spyOnRequests === void 0 ? void 0 : spyOnRequests()) !== null && _a !== void 0 ? _a : []; cy.allure().parameter('To access request bodies', "add environment variable: `allureAddBodiesToRequests`\n(value is requests split by comma that you wish to save, to save all set '*')"); cy.allure().parameter('To skip this message', "add environment variable `allureSkipSteps: '*\\[cypress-allure-adapter\\]*' `"); if (requestsToSpy.length > 0) { requestsToSpy.forEach(r => { cy.intercept(r).as('allure'); }); } else { // for not using step command cy.allure().startStep('will not intercept requests to save bodies'); cy.allure().endStep(); } requests.splice(0, requests.length); groups.resetGroups(); }); Cypress.on('log:added', (log) => { if (!allureLogCyCommands()) { return; } (0, command_names_1.withTry)('report log:added', () => { const logName = (0, command_names_1.logNameFn)(log); const logMessage = log.message; const chainerId = log.chainerId; const end = log.end || log.ended; const logState = log.state; const groupStart = log.groupStart; const cmdMessage = (0, command_names_1.stepMessage)(logName, logMessage === 'null' ? '' : logMessage); groups.endGroupMayBe(''); if (chainerId || !end || logName === command_names_1.COMMAND_REQUEST) { return; } // only synchronous logs without parent commands if (groupStart) { if (groups.startGroupMaybe(cmdMessage)) { // only start when no chainer return; } } Cypress.Allure.startStep(cmdMessage); let status = passedStatus; if (logName === 'WARNING') { status = brokenStatus; } if (logState === 'failed') { status = failedStatus; } Cypress.Allure.endStep(status); }); }); const addCommandLogs = (command) => { if (!allureLogCyCommands()) { return; } const filtered = (0, command_names_1.filterCommandLog)(command, ignoreCommands).sort((aLog, bLog) => { var _a, _b; const attrA = (_a = aLog === null || aLog === void 0 ? void 0 : aLog.attributes) === null || _a === void 0 ? void 0 : _a.commandLogId; const attrB = (_b = bLog === null || bLog === void 0 ? void 0 : bLog.attributes) === null || _b === void 0 ? void 0 : _b.commandLogId; if (!attrA || !attrB) { return 0; } return attrA < attrB ? -1 : 1; }); filtered.forEach(log => { var _a, _b; const attr = log.attributes; const logName = (0, command_names_1.logNameFn)(attr); const logErr = attr === null || attr === void 0 ? void 0 : attr.error; const message = attr === null || attr === void 0 ? void 0 : attr.message; const groupStart = attr === null || attr === void 0 ? void 0 : attr.groupStart; const logMessage = (0, command_names_1.stepMessage)(logName, message === 'null' ? '' : message); const getProps = () => { if (attr && attr.consoleProps && typeof attr.consoleProps === 'function') { return attr.consoleProps(); } if (attr && attr.consoleProps && typeof attr.consoleProps !== 'function') { return attr.consoleProps; } return undefined; }; const consoleProps = getProps(); // console.log('logName', logName); // console.log('logMessage', logMessage); // console.log('attr'); // console.log(attr); // console.log('consoleProps'); // console.log(consoleProps); // console.log(groups); groups.endGroupMayBe(logMessage); if (groupStart) { if (groups.startGroupMaybe(logMessage)) { return; } } Cypress.Allure.startStep(logMessage); if (logName !== 'assert' && message && message.length > command_names_1.ARGS_TRIM_AT) { Cypress.Allure.step('Commnad has long args...'); } let state = ((_a = consoleProps === null || consoleProps === void 0 ? void 0 : consoleProps.error) !== null && _a !== void 0 ? _a : logErr) ? failedStatus : passedStatus; let details = undefined; const isIgnoreException = () => { var _a, _b; const ignored = Cypress.env('allureIgnoreUncaughtExceptions'); if (!ignored) { return false; } const exceptions = (_a = ignored.split(',').map((x) => new RegExp(`^${x.replace(/\./g, '.').replace(/\*/g, '.*')}$`))) !== null && _a !== void 0 ? _a : []; const err = (_b = consoleProps === null || consoleProps === void 0 ? void 0 : consoleProps.props) === null || _b === void 0 ? void 0 : _b.Error; return (err === null || err === void 0 ? void 0 : err.message) && exceptions.some((e) => e.test(err.message)); }; if (logName.indexOf(UNCAUGHT_EXCEPTION_NAME) !== -1 && !isIgnoreException()) { const err = (_b = consoleProps === null || consoleProps === void 0 ? void 0 : consoleProps.props) === null || _b === void 0 ? void 0 : _b.Error; const isCommandFailed = command.state === 'failed'; // when command failed we mark uncaught exception log as error, // in other cases it will be marked as broken state = isCommandFailed ? failedStatus : UNCAUGHT_EXCEPTION_STATUS; details = { message: err === null || err === void 0 ? void 0 : err.message, trace: err === null || err === void 0 ? void 0 : err.stack }; } if (logName === 'WARNING') { state = brokenStatus; } Cypress.Allure.endStep(state, details); }); }; Cypress.on('command:start', (command) => { events.emit('cmd:started:tech', command); }); Cypress.on('command:failed', (command) => { events.emit('cmd:ended:tech', command); }); Cypress.on('command:end', (command) => { events.emit('cmd:ended:tech', command); }); events.on('cmd:started:tech', (command, isCustom) => { const { message: cmdMessage } = (0, command_names_1.commandParams)(command); groups.endGroupMayBe(); debug(`started tech: ${cmdMessage}`); if (isCustom) { customCommands.push(cmdMessage); // not start when custom because cypress already // fired event command:start return; } events.emit('cmd:started', command); }); Cypress.Allure.on('cmd:started', (command) => { const { name, isLog, message: cmdMessage, args } = (0, command_names_1.commandParams)(command); if (!isLogCommand(isLog, name) || !allureLogCyCommands()) { return; } debug(`started: ${cmdMessage}`); Cypress.Allure.startStep(cmdMessage); (0, command_names_1.withTry)('report command:attachment', () => { const requestAndLogRequests = allureAttachRequests && name === command_names_1.COMMAND_REQUEST; if (!requestAndLogRequests && args.join(',').length > command_names_1.ARGS_TRIM_AT) { Cypress.Allure.step('command has long args...'); } }); }); events.on('cmd:ended:tech', (command, isCustom) => { const { message: cmdMessage } = (0, command_names_1.commandParams)(command); const last = customCommands[customCommands.length - 1]; groups.endGroupMayBe(); if (!isCustom) { // will be added here for all custom or non-custom // since cypress ends custom commands right away addCommandLogs(command); } if (last && last === cmdMessage) { customCommands.pop(); // cypress ends custom commands right away // not end when custom started return; } events.emit('cmd:ended', command, isCustom); }); Cypress.Allure.on('cmd:ended', (command, isCustom) => { const { name, isLog, state, message: cmdMessage } = (0, command_names_1.commandParams)(command); const status = state; if (!isLogCommand(isLog, name)) { return; } if (name === command_names_1.COMMAND_REQUEST) { (0, command_names_1.withTry)('report attach:requests', () => { (0, requests_handler_1.attachRequests)(dbg, allureAttachRequests, command, { compactAttachments: allureCompactAttachmentsRequests }); }); } if (!allureLogCyCommands()) { return; } debug(`ended ${isCustom ? 'CUSTOM' : ''}: ${cmdMessage}`); Cypress.Allure.endStep(status); }); }; exports.handleCyLogEvents = handleCyLogEvents;