diff --git a/README.md b/README.md index d1d472e..8aaf1ab 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Reporter options should also be strings exception for suiteNameTemplate, classNa | `JEST_SUITE_NAME` | `suiteName` | `name` attribute of `` | `"jest tests"` | N/A | `JEST_JUNIT_OUTPUT_DIR` | `outputDirectory` | Directory to save the output. | `process.cwd()` | N/A | `JEST_JUNIT_OUTPUT_NAME` | `outputName` | File name for the output. | `"junit.xml"` | N/A +| `JEST_JUNIT_OUTPUT_FILE` | `outputFile` | File fullpath for the output. If defined, `outputDirectory` and `outputName` will be overridden | `undefined` | N/A | `JEST_JUNIT_UNIQUE_OUTPUT_NAME` | `uniqueOutputName` | Create unique file name for the output `junit-${uuid}.xml`, overrides `outputName` | `false` | N/A | `JEST_JUNIT_SUITE_NAME` | `suiteNameTemplate` | Template string for `name` attribute of the ``. | `"{title}"` | `{title}`, `{filepath}`, `{filename}`, `{displayName}` | `JEST_JUNIT_CLASSNAME` | `classNameTemplate` | Template string for the `classname` attribute of ``. | `"{classname} {title}"` | `{classname}`, `{title}`, `{suitename}`, `{filepath}`, `{filename}`, `{displayName}` diff --git a/__tests__/testResultProcessor.test.js b/__tests__/testResultProcessor.test.js index 194b8da..d8a0357 100644 --- a/__tests__/testResultProcessor.test.js +++ b/__tests__/testResultProcessor.test.js @@ -60,4 +60,32 @@ describe('jest-junit', () => { const xmlDoc = libxmljs.parseXml(fs.writeFileSync.mock.calls[0][1]); expect(xmlDoc).toBeTruthy(); }); + + + it('should generate xml at the output filepath defined by JEST_JUNIT_OUTPUT_FILE', () => { + process.env.JEST_JUNIT_OUTPUT_FILE = 'path_to_output/output_name.xml' + const noFailingTestsReport = require('../__mocks__/no-failing-tests.json'); + testResultProcessor(noFailingTestsReport); + + // Ensure fs.writeFileSync is called + expect(fs.writeFileSync).toHaveBeenCalledTimes(1); + + // Ensure file would have been generated + expect(fs.writeFileSync).toHaveBeenLastCalledWith( + expect.stringMatching(/path_to_output\S+\output_name.xml/), expect.any(String) + ); + }); + + it('should generate xml at the output filepath defined by outputFile config', () => { + const noFailingTestsReport = require('../__mocks__/no-failing-tests.json'); + testResultProcessor(noFailingTestsReport, {outputFile: 'path_to_output/output_name.xml' }); + + // Ensure fs.writeFileSync is called + expect(fs.writeFileSync).toHaveBeenCalledTimes(1); + + // Ensure file would have been generated + expect(fs.writeFileSync).toHaveBeenLastCalledWith( + expect.stringMatching(/path_to_output\S+\output_name.xml/), expect.any(String) + ); + }); }); diff --git a/constants/index.js b/constants/index.js index c1d0686..42f9662 100644 --- a/constants/index.js +++ b/constants/index.js @@ -5,6 +5,7 @@ module.exports = { JEST_SUITE_NAME: 'suiteName', JEST_JUNIT_OUTPUT_DIR: 'outputDirectory', JEST_JUNIT_OUTPUT_NAME: 'outputName', + JEST_JUNIT_OUTPUT_FILE: 'outputFile', JEST_JUNIT_UNIQUE_OUTPUT_NAME: 'uniqueOutputName', JEST_JUNIT_CLASSNAME: 'classNameTemplate', JEST_JUNIT_SUITE_NAME: 'suiteNameTemplate', diff --git a/index.js b/index.js index 2b1dea0..93bedc0 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ const path = require('path'); const buildJsonResults = require('./utils/buildJsonResults'); const getOptions = require('./utils/getOptions'); +const getOutputPath = require('./utils/getOutputPath'); // Store console results from onTestResult to later // append to result @@ -23,17 +24,13 @@ const processor = (report, reporterOptions = {}, jestRootDir = null) => { const jsonResults = buildJsonResults(report, fs.realpathSync(process.cwd()), options); - // Set output to use new outputDirectory and fallback on original output - const outputName = (options.uniqueOutputName === 'true') ? getOptions.getUniqueOutputName() : options.outputName - const output = path.join(options.outputDirectory, outputName); - - const finalOutput = getOptions.replaceRootDirInOutput(jestRootDir, output); + let outputPath = getOutputPath(options, jestRootDir); // Ensure output path exists - mkdirp.sync(path.dirname(finalOutput)); + mkdirp.sync(path.dirname(outputPath)); // Write data to file - fs.writeFileSync(finalOutput, xml(jsonResults, { indent: ' ', declaration: true })); + fs.writeFileSync(outputPath, xml(jsonResults, { indent: ' ', declaration: true })); // Jest 18 compatibility return report; diff --git a/utils/getOutputPath.js b/utils/getOutputPath.js new file mode 100644 index 0000000..8d25a68 --- /dev/null +++ b/utils/getOutputPath.js @@ -0,0 +1,15 @@ +const path = require('path'); +const getOptions = require('./getOptions'); + +module.exports = (options, jestRootDir) => { + // Override outputName and outputDirectory with outputFile if outputFile is defined + let output = options.outputFile; + if (!output) { + // Set output to use new outputDirectory and fallback on original output + const outputName = (options.uniqueOutputName === 'true') ? getOptions.getUniqueOutputName() : options.outputName + output = path.join(options.outputDirectory, outputName); + } + + const finalOutput = getOptions.replaceRootDirInOutput(jestRootDir, output); + return finalOutput; +};