@salesforce/plugin-apex
Version:
166 lines • 6.99 kB
JavaScript
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { HumanReporter, JUnitReporter, ResultFormat, TapReporter, TestService, } from '@salesforce/apex-node';
import { Messages } from '@salesforce/core';
import { JsonReporter } from './jsonReporter.js';
const FAILURE_EXIT_CODE = 100;
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'runtest');
export class TestReporter {
ux;
connection;
/**
* Create a TestReporter that will format test results
*
* @param ux a new Ux instance based on if the command is in json mode
* @param connection a connection to the org the tests are being run against - used for getting username for hints
*/
constructor(ux, connection) {
this.ux = ux;
this.connection = connection;
}
async report(result, options) {
if (options['output-dir']) {
const jsonOutput = this.formatResultInJson(result);
const outputDirConfig = this.buildOutputDirConfig(result, jsonOutput, options['output-dir'], options['result-format'], Boolean(options['detailed-coverage']), options.concise, options.synchronous);
const testService = new TestService(this.connection);
await testService.writeResultFiles(result, outputDirConfig, options['code-coverage']);
}
try {
if (result.summary && result.summary.outcome === 'Failed') {
process.exitCode = FAILURE_EXIT_CODE;
}
switch (options['result-format']) {
case 'human':
this.logHuman(result, options['detailed-coverage'], options['concise'], options['output-dir']);
break;
case 'tap':
this.logTap(result);
break;
case 'junit':
this.logJUnit(result);
break;
case 'json':
// when --json flag is specified, we should log CLI json format
if (!options.json) {
this.ux.styledJSON({
status: process.exitCode,
result: this.formatResultInJson(result),
});
}
break;
default:
this.logHuman(result, options['detailed-coverage'], options['concise'], options['output-dir']);
}
}
catch (e) {
this.ux.styledJSON(result);
throw messages.createError('testResultProcessErr', [e.message]);
}
return this.formatResultInJson(result);
}
/**
* Builds output directory configuration with CLI format result files
*
* @param result Test results from async/sync test run
* @param jsonOutput JSON CLI format of test results
* @param outputDir Output directory for result files
* @param resultFormat Result format for output files
* @param detailedCoverage Boolean to control detailed coverage reporting
* @param synchronous Whether the test run was synchronous
* @returns Output directory configuration
*/
// eslint-disable-next-line class-methods-use-this
buildOutputDirConfig(result, jsonOutput, outputDir, resultFormat, detailedCoverage, concise, synchronous = false) {
const outputDirConfig = {
dirPath: outputDir,
};
if ('summary' in result) {
jsonOutput = jsonOutput;
if (typeof resultFormat !== 'undefined' || synchronous) {
outputDirConfig.fileInfos = [
{
filename: result.summary.testRunId ? `test-result-${result.summary.testRunId}.json` : 'test-result.json',
content: jsonOutput,
},
...(jsonOutput.coverage
? [
{
filename: 'test-result-codecoverage.json',
content: jsonOutput.coverage?.coverage,
},
]
: []),
];
outputDirConfig.resultFormats = [ResultFormat.junit];
}
if (typeof resultFormat === 'undefined' && synchronous) {
resultFormat = ResultFormat.human;
}
switch (resultFormat) {
case ResultFormat.tap:
outputDirConfig.fileInfos?.push({
filename: 'test-result.txt',
content: new TapReporter().format(result),
});
outputDirConfig.resultFormats?.push(ResultFormat.tap);
break;
case ResultFormat.junit:
outputDirConfig.fileInfos?.push({
filename: 'test-result.xml',
content: new JUnitReporter().format(result),
});
break;
case ResultFormat.human:
outputDirConfig.fileInfos?.push({
filename: 'test-result.txt',
content: new HumanReporter().format(result, detailedCoverage, concise),
});
break;
default:
break;
}
}
return outputDirConfig;
}
formatResultInJson(result) {
try {
const reporter = new JsonReporter();
return reporter.format(result);
}
catch (e) {
this.ux.styledJSON(result);
throw messages.createError('testResultProcessErr', [e.message]);
}
}
logHuman(result, detailedCoverage, concise, outputDir) {
if (outputDir) {
this.ux.log(messages.getMessage('outputDirHint', [outputDir]));
}
const humanReporter = new HumanReporter();
const output = humanReporter.format(result, detailedCoverage, concise);
this.ux.log(output);
}
logTap(result) {
const reporter = new TapReporter();
const hint = this.formatReportHint(result);
this.ux.log(reporter.format(result, [hint]));
}
logJUnit(result) {
const reporter = new JUnitReporter();
this.ux.log(reporter.format(result));
}
formatReportHint(result) {
let reportArgs = `-i ${result.summary.testRunId}`;
const username = this.connection?.getUsername();
if (username) {
reportArgs += ` -o ${username}`;
}
return messages.getMessage('apexTestReportFormatHint', [reportArgs]);
}
}
//# sourceMappingURL=testReporter.js.map