diff --git a/README.md b/README.md index 9aec0e1..43b573c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ yarn add --dev jest-junit ``` ## Important Notice -In an upcoming major version 5.x jest-junit will no longer function as a testResultProcessor. It will only work as a jest reporter. See the docs just below this for how to transition your project. +In an upcoming major version 7.x jest-junit will no longer function as a testResultProcessor. It will only work as a jest reporter. See the docs just below this for how to transition your project. ## Usage In your jest config add the following entry: @@ -51,22 +51,23 @@ jest --ci --testResultsProcessor="jest-junit" ## Configuration -`jest-junit` offers seven configurations based on environment variables or a `jest-junit` key defined in `package.json` or a reporter option. +`jest-junit` offers several configurations based on environment variables or a `jest-junit` key defined in `package.json` or a reporter option. Environment variable and package.json configuration should be **strings**. Reporter options should also be strings exception for suiteNameTemplate, classNameTemplate, titleNameTemplate that can also accept a function returning a string. -| Variable Name | Description | Default | Possible Injection Values -|--|--|--|--| -| `JEST_SUITE_NAME` | `name` attribute of `` | `"jest tests"` | N/A -| `JEST_JUNIT_OUTPUT` | File path to save the output. | `"./junit.xml"` | N/A -| `JEST_JUNIT_OUTPUT_DIR` | Directory to save the output. | `null` | N/A -| `JEST_JUNIT_OUTPUT_NAME` | File name for the output. | `"./junit.xml"` | N/A -| `JEST_JUNIT_SUITE_NAME` | Template string for `name` attribute of the ``. | `"{title}"` | `{title}`, `{filepath}`, `{filename}`, `{displayName}` -| `JEST_JUNIT_CLASSNAME` | Template string for the `classname` attribute of ``. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}` -| `JEST_JUNIT_TITLE` | Template string for the `name` attribute of ``. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}` -| `JEST_JUNIT_ANCESTOR_SEPARATOR` | Character(s) used to join the `describe` blocks. | `" "` | N/A -| `JEST_JUNIT_ADD_FILE_ATTRIBUTE` | Add file attribute to the output. This config is primarily for Circle CI. This setting provides richer details but may break on other CI platforms. | `false` | N/A -| `JEST_USE_PATH_FOR_SUITE_NAME` | **DEPRECATED. Use `suiteNameTemplate` instead.** Use file path as the `name` attribute of `` | `"false"` | N/A +| Environment Variable Name | Reporter Config Name| Description | Default | Possible Injection Values +|--|--|--|--|--| +| `JEST_SUITE_NAME` | `suiteName` | `name` attribute of `` | `"jest tests"` | N/A +| `JEST_JUNIT_OUTPUT` | `output` | File path to save the output. | `"./junit.xml"` | N/A +| `JEST_JUNIT_OUTPUT_DIR` | `outputDirectory` | Directory to save the output. | `null` | N/A +| `JEST_JUNIT_OUTPUT_NAME` | `outputName` | File name for the output. | `"./junit.xml"` | 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}`, `{filepath}`, `{filename}`, `{displayName}` +| `JEST_JUNIT_TITLE` | `titleTemplate` | Template string for the `name` attribute of ``. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}` +| `JEST_JUNIT_ANCESTOR_SEPARATOR` | `ancestorSeparator` | Character(s) used to join the `describe` blocks. | `" "` | N/A +| `JEST_JUNIT_ADD_FILE_ATTRIBUTE` | `addFileAttribute` | Add file attribute to the output. This config is primarily for Circle CI. This setting provides richer details but may break on other CI platforms. | `false` | N/A +| `JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT` | `includeConsoleOutput` | Adds console output to any testSuite that generates stdout during a test run. | `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 You can configure these options via the command line as seen below: diff --git a/__mocks__/test-with-console-output.json b/__mocks__/test-with-console-output.json new file mode 100644 index 0000000..5ad9c4e --- /dev/null +++ b/__mocks__/test-with-console-output.json @@ -0,0 +1,128 @@ +{ + "numFailedTestSuites": 0, + "numFailedTests": 0, + "numPassedTestSuites": 2, + "numPassedTests": 2, + "numPendingTestSuites": 0, + "numPendingTests": 0, + "numRuntimeErrorTestSuites": 0, + "numTodoTests": 0, + "numTotalTestSuites": 2, + "numTotalTests": 2, + "openHandles": [], + "snapshot": { + "added": 0, + "didUpdate": false, + "failure": false, + "filesAdded": 0, + "filesRemoved": 0, + "filesUnmatched": 0, + "filesUpdated": 0, + "matched": 0, + "total": 0, + "unchecked": 0, + "uncheckedKeysByFile": [], + "unmatched": 0, + "updated": 0 + }, + "startTime": 1552322034304, + "success": false, + "testResults": [ + { + "console": [ + { + "message": "I am bar", + "origin": "/path/to/my/test/__tests__/bar.test.js:5", + "type": "log" + }, + { + "message": "Some output here from a lib", + "origin": "/path/to/my/test/sample.js:3", + "type": "log" + } + ], + "failureMessage": null, + "numFailingTests": 0, + "numPassingTests": 1, + "numPendingTests": 0, + "numTodoTests": 0, + "perfStats": { + "end": 1552322035185, + "start": 1552322034769 + }, + "snapshot": { + "added": 0, + "fileDeleted": false, + "matched": 0, + "unchecked": 0, + "unmatched": 0, + "updated": 0, + "uncheckedKeys": [] + }, + "testFilePath": "/path/to/my/test/__tests__/bar.test.js", + "testResults": [ + { + "ancestorTitles": [ + "bar" + ], + "duration": 5, + "failureMessages": [], + "fullName": "bar should bar", + "location": null, + "numPassingAsserts": 0, + "status": "passed", + "title": "should bar" + } + ], + "sourceMaps": {}, + "skipped": false, + "leaks": false + }, + { + "console": [ + { + "message": "I am foo", + "origin": "/path/to/my/test/__tests__/foo.test.js:3", + "type": "log" + } + ], + "failureMessage": null, + "numFailingTests": 0, + "numPassingTests": 1, + "numPendingTests": 0, + "numTodoTests": 0, + "perfStats": { + "end": 1552322035238, + "start": 1552322035196 + }, + "snapshot": { + "added": 0, + "fileDeleted": false, + "matched": 0, + "unchecked": 0, + "unmatched": 0, + "updated": 0, + "uncheckedKeys": [] + }, + "testFilePath": "/path/to/my/test/__tests__/foo.test.js", + "testResults": [ + { + "ancestorTitles": [ + "foo" + ], + "duration": 1, + "failureMessages": [], + "fullName": "foo should foo", + "location": null, + "numPassingAsserts": 0, + "status": "passed", + "title": "should foo" + } + ], + "sourceMaps": {}, + "skipped": false, + "leaks": false + } + ], + "wasInterrupted": false +} diff --git a/__tests__/buildJsonResults.test.js b/__tests__/buildJsonResults.test.js index 1352a7e..cf53f99 100644 --- a/__tests__/buildJsonResults.test.js +++ b/__tests__/buildJsonResults.test.js @@ -170,4 +170,23 @@ describe('buildJsonResults', () => { expect(jsonResults.testsuites[1].testsuite[1].testcase[0]._attr.file).toBe('path/to/test/__tests__/foo.test.js'); }); + it('should show output of console if includeConsoleOutput is true', () => { + const reportWithConsoleOutput = require('../__mocks__/test-with-console-output.json'); + const jsonResults = buildJsonResults(reportWithConsoleOutput, '/', + Object.assign({}, constants.DEFAULT_OPTIONS, { + includeConsoleOutput: "true" + })); + + expect(jsonResults.testsuites[1].testsuite[1]['system-out']).toBeDefined(); + }); + + it('should NOT show output of console if includeConsoleOutput is not set or false', () => { + const reportWithConsoleOutput = require('../__mocks__/test-with-console-output.json'); + const jsonResults = buildJsonResults(reportWithConsoleOutput, '/', + Object.assign({}, constants.DEFAULT_OPTIONS, { + includeConsoleOutput: "false" + })); + + expect(jsonResults.testsuites[1].testsuite[1]['system-out']).not.toBeDefined(); + }); }); diff --git a/constants/index.js b/constants/index.js index 4721e7d..0344a16 100644 --- a/constants/index.js +++ b/constants/index.js @@ -13,6 +13,7 @@ module.exports = { JEST_JUNIT_TITLE: 'titleTemplate', JEST_JUNIT_ANCESTOR_SEPARATOR: 'ancestorSeparator', JEST_JUNIT_ADD_FILE_ATTRIBUTE: 'addFileAttribute', + JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT: 'includeConsoleOutput', JEST_USE_PATH_FOR_SUITE_NAME: 'usePathForSuiteName', }, DEFAULT_OPTIONS: { @@ -26,6 +27,7 @@ module.exports = { ancestorSeparator: ' ', usePathForSuiteName: 'false', addFileAttribute: 'false', + includeConsoleOutput: 'false', }, CLASSNAME_VAR: 'classname', FILENAME_VAR: 'filename', diff --git a/package.json b/package.json index 27204d6..3117c0b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ ], "scripts": { "test": "jest", - "pretest:ci": "npm install jest@$JEST_VERSION", + "pretest:ci": "npm uninstall jest babel-jest && npm install jest@$JEST_VERSION babel-jest@$JEST_VERSION --no-save", "test:ci": "jest --ci" }, "dependencies": { diff --git a/utils/buildJsonResults.js b/utils/buildJsonResults.js index 242b29a..92c96a4 100644 --- a/utils/buildJsonResults.js +++ b/utils/buildJsonResults.js @@ -101,6 +101,20 @@ module.exports = function (report, appDirectory, options) { jsonResults.testsuites[0]._attr.failures += suite.numFailingTests; jsonResults.testsuites[0]._attr.tests += suiteNumTests; + // Write stdout console output if available + if (options.includeConsoleOutput === 'true' && suite.console && suite.console.length) { + // Stringify the entire console object + // Easier this way because formatting in a readable way is tough with XML + // And this can be parsed more easily + let testSuiteConsole = { + 'system-out': { + _cdata: JSON.stringify(suite.console, null, 2) + } + }; + + testSuite.testsuite.push(testSuiteConsole); + } + // Iterate through test cases suite.testResults.forEach((tc) => { const classname = tc.ancestorTitles.join(options.ancestorSeparator); @@ -153,4 +167,4 @@ module.exports = function (report, appDirectory, options) { }); return jsonResults; -}; \ No newline at end of file +};