diff --git a/packages/bruno-cli/src/reporters/junit.js b/packages/bruno-cli/src/reporters/junit.js index 30fb51939e..9238e49287 100644 --- a/packages/bruno-cli/src/reporters/junit.js +++ b/packages/bruno-cli/src/reporters/junit.js @@ -23,9 +23,32 @@ const makeJUnitOutput = async (results, outputPath) => { '@timestamp': new Date().toISOString().split('Z')[0], '@hostname': os.hostname(), '@time': result.runtime.toFixed(3), + 'system-out': { '#cdata': `> ${result.request.method} ${result.request.url}\n` }, testcase: [] }; + if (result.request.headers) { + Object.entries(result.request.headers).forEach((header) => { + suite['system-out']['#cdata'] += `> ${header[0]}: ${header[1]}\n`; + }); + } + suite['system-out']['#cdata'] += '>\n'; + + if (result.response && result.response.status) { + suite['system-out']['#cdata'] += `< ${result.response.status} ${result.response.statusText}\n`; + if (result.response.headers) { + Object.entries(result.response.headers).forEach((header) => { + suite['system-out']['#cdata'] += `< ${header[0]}: ${header[1]}\n`; + }); + } + suite['system-out']['#cdata'] += '<\n'; + + if (result.response.data) { + suite['system-out']['#cdata'] += + typeof result.response.data === 'string' ? result.response.data : JSON.stringify(result.response.data); + } + } + result.assertionResults && result.assertionResults.forEach((assertion) => { const testcase = { @@ -79,7 +102,7 @@ const makeJUnitOutput = async (results, outputPath) => { output.testsuites.testsuite.push(suite); }); - fs.writeFileSync(outputPath, xmlbuilder.create(output).end({ pretty: true })); + fs.writeFileSync(outputPath, xmlbuilder.create(output, { invalidCharReplacement: ' ' }).end({ pretty: true })); }; module.exports = makeJUnitOutput; diff --git a/packages/bruno-cli/tests/reporters/junit.spec.js b/packages/bruno-cli/tests/reporters/junit.spec.js index 5d2154a881..477e918248 100644 --- a/packages/bruno-cli/tests/reporters/junit.spec.js +++ b/packages/bruno-cli/tests/reporters/junit.spec.js @@ -25,7 +25,18 @@ describe('makeJUnitOutput', () => { suitename: 'Tests/Suite A', request: { method: 'GET', - url: 'https://ima.test' + url: 'https://ima.test', + headers: { + Authorization: 'Bearer your_secret_token' + } + }, + response: { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': 'text/plain; charset=utf-8' + }, + data: 'I am the response content' }, assertionResults: [ { @@ -73,6 +84,15 @@ describe('makeJUnitOutput', () => { expect(junit.testsuites).toBeDefined; expect(junit.testsuites.testsuite.length).toBe(2); + expect(junit.testsuites.testsuite[0]['system-out']['#cdata']).toContain('> GET https://ima.test'); + expect(junit.testsuites.testsuite[0]['system-out']['#cdata']).toContain( + '> Authorization: Bearer your_secret_token' + ); + expect(junit.testsuites.testsuite[0]['system-out']['#cdata']).toContain('< 200 OK'); + expect(junit.testsuites.testsuite[0]['system-out']['#cdata']).toContain( + '< Content-Type: text/plain; charset=utf-8' + ); + expect(junit.testsuites.testsuite[0]['system-out']['#cdata']).toContain('I am the response content'); expect(junit.testsuites.testsuite[0].testcase.length).toBe(2); expect(junit.testsuites.testsuite[1].testcase.length).toBe(2);