UNPKG

appcenter-cli

Version:

Command line tool for Visual Studio App Center

145 lines (144 loc) 6.95 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.JUnitXmlUtil = void 0; const pfs = require("../../../util/misc/promisfied-fs"); const xml_util_1 = require("./xml-util"); const fs = require("fs"); const xmldom_1 = require("@xmldom/xmldom"); class JUnitXmlUtil extends xml_util_1.XmlUtil { mergeXmlResults(pathToArchive) { return __awaiter(this, void 0, void 0, function* () { const tempPath = yield pfs.mkTempDir("appcenter-junittestreports"); let mainXml = this.getEmptyXmlDocument(); const self = this; return this.getMergeXmlResultsPromise(pathToArchive, tempPath, (fullPath, relativePath) => { const xml = new xmldom_1.DOMParser(xml_util_1.XmlUtil.DOMParserConfig).parseFromString(fs.readFileSync(fullPath, "utf-8"), "text/xml"); let name = "unknown"; const matches = relativePath.match("^(.*)_TEST.*"); if (matches && matches.length > 1) { name = matches[1].replace(/\./gi, "_"); } self.appendToTestNameTransformation(xml, name); self.removeIgnoredTransformation(xml); mainXml = self.combine(mainXml, xml); }, (resolve) => { resolve(mainXml); }); }); } getArchiveName() { return "junit_xml_zip.zip"; } combine(xml1, xml2) { const testSuitesElement = this.collectAllElements(xml1.documentElement, "testsuites")[0]; const xml1testSuites = this.collectChildren(xml1.documentElement, "testsuite"); const xml2TestSuites = this.collectChildren(xml2.documentElement, "testsuite"); xml2TestSuites.forEach((xml2TestSuite) => { let needToAddNewTestSuite = true; // Skip test suite without test cases if (this.collectAllElements(xml2TestSuite, "testcase").length === 0) { return; } // Combine all test cases in one test suite with the same class name const testSuiteName = xml2TestSuite.attributes.getNamedItem("name").value; xml1testSuites.every((xml1TestSuite) => { const suiteNameAttr = xml1TestSuite.attributes.getNamedItem("name"); if (!suiteNameAttr || suiteNameAttr.value !== testSuiteName) { // Take the next test suite return true; } // Combine test suite attributes this.combineAllAttributes(xml1TestSuite, xml2TestSuite); const testCases = this.collectChildren(xml2TestSuite, "testcase"); testCases.forEach((testCase) => { xml1TestSuite.appendChild(testCase); }); needToAddNewTestSuite = false; // Stop processing return false; }); if (needToAddNewTestSuite) { testSuitesElement.appendChild(xml2TestSuite); } // Add test suite info to summary this.combineAllAttributes(testSuitesElement, xml2TestSuite); }); return xml1; } getEmptyXmlDocument() { return new xmldom_1.DOMParser().parseFromString('<?xml version="1.0" encoding="UTF-8"?>\ <testsuites tests="0" failures="0" time="0" errors="0" skipped="0"></testsuites>', "text/xml"); } appendToTestNameTransformation(xml, text) { const testCases = this.collectAllElements(xml.documentElement, "testcase"); testCases.forEach((testCase) => { const name = testCase.attributes.getNamedItem("name"); if (name) { name.value = `${name.value}${text}`; } }); } removeIgnoredTransformation(xml) { const testCases = this.collectAllElements(xml.documentElement, "testcase"); testCases.forEach((testCase) => { if (this.collectAllElements(testCase, "skipped").length === 0) { return; } const parent = testCase.parentNode; parent.removeChild(testCase); const testCaseTime = Number(testCase.attributes.getNamedItem("time").value); const timeAttr = parent.attributes.getNamedItem("time"); if (timeAttr && timeAttr.value) { const time = Number(timeAttr.value) - testCaseTime; timeAttr.value = String(Math.round(time * 1000) / 1000); } const skippedAttr = parent.attributes.getNamedItem("skipped"); if (skippedAttr && skippedAttr.value) { skippedAttr.value = String(Number(skippedAttr.value) - 1); } const testsAttr = parent.attributes.getNamedItem("tests"); if (testsAttr && testsAttr.value) { testsAttr.value = String(Number(testsAttr.value) - 1); } }); } removeEmptySuitesTransformation(xml) { const testSuites = this.collectAllElements(xml.documentElement, "testsuite"); testSuites.forEach((testSuite) => { if (this.collectAllElements(testSuite, "testcase").length === 0) { testSuite.parentElement.removeChild(testSuite); xml.removeChild(testSuite); } }); } combineAllAttributes(element1, element2) { this.combineAttributes(element1, element2, "tests"); this.combineAttributes(element1, element2, "failures"); this.combineAttributes(element1, element2, "time"); this.combineAttributes(element1, element2, "errors"); this.combineAttributes(element1, element2, "skipped"); } combineAttributes(element1, element2, attributeName) { const attr1 = element1.attributes.getNamedItem(attributeName); const attr2 = element2.attributes.getNamedItem(attributeName); if (!attr1 || !attr1.value) { return; } if (!attr2 || !attr2.value) { return; } const attr1Value = Number(attr1.value); const attr2Value = Number(attr2.value); attr1.value = String(Math.round((attr1Value + attr2Value) * 1000) / 1000); } } exports.JUnitXmlUtil = JUnitXmlUtil;