playwright-performance
Version:
Playwright plugin for analyzing test flow performance
129 lines (128 loc) • 6.61 kB
JavaScript
;
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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__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 });
exports.PerformanceAnalyzer = void 0;
const performance_result_1 = require("./entities/performance-result");
const calculator_1 = __importDefault(require("./helpers/calculator"));
const file_writer_1 = require("./helpers/file-writer");
const group_1 = __importDefault(require("./helpers/group"));
const objects_to_csv_1 = __importDefault(require("objects-to-csv"));
const variables_1 = require("./constants/variables");
const logger_1 = __importDefault(require("./helpers/logger"));
const graph_generator_1 = require("./helpers/graph-generator");
const path = __importStar(require("path"));
class PerformanceAnalyzer {
constructor() {
this._performanceResults = new Array();
}
async analyze(options, workerIndex) {
const logger = new logger_1.default(options.suppressConsoleResults);
let recentDaysMessage = '';
const fileWriter = file_writer_1.FileWriter.getInstance();
const resultsDir = global._playwrightPerformanceResultsDir;
const logFilePath = fileWriter.getFilePath(resultsDir, variables_1.variables.logFileName);
const saveDataFilePath = fileWriter.getFilePath(resultsDir, options.performanceResultsFileName);
let performanceLogEntries = await this.deserializeData(logFilePath);
let groupedResults;
if (options.recentDays) {
recentDaysMessage = `[Recent days:${options.recentDays}]`;
}
if (options.dropResultsFromFailedTest || options.recentDays) {
const cutoffDate = Date.now() - ((options.recentDays || 0) * 24 * 60 * 60 * 1000);
const filteredEntries = performanceLogEntries.filter((e) => {
if (options.recentDays && e.startTime < cutoffDate) {
return false;
}
if (options.dropResultsFromFailedTest) {
return e.isTestPassed;
}
return true;
});
performanceLogEntries = filteredEntries;
}
if (!performanceLogEntries || performanceLogEntries.length == 0) {
return;
}
groupedResults = !options.analyzeByBrowser ? group_1.default.groupBy(performanceLogEntries, p => [p.name]) : group_1.default.groupBy(performanceLogEntries, p => [p.name, p.brName]);
groupedResults.forEach(group => {
const durationList = group.map(t => t.duration);
const performanceResult = new performance_result_1.PerformanceResult();
const avgAndSte = calculator_1.default.getAverageAndStandardDeviation(durationList);
performanceResult.name = group[0].name;
performanceResult.brName = options.analyzeByBrowser ? group[0].brName : "general";
performanceResult.earliestTime = group[0].startDisplayTime;
performanceResult.latestTime = group[group.length - 1].startDisplayTime;
performanceResult.avgTime = avgAndSte[0];
performanceResult.sem = avgAndSte[1];
performanceResult.repeats = durationList.length;
performanceResult.minValue = Math.min(...durationList);
performanceResult.maxValue = Math.max(...durationList);
this._performanceResults.push(performanceResult);
});
const picked = this._performanceResults.map(({ name, brName, avgTime, sem, repeats, minValue, maxValue }) => ({ name, brName, avgTime, sem, repeats, minValue, maxValue }));
logger.info(`\nPlaywright-performance results${recentDaysMessage}(worker[${workerIndex}]):\n`, false);
logger.info(picked, false, true);
await this.serializeData(saveDataFilePath);
if (options.generateHtmlChart) {
await (0, graph_generator_1.generatePerformanceChart)(path.join(resultsDir, options.performanceResultsFileName + '.json'), path.join(resultsDir, "performance-chart.html"));
}
logger.info(`\nPlaywright-performance results saved to: ${saveDataFilePath}.csv/json\n`, true);
}
async serializeData(saveDataFilePath) {
const fileWriter = file_writer_1.FileWriter.getInstance();
await fileWriter.writeToFile(saveDataFilePath + ".json", JSON.stringify(this._performanceResults));
const csv = new objects_to_csv_1.default(this._performanceResults);
const csvString = await csv.toString(true);
await fileWriter.writeToFile(saveDataFilePath + ".csv", csvString);
}
async deserializeData(fileName) {
const fileWriter = file_writer_1.FileWriter.getInstance();
const resultsArray = new Array();
const textResultsArray = await fileWriter.readAllLines(fileName);
textResultsArray.forEach(textResult => {
if (textResult != "") {
const performanceResult = JSON.parse(textResult);
if (performanceResult.id !== undefined) {
resultsArray.push(performanceResult);
}
}
});
return resultsArray;
}
}
exports.PerformanceAnalyzer = PerformanceAnalyzer;