@testrigor/testrigor-cli 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -1
- package/dist/commands/test-suite/run.js +9 -4
- package/dist/commands/test-suite/validate-syntax.d.ts +1 -0
- package/dist/commands/test-suite/validate-syntax.js +12 -4
- package/dist/util/parser.d.ts +1 -0
- package/dist/util/parser.js +34 -2
- package/npm-shrinkwrap.json +2 -2
- package/oclif.manifest.json +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,6 +57,22 @@ Or skip stored credentials entirely and set `TESTRIGOR_API_KEY`, or pass
|
|
|
57
57
|
23. Authenticate with TestRigor and store credentials (interactive prompt): `testrigor authenticate`
|
|
58
58
|
24. Run with override chrome extensions at runtime (one or more chrome extensions): `test-suite run <test-suite-id> --token <token> --chrome-extension "name=<extension-name> file=<extension-file>" --chrome-extension "name=<extension-name> file=<extension-file>"`
|
|
59
59
|
|
|
60
|
+
### Test case files
|
|
61
|
+
|
|
62
|
+
Each file passed with `--test-cases-path` is one test case, and its file name (without extension) becomes the test case name. `.txt` files contain only the steps. `.yaml` files support:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
testCaseUuid: 0f32d5b2-84aa-43ae-b8ae-17d4b33f114e # "uuid" is also accepted
|
|
66
|
+
customSteps: |
|
|
67
|
+
click "Sign in"
|
|
68
|
+
check that page contains "Welcome"
|
|
69
|
+
labels:
|
|
70
|
+
- smoke
|
|
71
|
+
datasetName: users
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
With a UUID, the existing test case is matched by UUID and updated, including its name if the file was renamed. Without one, test cases are matched by name. With `--explicit-mutations`, renaming a file that has no UUID deletes the old test case and creates a new one.
|
|
75
|
+
|
|
60
76
|
### Mobile Testing
|
|
61
77
|
|
|
62
78
|
Run mobile tests on your own local devices (emulators/simulators/real devices) using the same `--localhost` flag. The CLI auto-detects mobile suites and handles everything behind the scenes (mobile server, tunnel, configuration).
|
|
@@ -116,7 +132,188 @@ Pull requests to `master` must pass two CircleCI checks before they can be merge
|
|
|
116
132
|
npm version patch --no-git-tag-version
|
|
117
133
|
```
|
|
118
134
|
|
|
119
|
-
This updates the version in `package.json` and in both root entries of `package-lock.json` (`version` and `packages[""].version`). `--no-git-tag-version` stops npm from creating its own commit and `v*` tag. npm also runs the `version` script (`oclif readme && git add README.md`). That script loads the commands from `dist`, which is why you build first. It only rewrites README sections between oclif
|
|
135
|
+
This updates the version in `package.json` and in both root entries of `package-lock.json` (`version` and `packages[""].version`). `--no-git-tag-version` stops npm from creating its own commit and `v*` tag. npm also runs the `version` script (`oclif readme && git add README.md`). That script loads the commands from `dist`, which is why you build first. It only rewrites README sections between oclif markers such as `<!-- commands -->
|
|
136
|
+
* [`testrigor authenticate`](#testrigor-authenticate)
|
|
137
|
+
* [`testrigor help [COMMAND]`](#testrigor-help-command)
|
|
138
|
+
* [`testrigor test-suite config`](#testrigor-test-suite-config)
|
|
139
|
+
* [`testrigor test-suite run [TESTSUITEID]`](#testrigor-test-suite-run-testsuiteid)
|
|
140
|
+
* [`testrigor test-suite validate-syntax [TESTSUITEID]`](#testrigor-test-suite-validate-syntax-testsuiteid)
|
|
141
|
+
|
|
142
|
+
## `testrigor authenticate`
|
|
143
|
+
|
|
144
|
+
Set your testRigor authentication token
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
USAGE
|
|
148
|
+
$ testrigor authenticate [--token <value>]
|
|
149
|
+
|
|
150
|
+
FLAGS
|
|
151
|
+
--token=<value> API authentication token to store, instead of prompting for it
|
|
152
|
+
|
|
153
|
+
DESCRIPTION
|
|
154
|
+
Set your testRigor authentication token
|
|
155
|
+
|
|
156
|
+
EXAMPLES
|
|
157
|
+
$ testrigor authenticate
|
|
158
|
+
|
|
159
|
+
Prompts for your API authentication token
|
|
160
|
+
|
|
161
|
+
$ testrigor authenticate --token YOUR_TOKEN
|
|
162
|
+
|
|
163
|
+
Sets the token without prompting (for CI and scripts)
|
|
164
|
+
|
|
165
|
+
Use 'testrigor test-suite config' to set default test suite ID separately
|
|
166
|
+
|
|
167
|
+
Config will be stored in ~/.testrigor/testrigor.yml
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
_See code: [src/commands/authenticate.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.4/src/commands/authenticate.ts)_
|
|
171
|
+
|
|
172
|
+
## `testrigor help [COMMAND]`
|
|
173
|
+
|
|
174
|
+
Display help for testrigor.
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
USAGE
|
|
178
|
+
$ testrigor help [COMMAND...] [-n]
|
|
179
|
+
|
|
180
|
+
ARGUMENTS
|
|
181
|
+
[COMMAND...] Command to show help for.
|
|
182
|
+
|
|
183
|
+
FLAGS
|
|
184
|
+
-n, --nested-commands Include all nested commands in the output.
|
|
185
|
+
|
|
186
|
+
DESCRIPTION
|
|
187
|
+
Display help for testrigor.
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.3.0/src/commands/help.ts)_
|
|
191
|
+
|
|
192
|
+
## `testrigor test-suite config`
|
|
193
|
+
|
|
194
|
+
Configure test suite settings and default test suite ID
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
USAGE
|
|
198
|
+
$ testrigor test-suite config [--default <value> | --delete | --show]
|
|
199
|
+
|
|
200
|
+
FLAGS
|
|
201
|
+
--default=<value> Set the default test suite ID
|
|
202
|
+
--delete Remove the default test suite ID
|
|
203
|
+
--show Show current configuration
|
|
204
|
+
|
|
205
|
+
DESCRIPTION
|
|
206
|
+
Configure test suite settings and default test suite ID
|
|
207
|
+
|
|
208
|
+
EXAMPLES
|
|
209
|
+
$ testrigor test-suite config --default TEST-SUITE-ID
|
|
210
|
+
|
|
211
|
+
$ testrigor test-suite config --show
|
|
212
|
+
|
|
213
|
+
$ testrigor test-suite config --delete
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
_See code: [src/commands/test-suite/config.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.4/src/commands/test-suite/config.ts)_
|
|
217
|
+
|
|
218
|
+
## `testrigor test-suite run [TESTSUITEID]`
|
|
219
|
+
|
|
220
|
+
Run all tests of a Test Suite
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
USAGE
|
|
224
|
+
$ testrigor test-suite run [TESTSUITEID] [--auth-token <value>] [-t <value>] [--min-port <value>] [--max-port
|
|
225
|
+
<value>] [--verbose] [-w] [--branch <value> --commit <value>] [--localhost] [--url <value>]
|
|
226
|
+
[--junit-report-save-path <value>] [--variables-path <value>] [--test-cases-path <value>] [--rules-path <value>]
|
|
227
|
+
[--settings-path <value>] [--local-test-nodes-path <value>] [--test-case-uuid <value>...] [--auto-create-ai-rules]
|
|
228
|
+
[--explicit-mutations] [--labels <value>...] [--excluded-labels <value>...] [--base-url-web <value>] [--base-url-api
|
|
229
|
+
<value>] [--chrome-extension <value>... | --file-path <value>] [--xray-execution-key <value>]
|
|
230
|
+
|
|
231
|
+
ARGUMENTS
|
|
232
|
+
[TESTSUITEID] The test suite id (optional if set in config)
|
|
233
|
+
|
|
234
|
+
FLAGS
|
|
235
|
+
-w, --async Don't wait for the test suite to finish
|
|
236
|
+
--auto-create-ai-rules Enable auto create AI based rules
|
|
237
|
+
--base-url-api=<value> Base URL for API2 (e.g., https://api2.testrigor.com)
|
|
238
|
+
--base-url-web=<value> Base URL for web interface (e.g., https://app.testrigor.com)
|
|
239
|
+
--branch=<value> [env: TR_BRANCH] The branch name
|
|
240
|
+
--chrome-extension=<value>... Chrome extension: "name=EXT_NAME file=PATH_TO_CRX"
|
|
241
|
+
--commit=<value> [env: TR_COMMIT] The commit
|
|
242
|
+
--excluded-labels=<value>... Not run tests of specific labels
|
|
243
|
+
--explicit-mutations In cases where you are always using mutations, such as storing test cases in
|
|
244
|
+
your own repository, and you always send us the set of test cases you have
|
|
245
|
+
through our API you should send "--explicit-mutations"
|
|
246
|
+
--file-path=<value> Path to the file stored locally. It will upload the new file to be used. File
|
|
247
|
+
type should be according to the file type accepted for the Test Suite type of
|
|
248
|
+
testing. If the parameter --url is used, this parameter will be ignored.
|
|
249
|
+
--junit-report-save-path=<value> JUnit report save path
|
|
250
|
+
--labels=<value>... Run tests of specific labels
|
|
251
|
+
--local-test-nodes-path=<value> Path to a YAML or JSON file with local test nodes configuration
|
|
252
|
+
--localhost Localhost run (auto-detects web vs mobile)
|
|
253
|
+
--max-port=<value> [default: 50000] Max port for tunnel
|
|
254
|
+
--min-port=<value> [default: 40000] Min port for tunnel
|
|
255
|
+
--rules-path=<value> Rules path
|
|
256
|
+
--settings-path=<value> Settings path
|
|
257
|
+
--test-case-uuid=<value>... Test case uuid (can be repeated). Requires --url (web) or --file-path (mobile
|
|
258
|
+
app upload).
|
|
259
|
+
--test-cases-path=<value> Test cases files
|
|
260
|
+
--url=<value> The url
|
|
261
|
+
--variables-path=<value> Variables path
|
|
262
|
+
--xray-execution-key=<value> Reuse an existing Xray Cloud Test Execution by key (e.g. XR-123) instead of
|
|
263
|
+
creating a new one. Optional; leave blank to create a new execution.
|
|
264
|
+
|
|
265
|
+
GLOBAL FLAGS
|
|
266
|
+
-t, --token=<value> Suite authentication token
|
|
267
|
+
--auth-token=<value> Personal authentication token
|
|
268
|
+
--verbose Verbose output
|
|
269
|
+
|
|
270
|
+
DESCRIPTION
|
|
271
|
+
Run all tests of a Test Suite
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
_See code: [src/commands/test-suite/run.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.4/src/commands/test-suite/run.ts)_
|
|
275
|
+
|
|
276
|
+
## `testrigor test-suite validate-syntax [TESTSUITEID]`
|
|
277
|
+
|
|
278
|
+
Validate step syntax against a test suite's reusable rules, without running the steps
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
USAGE
|
|
282
|
+
$ testrigor test-suite validate-syntax [TESTSUITEID] [--auth-token <value>] [-t <value>] [--min-port <value>] [--max-port
|
|
283
|
+
<value>] [--verbose] [--steps <value> | --test-cases-path <value>] [--base-url-api <value>] [--rules-path <value>]
|
|
284
|
+
[--explicit-mutations] [--use-suite-parsing-mode]
|
|
285
|
+
|
|
286
|
+
ARGUMENTS
|
|
287
|
+
[TESTSUITEID] The test suite id (optional if set in config)
|
|
288
|
+
|
|
289
|
+
FLAGS
|
|
290
|
+
--base-url-api=<value> Base URL for API2 (e.g., https://api2.testrigor.com)
|
|
291
|
+
--explicit-mutations Validate using only the supplied rules instead of merging them with the suite's saved rules
|
|
292
|
+
--max-port=<value> [default: 50000] Max port for tunnel
|
|
293
|
+
--min-port=<value> [default: 40000] Min port for tunnel
|
|
294
|
+
--rules-path=<value> Ad hoc reusable rules to validate against, for rules not yet saved to this suite (same glob
|
|
295
|
+
format as `test-suite run --rules-path`)
|
|
296
|
+
--steps=<value> Raw step text to validate directly
|
|
297
|
+
--test-cases-path=<value> Test case files to validate (same glob format as `test-suite run --test-cases-path`)
|
|
298
|
+
--use-suite-parsing-mode Validate with the suite's own parsing mode setting instead of strict parsing
|
|
299
|
+
|
|
300
|
+
GLOBAL FLAGS
|
|
301
|
+
-t, --token=<value> Suite authentication token
|
|
302
|
+
--auth-token=<value> Personal authentication token
|
|
303
|
+
--verbose Verbose output
|
|
304
|
+
|
|
305
|
+
DESCRIPTION
|
|
306
|
+
Validate step syntax against a test suite's reusable rules, without running the steps
|
|
307
|
+
|
|
308
|
+
EXAMPLES
|
|
309
|
+
$ testrigor test-suite validate-syntax <test-suite-id> --steps "click \"Login\""
|
|
310
|
+
|
|
311
|
+
$ testrigor test-suite validate-syntax <test-suite-id> --test-cases-path "test_cases/**/*.{yaml,txt}"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
_See code: [src/commands/test-suite/validate-syntax.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.4/src/commands/test-suite/validate-syntax.ts)_
|
|
315
|
+
<!-- commandsstop -->`, so this README currently stays unchanged.
|
|
316
|
+
|
|
120
317
|
3. Check that the diff only touches the version fields, then build and test from the lockfile:
|
|
121
318
|
|
|
122
319
|
```
|
|
@@ -142,15 +142,20 @@ class Run extends command_base_1.CommandBase {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
if (testCasesPath) {
|
|
145
|
+
let testCases = [];
|
|
145
146
|
try {
|
|
146
|
-
|
|
147
|
-
if (testCases.length) {
|
|
148
|
-
context.configuration.baselineMutations = testCases;
|
|
149
|
-
}
|
|
147
|
+
testCases = await (0, parser_1.parseTestCases)(testCasesPath);
|
|
150
148
|
}
|
|
151
149
|
catch {
|
|
152
150
|
core_1.ux.error("--test-cases-path must be a valid JSON path");
|
|
153
151
|
}
|
|
152
|
+
const duplicateUuids = (0, parser_1.findDuplicateUuids)(testCases);
|
|
153
|
+
if (duplicateUuids.length) {
|
|
154
|
+
core_1.ux.error(`--test-cases-path has test cases sharing a UUID: ${duplicateUuids.join("; ")}`);
|
|
155
|
+
}
|
|
156
|
+
if (testCases.length) {
|
|
157
|
+
context.configuration.baselineMutations = testCases;
|
|
158
|
+
}
|
|
154
159
|
}
|
|
155
160
|
if (rulesPath) {
|
|
156
161
|
try {
|
|
@@ -9,6 +9,7 @@ export default class ValidateSyntax extends CommandBase<typeof ValidateSyntax> {
|
|
|
9
9
|
"base-url-api": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
"rules-path": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
"explicit-mutations": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
"use-suite-parsing-mode": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
13
|
};
|
|
13
14
|
static args: {
|
|
14
15
|
testSuiteId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
@@ -24,7 +24,8 @@ class ValidateSyntax extends command_base_1.CommandBase {
|
|
|
24
24
|
? await (0, parser_1.parseRules)(flags["rules-path"])
|
|
25
25
|
: [];
|
|
26
26
|
const explicitMutations = flags["explicit-mutations"];
|
|
27
|
-
|
|
27
|
+
const useSuiteParsingMode = flags["use-suite-parsing-mode"];
|
|
28
|
+
await this.reportValidationResults(testSuiteId, token, casesToValidate, rules, explicitMutations, useSuiteParsingMode);
|
|
28
29
|
}
|
|
29
30
|
async resolveStepsToValidate(steps, testCasesPath) {
|
|
30
31
|
if (steps) {
|
|
@@ -36,10 +37,10 @@ class ValidateSyntax extends command_base_1.CommandBase {
|
|
|
36
37
|
customSteps: testCase.customSteps,
|
|
37
38
|
}));
|
|
38
39
|
}
|
|
39
|
-
async reportValidationResults(testSuiteId, token, cases, rules, explicitMutations) {
|
|
40
|
+
async reportValidationResults(testSuiteId, token, cases, rules, explicitMutations, useSuiteParsingMode) {
|
|
40
41
|
let hasAnyInvalidTestCases = false;
|
|
41
42
|
for (const testCase of cases) {
|
|
42
|
-
const response = await this.callValidateSyntax(testSuiteId, testCase.customSteps, token, rules, explicitMutations);
|
|
43
|
+
const response = await this.callValidateSyntax(testSuiteId, testCase.customSteps, token, rules, explicitMutations, useSuiteParsingMode);
|
|
43
44
|
if (response.data && response.data.length > 0) {
|
|
44
45
|
const parserErrors = response.data;
|
|
45
46
|
core_2.ux.stdout(`${testCase.description}: invalid`);
|
|
@@ -58,7 +59,7 @@ class ValidateSyntax extends command_base_1.CommandBase {
|
|
|
58
59
|
core_2.ux.stdout("All provided steps are valid.");
|
|
59
60
|
this.exit(0);
|
|
60
61
|
}
|
|
61
|
-
async callValidateSyntax(testSuiteId, steps, token, rules, explicitMutations) {
|
|
62
|
+
async callValidateSyntax(testSuiteId, steps, token, rules, explicitMutations, useSuiteParsingMode) {
|
|
62
63
|
const body = { steps };
|
|
63
64
|
if (rules.length > 0) {
|
|
64
65
|
body.rules = rules;
|
|
@@ -66,6 +67,9 @@ class ValidateSyntax extends command_base_1.CommandBase {
|
|
|
66
67
|
if (explicitMutations) {
|
|
67
68
|
body.explicitMutations = explicitMutations;
|
|
68
69
|
}
|
|
70
|
+
if (useSuiteParsingMode) {
|
|
71
|
+
body.useSuiteParsingMode = useSuiteParsingMode;
|
|
72
|
+
}
|
|
69
73
|
const response = await fetch(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/validate-syntax`, {
|
|
70
74
|
method: "POST",
|
|
71
75
|
body: JSON.stringify(body),
|
|
@@ -105,6 +109,10 @@ ValidateSyntax.flags = {
|
|
|
105
109
|
description: "Validate using only the supplied rules instead of merging them with the suite's saved rules",
|
|
106
110
|
default: false,
|
|
107
111
|
}),
|
|
112
|
+
"use-suite-parsing-mode": core_1.Flags.boolean({
|
|
113
|
+
description: "Validate with the suite's own parsing mode setting instead of strict parsing",
|
|
114
|
+
default: false,
|
|
115
|
+
}),
|
|
108
116
|
};
|
|
109
117
|
ValidateSyntax.args = {
|
|
110
118
|
testSuiteId: core_1.Args.string({
|
package/dist/util/parser.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Rule, TestCase } from "../types";
|
|
2
2
|
export declare function parseTestCases(path: string): Promise<TestCase[]>;
|
|
3
|
+
export declare function findDuplicateUuids(testCases: TestCase[]): string[];
|
|
3
4
|
export declare function parseRules(path: string): Promise<Rule[]>;
|
|
4
5
|
export declare function parseSettings(path: string): Promise<object>;
|
package/dist/util/parser.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseTestCases = parseTestCases;
|
|
4
|
+
exports.findDuplicateUuids = findDuplicateUuids;
|
|
4
5
|
exports.parseRules = parseRules;
|
|
5
6
|
exports.parseSettings = parseSettings;
|
|
6
7
|
const tslib_1 = require("tslib");
|
|
8
|
+
const core_1 = require("@oclif/core");
|
|
7
9
|
const fs_1 = tslib_1.__importDefault(require("@supercharge/fs"));
|
|
8
10
|
const glob_1 = require("glob");
|
|
9
11
|
const yaml_1 = require("yaml");
|
|
10
12
|
const utils_1 = require("./utils");
|
|
13
|
+
function normalizeUuid(value) {
|
|
14
|
+
if (value == null) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const uuid = String(value).trim();
|
|
18
|
+
return uuid || undefined;
|
|
19
|
+
}
|
|
11
20
|
async function parseTestCases(path) {
|
|
12
21
|
const result = [];
|
|
13
22
|
const files = await (0, glob_1.glob)(path, { withFileTypes: true });
|
|
@@ -20,8 +29,18 @@ async function parseTestCases(path) {
|
|
|
20
29
|
customSteps: json.customSteps,
|
|
21
30
|
description: (0, utils_1.removeExtension)(file.name),
|
|
22
31
|
};
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
// "uuid" is the key used by exported test cases. Dropping it makes
|
|
33
|
+
// the backend match by description instead, which with explicit
|
|
34
|
+
// mutations deletes and recreates the test (TR-17226).
|
|
35
|
+
const testCaseUuid = normalizeUuid(json.testCaseUuid ?? json.uuid);
|
|
36
|
+
if (testCaseUuid) {
|
|
37
|
+
testCase.testCaseUuid = testCaseUuid;
|
|
38
|
+
}
|
|
39
|
+
const aliasUuid = normalizeUuid(json.uuid);
|
|
40
|
+
if (json.testCaseUuid != null &&
|
|
41
|
+
aliasUuid &&
|
|
42
|
+
aliasUuid !== testCaseUuid) {
|
|
43
|
+
core_1.ux.warn(`${file.name} has both "testCaseUuid" and "uuid"; using "testCaseUuid"`);
|
|
25
44
|
}
|
|
26
45
|
if (json.labels) {
|
|
27
46
|
testCase.labels = json.labels;
|
|
@@ -42,6 +61,19 @@ async function parseTestCases(path) {
|
|
|
42
61
|
}
|
|
43
62
|
return result;
|
|
44
63
|
}
|
|
64
|
+
function findDuplicateUuids(testCases) {
|
|
65
|
+
const descriptionsByUuid = new Map();
|
|
66
|
+
for (const testCase of testCases) {
|
|
67
|
+
if (testCase.testCaseUuid) {
|
|
68
|
+
const descriptions = descriptionsByUuid.get(testCase.testCaseUuid) ?? [];
|
|
69
|
+
descriptions.push(testCase.description);
|
|
70
|
+
descriptionsByUuid.set(testCase.testCaseUuid, descriptions);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return [...descriptionsByUuid]
|
|
74
|
+
.filter(([, descriptions]) => descriptions.length > 1)
|
|
75
|
+
.map(([uuid, descriptions]) => `${uuid} (${descriptions.join(", ")})`);
|
|
76
|
+
}
|
|
45
77
|
async function parseRules(path) {
|
|
46
78
|
const result = [];
|
|
47
79
|
const files = await (0, glob_1.glob)(path, { withFileTypes: true });
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testrigor/testrigor-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@testrigor/testrigor-cli",
|
|
9
|
-
"version": "2.0.
|
|
9
|
+
"version": "2.0.4",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
package/oclif.manifest.json
CHANGED
|
@@ -431,6 +431,12 @@
|
|
|
431
431
|
"name": "explicit-mutations",
|
|
432
432
|
"allowNo": false,
|
|
433
433
|
"type": "boolean"
|
|
434
|
+
},
|
|
435
|
+
"use-suite-parsing-mode": {
|
|
436
|
+
"description": "Validate with the suite's own parsing mode setting instead of strict parsing",
|
|
437
|
+
"name": "use-suite-parsing-mode",
|
|
438
|
+
"allowNo": false,
|
|
439
|
+
"type": "boolean"
|
|
434
440
|
}
|
|
435
441
|
},
|
|
436
442
|
"hasDynamicHelp": false,
|
|
@@ -450,5 +456,5 @@
|
|
|
450
456
|
]
|
|
451
457
|
}
|
|
452
458
|
},
|
|
453
|
-
"version": "2.0.
|
|
459
|
+
"version": "2.0.4"
|
|
454
460
|
}
|