flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
283 lines • 13 kB
JavaScript
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, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
}
exports.FlagpoleReport = FlagpoleReport;
//# sourceMappingURL=flagpole-report.js.map
;