Skip to content

Commit

Permalink
Ensure that the xunit reporter emits well-formed XML
Browse files Browse the repository at this point in the history
XML does not allow certain characters to appear in documents. This
change ensures that those restricted characters are replaced by legal
characters.

This bug means that when a test ends up containing, for example, ANSI
color codes (i.e. `[36m<div[39m`) then the generated
XML file is invalid and some consumers (such as CircleCI) are unable to
parse the contents.

Link: https://www.w3.org/TR/2006/REC-xml11-20060816/#charsets
  • Loading branch information
malloryavvir committed Jul 25, 2023
1 parent 37deed2 commit c953873
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/utils.js
Expand Up @@ -15,6 +15,7 @@ var util = require('util');
var he = require('he');

const MOCHA_ID_PROP_NAME = '__mocha_id__';
const RESTRICTED_CHAR = /[\x01-\x08\x0B-\x0C\x0E-\x1F\x7F-\x84\x86-\x9F]/g;

/**
* Inherit the prototype methods from one constructor into another.
Expand All @@ -35,6 +36,7 @@ exports.inherits = util.inherits;
* @return {string}
*/
exports.escape = function (html) {
html = html.toString().replaceAll(RESTRICTED_CHAR, "�");
return he.encode(String(html), {useNamedReferences: false});
};

Expand Down
39 changes: 39 additions & 0 deletions test/reporters/xunit.spec.js
Expand Up @@ -357,6 +357,45 @@ describe('XUnit reporter', function () {
expect(expectedWrite, 'to be', expectedTag);
});

it('should write well-formed XML', function () {
var xunit = new XUnit(runner);
var inputMessage = '\x1Bsome message';
expectedMessage = '�some message';
var expectedTest = {
state: STATE_FAILED,
title: expectedTitle,
parent: {
fullTitle: function () {
return expectedClassName;
}
},
duration: 1000,
err: {
actual: 'foo',
expected: 'bar',
message: inputMessage,
stack: expectedStack
}
};

xunit.test.call(fakeThis, expectedTest);
sinon.restore();

var expectedTag =
'<testcase classname="' +
expectedClassName +
'" name="' +
expectedTitle +
'" time="1"><failure>' +
expectedMessage +
'\n' +
expectedDiff +
'\n' +
expectedStack +
'</failure></testcase>';
expect(expectedWrite, 'to be', expectedTag);
});

it('should handle non-string diff values', function () {
var runner = new EventEmitter();
createStatsCollector(runner);
Expand Down

0 comments on commit c953873

Please sign in to comment.