UNPKG

flagpole

Version:

Simple and fast DOM integration, headless or headful browser, and REST API testing framework.

283 lines 13 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FlagpoleReport = void 0; const console_line_1 = require("./console-line"); const comment_1 = require("./comment"); const util_1 = require("../util"); const flagpole_execution_1 = require("../flagpole-execution"); const verbosity_1 = require("./verbosity"); class FlagpoleReport { constructor(suite) { this.suite = suite; } toConsole() { var _a; return __awaiter(this, void 0, void 0, function* () { let lines = []; lines.push(new console_line_1.HeadingLine(this.suite.title)); lines.push(new console_line_1.CommentLine(`Base URL: ${this.suite.baseUrl}`)); lines.push(new console_line_1.CommentLine(`Environment: ${(_a = flagpole_execution_1.FlagpoleExecution.global.environment) === null || _a === void 0 ? void 0 : _a.name}`)); lines.push(new console_line_1.CommentLine(`Took ${this.suite.executionDuration}ms`)); const failCount = this.suite.failCount; const totalCount = this.suite.scenarios.length; failCount == 0 ? lines.push(new console_line_1.PassLine(`Passed (${totalCount} scenario${totalCount == 1 ? "" : "s"})`)) : lines.push(new console_line_1.FailLine(`Failed (${failCount} of ${totalCount} scenario${totalCount == 1 ? "" : "s"})`)); lines.push(new console_line_1.LineBreak()); yield util_1.asyncForEach(this.suite.scenarios, (scenario) => __awaiter(this, void 0, void 0, function* () { const log = yield scenario.getLog(); log.forEach((item) => { lines = lines.concat(item.toConsole()); }); lines.push(new console_line_1.LineBreak()); })); return lines; }); } toJson() { return __awaiter(this, void 0, void 0, function* () { const scenarios = this.suite.scenarios; const out = { title: this.suite.title, baseUrl: String(this.suite.baseUrl), summary: {}, scenarios: [], }; let failCount = 0; let passCount = 0; for (let i = 0; i < scenarios.length; i++) { const scenario = scenarios[i]; const log = yield scenario.getLog(); out.scenarios[i] = { title: scenario.title, done: scenario.hasFinished, failCount: 0, passCount: 0, log: [], }; log.forEach((item) => { out.scenarios[i].log.push(item.toJson()); if (item.type.startsWith("result")) { if (item.passed) { out.scenarios[i].passCount++; passCount++; } else if (item.failed && item.isOptional) { out.scenarios[i].failCount++; failCount++; } } }); } out.summary = { passed: failCount == 0, passCount: passCount, failCount: failCount, duration: this.suite.executionDuration, }; return out; }); } toHTML() { var _a; return __awaiter(this, void 0, void 0, function* () { const scenarios = this.suite.scenarios; let html = ""; html += '<article class="suite">' + "\n"; html += `<h2>${this.suite.title}</h2>\n`; html += "<aside>\n"; html += "<ul>\n"; html += ` <li>Duration: ${this.suite.executionDuration}ms</li> <li>Base URL: ${this.suite.baseUrl}</li> <li>Environment: ${(_a = flagpole_execution_1.FlagpoleExecution.global.environment) === null || _a === void 0 ? void 0 : _a.name}</li> `; html += "</ul>\n"; html += "</aside>\n"; for (let i = 0; i < scenarios.length; i++) { const scenario = scenarios[i]; const log = yield scenario.getLog(); html += '<section class="scenario">' + "\n"; html += ` <h3>${scenario.title}</h3> `; html += "<ul>\n"; log.forEach((item) => { if (item.type.startsWith("result") || item.type == "comment") { html += item.toHtml(); } }); html += "</ul>\n"; html += "</section>\n"; } html += "</article>\n"; return html; }); } toXML() { return __awaiter(this, void 0, void 0, function* () { const scenarios = this.suite.scenarios; const testCases = []; for (let i = 0; i < scenarios.length; i++) { const scenario = scenarios[i]; const log = yield scenario.getLog(); let subScenarioTitle; log.forEach((item) => { if (item.className === "heading") { subScenarioTitle = this.cleanXMLCharacters(item.message); } if (item.type.startsWith("result")) { let testCase = ""; const message = this.cleanXMLCharacters(item.message); if (item.type === "resultFailure") { testCase += `<testcase id="${subScenarioTitle}" name="${scenario.title}">`; testCase += `<failure message="${message}" type="WARNING">`; testCase += message; if (item["detailsMessage"]) { const rawDetails = this.cleanXMLCharacters(`\n${item["detailsMessage"] .join(" - ") .replace(/\s+/g, " ") .trim()}`); testCase += rawDetails; } testCase += `</failure></testcase>`; } else { testCase += `<testcase id="${subScenarioTitle}" name="${scenario.title}"></testcase>`; } testCases.push(testCase); } }); } const suiteDurantionInSeconds = this.suite.executionDuration / 1000; let xml = `<testsuite id="${this.suite.title}" name="${this.suite.title}" tests="${testCases.length}" failures="${this.suite.failCount}" time="${suiteDurantionInSeconds}">`; xml += testCases.join(""); xml += `</testsuite>`; return xml; }); } toCI() { return __awaiter(this, void 0, void 0, function* () { const scenarios = this.suite.scenarios; const ciOutput = []; for (let i = 0; i < scenarios.length; i++) { const scenario = scenarios[i]; const log = yield scenario.getLog(); let subScenarioTitle; log.forEach((item) => { if (item.className === "heading") { subScenarioTitle = item.message; } if (item.type.startsWith("result")) { const message = item.message; if (item.type === "resultFailure") { ciOutput.push("---FAILURE---"); ciOutput.push(`Suite: ${this.suite.title}`); ciOutput.push(`Scenario: ${scenario.title} - ${subScenarioTitle}`); ciOutput.push(`Assertion: ${message}`); if (item["detailsMessage"] && item["detailsMessage"].length) { ciOutput.push(item["detailsMessage"].join(" - ").replace(/\s+/g, " ").trim()); } } } }); } return ciOutput.join("\n"); }); } toDelimited(format) { return __awaiter(this, void 0, void 0, function* () { const funcName = `to${format.charAt(0).toUpperCase()}${format.slice(1)}`; if (!Reflect.has(new comment_1.LogComment(""), funcName)) { throw new Error(`Method for ${funcName} does not exist.`); } const lines = []; yield this.suite.scenarios.forEach(function (scenario) { return __awaiter(this, void 0, void 0, function* () { const log = yield scenario.getLog(); log.forEach((item) => { lines.push(item[funcName]()); }); }); }); return lines; }); } print() { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { const output = yield this.toString(); const lines = output.split("\n"); lines.forEach((line) => { const chunks = line.match(/.{1,8192}/g) || []; chunks.forEach((chunk) => { process.send ? process.send(chunk) : console.log(chunk); }); }); setTimeout(() => { resolve(); }, 0); } catch (error) { reject(error); } })); }); } toString() { return __awaiter(this, void 0, void 0, function* () { let out = ""; switch (true) { case flagpole_execution_1.FlagpoleExecution.global.shouldWriteHtml: return this.toHTML(); case flagpole_execution_1.FlagpoleExecution.global.isJsonOutput: const json = yield this.toJson(); return JSON.stringify(json, null, 2); case flagpole_execution_1.FlagpoleExecution.global.isDelimitedOutput: const format = flagpole_execution_1.FlagpoleExecution.global.outputFormat; (yield this.toDelimited(format)).forEach((line) => { out += line + "\n"; }); return out; case flagpole_execution_1.FlagpoleExecution.global.isXmlOutput: return this.toXML(); case flagpole_execution_1.FlagpoleExecution.global.isTextOutput: (yield this.toConsole()).forEach((line) => { if (verbosity_1.lineToVerbosity[line.type] <= flagpole_execution_1.FlagpoleExecution.global.volume) { out += line.toString() + "\n"; } }); return out; case flagpole_execution_1.FlagpoleExecution.global.isCiOutput: return this.toCI(); default: (yield this.toConsole()).forEach((line) => { if (verbosity_1.lineToVerbosity[line.type] <= flagpole_execution_1.FlagpoleExecution.global.volume) { out += line.toConsoleString() + "\n"; } }); return out; } }); } cleanXMLCharacters(unsafe) { return unsafe .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/"/g, "&quot;") .replace(/'/g, "&apos;"); } } exports.FlagpoleReport = FlagpoleReport; //# sourceMappingURL=flagpole-report.js.map