Skip to content

Commit

Permalink
Merge pull request #230 from stevenxu-db/escape-fix
Browse files Browse the repository at this point in the history
Remove invalid ESC control sequence from XML output
  • Loading branch information
palmerj3 authored Nov 18, 2022
2 parents ff4efe6 + 862b858 commit 22db501
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
68 changes: 68 additions & 0 deletions __mocks__/failing-tests-with-esc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"numFailedTestSuites": 0,
"numFailedTests": 0,
"numPassedTestSuites": 1,
"numPassedTests": 1,
"numPendingTestSuites": 0,
"numPendingTests": 0,
"numRuntimeErrorTestSuites": 0,
"numTotalTestSuites": 1,
"numTotalTests": 1,
"snapshot": {
"added": 0,
"failure": false,
"filesAdded": 0,
"filesRemoved": 0,
"filesUnmatched": 0,
"filesUpdated": 0,
"matched": 0,
"total": 0,
"unchecked": 0,
"unmatched": 0,
"updated": 0
},
"startTime": 1489712747092,
"success": true,
"testResults": [
{
"console": [],
"failureMessage": "\u001b[1m\u001b[31m \u001b[1m● \u001b[1mSample Failing Test › Should fail\u001b[39m\u001b[22m\n\n foo\u001bbar\n\u001b[2m \n \u001b[2mat _callee$ (\u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:26:15)\u001b[2m\n \u001b[2mat tryCatch (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:64:40)\u001b[2m\n \u001b[2mat GeneratorFunctionPrototype.invoke [as _invoke] (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:299:22)\u001b[2m\n \u001b[2mat GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:116:21)\u001b[2m\n \u001b[2mat step (\u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:2:394)\u001b[2m\n \u001b[2mat \u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:2:554\u001b[2m\u001b[22m\n",
"numFailingTests": 1,
"numPassingTests": 0,
"numPendingTests": 0,
"perfStats": {
"end": 1499904221109,
"start": 1499904215586
},
"snapshot": {
"added": 0,
"fileDeleted": false,
"matched": 0,
"unchecked": 0,
"unmatched": 0,
"updated": 0
},
"testFilePath": "/path/to/failing.test.js",
"testResults": [
{
"ancestorTitles": [
"Sample Failing Test",
"Inner",
"Inner Inner"
],
"duration": 3930,
"failureMessages": [
"\u001b[1m\u001b[31m \u001b[1m● \u001b[1mSample Failing Test › Inner › Inner Inner › Should fail\u001b[39m\u001b[22m\n\n foo\u001bbar\n\u001b[2m \n \u001b[2mat _callee$ (\u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:26:15)\u001b[2m\n \u001b[2mat tryCatch (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:64:40)\u001b[2m\n \u001b[2mat GeneratorFunctionPrototype.invoke [as _invoke] (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:299:22)\u001b[2m\n \u001b[2mat GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (\u001b[2m\u001b[0m\u001b[36mnode_modules/regenerator-runtime/runtime.js\u001b[39m\u001b[0m\u001b[2m:116:21)\u001b[2m\n \u001b[2mat step (\u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:2:394)\u001b[2m\n \u001b[2mat \u001b[2m\u001b[0m\u001b[36mpath/to/failing.test.js\u001b[39m\u001b[0m\u001b[2m:2:554\u001b[2m\u001b[22m\n"
],
"fullName": "Sample Failing Test Inner Inner Inner Should fail",
"numPassingAsserts": 0,
"status": "failed",
"title": "Should fail"
}
],
"sourceMaps": {},
"skipped": false
}
],
"wasInterrupted": false
}
31 changes: 30 additions & 1 deletion __tests__/testResultProcessor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,22 @@ const path = require('path');
const testResultProcessor = require('../');

describe('jest-junit', () => {
beforeEach(() => {
const foundKeys = Object.keys(process.env).filter(k => k.startsWith('JEST_JUNIT'));
if (foundKeys.length > 0) {
throw new Error(`process.env should not have JEST_JUNIT keys set. Found: ${foundKeys.join(', ')}`);
}
});

afterEach(() => {
jest.clearAllMocks();

afterEach(() => jest.clearAllMocks())
for (let key in process.env) {
if (key.startsWith('JEST_JUNIT')) {
delete process.env[key];
}
}
});

it('should generate valid xml with default name', () => {
const noFailingTestsReport = require('../__mocks__/no-failing-tests.json');
Expand Down Expand Up @@ -67,6 +81,20 @@ describe('jest-junit', () => {
expect(xmlDoc).toBeTruthy();
});

it('should generate valid xml despite illegal characters', () => {
const failingTestsWithEscReport = require('../__mocks__/failing-tests-with-esc.json');
testResultProcessor(failingTestsWithEscReport);

// Ensure fs.writeFileSync is called
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);

// Ensure file would have been generated
expect(fs.writeFileSync).toHaveBeenLastCalledWith(path.resolve('junit.xml'), expect.any(String));

// Ensure generated file is valid xml
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'
Expand All @@ -83,6 +111,7 @@ describe('jest-junit', () => {
});

it('should generate xml at the output filepath defined by outputFile config', () => {
process.env.JEST_JUNIT_OUTPUT_FILE = 'path_to_output/output_name.xml'
const noFailingTestsReport = require('../__mocks__/no-failing-tests.json');
testResultProcessor(noFailingTestsReport, {outputFile: 'path_to_output/output_name.xml' });

Expand Down
7 changes: 6 additions & 1 deletion utils/buildJsonResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const generateTestCase = function(junitOptions, suiteOptions, tc, filepath, file
failureMessages.forEach((failure) => {
const tagName = tc.status === testFailureStatus ? 'failure': testErrorStatus
testCase.testcase.push({
[tagName]: stripAnsi(failure)
[tagName]: strip(failure)
});
})
}
Expand Down Expand Up @@ -102,6 +102,11 @@ const addErrorTestResult = function (suite) {
})
}

// Strips escape codes for readability and illegal XML characters to produce valid output.
const strip = function (str) {
return stripAnsi(str).replace(/\u001b/g, '');
}

module.exports = function (report, appDirectory, options, rootDir = null) {
// Check if there is a junitProperties.js (or whatever they called it)
const junitSuitePropertiesFilePath = getTestSuitePropertiesPath(
Expand Down

0 comments on commit 22db501

Please sign in to comment.