@testrigor/testrigor-cli 2.0.3 → 2.0.5

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 CHANGED
@@ -48,8 +48,8 @@ Or skip stored credentials entirely and set `TESTRIGOR_API_KEY`, or pass
48
48
  14. Run with explicit mutations enabled `testrigor test-suite run <test-suite-id> --token <token> --test-cases-path test_cases/**/*.{yaml,txt} --explicit-mutations`
49
49
  15. With all options `testrigor test-suite run <test-suite-id> --token <token> --url <url> --branch <branch> --commit <commit> --variables-path file.json --localhost --test-cases-path test_cases/**/*.{yaml,txt} --rules-path rules/**/*.{yaml,txt} --auto-create-ai-rules --explicit-mutations`
50
50
  16. Save JUnit report to `./junit-report.xml` (works only in sync mode): `testrigor test-suite run <test-suite-id> --token <token> --junit-report-save-path ./report.xml`
51
- 17. With comma-separated labels `testrigor test-suite run <test-suite-id> --token <token> --labels <labels>`
52
- 18. Excluding comma-separated labels `testrigor test-suite run <test-suite-id> --token <token> --excluded-labels <excluded-labels>`
51
+ 17. With labels separated by commas (or by repeating the flag) `testrigor test-suite run <test-suite-id> --token <token> --labels label1,label2`. Only commas separate labels: `--labels "label1;label2"` is a single label named `label1;label2`.
52
+ 18. Excluding labels separated by commas (or by repeating the flag) `testrigor test-suite run <test-suite-id> --token <token> --excluded-labels label1,label2`
53
53
  19. With different WEB and API URLs `testrigor test-suite run <test-suite-id> --token <token> --base-url-web=<base-web-url> --base-url-api=<base_api_url>`
54
54
  20. Set the default test suite ID: `testrigor test-suite config --default <test-suite-id>`
55
55
  21. Remove the default test suite ID: `testrigor test-suite config --delete`
@@ -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,190 @@ 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's marker comments (`commands`, `usage`, `toc`). This README has none, so it stays unchanged. Don't write those markers literally anywhere in the README, not even in code spans: `oclif readme` also runs on every publish and would insert the command docs there.
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.5/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.5/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. Separate multiple labels with commas only
243
+ (e.g. "smoke,login"), or repeat the flag
244
+ --explicit-mutations In cases where you are always using mutations, such as storing test cases in
245
+ your own repository, and you always send us the set of test cases you have
246
+ through our API you should send "--explicit-mutations"
247
+ --file-path=<value> Path to the file stored locally. It will upload the new file to be used. File
248
+ type should be according to the file type accepted for the Test Suite type of
249
+ testing. If the parameter --url is used, this parameter will be ignored.
250
+ --junit-report-save-path=<value> JUnit report save path
251
+ --labels=<value>... Run tests of specific labels. Separate multiple labels with commas only (e.g.
252
+ "smoke,login"), or repeat the flag
253
+ --local-test-nodes-path=<value> Path to a YAML or JSON file with local test nodes configuration
254
+ --localhost Localhost run (auto-detects web vs mobile)
255
+ --max-port=<value> [default: 50000] Max port for tunnel
256
+ --min-port=<value> [default: 40000] Min port for tunnel
257
+ --rules-path=<value> Rules path
258
+ --settings-path=<value> Settings path
259
+ --test-case-uuid=<value>... Test case uuid (can be repeated). Requires --url (web) or --file-path (mobile
260
+ app upload).
261
+ --test-cases-path=<value> Test cases files
262
+ --url=<value> The url
263
+ --variables-path=<value> Variables path
264
+ --xray-execution-key=<value> Reuse an existing Xray Cloud Test Execution by key (e.g. XR-123) instead of
265
+ creating a new one. Optional; leave blank to create a new execution.
266
+
267
+ GLOBAL FLAGS
268
+ -t, --token=<value> Suite authentication token
269
+ --auth-token=<value> Personal authentication token
270
+ --verbose Verbose output
271
+
272
+ DESCRIPTION
273
+ Run all tests of a Test Suite
274
+ ```
275
+
276
+ _See code: [src/commands/test-suite/run.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.5/src/commands/test-suite/run.ts)_
277
+
278
+ ## `testrigor test-suite validate-syntax [TESTSUITEID]`
279
+
280
+ Validate step syntax against a test suite's reusable rules, without running the steps
281
+
282
+ ```
283
+ USAGE
284
+ $ testrigor test-suite validate-syntax [TESTSUITEID] [--auth-token <value>] [-t <value>] [--min-port <value>] [--max-port
285
+ <value>] [--verbose] [--steps <value> | --test-cases-path <value>] [--base-url-api <value>] [--rules-path <value>]
286
+ [--explicit-mutations] [--use-suite-parsing-mode]
287
+
288
+ ARGUMENTS
289
+ [TESTSUITEID] The test suite id (optional if set in config)
290
+
291
+ FLAGS
292
+ --base-url-api=<value> Base URL for API2 (e.g., https://api2.testrigor.com)
293
+ --explicit-mutations Validate using only the supplied rules instead of merging them with the suite's saved rules
294
+ --max-port=<value> [default: 50000] Max port for tunnel
295
+ --min-port=<value> [default: 40000] Min port for tunnel
296
+ --rules-path=<value> Ad hoc reusable rules to validate against, for rules not yet saved to this suite (same glob
297
+ format as `test-suite run --rules-path`)
298
+ --steps=<value> Raw step text to validate directly
299
+ --test-cases-path=<value> Test case files to validate (same glob format as `test-suite run --test-cases-path`)
300
+ --use-suite-parsing-mode Validate with the suite's own parsing mode setting instead of strict parsing
301
+
302
+ GLOBAL FLAGS
303
+ -t, --token=<value> Suite authentication token
304
+ --auth-token=<value> Personal authentication token
305
+ --verbose Verbose output
306
+
307
+ DESCRIPTION
308
+ Validate step syntax against a test suite's reusable rules, without running the steps
309
+
310
+ EXAMPLES
311
+ $ testrigor test-suite validate-syntax <test-suite-id> --steps "click \"Login\""
312
+
313
+ $ testrigor test-suite validate-syntax <test-suite-id> --test-cases-path "test_cases/**/*.{yaml,txt}"
314
+ ```
315
+
316
+ _See code: [src/commands/test-suite/validate-syntax.ts](https://github.com/TestRigor/testrigor-cli/blob/v2.0.5/src/commands/test-suite/validate-syntax.ts)_
317
+ <!-- commandsstop -->`, so this README currently stays unchanged.
318
+
120
319
  3. Check that the diff only touches the version fields, then build and test from the lockfile:
121
320
 
122
321
  ```
@@ -83,8 +83,8 @@ class Run extends command_base_1.CommandBase {
83
83
  const testCaseUuids = flags["test-case-uuid"];
84
84
  const isAutoCreateAIBasedRulesEnabled = flags["auto-create-ai-rules"];
85
85
  const explicitMutations = flags["explicit-mutations"];
86
- const labels = flags["labels"];
87
- const excludedLabels = flags["excluded-labels"];
86
+ const labels = (0, utils_1.splitLabels)(flags["labels"]);
87
+ const excludedLabels = (0, utils_1.splitLabels)(flags["excluded-labels"]);
88
88
  const xrayExecutionKey = flags["xray-execution-key"];
89
89
  const chromeExtensions = flags["chrome-extension"];
90
90
  const context = {
@@ -97,10 +97,10 @@ class Run extends command_base_1.CommandBase {
97
97
  isMobile: false,
98
98
  appiumStartedByUs: false,
99
99
  };
100
- if (labels) {
100
+ if (labels.length > 0) {
101
101
  context.configuration.labels = labels;
102
102
  }
103
- if (excludedLabels) {
103
+ if (excludedLabels.length > 0) {
104
104
  context.configuration.excludedLabels = excludedLabels;
105
105
  }
106
106
  if (xrayExecutionKey) {
@@ -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
- const testCases = await (0, parser_1.parseTestCases)(testCasesPath);
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 {
@@ -933,11 +938,11 @@ Run.flags = {
933
938
  default: false,
934
939
  }),
935
940
  labels: core_1.Flags.string({
936
- description: "Run tests of specific labels",
941
+ description: 'Run tests of specific labels. Separate multiple labels with commas only (e.g. "smoke,login"), or repeat the flag',
937
942
  multiple: true,
938
943
  }),
939
944
  "excluded-labels": core_1.Flags.string({
940
- description: "Not run tests of specific labels",
945
+ description: 'Not run tests of specific labels. Separate multiple labels with commas only (e.g. "smoke,login"), or repeat the flag',
941
946
  multiple: true,
942
947
  }),
943
948
  "base-url-web": core_1.Flags.string({
@@ -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
- await this.reportValidationResults(testSuiteId, token, casesToValidate, rules, explicitMutations);
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({
@@ -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>;
@@ -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
- if (json.testCaseUuid) {
24
- testCase.testCaseUuid = json.testCaseUuid;
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 });
@@ -14,3 +14,4 @@ export declare function removeExtension(fileName: string): string;
14
14
  export declare function extractUrlWithoutQueryParams(urlString: string): string;
15
15
  export declare function extractRunIdFromDetailsUrl(detailsUrl: string | undefined): string;
16
16
  export declare function isValidUrl(url: string): boolean;
17
+ export declare function splitLabels(values: string[] | undefined): string[];
@@ -15,6 +15,7 @@ exports.removeExtension = removeExtension;
15
15
  exports.extractUrlWithoutQueryParams = extractUrlWithoutQueryParams;
16
16
  exports.extractRunIdFromDetailsUrl = extractRunIdFromDetailsUrl;
17
17
  exports.isValidUrl = isValidUrl;
18
+ exports.splitLabels = splitLabels;
18
19
  const tslib_1 = require("tslib");
19
20
  const fs_1 = tslib_1.__importDefault(require("@supercharge/fs"));
20
21
  const path = tslib_1.__importStar(require("path"));
@@ -95,3 +96,14 @@ function isValidUrl(url) {
95
96
  return false;
96
97
  }
97
98
  }
99
+ // Splits label flag values on "," so "a,b", repeated flags and space-separated
100
+ // values all produce the same list. Empty entries are dropped.
101
+ function splitLabels(values) {
102
+ if (!values) {
103
+ return [];
104
+ }
105
+ return values
106
+ .flatMap((value) => value.split(","))
107
+ .map((label) => label.trim())
108
+ .filter((label) => label.length > 0);
109
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@testrigor/testrigor-cli",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@testrigor/testrigor-cli",
9
- "version": "2.0.3",
9
+ "version": "2.0.5",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
@@ -274,14 +274,14 @@
274
274
  "type": "boolean"
275
275
  },
276
276
  "labels": {
277
- "description": "Run tests of specific labels",
277
+ "description": "Run tests of specific labels. Separate multiple labels with commas only (e.g. \"smoke,login\"), or repeat the flag",
278
278
  "name": "labels",
279
279
  "hasDynamicHelp": false,
280
280
  "multiple": true,
281
281
  "type": "option"
282
282
  },
283
283
  "excluded-labels": {
284
- "description": "Not run tests of specific labels",
284
+ "description": "Not run tests of specific labels. Separate multiple labels with commas only (e.g. \"smoke,login\"), or repeat the flag",
285
285
  "name": "excluded-labels",
286
286
  "hasDynamicHelp": false,
287
287
  "multiple": true,
@@ -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.3"
459
+ "version": "2.0.5"
454
460
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testrigor/testrigor-cli",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "TestRigor Command Line",
5
5
  "author": "Ivo Parun Rua @parunruaivo",
6
6
  "bin": {