@honeybook/jest-stare
Version:
jest html reporter (results processor) to view HTML jest results, save raw JSON, and invoke multiple reporters
1,256 lines (1,239 loc) • 1.08 MB
JavaScript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Constants = void 0;
const chalk = require("chalk");
class Constants {
}
exports.Constants = Constants;
Constants.NAME = "jest-stare";
Constants.LOGO = chalk.green("** ") + chalk.green("jest") + chalk.yellow("-") + chalk.red("stare");
Constants.SUFFIX = chalk.green("\t**");
Constants.DEFAULT_RESULTS_DIR = "./" + Constants.NAME;
Constants.HTML_EXTENSION = ".html";
Constants.MAIN_HTML = "index" + Constants.HTML_EXTENSION;
Constants.JEST_STARE_JS = "view.js";
Constants.REPORTER_WRITTING = " will write each completed run to ";
Constants.RESULTS_RAW = "jest-results.json";
Constants.JEST_STARE_CSS = Constants.NAME + ".css";
Constants.TEMPLATE_HTML = "template.html";
Constants.CSS_DIR = "css/";
Constants.JS_DIR = "js/";
Constants.IMAGE_SNAPSHOT_DIFF_DIR = "image_snapshot_diff/";
Constants.TEST_RESULTS_PROCESSOR = "--testResultsProcessor";
Constants.REPORTERS = "--reporters";
Constants.LOG_MESSAGE = ": wrote output report to ";
Constants.MERGE_MESSAGE = ": will merge with ";
Constants.NO_INPUT = Constants.NAME + " was called without input results";
Constants.NO_CLI_INPUT = Constants.NAME + " CLI was called without input JSON file to read";
Constants.OVERRIDE_JEST_STARE_CONFIG = Constants.NAME + " was called with programmatic config";
},{"chalk":17}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Constants = void 0;
class Constants {
}
exports.Constants = Constants;
Constants.PASSED_LABEL = "Passed";
Constants.FAILED_LABEL = "Failed";
Constants.PENDING_LABEL = "Pending";
Constants.TODO_LABEL = "Todo";
Constants.OBSOLETE_SNAPSHOT_TEST_LABEL = "Obsolete Test";
Constants.CHANGED_LABEL = "Changed";
Constants.ADDED_LABEL = "Added";
Constants.UPDATED_SNAPSHOT_TEST_LABEL = "Updated Snapshot Test";
Constants.REMOVED_OBSOLETE_SNAPSHOT_FILE_LABEL = "Removed Obsolete Snapshot File";
Constants.OBSOLETE_SNAPSHOT_FILE_LABEL = "Obsolete File";
Constants.TEST_STATUS_PASS = "passed";
Constants.TEST_STATUS_FAIL = "failed";
Constants.TEST_STATUS_PEND = "pending";
Constants.TEST_STATUS_TODO = "todo";
Constants.OBSOLETE_SNAPSHOT_FILE = "#f8f9fa";
Constants.OBSOLETE_SNAPSHOT_TEST = "#ffc107";
Constants.ADDED = "#007bff";
Constants.UPDATED_SNAPSHOT_TEST = "#17a2b8";
Constants.REMOVED_OBSOLETE_SNAPSHOT_FILE = "#343a40";
Constants.CHANGED = "#6c757d";
Constants.PASS_RAW = "28a745";
Constants.PASS = "#" + Constants.PASS_RAW;
Constants.FAIL_RAW = "dc3545";
Constants.FAIL = "#" + Constants.FAIL_RAW;
Constants.PENDING_RAW = "ffc107";
Constants.PENDING = "#" + Constants.PENDING_RAW;
Constants.TODO_RAW = "17a2b8";
Constants.TODO = "#" + Constants.TODO_RAW;
Constants.PASSED_TEST = "passed-test";
Constants.FAILED_TEST = "failed-test";
Constants.PENDING_TEST = "pending-test";
Constants.TODO_TEST = "todo-test";
},{}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Render = void 0;
const $ = require("jquery");
const Switch_1 = require("./navigation/Switch");
const Constants_1 = require("./Constants");
const Status_1 = require("./charts/Status");
const Doughnut_1 = require("./charts/Doughnut");
const TestSuite_1 = require("./suites/TestSuite");
const TestSummary_1 = require("./summary/TestSummary");
class Render {
static init() {
document.addEventListener("DOMContentLoaded", () => {
const config = JSON.parse($("#test-config").text());
const results = JSON.parse($("#test-results").text());
try {
const globalConfig = JSON.parse($("#test-global-config").text());
const regex = new RegExp(Render.escapeRegExp(globalConfig.rootDir), "g");
results.testResults.forEach((testResult) => {
testResult.testFilePath = testResult.testFilePath.replace(regex, "");
});
}
catch (e) {
}
Render.show(results, config);
});
}
static escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
static show(results, config) {
const labels = [Constants_1.Constants.PASSED_LABEL, Constants_1.Constants.FAILED_LABEL];
const backgroundColor = [Constants_1.Constants.PASS, Constants_1.Constants.FAIL];
Render.setReportTitle(config);
Render.setReportHeadline(config);
Render.setCoverageLink(config);
if (!config.disableCharts) {
const suitesData = Render.buildChartsData(results.numPassedTestSuites, results.numFailedTestSuites, results.numPendingTestSuites);
Doughnut_1.Doughnut.createChart($("#test-suites-canvas"), suitesData);
const testsChart = Render.buildChartsData(results.numPassedTests, results.numFailedTests, results.numPendingTests, results.numTodoTests);
Doughnut_1.Doughnut.createChart($("#tests-canvas"), testsChart);
let snapshotChart = Render.buildChartsData(results.snapshot.matched, results.snapshot.unmatched);
snapshotChart = Render.addSnapshotChartData(results, snapshotChart);
Doughnut_1.Doughnut.createChart($("#snapshots-canvas"), snapshotChart);
}
this.updateStatusArea(results);
const tableHtml = TestSuite_1.TestSuite.create(results);
$("#loading-info").hide();
$("#test-results").replaceWith($(tableHtml));
if (config.reportSummary) {
const testSummary = TestSummary_1.TestSummary.create(results);
$("#test-summary").replaceWith($(testSummary));
}
if (config.hidePassing) {
$("#lab-passoff-switch").prop("checked", false);
$(`.${Constants_1.Constants.PASSED_TEST}`).hide();
}
if (config.hideFailing) {
$("#lab-failoff-switch").prop("checked", false);
$(`.${Constants_1.Constants.FAILED_TEST}`).hide();
}
if (config.hidePending) {
$("#lab-pendingoff-switch").prop("checked", false);
$(`.${Constants_1.Constants.PENDING_TEST}`).hide();
}
if (config.hideTodo) {
$("#lab-todooff-switch").prop("checked", false);
$(`.${Constants_1.Constants.TODO_TEST}`).hide();
}
if (config.hideFailing && config.hidePassing) {
$(`.${Constants_1.Constants.FAILED_TEST}\\.${Constants_1.Constants.PASSED_TEST}`).hide();
}
if (config.hidePending && config.hidePassing) {
$(`.${Constants_1.Constants.PASSED_TEST}\\.${Constants_1.Constants.PENDING_TEST}`).hide();
}
if (config.hideFailing && config.hidePending) {
$(`.${Constants_1.Constants.FAILED_TEST}\\.${Constants_1.Constants.PENDING_TEST}`).hide();
}
if (config.hideFailing && config.hidePassing && config.hidePending) {
$(`.${Constants_1.Constants.FAILED_TEST}\\.${Constants_1.Constants.PASSED_TEST}\\.${Constants_1.Constants.PENDING_TEST}`).hide();
}
const allCheckArray = new Array();
allCheckArray.push($("#lab-passoff-switch"));
allCheckArray.push($("#lab-failoff-switch"));
allCheckArray.push($("#lab-pendingoff-switch"));
allCheckArray.push($("#lab-todooff-switch"));
const allStylesArray = [Constants_1.Constants.PASSED_TEST, Constants_1.Constants.FAILED_TEST, Constants_1.Constants.PENDING_TEST, Constants_1.Constants.TODO_TEST];
const allSwitchArray = ["#lab-passoff-switch", "#lab-failoff-switch", "#lab-pendingoff-switch", "#lab-todooff-switch"];
allStylesArray.forEach((style, index) => {
const checksMinusCurrentOne = allCheckArray.slice();
checksMinusCurrentOne.splice(index, 1);
const stylesMinusCurrentOne = allStylesArray.slice();
stylesMinusCurrentOne.splice(index, 1);
const switchElement = new Switch_1.Switch($(allSwitchArray[index]), $("." + style), style, checksMinusCurrentOne, stylesMinusCurrentOne);
});
}
static updateStatusArea(results) {
Status_1.Status.setResultsClass($("#test-suites-results"), results.numPassedTestSuites, results.numTotalTestSuites - results.numPassedTestSuites - results.numPendingTestSuites);
Status_1.Status.setResultsClass($("#tests-results"), results.numPassedTests, results.numTotalTests - results.numPassedTests - results.numPendingTests);
Status_1.Status.setResultsClass($("#snapshots-results"), results.snapshot.matched, results.snapshot.unmatched);
if (results.snapshot.added === 0 &&
results.snapshot.matched === 0 &&
results.snapshot.unchecked === 0 &&
results.snapshot.unmatched === 0 &&
results.snapshot.updated === 0) {
$("#snapshots-group").hide();
}
}
static setReportTitle(config) {
const tabTitle = config.reportTitle != null ? config.reportTitle : "jest-stare!";
document.title = tabTitle;
}
static setReportHeadline(config) {
const brandTitle = config.reportHeadline != null ? config.reportHeadline : "jest-stare";
const a = $("#navbar-title");
a.text(brandTitle);
}
static setCoverageLink(config) {
if (config.coverageLink != null) {
const a = $("#coverage-link");
a.addClass("active");
a.removeClass("disabled");
a.attr("href", config.coverageLink);
}
}
static buildChartsData(passedTests, failedTests, pendingTests, todoTests) {
const chartData = {
labels: [],
backgroundColor: [],
data: [],
};
if (passedTests > 0) {
chartData.labels.push(Constants_1.Constants.PASSED_LABEL);
chartData.backgroundColor.push(Constants_1.Constants.PASS);
chartData.data.push(passedTests);
}
if (failedTests > 0) {
chartData.labels.push(Constants_1.Constants.FAILED_LABEL);
chartData.backgroundColor.push(Constants_1.Constants.FAIL);
chartData.data.push(failedTests);
}
if (pendingTests > 0) {
chartData.labels.push(Constants_1.Constants.PENDING_LABEL);
chartData.backgroundColor.push(Constants_1.Constants.PENDING);
chartData.data.push(pendingTests);
}
if (todoTests > 0) {
chartData.labels.push(Constants_1.Constants.TODO_LABEL);
chartData.backgroundColor.push(Constants_1.Constants.TODO);
chartData.data.push(todoTests);
}
return chartData;
}
static addSnapshotChartData(results, snapshotChart) {
if (results.snapshot.filesAdded > 0) {
snapshotChart.labels.push(Constants_1.Constants.ADDED_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.ADDED);
snapshotChart.data.push(results.snapshot.filesAdded);
}
if (results.snapshot.unchecked > 0) {
if (results.snapshot.didUpdate) {
snapshotChart.labels.push(Constants_1.Constants.UPDATED_SNAPSHOT_TEST_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.UPDATED_SNAPSHOT_TEST);
snapshotChart.data.push(results.snapshot.unchecked);
}
else {
snapshotChart.labels.push(Constants_1.Constants.OBSOLETE_SNAPSHOT_TEST_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.OBSOLETE_SNAPSHOT_TEST);
snapshotChart.data.push(results.snapshot.unchecked);
}
}
if (results.snapshot.updated > 0) {
snapshotChart.labels.push(Constants_1.Constants.CHANGED_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.CHANGED);
snapshotChart.data.push(results.snapshot.updated);
}
if (results.snapshot.filesRemoved > 0) {
if (results.snapshot.didUpdate) {
snapshotChart.labels.push(Constants_1.Constants.REMOVED_OBSOLETE_SNAPSHOT_FILE_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.REMOVED_OBSOLETE_SNAPSHOT_FILE);
snapshotChart.data.push(results.snapshot.filesRemoved);
}
else {
snapshotChart.labels.push(Constants_1.Constants.OBSOLETE_SNAPSHOT_FILE_LABEL);
snapshotChart.backgroundColor.push(Constants_1.Constants.OBSOLETE_SNAPSHOT_FILE);
snapshotChart.data.push(results.snapshot.filesRemoved);
}
}
return snapshotChart;
}
}
exports.Render = Render;
},{"./Constants":2,"./charts/Doughnut":4,"./charts/Status":5,"./navigation/Switch":8,"./suites/TestSuite":9,"./summary/TestSummary":11,"jquery":41}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Doughnut = void 0;
const chart_js_1 = require("chart.js");
class Doughnut {
static createChart(canvas, chartData) {
chart_js_1.Chart.register(...chart_js_1.registerables);
const doughnut = "doughnut";
const config = {
type: doughnut,
data: {
labels: chartData.labels,
datasets: [
{
backgroundColor: chartData.backgroundColor,
data: chartData.data,
}
]
}
};
Doughnut.buildCanvas(canvas.get(0), config);
}
static buildCanvas(canvas, config) {
const doughnut = new chart_js_1.Chart(canvas, config);
}
}
exports.Doughnut = Doughnut;
},{"chart.js":20}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Status = void 0;
class Status {
static setResultsClass(statusElement, passed, failed) {
const total = passed + failed;
if (total === 0) {
statusElement.addClass("list-group-item-info");
}
else {
if (passed === 0) {
statusElement.addClass("list-group-item-danger");
}
else if (passed === total) {
statusElement.addClass("list-group-item-success");
}
else {
statusElement.addClass("list-group-item-warning");
}
}
}
}
exports.Status = Status;
},{}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageSnapshotDifference = void 0;
const $ = require("jquery");
const Constants_1 = require("../../processor/Constants");
const AnsiParser = require("ansi-parser");
class ImageSnapshotDifference {
static containsDiff(jestFailureMessage) {
let isFailure = false;
for (const indicator of ImageSnapshotDifference.DIFF_INDICATOR) {
if (jestFailureMessage.indexOf(indicator) >= 0) {
isFailure = true;
break;
}
}
return isFailure;
}
static generate(jestFailureMessage) {
const imageDiffFilename = ImageSnapshotDifference.parseDiffImageName(jestFailureMessage);
const errorMessage = ImageSnapshotDifference.parseDiffError(jestFailureMessage);
const diffDiv = document.createElement("div");
diffDiv.className = "image-snapshot-diff";
const diffMessage = document.createElement("span");
diffMessage.textContent = errorMessage;
diffMessage.className = "text-muted";
diffDiv.appendChild(diffMessage);
const diffImageLink = document.createElement("a");
diffImageLink.href = Constants_1.Constants.IMAGE_SNAPSHOT_DIFF_DIR + imageDiffFilename;
diffDiv.appendChild(diffImageLink);
const diffImage = document.createElement("img");
diffImage.src = Constants_1.Constants.IMAGE_SNAPSHOT_DIFF_DIR + imageDiffFilename;
diffImageLink.appendChild(diffImage);
return $(diffDiv).get(0);
}
static parseDiffImagePath(jestFailureMessage) {
const match = ImageSnapshotDifference.DIFF_IMAGE.exec(jestFailureMessage);
if (match) {
return AnsiParser.removeAnsi(match[1]).trim();
}
return null;
}
static parseDiffImageName(jestFailureMessage) {
const path = ImageSnapshotDifference.parseDiffImagePath(jestFailureMessage);
if (path) {
return path.replace(/^.*[\\\/]/, "");
}
}
static parseDiffError(jestFailureMessage) {
const match = ImageSnapshotDifference.DIFF_DETAILS.exec(jestFailureMessage);
if (match) {
return match[1];
}
return null;
}
}
exports.ImageSnapshotDifference = ImageSnapshotDifference;
ImageSnapshotDifference.DIFF_INDICATOR = ["different from snapshot", "image to be the same size"];
ImageSnapshotDifference.DIFF_IMAGE = /See diff for details:\s*((.*?)\.png)/;
ImageSnapshotDifference.DIFF_DETAILS = /Error: (.*)/;
},{"../../processor/Constants":1,"ansi-parser":15,"jquery":41}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestDifference = void 0;
const diff2html = require("diff2html");
const $ = require("jquery");
class TestDifference {
static containsDiff(jestFailureMessage) {
return jestFailureMessage.search(TestDifference.DIFF_INDICATOR) >= 0;
}
static generate(jestFailureMessage) {
const jestDiff = TestDifference.isolateDiff(jestFailureMessage);
const diffjson = diff2html.parse(jestDiff);
const diffHtml = diff2html.html(diffjson, {
drawFileList: false,
outputFormat: "side-by-side",
matching: "lines"
});
return $(diffHtml).get(0);
}
static isolateDiff(jestFailureMessage) {
const beginIndex = jestFailureMessage.search(TestDifference.DIFF_INDICATOR);
const endIndex = jestFailureMessage.search(TestDifference.DIFF_END_INDICATOR);
let isolated = jestFailureMessage.substring(beginIndex, endIndex);
let snapshotChanges = 0;
let receivedChanges = 0;
const changeLines = isolated.split(/\r?\n/g);
for (const line of changeLines) {
if (/^- /.test(line)) {
snapshotChanges++;
}
else if (/^\+ /.test(line)) {
receivedChanges++;
}
}
const changesIndicator = `\n@@ -0,${snapshotChanges} +0,${receivedChanges} @@\n`;
isolated = isolated.replace("- Snapshot", "--- Snapshot");
isolated = isolated.replace("+ Received", "+++ Received");
const lines = isolated.split(/\r?\n/g);
lines.splice(2, 0, changesIndicator);
return lines.join(`\n`);
}
}
exports.TestDifference = TestDifference;
TestDifference.DIFF_INDICATOR = /- Snapshot\s*(\-\s*[0-9]+)?\n\s*\+ Received\s*(\+\s*[0-9]+)?/g;
TestDifference.DIFF_END_INDICATOR = /(at .*? \(.*?:[0-9]+:[0-9]+\)\s)/g;
},{"diff2html":29,"jquery":41}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Switch = void 0;
class Switch {
static mixStatus(currentStatus, oldStatus) {
const statusArray = oldStatus.split(Switch.JOIN_CHAR);
statusArray.push(currentStatus);
const sortedUniqueStatusArray = [...new Set(statusArray)].sort();
return sortedUniqueStatusArray.join(Switch.JOIN_CHAR);
}
constructor(checkBox, divClass, divClassName, addtnlCheckBoxArray, addtnlClassNameArray) {
this.activateFilters(checkBox, divClass, divClassName, addtnlCheckBoxArray, addtnlClassNameArray);
}
activateFilters(checkBox, divClass, divClassName, addtnlCheckBoxArray, addtnlClassNameArray) {
checkBox.change(() => {
if (checkBox.is(":checked")) {
divClass.show();
if (addtnlCheckBoxArray != null) {
addtnlCheckBoxArray.forEach((addtnlCheckBox, index) => {
const mixedDualClass = Switch.mixStatus(addtnlClassNameArray[index], divClassName);
const mixedClassDiv = $("." + mixedDualClass);
mixedClassDiv.show();
});
const mixedClass = Switch.mixStatus(addtnlClassNameArray[0], divClassName);
const allMixedClass = Switch.mixStatus(addtnlClassNameArray[1], mixedClass);
const allMixedClassDiv = $("." + allMixedClass);
allMixedClassDiv.show();
}
}
else {
divClass.hide();
if (addtnlCheckBoxArray != null) {
let allUnchecked = true;
addtnlCheckBoxArray.forEach((addtnlCheckBox, index) => {
if (!addtnlCheckBox.is(":checked")) {
const mixedClass = Switch.mixStatus(addtnlClassNameArray[index], divClassName);
const mixedClassDiv = $("." + mixedClass);
mixedClassDiv.hide();
}
else {
allUnchecked = false;
}
});
if (allUnchecked) {
const mixedClass = Switch.mixStatus(addtnlClassNameArray[0], divClassName);
const allMixedClass = Switch.mixStatus(addtnlClassNameArray[1], mixedClass);
const allMixedClassDiv = $("." + allMixedClass);
allMixedClassDiv.hide();
}
}
}
});
}
}
exports.Switch = Switch;
Switch.JOIN_CHAR = "\\.";
},{}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestSuite = void 0;
const Constants_1 = require("../Constants");
const Test_1 = require("../tests/Test");
class TestSuite {
static create(results) {
const elements = [];
results.testResults.forEach((testResult) => {
if (testResult.testResults == null) {
console.error("Unexpected testResults field missing");
if (testResult.assertionResults != null) {
console.warn("Attempting to use assertionResults: results are unpredictable");
testResult.testResults = testResult.assertionResults;
}
}
let testStatusClass;
const testSectionStatus = new Map();
for (const result of testResult.testResults) {
testStatusClass = TestSuite.asignStatus(testStatusClass, result, testSectionStatus);
}
if (testStatusClass === undefined) {
testStatusClass = Constants_1.Constants.PASSED_TEST;
}
const accordionCard = TestSuite.buildAccordionCard(testResult, testStatusClass);
const divMap = new Map();
testResult.testResults.forEach((test) => {
const element = Test_1.Test.create(test);
if (test.ancestorTitles.length > 0) {
test.ancestorTitles.forEach((title, index) => {
const titlesCopy = test.ancestorTitles.slice();
titlesCopy.splice(index + 1);
const key = titlesCopy.join(TestSuite.JOIN_CHAR);
if (divMap.has(key)) {
divMap.get(key).appendChild(element);
}
else {
const nestDiv = document.createElement("div");
const statusClass = testSectionStatus.get(key) ||
Constants_1.Constants.PASSED_TEST;
nestDiv.classList.add("my-3", "p-3", "bg-white", "rounded", "box-shadow", statusClass);
const h6 = document.createElement("h6");
h6.classList.add("border-bottom", "pb-2", "mb-0", "display-6");
h6.textContent = title;
nestDiv.appendChild(h6);
nestDiv.appendChild(element);
nestDiv.id = key;
divMap.set(key, nestDiv);
if (index === 0) {
accordionCard
.querySelector(".card-body")
.appendChild(nestDiv);
}
else {
titlesCopy.pop();
const parentKey = titlesCopy.join(TestSuite.JOIN_CHAR);
divMap.get(parentKey).appendChild(nestDiv);
}
}
});
}
else {
accordionCard
.querySelector(".card-body")
.appendChild(element);
}
});
elements.push(accordionCard);
});
return elements;
}
static asignStatus(testStatusClass, result, testSectionStatus) {
const currentStatus = TestSuite.getStatusClassFromJestStatus(result.status);
if (!testStatusClass) {
testStatusClass = currentStatus;
}
else if (testStatusClass !== currentStatus) {
testStatusClass = TestSuite.mixStatus(currentStatus, testStatusClass);
}
else {
testStatusClass = currentStatus;
}
for (let index = 0; index < result.ancestorTitles.length; index++) {
const titlesCopy = result.ancestorTitles.slice();
titlesCopy.splice(index + 1);
const key = titlesCopy.join(TestSuite.JOIN_CHAR);
if (testSectionStatus.has(key)) {
if (testStatusClass !== currentStatus) {
testSectionStatus.set(key, TestSuite.mixStatus(currentStatus, testStatusClass));
}
else {
testSectionStatus.set(key, currentStatus);
}
}
else {
testSectionStatus.set(key, currentStatus);
}
}
return testStatusClass;
}
static getStatusClassFromJestStatus(jestStatus) {
if (jestStatus === Constants_1.Constants.TEST_STATUS_PEND) {
return Constants_1.Constants.PENDING_TEST;
}
else if (jestStatus === Constants_1.Constants.TEST_STATUS_FAIL) {
return Constants_1.Constants.FAILED_TEST;
}
else {
return Constants_1.Constants.PASSED_TEST;
}
}
static mixStatus(currentStatus, oldStatus) {
const statusArray = oldStatus.split(TestSuite.JOIN_CHAR);
statusArray.push(currentStatus);
const sortedUniqueStatusArray = [...new Set(statusArray)].sort();
return sortedUniqueStatusArray.join(TestSuite.JOIN_CHAR);
}
static buildAccordionCard(testResult, testStatusClass) {
const accordionCard = document.createElement("div");
accordionCard.classList.add("my-3", "p-3", "bg-white", "rounded", "box-shadow", "card", testStatusClass);
const cardHeader = TestSuite.buildAccordionCardHeader(testResult.testFilePath, testResult.numPassingTests, testResult.numFailingTests, testResult.numPendingTests, testResult.numTodoTests);
accordionCard.appendChild(cardHeader);
const cardBody = TestSuite.buildAccordionCardBody(testResult.testFilePath);
accordionCard.appendChild(cardBody);
return accordionCard;
}
static buildAccordionCardHeader(testFilePath, passCount, failCount, pendingCount, todoCount) {
const fileName = TestSuite.sanitizeFilePath(testFilePath);
const cardHeader = document.createElement("div");
cardHeader.classList.add("card-header");
cardHeader.classList.add("text-center");
cardHeader.id = `${fileName}_header`;
const h5 = document.createElement("h5");
h5.classList.add("border-bottom", "pb-2", "mb-0", "display-5");
const btn = document.createElement("button");
btn.style.userSelect = "text";
btn.classList.add("btn", "btn-block");
btn.setAttribute("data-bs-toggle", "collapse");
btn.setAttribute("data-bs-target", `#${fileName}_detail`);
btn.textContent = testFilePath;
const resultCounts = document.createElement("div");
resultCounts.style.userSelect = "none";
const passBadge = document.createElement("span");
passBadge.classList.add("badge", "bg-success", "border");
passBadge.textContent = passCount.toString();
resultCounts.appendChild(passBadge);
const failBadge = document.createElement("span");
failBadge.classList.add("badge", "bg-danger", "border");
failBadge.textContent = failCount.toString();
resultCounts.appendChild(failBadge);
const skipBadge = document.createElement("span");
skipBadge.classList.add("badge", "bg-warning", "border");
skipBadge.textContent = pendingCount.toString();
resultCounts.appendChild(skipBadge);
const todoBadge = document.createElement("span");
todoBadge.classList.add("badge", "bg-info", "border");
todoBadge.textContent = todoCount.toString();
resultCounts.appendChild(todoBadge);
btn.appendChild(resultCounts);
h5.appendChild(btn);
cardHeader.appendChild(h5);
return cardHeader;
}
static buildAccordionCardBody(testFilePath) {
const fileName = TestSuite.sanitizeFilePath(testFilePath);
const cardContainer = document.createElement("div");
cardContainer.classList.add("collapse");
cardContainer.setAttribute("data-parent", "#accordion");
cardContainer.id = `${fileName}_detail`;
const cardBody = document.createElement("div");
cardBody.classList.add("card-body");
cardContainer.appendChild(cardBody);
return cardContainer;
}
static sanitizeFilePath(testFilePath) {
return testFilePath.replace(/(\/)|\\|(:)|(\s)|\.|(@)/g, "_");
}
}
exports.TestSuite = TestSuite;
TestSuite.JOIN_CHAR = ".";
},{"../Constants":2,"../tests/Test":12}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Test = void 0;
const Constants_1 = require("../Constants");
class Test {
static create(innerTestResult) {
const containerDiv = document.createElement("div");
const anchor = document.createElement("a");
anchor.href = "#" + innerTestResult.title.replace(/\s+/g, "-").toLowerCase();
const testName = document.createElement("span");
testName.textContent = innerTestResult.title;
anchor.appendChild(Test.getSimbolSpanFromStatus(innerTestResult.status));
anchor.appendChild(testName);
containerDiv.appendChild(anchor);
return containerDiv;
}
static getSimbolSpanFromStatus(status) {
const span = document.createElement("span");
span.classList.add("summary-test-label", "test");
if (status === Constants_1.Constants.TEST_STATUS_PASS) {
span.textContent = "✓";
span.classList.add("pass");
}
if (status === Constants_1.Constants.TEST_STATUS_PEND) {
span.textContent = "O";
span.classList.add("pending");
}
if (status === Constants_1.Constants.TEST_STATUS_FAIL) {
span.textContent = "X";
span.classList.add("fail");
}
return span;
}
}
exports.Test = Test;
},{"../Constants":2}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestSummary = void 0;
const Test_1 = require("./Test");
class TestSummary {
static create(results) {
const elements = [];
const div = document.createElement("div");
div.classList.add("my-3", "p-3", "bg-white", "rounded", "box-shadow", "summary");
const h5 = document.createElement("h5");
h5.classList.add("border-bottom", "pb-2", "display-5", "summary-title");
h5.textContent = "Summary";
div.appendChild(h5);
div.id = "test-summary";
elements.push(div);
results.testResults.forEach((testResult) => {
if (testResult.testResults == null) {
console.error("Unexpected testResults field missing");
if (testResult.assertionResults != null) {
console.warn("Attempting to use assertionResults: results are unpredictable");
testResult.testResults = testResult.assertionResults;
}
}
const divMap = new Map();
const testTitleDiv = document.createElement("div");
testTitleDiv.classList.add("summary-test-suite");
const testFileLink = document.createElement("a");
const passingTestsCount = "[" + testResult.numPassingTests + "/" + testResult.testResults.length + "]";
const isPass = (testResult.testResults.length - (testResult.numPassingTests + testResult.numPendingTests)) === 0;
const testStatus = document.createElement("strong");
testStatus.classList.add("summary-test-label");
if (isPass) {
testStatus.classList.add("pass");
testStatus.textContent = "PASS";
}
else {
testStatus.classList.add("fail");
testStatus.textContent = "FAIL";
}
const testFileLine = document.createElement("strong");
testFileLine.classList.add("summary-test-label", "path");
testFileLine.textContent = testResult.testFilePath;
const testCount = document.createElement("strong");
testCount.classList.add("summary-test-count");
testCount.textContent = passingTestsCount;
testFileLink.href = "#" + testResult.testFilePath;
testFileLink.appendChild(testStatus);
testFileLink.appendChild(testFileLine);
testFileLink.appendChild(testCount);
testTitleDiv.appendChild(testFileLink);
div.appendChild(testTitleDiv);
testResult.testResults.forEach((test) => {
const testDetail = Test_1.Test.create(test);
div.appendChild(testDetail);
});
});
return elements;
}
}
exports.TestSummary = TestSummary;
TestSummary.JOIN_CHAR = ".";
},{"./Test":10}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Test = void 0;
const Constants_1 = require("../Constants");
const AnsiParser = require("ansi-parser");
const TestDifference_1 = require("../diff/TestDifference");
const ImageSnapshotDifference_1 = require("../diff/ImageSnapshotDifference");
class Test {
static create(innerTestResult) {
let color = Constants_1.Constants.PASS_RAW;
let testStatusClass = Constants_1.Constants.PASSED_TEST;
let failed = false;
switch (innerTestResult.status) {
case Constants_1.Constants.TEST_STATUS_FAIL:
color = Constants_1.Constants.FAIL_RAW;
testStatusClass = Constants_1.Constants.FAILED_TEST;
failed = true;
break;
case Constants_1.Constants.TEST_STATUS_PEND:
color = Constants_1.Constants.PENDING_RAW;
testStatusClass = Constants_1.Constants.PENDING_TEST;
break;
case Constants_1.Constants.TEST_STATUS_TODO:
color = Constants_1.Constants.TODO_RAW;
testStatusClass = Constants_1.Constants.TODO_TEST;
break;
case Constants_1.Constants.TEST_STATUS_PASS:
break;
default:
break;
}
const firstDiv = document.createElement("div");
firstDiv.classList.add("media", "text-muted", "pt-3", testStatusClass);
const img = document.createElement("img");
img.classList.add("mr-2", "rounded");
img.alt = "";
img.setAttribute("data-src", "holder.js/32x32?theme=thumb&bg=" +
color +
"&fg=" +
color +
"&size=1");
firstDiv.appendChild(img);
const secondDiv = document.createElement("div");
secondDiv.classList.add("media-body", "pb-3", "mb-0", "small", "lh-125", "border-bottom", "overflow-auto");
firstDiv.appendChild(secondDiv);
const thirdDiv = document.createElement("div");
thirdDiv.classList.add("d-flex", "justify-content-between", "align-items-center", "w-100");
secondDiv.appendChild(thirdDiv);
const strong = document.createElement("strong");
strong.classList.add("text-gray-dark");
strong.textContent = innerTestResult.title;
const titleId = innerTestResult.title
.replace(/\s+/g, "-")
.toLowerCase();
const diffId = titleId + "-diff";
thirdDiv.appendChild(strong);
const small = document.createElement("small");
small.classList.add("d-block", "text-right", "mt-3");
const conversionValu = 1000;
small.textContent =
innerTestResult.duration / conversionValu + "s";
thirdDiv.appendChild(small);
const span = document.createElement("span");
span.classList.add("d-block", "mb-2");
span.textContent = innerTestResult.status;
secondDiv.appendChild(span);
if (failed) {
const failMessage = AnsiParser.removeAnsi(innerTestResult.failureMessages[0]);
const failMessageSplit = failMessage.split("\n");
let show = true;
if (failMessage.search(TestDifference_1.TestDifference.DIFF_INDICATOR) >= 0) {
const diffHtml = TestDifference_1.TestDifference.generate(failMessage);
secondDiv.appendChild(diffHtml);
show = false;
}
if (ImageSnapshotDifference_1.ImageSnapshotDifference.containsDiff(failMessage)) {
const diffHtml = ImageSnapshotDifference_1.ImageSnapshotDifference.generate(failMessage);
secondDiv.appendChild(diffHtml);
show = false;
}
const collapseDiv = document.createElement("div");
collapseDiv.classList.add("d-flex", "justify-content-between", "align-items-center", "w-100");
const worthlessDiv = document.createElement("div");
secondDiv.appendChild(collapseDiv);
collapseDiv.appendChild(worthlessDiv);
const button = document.createElement("button");
button.classList.add("btn", "btn-light", "btn-sm");
button.type = "button";
button.setAttribute("data-bs-toggle", "collapse");
button.setAttribute("data-bs-target", "#" + diffId);
button.setAttribute("aria-expanded", "false");
button.setAttribute("aria-controls", diffId);
button.textContent = "raw";
collapseDiv.appendChild(button);
const pre = document.createElement("pre");
secondDiv.appendChild(pre);
pre.classList.add("collapse");
if (show) {
pre.classList.add("show");
}
pre.id = diffId;
const code = document.createElement("code");
pre.appendChild(code);
if (innerTestResult.domSnapshot) {
const iframe = createIframeForDOMSnapshot(innerTestResult.domSnapshot);
const iframeVisibilityCheckbox = createIframeVisibilityCheckbox(iframe);
secondDiv.appendChild(iframeVisibilityCheckbox);
secondDiv.appendChild(iframe);
}
failMessageSplit.forEach((entry, index) => {
const codeSpan = document.createElement("span");
if (entry[0] === "+") {
codeSpan.setAttribute("style", "color:" + Constants_1.Constants.PASS);
codeSpan.textContent = entry;
}
else if (entry[0] === "-") {
codeSpan.setAttribute("style", "color:" + Constants_1.Constants.FAIL);
codeSpan.textContent = entry;
}
else {
codeSpan.textContent = entry;
}
const spanDiv = document.createElement("div");
spanDiv.appendChild(codeSpan);
code.appendChild(spanDiv);
});
}
firstDiv.id = titleId;
return firstDiv;
}
}
exports.Test = Test;
function createIframeForDOMSnapshot(content) {
const iframe = document.createElement("iframe");
Object.assign(iframe.style, {
width: "100%",
height: "1100px",
border: "1px solid black",
});
iframe.onload = () => {
var _a;
const doc = iframe.contentDocument || ((_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document);
if (doc) {
doc.open();
doc.write(content);
doc.close();
}
};
return iframe;
}
function createIframeVisibilityCheckbox(iframe) {
const checkboxId = `iframe-visibility"_${Math.random()
.toString(36)
.substring(7)}`;
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = checkboxId;
checkbox.checked = true;
checkbox.addEventListener("change", (event) => {
const checked = event.target.checked;
iframe.style.display = checked ? "" : "none";
});
Object.assign(checkbox.style, {
cursor: "pointer",
});
const label = document.createElement("label");
label.htmlFor = checkboxId;
label.textContent = "Show DOM Snapshot";
Object.assign(label.style, {
cursor: "pointer",
});
const container = document.createElement("div");
container.appendChild(checkbox);
container.appendChild(label);
Object.assign(container.style, {
display: "flex",
gap: "4px",
marginBottom: "6px",
});
return container;
}
},{"../Constants":2,"../diff/ImageSnapshotDifference":6,"../diff/TestDifference":7,"ansi-parser":15}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Render_1 = require("./Render");
Render_1.Render.init();
},{"./Render":3}],14:[function(require,module,exports){
/*!
* @kurkle/color v0.3.4
* https://github.com/kurkle/color#readme
* (c) 2024 Jukka Kurkela
* Released under the MIT License
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["@kurkle/color"] = factory());
})(this, (function () { 'use strict';
function round(v) {
return v + 0.5 | 0;
}
const lim = (v, l, h) => Math.max(Math.min(v, h), l);
function p2b(v) {
return lim(round(v * 2.55), 0, 255);
}
function b2p(v) {
return lim(round(v / 2.55), 0, 100);
}
function n2b(v) {
return lim(round(v * 255), 0, 255);
}
function b2n(v) {
return lim(round(v / 2.55) / 100, 0, 1);
}
function n2p(v) {
return lim(round(v * 100), 0, 100);
}
const map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};
const hex = [...'0123456789ABCDEF'];
const h1 = b => hex[b & 0xF];
const h2 = b => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
const eq = b => ((b & 0xF0) >> 4) === (b & 0xF);
const isShort = v => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
function hexParse(str) {
var len = str.length;
var ret;
if (str[0] === '#') {
if (len === 4 || len === 5) {
ret = {
r: 255 & map$1[str[1]] * 17,
g: 255 & map$1[str[2]] * 17,
b: 255 & map$1[str[3]] * 17,
a: len === 5 ? map$1[str[4]] * 17 : 255
};
} else if (len === 7 || len === 9) {
ret = {
r: map$1[str[1]] << 4 | map$1[str[2]],
g: map$1[str[3]] << 4 | map$1[str[4]],
b: map$1[str[5]] << 4 | map$1[str[6]],
a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255
};
}
}
return ret;
}
const alpha = (a, f) => a < 255 ? f(a) : '';
function hexString(v) {
var f = isShort(v) ? h1 : h2;
return v
? '#' + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f)
: undefined;
}
const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
function hsl2rgbn(h, s, l) {
const a = s * Math.min(l, 1 - l);
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return [f(0), f(8), f(4)];
}
function hsv2rgbn(h, s, v) {
const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
return [f(5), f(3), f(1)];
}
function hwb2rgbn(h, w, b) {
const rgb = hsl2rgbn(h, 1, 0.5);
let i;
if (w + b > 1) {
i = 1 / (w + b);
w *= i;
b *= i;
}
for (i = 0; i < 3; i++) {
rgb[i] *= 1 - w - b;
rgb[i] += w;
}
return rgb;
}
function hueValue(r, g, b, d, max) {
if (r === max) {
return ((g - b) / d) + (g < b ? 6 : 0);
}
if (g === max) {
return (b - r) / d + 2;
}
return (r - g) / d + 4;
}
function rgb2hsl(v) {
const range = 255;
const r = v.r / range;
const g = v.g / range;
const b = v.b / range;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const l = (max + min) / 2;
let h, s, d;
if (max !== min) {
d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
h = hueValue(r, g, b, d, max);
h = h * 60 + 0.5;
}
return [h | 0, s || 0, l];
}
function calln(f, a, b, c) {
return (
Array.isArray(a)
? f(a[0], a[1], a[2])
: f(a, b, c)
).map(n2b);
}
function hsl2rgb(h, s, l) {
return calln(hsl2rgbn, h, s, l);
}
function hwb2rgb(h, w, b) {
return calln(hwb2rgbn, h, w, b);
}
function hsv2rgb(h, s, v) {
return calln(hsv2rgbn, h, s, v);
}
function hue(h) {
return (h % 360 + 360) % 360;
}
function hueParse(str) {
const m = HUE_RE.exec(str);
let a = 255;
let v;
if (!m) {
return;
}
if (m[5] !== v) {
a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
}
const h = hue(+m[2]);
const p1 = +m[3] / 100;
const p2 = +m[4] / 100;
if (m[1] === 'hwb') {
v = hwb2rgb(h, p1, p2);
} else if (m[1] === 'hsv') {
v = hsv2rgb(h, p1, p2);
} else {
v = hsl2rgb(h, p1, p2);
}
return {
r: v[0],
g: v[1],
b: v[2],
a: a
};
}
function rotate(v, deg) {
var h = rgb2hsl(v);
h[0] = hue(h[0] + deg);
h = hsl2rgb(h);
v.r = h[0];
v.g = h[1];
v.b = h[2];
}
function hslString(v) {
if (!v) {
return;
}
const a = rgb2hsl(v);
const h = a[0];
const s = n2p(a[1]);
const l = n2p(a[2]);
return v.a < 255
? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
: `hsl(${h}, ${s}%, ${l}%)`;
}
const map = {
x: 'dark',
Z: 'light',
Y: 're',
X: 'blu',
W: 'gr',
V: 'medium',
U: 'slate',
A: 'ee',
T: 'ol',
S: 'or',
B: 'ra',
C: 'lateg',
D: 'ights',
R: 'in',
Q: 'turquois',
E: 'hi',
P: 'ro',
O: 'al',
N: 'le',
M: 'de',
L: 'yello',
F: 'en',
K: 'ch',
G: 'arks',
H: 'ea',
I: 'ightg',
J: 'wh'
};
const names$1 = {
OiceXe: 'f0f8ff',
antiquewEte: 'faebd7',
aqua: 'ffff',
aquamarRe: '7fffd4',
azuY: 'f0ffff',
beige: 'f5f5dc',
bisque: 'ffe4c4',
black: '0',
blanKedOmond: 'ffebcd',
Xe: 'ff',
XeviTet: '8a2be2',
bPwn: 'a52a2a',
burlywood: 'deb887',
caMtXe: '5f9ea0',
KartYuse: '7fff00',
KocTate: 'd2691e',
cSO: 'ff7f50',
cSnflowerXe: '6495ed',
cSnsilk: 'fff8dc',
crimson: 'dc143c',
cyan: 'ffff',
xXe: '8b',
xcyan: '8b8b',
xgTMnPd: 'b8860b',
xWay: 'a9a9a9',
xgYF: '6400',
xgYy: 'a9a9a9',
xkhaki: 'bdb76b',
xmagFta: '8b008b',
xTivegYF: '556b2f',
xSange: 'ff8c00',
xScEd: '9932cc',
xYd: '8b0000',
xsOmon: 'e9967a',
xsHgYF: '8fbc8f',
xUXe: '483d8b',
xUWay: '2f4f4f',
xUgYy: '2f4f4f',
xQe: 'ced1',
xviTet: '9400d3',
dAppRk: 'ff1493',
dApskyXe: 'bfff',
dimWay: '696969',
dimgYy: '696969',
dodgerXe: '1e90ff',
fiYbrick: 'b22222',
flSOwEte: 'fffaf0',
foYstWAn: '228b22',
fuKsia: 'ff00ff',
gaRsbSo: 'dcdcdc',
ghostwEte: 'f8f8ff',
gTd: 'ffd700',
gTMnPd: 'daa520',
Way: '808080',
gYF: '8000',
gYFLw: 'adff2f',
gYy: '808080',
honeyMw: 'f0fff0',
hotpRk: 'ff69b4',
RdianYd: 'cd5c5c',
Rdigo: '4b0082',
ivSy: 'fffff0',
khaki: 'f0e68c',
lavFMr: 'e6e6fa',
lavFMrXsh: 'fff0f5',
lawngYF: '7cfc00',
NmoncEffon: 'fffacd',
ZXe: 'add8e6',
ZcSO: 'f08080',
Zcyan: 'e0ffff',
ZgTMnPdLw: 'fafad2',
ZWay: 'd3d3d3',
ZgYF: '90ee90',
ZgYy: 'd3d3d3',
ZpRk: 'ffb6c1',
ZsOmon: 'ffa07a',
ZsHgYF: '20b2aa',
ZskyXe: '87cefa',
ZUWay: '778899',
ZUgYy: '778899',
ZstAlXe: 'b0c4de',
ZLw: 'ffffe0',
lime: 'ff00',
limegYF: '32cd32',
lRF: