Skip to content

Commit

Permalink
Merge pull request #38 from salesforcecli/mdonnalley/junit
Browse files Browse the repository at this point in the history
feat: support junit test formatter
  • Loading branch information
shetzel authored Dec 10, 2024
2 parents 3999aca + 1914956 commit 0af5887
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 30 deletions.
22 changes: 16 additions & 6 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,34 @@
"alias": [],
"command": "agent:test:results",
"flagAliases": [],
"flagChars": ["i", "o"],
"flags": ["api-version", "flags-dir", "job-id", "json", "result-format", "target-org"],
"flagChars": ["f", "i", "o"],
"flags": ["api-version", "flags-dir", "job-id", "json", "output-dir", "result-format", "target-org"],
"plugin": "@salesforce/plugin-agent"
},
{
"alias": [],
"command": "agent:test:resume",
"flagAliases": [],
"flagChars": ["i", "o", "r", "w"],
"flags": ["api-version", "flags-dir", "job-id", "json", "result-format", "target-org", "use-most-recent", "wait"],
"flagChars": ["f", "i", "o", "r", "w"],
"flags": [
"api-version",
"flags-dir",
"job-id",
"json",
"output-dir",
"result-format",
"target-org",
"use-most-recent",
"wait"
],
"plugin": "@salesforce/plugin-agent"
},
{
"alias": [],
"command": "agent:test:run",
"flagAliases": [],
"flagChars": ["n", "o", "w"],
"flags": ["api-version", "flags-dir", "json", "name", "result-format", "target-org", "wait"],
"flagChars": ["f", "n", "o", "w"],
"flags": ["api-version", "flags-dir", "json", "name", "output-dir", "result-format", "target-org", "wait"],
"plugin": "@salesforce/plugin-agent"
}
]
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.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@inquirer/select": "^4.0.1",
"@oclif/core": "^4",
"@oclif/multi-stage-output": "^0.7.12",
"@salesforce/agents": "^0.3.0",
"@salesforce/agents": "^0.4.0",
"@salesforce/core": "^8.8.0",
"@salesforce/kit": "^3.2.1",
"@salesforce/sf-plugins-core": "^12.1.0",
Expand Down
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'),
});
62 changes: 62 additions & 0 deletions src/handleTestResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 { join } from 'node:path';
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(join(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);
}
}
}
Loading

0 comments on commit 0af5887

Please sign in to comment.