Skip to content

Commit

Permalink
feat: junit result formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Dec 9, 2024
1 parent 3999aca commit af485da
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 16 deletions.
8 changes: 8 additions & 0 deletions messages/shared.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# flags.result-format.summary

Format of the test run results.

# flags.output-dir.summary

Directory to write the test results to.

# flags.output-dir.description

If test run is complete, write the results to the specified directory. If the tests are still running, the test results will not be written.
16 changes: 11 additions & 5 deletions src/commands/agent/test/results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { AgentTester, AgentTestDetailsResponse, humanFormat } from '@salesforce/agents';
import { resultFormatFlag } from '../../../flags.js';
import { AgentTester, AgentTestDetailsResponse } from '@salesforce/agents';
import { resultFormatFlag, testOutputDirFlag } from '../../../flags.js';
import { handleTestResults } from '../../../handleTestResults.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.test.results');
Expand All @@ -30,16 +31,21 @@ export default class AgentTestResults extends SfCommand<AgentTestResultsResult>
required: true,
}),
'result-format': resultFormatFlag(),
'output-dir': testOutputDirFlag(),
};

public async run(): Promise<AgentTestResultsResult> {
const { flags } = await this.parse(AgentTestResults);

const agentTester = new AgentTester(flags['target-org'].getConnection(flags['api-version']));
const response = await agentTester.details(flags['job-id']);
if (flags['result-format'] === 'human') {
this.log(await humanFormat(flags['job-id'], response));
}
await handleTestResults({
id: flags['job-id'],
format: flags['result-format'],
results: response,
jsonEnabled: this.jsonEnabled(),
outputDir: flags['output-dir'],
});
return response;
}
}
16 changes: 11 additions & 5 deletions src/commands/agent/test/resume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { AgentTester, humanFormat } from '@salesforce/agents';
import { AgentTester } from '@salesforce/agents';
import { AgentTestCache } from '../../../agentTestCache.js';
import { TestStages } from '../../../testStages.js';
import { resultFormatFlag } from '../../../flags.js';
import { resultFormatFlag, testOutputDirFlag } from '../../../flags.js';
import { handleTestResults } from '../../../handleTestResults.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.test.resume');
Expand Down Expand Up @@ -48,6 +49,7 @@ export default class AgentTestResume extends SfCommand<AgentTestResumeResult> {
description: messages.getMessage('flags.wait.description'),
}),
'result-format': resultFormatFlag(),
'output-dir': testOutputDirFlag(),
};

public async run(): Promise<AgentTestResumeResult> {
Expand All @@ -68,9 +70,13 @@ export default class AgentTestResume extends SfCommand<AgentTestResumeResult> {

mso.stop();

if (response && flags['result-format'] === 'human') {
this.log(await humanFormat(name ?? aiEvaluationId, response));
}
await handleTestResults({
id: aiEvaluationId,
format: flags['result-format'],
results: response,
jsonEnabled: this.jsonEnabled(),
outputDir: flags['output-dir'],
});

return {
status: 'COMPLETED',
Expand Down
17 changes: 12 additions & 5 deletions src/commands/agent/test/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@

import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { AgentTester, humanFormat } from '@salesforce/agents';
import { AgentTester } from '@salesforce/agents';
import { colorize } from '@oclif/core/ux';
import { resultFormatFlag } from '../../../flags.js';
import { resultFormatFlag, testOutputDirFlag } from '../../../flags.js';
import { AgentTestCache } from '../../../agentTestCache.js';
import { TestStages } from '../../../testStages.js';
import { handleTestResults } from '../../../handleTestResults.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.test.run');
Expand Down Expand Up @@ -47,6 +48,7 @@ export default class AgentTestRun extends SfCommand<AgentTestRunResult> {
description: messages.getMessage('flags.wait.description'),
}),
'result-format': resultFormatFlag(),
'output-dir': testOutputDirFlag(),
};

public async run(): Promise<AgentTestRunResult> {
Expand All @@ -69,9 +71,14 @@ export default class AgentTestRun extends SfCommand<AgentTestRunResult> {

mso.stop();

if (detailsResponse && flags['result-format'] === 'human') {
this.log(await humanFormat(flags.name, detailsResponse));
}
await handleTestResults({
id: response.aiEvaluationId,
format: flags['result-format'],
results: detailsResponse,
jsonEnabled: this.jsonEnabled(),
outputDir: flags['output-dir'],
});

return {
status: 'COMPLETED',
aiEvaluationId: response.aiEvaluationId,
Expand Down
8 changes: 7 additions & 1 deletion src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ export const resultFormatFlag = Flags.option({
options: [
'json',
'human',
'junit',
// 'tap',
// 'junit'
] as const,
default: 'human',
summary: messages.getMessage('flags.result-format.summary'),
});

export const testOutputDirFlag = Flags.custom<string>({
char: 'f',
description: messages.getMessage('flags.output-dir.description'),
summary: messages.getMessage('flags.output-dir.summary'),
});
61 changes: 61 additions & 0 deletions src/handleTestResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2024, 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 { writeFile, mkdir } from 'node:fs/promises';
import { AgentTestDetailsResponse, jsonFormat, humanFormat, junitFormat } from '@salesforce/agents';
import { Ux } from '@salesforce/sf-plugins-core/Ux';

async function writeFileToDir(outputDir: string, fileName: string, content: string): Promise<void> {
// if directory doesn't exist, create it
await mkdir(outputDir, { recursive: true });

await writeFile(`${outputDir}/${fileName}`, content);
}

export async function handleTestResults({
id,
format,
results,
jsonEnabled,
outputDir,
}: {
id: string;
format: 'human' | 'json' | 'junit';
results: AgentTestDetailsResponse | undefined;
jsonEnabled: boolean;
outputDir?: string;
}): Promise<void> {
if (!results) {
// do nothing since there are no results to handle
return;
}

const ux = new Ux({ jsonEnabled });

if (format === 'human') {
const formatted = await humanFormat(results);
ux.log(formatted);
if (outputDir) {
await writeFileToDir(outputDir, `test-result-${id}.txt`, formatted);
}
}

if (format === 'json') {
const formatted = await jsonFormat(results);
ux.log(formatted);
if (outputDir) {
await writeFileToDir(outputDir, `test-result-${id}.json`, formatted);
}
}

if (format === 'junit') {
const formatted = await junitFormat(results);
ux.log(formatted);
if (outputDir) {
await writeFileToDir(outputDir, `test-result-${id}.xml`, formatted);
}
}
}

0 comments on commit af485da

Please sign in to comment.