UNPKG

html-reporter

Version:

Html-reporter and GUI for viewing and managing results of a tests run. Currently supports Testplane and Hermione.

189 lines 8.66 kB
"use strict"; 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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __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.mergeReports = void 0; const url = __importStar(require("url")); const path = __importStar(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const axios_1 = __importDefault(require("axios")); const _ = __importStar(require("lodash")); const serverUtils = __importStar(require("../server-utils")); const common_utils_1 = require("../common-utils"); const dbServerUtils = __importStar(require("../db-utils/server")); const constants_1 = require("../constants"); const mergeReports = async (toolAdapter, srcPaths, { destPath, headers }) => { await validateOpts({ srcPaths, destPath, headers }); let headersFromEnv; const { htmlReporter, reporterConfig } = toolAdapter; try { headersFromEnv = JSON.parse(process.env.html_reporter_headers || '{}'); } catch (e) { const error = e; throw new Error(`Couldn't parse headers from "html_reporter_headers" env variable: ${error.message}`); } const headersFromCli = headers.reduce((acc, header) => { const [key, ...values] = header.split('='); return _.set(acc, key, values.join('=')); }, {}); const parsedHeaders = { ...headersFromCli, ...headersFromEnv }; const resolvedUrls = await tryResolveUrls(srcPaths, parsedHeaders); const resolvedDbFiles = resolvedUrls.filter(serverUtils.isDbFile); const { true: remoteDbUrls = [], false: localDbPaths = [] } = _.groupBy(resolvedDbFiles, common_utils_1.isUrl); const dbPaths = localDbPaths.map((db, ind, arr) => { const dbName = arr.length > 1 ? genUniqDbName(db, ind + 1) : path.basename(db); return { src: path.resolve(process.cwd(), db), dest: path.resolve(destPath, dbName) }; }); const allDbPaths = [...remoteDbUrls, ...dbPaths.map(({ dest }) => path.parse(dest).base)]; const copyFilePromises = []; await fs_extra_1.default.ensureDir(destPath); if (!_.isEmpty(localDbPaths)) { const srcReportPaths = _.uniq(localDbPaths.map(db => path.resolve(process.cwd(), path.parse(db).dir))); copyFilePromises.push(...[ copyDbFiles(dbPaths), copyArtifacts({ srcPaths: srcReportPaths, destPath, folderName: constants_1.IMAGES_PATH }), copyArtifacts({ srcPaths: srcReportPaths, destPath, folderName: constants_1.SNAPSHOTS_PATH }), copyArtifacts({ srcPaths: srcReportPaths, destPath, folderName: constants_1.ERROR_DETAILS_PATH }) ]); } await Promise.all([ serverUtils.saveStaticFilesToReportDir(htmlReporter, reporterConfig, destPath), serverUtils.writeDatabaseUrlsFile(destPath, allDbPaths), ...copyFilePromises ]); await htmlReporter.emitAsync(htmlReporter.events.REPORT_SAVED, { reportPath: destPath }); }; exports.mergeReports = mergeReports; async function validateOpts({ srcPaths, destPath, headers }) { if (!srcPaths.length) { throw new Error('Nothing to merge, no source reports are passed'); } if (srcPaths.length === 1) { console.warn(`Only one source report is passed: ${srcPaths[0]}, which is usually not what you want. Now, a copy of source report will just be created.`); } if (srcPaths.includes(destPath)) { throw new Error(`Destination report path: ${destPath}, exists in source report paths`); } for (const srcPath of srcPaths) { if ((0, common_utils_1.isUrl)(srcPath)) { continue; } let srcPathStat; try { srcPathStat = await fs_extra_1.default.stat(srcPath); } catch (err) { const error = err; if (error.code !== 'ENOENT') { throw err; } else { throw new Error(`Specified source path: ${srcPath} doesn't exists on file system`); } } if (srcPathStat.isDirectory()) { const dbUrlsJsonPath = path.join(srcPath, constants_1.DATABASE_URLS_JSON_NAME); const isDbUrlsJsonPathExists = await fs_extra_1.default.pathExists(dbUrlsJsonPath); if (!isDbUrlsJsonPathExists) { throw new Error(`${constants_1.DATABASE_URLS_JSON_NAME} doesn't exist in specified source path: ${srcPath}`); } } else { if (!srcPath.endsWith(constants_1.DATABASE_URLS_JSON_NAME) && !srcPath.endsWith(constants_1.LOCAL_DATABASE_NAME)) { throw new Error(`Specified source path: ${srcPath} must be a directory or one of the following files: ${constants_1.DATABASE_URLS_JSON_NAME}, ${constants_1.LOCAL_DATABASE_NAME}.`); } } } for (const header of headers) { if (!header.includes('=')) { throw new Error(`Header must has key and value separated by "=" symbol, but got "${header}"`); } } } async function tryResolveUrls(urls, headers) { const resolvedUrls = []; const results = await Promise.all(urls.map(async (u) => { const extName = path.extname((0, common_utils_1.isUrl)(u) ? url.parse(u).pathname || '' : u); if (!extName) { u = (0, common_utils_1.isUrl)(u) ? new URL(constants_1.DATABASE_URLS_JSON_NAME, u).href : path.join(u, constants_1.DATABASE_URLS_JSON_NAME); } return tryResolveUrl(u, headers); })); results.forEach(({ jsonUrls, dbUrls }) => { resolvedUrls.push(...jsonUrls.concat(dbUrls)); }); return resolvedUrls; } async function tryResolveUrl(url, headers) { const jsonUrls = []; const dbUrls = []; if (serverUtils.isDbFile(url)) { dbUrls.push(url); } else if (serverUtils.isJsonUrl(url)) { try { const data = (0, common_utils_1.isUrl)(url) ? (await axios_1.default.get(url, { headers })).data : await fs_extra_1.default.readJSON(url); const currentDbUrls = _.get(data, 'dbUrls', []); const currentJsonUrls = _.get(data, 'jsonUrls', []); const preparedDbUrls = dbServerUtils.prepareUrls(currentDbUrls, url); const preparedJsonUrls = dbServerUtils.prepareUrls(currentJsonUrls, url); const responses = await Promise.all(preparedJsonUrls.map((url) => tryResolveUrl(url, headers))); dbUrls.push(...preparedDbUrls); responses.forEach(response => { dbUrls.push(...response.dbUrls); jsonUrls.push(...response.jsonUrls); }); } catch (e) { const error = e; common_utils_1.logger.warn(`Failed to handle ${url}: ${error.message}`); jsonUrls.push(url); } } return { jsonUrls, dbUrls }; } function genUniqDbName(dbPath, num) { return `${path.basename(dbPath, constants_1.DB_FILE_EXTENSION)}_${num}${constants_1.DB_FILE_EXTENSION}`; } async function copyDbFiles(dbPaths) { await Promise.all(dbPaths.map(({ src, dest }) => fs_extra_1.default.copy(src, dest))); } async function copyArtifacts({ srcPaths, destPath, folderName }) { for (const reportPath of srcPaths) { const src = path.resolve(reportPath, folderName); const dest = path.resolve(destPath, folderName); const exists = await fs_extra_1.default.pathExists(src); if (!exists) { continue; } await fs_extra_1.default.copy(src, dest, { recursive: true, overwrite: false }); } } //# sourceMappingURL=index.js.map