From 0dfdb9ded163376eaf217c75ef481b921f327e7d Mon Sep 17 00:00:00 2001 From: Johan Brorson Date: Tue, 5 Apr 2022 11:46:41 +0200 Subject: [PATCH 1/3] feat: make the test suite properties path configurable Make it possible to configure the path to test suite properties. The default path will still be in the current working directory. Example configuration: ``` [ 'jest-junit', { testSuitePropertiesFile: 'test-properties.js', testSuitePropertiesDirectory: '/config', }, ], ``` --- __tests__/buildJsonResults.test.js | 44 ++++++++++++++++++++ __tests__/getTestSuitePropertiesPath.test.js | 34 +++++++++++++++ constants/index.js | 6 ++- index.js | 7 +++- utils/buildJsonResults.js | 8 +++- utils/getTestSuitePropertiesPath.js | 16 +++++++ 6 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 __tests__/getTestSuitePropertiesPath.test.js create mode 100644 utils/getTestSuitePropertiesPath.js diff --git a/__tests__/buildJsonResults.test.js b/__tests__/buildJsonResults.test.js index 0f52054..57990f5 100644 --- a/__tests__/buildJsonResults.test.js +++ b/__tests__/buildJsonResults.test.js @@ -1,5 +1,6 @@ 'use strict'; +const fs = require('fs'); const slash = require('slash'); const buildJsonResults = require('../utils/buildJsonResults'); const constants = require('../constants/index'); @@ -396,4 +397,47 @@ describe('buildJsonResults', () => { expect(jsonResults.testsuites[1].testsuite[2]['system-out']).not.toBeDefined(); }); + + it('should get custom testsuite properties from specified file path', () => { + const noFailingTestsReport = require('../__mocks__/no-failing-tests.json'); + jest.mock( + '/path/to/properties.js', + () => { + return jest.fn(() => { + return { 'best-tester': 'Johan' }; + }); + }, + { virtual: true }, + ); + + jest.spyOn(fs, 'existsSync'); + fs.existsSync.mockReturnValue(true); + + const options = { + ...constants.DEFAULT_OPTIONS, + testSuitePropertiesFile: 'properties.js', + testSuitePropertiesDirectory: '', + }; + + jsonResults = buildJsonResults( + noFailingTestsReport, + '/', + options, + '/path/to', + ); + + expect(jsonResults.testsuites[1].testsuite[1].properties).toEqual( + expect.arrayContaining([ + { + property: expect.objectContaining({ + _attr: expect.objectContaining({ + name: 'best-tester', + value: 'Johan', + }), + }), + }, + ]), + ); + }); + }); diff --git a/__tests__/getTestSuitePropertiesPath.test.js b/__tests__/getTestSuitePropertiesPath.test.js new file mode 100644 index 0000000..4bcff33 --- /dev/null +++ b/__tests__/getTestSuitePropertiesPath.test.js @@ -0,0 +1,34 @@ +const path = require('path'); +const getTestSuitePropertiesPath = require('../utils/getTestSuitePropertiesPath'); + +jest.mock('path', () => { + return { + ...jest.requireActual('path'), + join: (...paths) => { + return paths.join('/'); + }, + resolve: (...paths) => { + return `/absolute/${paths.join('/')}` + } + }; +}); + +const options = { + testSuitePropertiesFile: 'properties.js', + testSuitePropertiesDirectory: '', +}; + +describe('getTestSuitePropertiesPath', () => { + it('should replace in test suite properties path', () => { + const testSuitePropertiesPath = getTestSuitePropertiesPath( + options, + 'path/to', + ); + expect(testSuitePropertiesPath).toEqual('/absolute/path/to/properties.js'); + }); + + it('should not replace in test suite properties path when rootDir is not set', () => { + const testSuitePropertiesPath = getTestSuitePropertiesPath(options); + expect(testSuitePropertiesPath).toEqual('/absolute//properties.js'); + }); +}); diff --git a/constants/index.js b/constants/index.js index db51dbd..72bcc55 100644 --- a/constants/index.js +++ b/constants/index.js @@ -17,7 +17,8 @@ module.exports = { JEST_JUNIT_REPORT_TEST_SUITE_ERRORS: 'reportTestSuiteErrors', JEST_JUNIT_NO_STACK_TRACE: "noStackTrace", JEST_USE_PATH_FOR_SUITE_NAME: 'usePathForSuiteName', - JEST_JUNIT_TEST_SUITE_PROPERTIES_JSON_FILE: 'testSuitePropertiesFile' + JEST_JUNIT_TEST_SUITE_PROPERTIES_JSON_FILE: 'testSuitePropertiesFile', + JEST_JUNIT_TEST_SUITE_PROPERTIES_DIR: 'testSuitePropertiesDirectory', }, DEFAULT_OPTIONS: { suiteName: 'jest tests', @@ -34,7 +35,8 @@ module.exports = { includeShortConsoleOutput: 'false', reportTestSuiteErrors: 'false', noStackTrace: 'false', - testSuitePropertiesFile: 'junitProperties.js' + testSuitePropertiesFile: 'junitProperties.js', + testSuitePropertiesDirectory: process.cwd(), }, SUITENAME_VAR: 'suitename', CLASSNAME_VAR: 'classname', diff --git a/index.js b/index.js index 93bedc0..13b7394 100644 --- a/index.js +++ b/index.js @@ -22,7 +22,12 @@ const processor = (report, reporterOptions = {}, jestRootDir = null) => { t.console = consoleBuffer[t.testFilePath]; }); - const jsonResults = buildJsonResults(report, fs.realpathSync(process.cwd()), options); + const jsonResults = buildJsonResults( + report, + fs.realpathSync(process.cwd()), + options, + jestRootDir + ); let outputPath = getOutputPath(options, jestRootDir); diff --git a/utils/buildJsonResults.js b/utils/buildJsonResults.js index e5b8c3b..a35df5f 100644 --- a/utils/buildJsonResults.js +++ b/utils/buildJsonResults.js @@ -4,6 +4,7 @@ const stripAnsi = require('strip-ansi'); const constants = require('../constants/index'); const path = require('path'); const fs = require('fs'); +const getTestSuitePropertiesPath = require('./getTestSuitePropertiesPath'); // Wrap the varName with template tags const toTemplateTag = function (varName) { @@ -46,9 +47,12 @@ const addErrorTestResult = function (suite) { }) } -module.exports = function (report, appDirectory, options) { +module.exports = function (report, appDirectory, options, rootDir = null) { // Check if there is a junitProperties.js (or whatever they called it) - const junitSuitePropertiesFilePath = path.join(process.cwd(), options.testSuitePropertiesFile); + const junitSuitePropertiesFilePath = getTestSuitePropertiesPath( + options, + rootDir, + ); let ignoreSuitePropertiesCheck = !fs.existsSync(junitSuitePropertiesFilePath); // If the usePathForSuiteName option is true and the diff --git a/utils/getTestSuitePropertiesPath.js b/utils/getTestSuitePropertiesPath.js new file mode 100644 index 0000000..4b0f519 --- /dev/null +++ b/utils/getTestSuitePropertiesPath.js @@ -0,0 +1,16 @@ +const path = require('path'); +const replaceRootDirInOutput = require('./getOptions').replaceRootDirInOutput; + +module.exports = (options, rootDir = null) => { + const testSuitePropertiesPath = replaceRootDirInOutput( + rootDir, + path.join( + options.testSuitePropertiesDirectory, + options.testSuitePropertiesFile, + ), + ); + + return path.isAbsolute(testSuitePropertiesPath) + ? testSuitePropertiesPath + : path.resolve(testSuitePropertiesPath); +}; From 0041247f72a7aae2616f45e97bb1ca7b0954d8ae Mon Sep 17 00:00:00 2001 From: Johan Brorson Date: Tue, 5 Apr 2022 14:57:02 +0200 Subject: [PATCH 2/3] docs: update configuration options in readme Add `testSuitePropertiesFile` and `testSuitePropertiesDirectory` configuration options to `README.md`. --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 90b3e58..c3a96ac 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ jest --ci --reporters=default --reporters=jest-junit ``` ## Usage as testResultsProcessor (deprecated) -The support for `testResultsProcessor` is only kept for [legacy reasons][test-results-processor] and might be removed in the future. +The support for `testResultsProcessor` is only kept for [legacy reasons][test-results-processor] and might be removed in the future. You should therefore prefer to configure `jest-junit` as a _reporter_. Should you still want to, add the following entry to your jest config: @@ -72,8 +72,10 @@ Reporter options should also be strings exception for suiteNameTemplate, classNa | `JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT` | `includeConsoleOutput` | Adds console output to any testSuite that generates stdout during a test run. | `false` | N/A | `JEST_JUNIT_INCLUDE_SHORT_CONSOLE_OUTPUT` | `includeShortConsoleOutput` | Adds short console output (only message value) to any testSuite that generates stdout during a test run. | `false` | N/A | `JEST_JUNIT_REPORT_TEST_SUITE_ERRORS` | `reportTestSuiteErrors` | Reports test suites that failed to execute altogether as `error`. _Note:_ since the suite name cannot be determined from files that fail to load, it will default to file path.| `false` | N/A -| `JEST_JUNIT_NO_STACK_TRACE` | `noStackTrace` | Omit stack traces from test failure reports, similar to `jest --noStackTrace` | `false` | N/A +| `JEST_JUNIT_NO_STACK_TRACE` | `noStackTrace` | Omit stack traces from test failure reports, similar to `jest --noStackTrace` | `false` | N/A | `JEST_USE_PATH_FOR_SUITE_NAME` | `usePathForSuiteName` | **DEPRECATED. Use `suiteNameTemplate` instead.** Use file path as the `name` attribute of `` | `"false"` | N/A +| `JEST_JUNIT_TEST_SUITE_PROPERTIES_JSON_FILE` | `testSuitePropertiesFile` | Name of the custom testsuite properties file | `"junitProperties.js"` | N/A +| `JEST_JUNIT_TEST_SUITE_PROPERTIES_DIR` | `testSuitePropertiesDirectory` | Location of the custom testsuite properties file | `process.cwd()` | N/A You can configure these options via the command line as seen below: From a15a3fbb1304fc1dd9a99548555b7a7276c3e9f2 Mon Sep 17 00:00:00 2001 From: Johan Brorson Date: Tue, 5 Apr 2022 16:51:17 +0200 Subject: [PATCH 3/3] fix: restore all mocks between tests Restore all mocks between tests in `buildJsonResults.test.js` to ensure that it works with Jest 24. --- __tests__/buildJsonResults.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/__tests__/buildJsonResults.test.js b/__tests__/buildJsonResults.test.js index 57990f5..2e19c17 100644 --- a/__tests__/buildJsonResults.test.js +++ b/__tests__/buildJsonResults.test.js @@ -9,7 +9,13 @@ let jsonResults; let ignoreJunitErrors = false; describe('buildJsonResults', () => { + beforeEach(() => { + jest.spyOn(fs, 'existsSync'); + }) + afterEach(() => { + jest.restoreAllMocks(); + if (ignoreJunitErrors !== true) { // Verify each tests JSON output results in a // compliant junit.xml file based on __tests__/lib/junit.xsd (jenkins xsd) @@ -410,7 +416,6 @@ describe('buildJsonResults', () => { { virtual: true }, ); - jest.spyOn(fs, 'existsSync'); fs.existsSync.mockReturnValue(true); const options = { @@ -439,5 +444,4 @@ describe('buildJsonResults', () => { ]), ); }); - });