UNPKG

@avitalique/k6-html-reporter

Version:
215 lines 8.16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generate = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const ejs_1 = __importDefault(require("ejs")); const types_1 = require("./types"); const util_1 = require("./util"); function generate(options) { const resolvedInputPath = path_1.default.resolve(process.cwd(), options.jsonFile); const resolvedOutputPath = path_1.default.resolve(process.cwd(), options.output); const jsonReport = readJsonReport(resolvedInputPath); writeHtmlReport(jsonReport, resolvedOutputPath); } exports.generate = generate; function readJsonReport(filePath) { const resolvedPath = path_1.default.resolve(__dirname, filePath); const rawData = fs_1.default.readFileSync(resolvedPath); return JSON.parse(rawData.toString()); } function writeHtmlReport(content, filePath) { const time = new Date().toLocaleString(); const templatePath = path_1.default.resolve(__dirname, "../templates/template.ejs"); const checkRootGroupData = content["root_group"]; const metricsData = content["metrics"]; const { checkMetric, counterMetrics, trendMetrics, gaugeMetrics, rateMetrics, allThresholds, totalThresholdResult, } = mapMetrics(metricsData); const checks = getChecks(checkRootGroupData).map((data) => { const splitedPath = data.path.split("::"); splitedPath.shift(); return { ...data, pathArray: splitedPath.join(" \u21C0 "), }; }); // add pass rate to checks checks.forEach((check) => { check['passRate'] = '' + (0, util_1.calculatePassRate)(check['passes'], check['fails']) + '%'; }); // humanize counter metric values counterMetrics.forEach((metric) => { if (metric.contains === 'data') { metric.values.count = (0, util_1.humanizeBytes)(metric.values.count); metric.values.rate = (0, util_1.humanizeBytes)(metric.values.rate) + '/s'; } else { metric.values.rate = '' + (0, util_1.roundDecimal)(metric.values.rate, 2) + '/s'; } }); // humanize trend metric values trendMetrics.forEach((metric) => { Object.keys(metric.values).forEach((key) => { metric.values[key] = (0, util_1.humanizeDuration)(metric.values[key]); }); }); // humanize rate metric values rateMetrics.forEach((metric) => { metric.values.rate = '' + (0, util_1.roundDecimal)(metric.values.rate, 3) + '/s'; }); ejs_1.default.renderFile(templatePath, { checks, rateMetrics: rateMetrics.sort(util_1.compareNameAscending), checkMetric, counterMetrics: counterMetrics.sort(util_1.compareNameAscending), trendMetrics: trendMetrics.sort(util_1.compareNameAscending), gaugeMetrics: gaugeMetrics.sort(util_1.compareNameAscending), allThresholds, totalThresholdResult, time, }, {}, function (err, str) { if (err) { console.error(err); } let html = ejs_1.default.render(str); if (!fs_1.default.existsSync(filePath)) { fs_1.default.mkdirSync(filePath, { recursive: true }); } fs_1.default.writeFileSync(`${filePath}/report.html`, html); console.log(`Report is created at ${filePath}`); }); } function mapMetrics(data) { let checkMetric = {}; const counterMetrics = []; const trendMetrics = []; const gaugeMetrics = []; const rateMetrics = []; const allThresholds = []; let totalThresholdResult = { passes: 0, fails: 0, failedMetricsNum: 0, }; Object.entries(data).forEach(([key, value]) => { if (value.type === types_1.MetricsType.COUNTER) { const { updatedThresholdResult, displayThreshold, metric } = handleMetricValues(key, value, totalThresholdResult); totalThresholdResult = { ...totalThresholdResult, ...updatedThresholdResult, }; if (displayThreshold) { allThresholds.push(displayThreshold); } counterMetrics.push(metric); } else if (value.type === types_1.MetricsType.TREND) { const { updatedThresholdResult, displayThreshold, metric } = handleMetricValues(key, value, totalThresholdResult); totalThresholdResult = { ...totalThresholdResult, ...updatedThresholdResult, }; if (displayThreshold) { allThresholds.push(displayThreshold); } trendMetrics.push(metric); } else if (key === "checks") { const { updatedThresholdResult, displayThreshold, metric } = handleMetricValues(key, value, totalThresholdResult); totalThresholdResult = { ...totalThresholdResult, ...updatedThresholdResult, }; if (displayThreshold) { allThresholds.push(displayThreshold); } checkMetric = metric; } else if (value.type === types_1.MetricsType.GAUGE) { const { updatedThresholdResult, displayThreshold, metric } = handleMetricValues(key, value, totalThresholdResult); totalThresholdResult = { ...totalThresholdResult, ...updatedThresholdResult, }; if (displayThreshold) { allThresholds.push(displayThreshold); } gaugeMetrics.push(metric); } else if (value.type === types_1.MetricsType.RATE && key !== "checks") { const { updatedThresholdResult, displayThreshold, metric } = handleMetricValues(key, value, totalThresholdResult); totalThresholdResult = { ...totalThresholdResult, ...updatedThresholdResult, }; if (displayThreshold) { allThresholds.push(displayThreshold); } rateMetrics.push(metric); } }); return { checkMetric, counterMetrics, trendMetrics, gaugeMetrics, rateMetrics, allThresholds, totalThresholdResult, }; } function handleMetricValues(key, value, currentTotalThresholdResult) { const metric = { name: key, ...value, thresholdFailed: undefined, }; const updatedThresholdResult = { ...currentTotalThresholdResult }; if (value.thresholds) { const [passes, fails] = thresholdResult(value.thresholds); if (fails > 0 && key !== "checks") { updatedThresholdResult.failedMetricsNum++; } updatedThresholdResult.passes += passes; updatedThresholdResult.fails += fails; metric.thresholdFailed = fails > 0; return { displayThreshold: { name: key, thresholds: value.thresholds, }, updatedThresholdResult, metric, }; } return { updatedThresholdResult, metric }; } function thresholdResult(thresholds) { if (thresholds) { const thresholdArr = Object.values(thresholds); const passes = thresholdArr.filter((value) => value.ok === true).length; const fails = thresholdArr.length - passes; return [passes, fails]; } } function getChecks(data) { let checksOutput = []; findChecksRecursively(data); function findChecksRecursively(data) { if (data.groups.length === 0 && data.checks.length === 0) { return; } if (data.checks.length > 0) { Object.values(data.checks).forEach((value) => { checksOutput.push(value); }); } for (let item in data.groups) { findChecksRecursively(data.groups[item]); } } return checksOutput; } //# sourceMappingURL=reporter.js.map