#!/usr/bin/env node const yargs = require('yargs') const argv = yargs .usage('Usage: $0 [options]') .help('help') .option('search-folder', { string: true, demandOption: true, requiresArg: true, describe: 'Directory to search for JUnit XML results' }) .option('test-results-files', { string: true, demandOption: true, requiresArg: true, describe: 'Glob that matches JUnit XML files within searchFolder' }) .wrap(yargs.terminalWidth()) .argv const fs = require('fs') const path = require('path') const glob = require('glob') const cheerio = require('cheerio') function discoverTestFiles() { return new Promise((resolve, reject) => { glob(argv.testResultsFiles, {cwd: argv.searchFolder}, (err, paths) => { if (err) { reject(err) } else { resolve(paths) } }) }) } async function postProcessJUnitXML(junitXmlPath) { const fullPath = path.resolve(argv.searchFolder, junitXmlPath) const friendlyName = path.basename(junitXmlPath, '.xml').replace(/-+/g, ' ') console.log(`${fullPath}: loading`) const original = await new Promise((resolve, reject) => { fs.readFile(fullPath, {encoding: 'utf8'}, (err, content) => { if (err) { reject(err) } else { resolve(content) } }) }) const $ = cheerio.load(original, { xmlMode: true }) $('testcase').attr('name', (i, oldName) => `[${friendlyName}] ${oldName}`) const modified = $.xml() await new Promise((resolve, reject) => { fs.writeFile(fullPath, modified, {encoding: 'utf8'}, err => { if (err) { reject(err) } else { resolve() } }) }) console.log(`${fullPath}: complete`) } ;(async function() { const testResultFiles = await discoverTestFiles() console.log(`Post-processing ${testResultFiles.length} JUnit XML files`) await Promise.all( testResultFiles.map(postProcessJUnitXML) ) console.log(`${testResultFiles.length} JUnit XML files complete`) })().then( () => process.exit(0), err => { console.error(err.stack || err) process.exit(1) } )