Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions messages/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@ ID of the test run.
# flags.detailed-coverage.summary

Not available for flow tests.

# flags.wait.summary

Sets the streaming client socket timeout in minutes; specify a longer wait time if timeouts occur frequently.
4 changes: 2 additions & 2 deletions messages/flow.run.test.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Specify which tests to run by using the --class-names flag followed by the names

To see code coverage results, use the --code-coverage flag with --result-format. The output displays a high-level summary of the test run and the code coverage values for classes in your org. If you specify human-readable result format, use the --detailed-coverage flag to see detailed coverage results for each test method run.

By default, "flow run test" runs asynchronously and immediately returns a test run ID. If you use the -synchronous flag, you can use the --wait flag to specify the number of minutes to wait; if the tests finish in that timeframe, the command displays the results. If the tests haven't finished by the end of the wait time, the command displays a test run ID. Use the "flow get test --test-run-id" command to get the results.
By default, "flow run test" runs asynchronously and immediately returns a test run ID. If you use the --synchronous flag, you can use the --wait flag to specify the number of minutes to wait; if the tests finish in that timeframe, the command displays the results. If the tests haven't finished by the end of the wait time, the command displays a test run ID. Use the "flow get test --test-run-id" command to get the results.

You must have the "View All Data" org system permission to use this command. The permission is disabled by default and can be enabled only by a system administrator.

Expand All @@ -24,7 +24,7 @@ You must have the "View All Data" org system permission to use this command. The
<%= config.bin %> <%= command.id %> --tests Flow1.Test1 --tests Flow2.Test2 --test-level RunSpecifiedTests

- Run all tests synchronously in your default org; the command waits to display the test results until all tests finish:
<%= config.bin %> <%= command.id %> synchronous
<%= config.bin %> <%= command.id %> --synchronous

- Run all local tests in the org with the username “[email protected]”; save the output to the specified directory:
<%= config.bin %> <%= command.id %> --test-level RunLocalTests --output-dir /Users/susan/temp/cliOutput --target-org [email protected]
Expand Down
2 changes: 2 additions & 0 deletions src/commands/flow/run/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
classNamesFlag,
suiteNamesFlag,
testsFlag,
waitFlag,
} from '../../../flags.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
Expand All @@ -53,6 +54,7 @@ export default class FlowRunTest extends SfCommand<FlowRunTestResult> {
'class-names': classNamesFlag,
'suite-names': suiteNamesFlag,
tests: testsFlag,
wait: waitFlag,
};
protected cancellationTokenSource = new CancellationTokenSource();

Expand Down
7 changes: 7 additions & 0 deletions src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,10 @@ export const detailedCoverageSummaryFlag = Flags.boolean({
summary: messages.getMessage('flags.detailed-coverage.summary'),
dependsOn: ['code-coverage'],
});

export const waitFlag = Flags.duration({
unit: 'minutes',
char: 'w',
summary: messages.getMessage('flags.wait.summary'),
min: 0,
});
37 changes: 28 additions & 9 deletions test/commands/flow/run/test.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,52 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import path from 'node:path';
import { join } from 'node:path';
import fs from 'node:fs';
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
import { config } from 'chai';

import { expect, config } from 'chai';
config.truncateThreshold = 0;

describe('flow run test', () => {
let session: TestSession;
before(async () => {
session = await TestSession.create({
project: {
gitClone: 'https://github.com/trailheadapps/dreamhouse-lwc.git',
},
project: { sourceDir: join('test', 'mock-projects', 'flow-run-template') },
devhubAuthStrategy: 'AUTO',
scratchOrgs: [
{
config: path.join('config', 'project-scratch-def.json'),
config: join('config', 'project-scratch-def.json'),
setDefault: true,
alias: 'org',
},
],
});
execCmd('project:deploy:start -o org --source-dir force-app', { ensureExitCode: 0, cli: 'sf' });

execCmd('project deploy start -o org --source-dir force-app', { ensureExitCode: 0, cli: 'sf' });
});

after(async () => {
await session?.zip(undefined, 'artifacts');
await session?.clean();
});

describe('--result-format', () => {
it('will print tap format', async () => {
const result = execCmd('flow run test --result-format tap --wait 400', { ensureExitCode: 0 }).shellOutput.stdout;
expect(result).to.include('1..1');
expect(result).to.include('ok 1');
expect(result).to.include('--result-format <format>" to retrieve test results in a different format.');
});
});

it('will create --output-dir', () => {
const result = execCmd('flow run test --output-dir testresults --code-coverage --wait 100', { ensureExitCode: 0 })
.shellOutput.stdout;
expect(result).to.include('Test result files written to testresults');
const outputDir = join(session.project.dir, 'testresults');
expect(fs.statSync(outputDir).isDirectory()).to.be.true;
expect(fs.readdirSync(outputDir).length).to.equal(6);
expect(fs.existsSync(join(outputDir, 'test-result-codecoverage.json'))).to.be.true;
expect(fs.existsSync(join(outputDir, 'test-result.txt'))).to.be.true;
expect(fs.existsSync(join(outputDir, 'test-run-id.txt'))).to.be.true;
});
});
16 changes: 16 additions & 0 deletions test/mock-projects/flow-run-template/.forceignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status

# More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm

#

package.xml

# LWC configuration files

**/jsconfig.json
**/.eslintrc.json

# LWC Jest

**/__tests__/**
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"orgName": "flowtest company",
"edition": "Developer",
"features": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>64.0</apiVersion>
<areMetricsLoggedToDataCloud>false</areMetricsLoggedToDataCloud>
<environments>Default</environments>
<interviewLabel>Flow1 {!$Flow.CurrentDateTime}</interviewLabel>
<label>Flow1</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>AutoLaunchedFlow</processType>
<recordUpdates>
<name>updateAccount</name>
<label>updateAccount</label>
<locationX>0</locationX>
<locationY>0</locationY>
<inputAssignments>
<field>Description</field>
<value>
<stringValue>Test</stringValue>
</value>
</inputAssignments>
<inputReference>$Record</inputReference>
</recordUpdates>
<start>
<locationX>0</locationX>
<locationY>0</locationY>
<connector>
<targetReference>updateAccount</targetReference>
</connector>
<object>Account</object>
<recordTriggerType>Create</recordTriggerType>
<triggerType>RecordAfterSave</triggerType>
</start>
<status>Draft</status>
</Flow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<FlowTest xmlns="http://soap.sforce.com/2006/04/metadata">
<flowApiName>Flow1</flowApiName>
<label>test</label>
<testPoints>
<elementApiName>Start</elementApiName>
<parameters>
<leftValueReference>$Record</leftValueReference>
<type>InputTriggeringRecordInitial</type>
<value>
<sobjectValue>{&quot;Name&quot;:&quot;FlowTestAccount1&quot;,&quot;OwnerId&quot;:&quot;005xx000001X7qfAAC&quot;}</sobjectValue>
</value>
</parameters>
</testPoints>
<testPoints>
<assertions>
<conditions>
<leftValueReference>updateAccount</leftValueReference>
<operator>HasError</operator>
<rightValue>
<booleanValue>false</booleanValue>
</rightValue>
</conditions>
</assertions>
<elementApiName>Finish</elementApiName>
</testPoints>
</FlowTest>
12 changes: 12 additions & 0 deletions test/mock-projects/flow-run-template/sfdx-project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"packageDirectories": [
{
"path": "force-app",
"default": true
}
],
"name": "flow-run-template",
"namespace": "",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "64.0"
}
Loading