@automatify-au/cli 0.1.17 → 0.1.18
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 +37 -21
- package/dist/automatify.cjs +162 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,8 +74,10 @@ Publish notes:
|
|
|
74
74
|
Minimum:
|
|
75
75
|
- `JIRA_BASE_URL`
|
|
76
76
|
- At least one of `JIRA_PROJECT_KEY` or `JIRA_ISSUE_KEY`
|
|
77
|
-
- `TESTOPS_FORGE_ENDPOINT` for commands that call Forge contracts (`doctor`, `ingest`, `run`, `sync`)
|
|
78
|
-
- `TESTOPS_FORGE_AUTH_TOKEN`
|
|
77
|
+
- `TESTOPS_FORGE_ENDPOINT` for commands that call Forge contracts (`doctor`, `ingest`, `run`, `sync`); copy the installation-specific endpoint from Jira `Automatify TestOps -> CLI`
|
|
78
|
+
- `TESTOPS_FORGE_AUTH_TOKEN`; create a CLI key in Jira `Automatify TestOps -> CLI` and copy the one-time token when it is shown
|
|
79
|
+
|
|
80
|
+
Customer admins do not need the Forge developer CLI to obtain either value. The Jira CLI workspace resolves the webtrigger endpoint for the current app installation at runtime.
|
|
79
81
|
|
|
80
82
|
Local Jira auth helper on macOS/Windows:
|
|
81
83
|
```bash
|
|
@@ -88,10 +90,10 @@ automatify testops auth status
|
|
|
88
90
|
|
|
89
91
|
On Linux/CI, keep `JIRA_API_TOKEN` in the environment and run `auth login` without `--token-stdin`; the CLI stores only non-secret Jira settings. Use `automatify testops auth logout` to remove local Jira and Forge credentials while preserving non-secret URL/email settings. Environment variables are not modified by logout.
|
|
90
92
|
|
|
91
|
-
Forge transport auth remains an advanced setting:
|
|
93
|
+
Forge transport auth remains an advanced setting. First open the Jira project, go to `Automatify TestOps -> CLI`, copy the displayed CLI endpoint, create a CLI key, and copy its one-time token. Then configure the CLI:
|
|
92
94
|
```bash
|
|
93
95
|
automatify testops config set projectKey DEV
|
|
94
|
-
automatify testops config set forgeEndpoint "<
|
|
96
|
+
automatify testops config set forgeEndpoint "<endpoint-copied-from-jira>"
|
|
95
97
|
printf "%s" "$TESTOPS_FORGE_AUTH_TOKEN" | automatify testops config set forgeAuthToken --stdin
|
|
96
98
|
```
|
|
97
99
|
|
|
@@ -110,6 +112,9 @@ All TestOps commands are invoked as `automatify testops <command>`:
|
|
|
110
112
|
### Core browse commands
|
|
111
113
|
|
|
112
114
|
- `bdd`
|
|
115
|
+
- `automatify testops bdd scenarios list`
|
|
116
|
+
- `automatify testops bdd scenarios list --json`
|
|
117
|
+
- `automatify testops bdd scenarios list --project-key <PROJECT_KEY> --issue-key <ISSUE_KEY>`
|
|
113
118
|
- `automatify testops bdd scenarios show --id <SCENARIO_ID>`
|
|
114
119
|
- `automatify testops bdd scenarios show --id <SCENARIO_ID> --format feature`
|
|
115
120
|
- `automatify testops bdd scenarios show --id <SCENARIO_ID|SC-4> --feature`
|
|
@@ -141,6 +146,15 @@ All TestOps commands are invoked as `automatify testops <command>`:
|
|
|
141
146
|
- `automatify allure open ./allure-report.zip`
|
|
142
147
|
- `automatify allure open ./allure-report.zip --no-open --port 8080`
|
|
143
148
|
|
|
149
|
+
`bdd scenarios list` uses the configured project context or `--project-key`; `--issue-key` optionally narrows the Jira issue context. Human output is concise and selector-first:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
BDD scenarios (1) for project DEV:
|
|
153
|
+
SC-14 | Guest payment | Feature: Checkout | Steps: 3 | Issues: DEV-2
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
With `--json`, the command emits one JSON object with stable action `bdd-scenarios-list`, `projectKey`, optional `issueKey`, `count`, and `items`.
|
|
157
|
+
|
|
144
158
|
### Advanced browse commands
|
|
145
159
|
|
|
146
160
|
- `cases`
|
|
@@ -224,7 +238,7 @@ Secrets must come from stdin or safe environment references. Secret values are r
|
|
|
224
238
|
```bash
|
|
225
239
|
export TESTOPS_GITHUB_PROVIDER_TOKEN="<github-app-installation-or-fine-grained-token>"
|
|
226
240
|
export TESTOPS_GITHUB_ADMIN_TOKEN="<least-privilege-token-allowed-to-manage-actions-secrets>"
|
|
227
|
-
export TESTOPS_FORGE_ENDPOINT="<
|
|
241
|
+
export TESTOPS_FORGE_ENDPOINT="<endpoint-copied-from-jira-cli-workspace>"
|
|
228
242
|
export TESTOPS_FORGE_AUTH_TOKEN="<one-time-project-cli-key>"
|
|
229
243
|
|
|
230
244
|
automatify testops setup apply \
|
|
@@ -270,7 +284,8 @@ Doctor verifies the local workflow hash, GitHub workflow metadata/content at the
|
|
|
270
284
|
|
|
271
285
|
Current authentication boundary:
|
|
272
286
|
|
|
273
|
-
- `
|
|
287
|
+
- `TESTOPS_FORGE_ENDPOINT` is copied from the installation-specific endpoint displayed in Jira `Automatify TestOps -> CLI`.
|
|
288
|
+
- `TESTOPS_FORGE_AUTH_TOKEN` is a project-scoped, project-admin-created CLI key from the same Jira CLI workspace.
|
|
274
289
|
- The key authorizes the current Forge webtrigger transport for that project; command groups are not separate security scopes.
|
|
275
290
|
- Setup does not turn this into an all-user auth model. Customer-admin packaging and any future user-level authentication remain separate work.
|
|
276
291
|
- The same callback key may be stored as a GitHub Actions repository secret only under the explicit `github-secrets` apply scope.
|
|
@@ -423,20 +438,18 @@ Required env/config for real upload mode:
|
|
|
423
438
|
- `TESTOPS_FORGE_ENDPOINT`
|
|
424
439
|
- `TESTOPS_FORGE_AUTH_TOKEN` for the repo-owned authenticated webtrigger transport
|
|
425
440
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
forge webtrigger create --functionKey cli-transport-webtrigger --site automatify-com-au.atlassian.net --product Jira -e development
|
|
432
|
-
```
|
|
441
|
+
Customer CLI transport setup (no Forge developer CLI required):
|
|
442
|
+
1. Open the Jira project and go to `Automatify TestOps -> CLI`.
|
|
443
|
+
2. Copy the `CLI endpoint` displayed for the current installation.
|
|
444
|
+
3. Create a project CLI key and copy the token immediately; it is shown once only.
|
|
445
|
+
4. Configure those two values in the local shell, CI secret store, or CLI config.
|
|
433
446
|
|
|
434
|
-
|
|
447
|
+
Repository maintainers deploy/install the Forge app through the repository's controlled deployment workflow. That internal deployment process is separate from customer CLI onboarding.
|
|
435
448
|
|
|
436
|
-
Export the
|
|
449
|
+
Export the installation endpoint and one-time token for CLI use:
|
|
437
450
|
```bash
|
|
438
|
-
export TESTOPS_FORGE_ENDPOINT="<
|
|
439
|
-
export TESTOPS_FORGE_AUTH_TOKEN="<one-time-token-from-
|
|
451
|
+
export TESTOPS_FORGE_ENDPOINT="<endpoint-copied-from-jira>"
|
|
452
|
+
export TESTOPS_FORGE_AUTH_TOKEN="<one-time-token-from-jira-cli-workspace>"
|
|
440
453
|
export JIRA_BASE_URL="https://automatify-com-au.atlassian.net"
|
|
441
454
|
export JIRA_PROJECT_KEY="DEV"
|
|
442
455
|
```
|
|
@@ -445,18 +458,19 @@ Or store the non-secret values in `.testops-cli.json`; on macOS the token is sto
|
|
|
445
458
|
```bash
|
|
446
459
|
automatify testops config set baseUrl https://automatify-com-au.atlassian.net
|
|
447
460
|
automatify testops config set projectKey DEV
|
|
448
|
-
automatify testops config set forgeEndpoint "<
|
|
461
|
+
automatify testops config set forgeEndpoint "<endpoint-copied-from-jira>"
|
|
449
462
|
printf "%s" "$TESTOPS_FORGE_AUTH_TOKEN" | automatify testops config set forgeAuthToken --stdin
|
|
450
463
|
```
|
|
451
464
|
|
|
452
465
|
On Linux and CI, keep the token in environment variables. Windows users can use the same `config set forgeAuthToken --stdin` flow from PowerShell; see [WINDOWS.md](./WINDOWS.md).
|
|
453
466
|
```bash
|
|
454
|
-
export TESTOPS_FORGE_AUTH_TOKEN="<one-time-token-from-
|
|
467
|
+
export TESTOPS_FORGE_AUTH_TOKEN="<one-time-token-from-jira-cli-workspace>"
|
|
455
468
|
```
|
|
456
469
|
|
|
457
470
|
Transport notes:
|
|
458
471
|
- Bearer auth is required for operator/CI use. Forge stores only the token hash plus metadata.
|
|
459
|
-
- Tokens are project-scoped, shown once at creation time, and can be revoked from the
|
|
472
|
+
- Tokens are project-scoped, shown once at creation time, and can be revoked from the Jira CLI workspace.
|
|
473
|
+
- The endpoint is resolved by the Forge runtime for the current installation; customers do not configure a Forge-side endpoint variable.
|
|
460
474
|
- Expired or revoked tokens are rejected by the transport.
|
|
461
475
|
|
|
462
476
|
Scenario automation callback example:
|
|
@@ -545,6 +559,7 @@ Azure DevOps setup note:
|
|
|
545
559
|
|
|
546
560
|
Core browse examples:
|
|
547
561
|
```bash
|
|
562
|
+
automatify testops bdd scenarios list --project-key DEV --json
|
|
548
563
|
automatify testops bdd scenarios show --project-key DEV --id <SCENARIO_ID> --json
|
|
549
564
|
automatify testops bdd scenarios export --project-key DEV --id SC-4 --output-dir ./artifacts/scenario-export --json
|
|
550
565
|
automatify testops bdd scenarios import --project-key DEV --file ./artifacts/scenario-export/SC-4.feature --json
|
|
@@ -570,6 +585,7 @@ automatify testops suites cases list --project-key DEV --key TS-1
|
|
|
570
585
|
Recommended browse flow:
|
|
571
586
|
```bash
|
|
572
587
|
# Path A: scenario-first browse
|
|
588
|
+
automatify testops bdd scenarios list --project-key DEV --json
|
|
573
589
|
automatify testops bdd scenarios show --project-key DEV --id <SCENARIO_ID> --json
|
|
574
590
|
automatify testops runs show --project-key DEV --id <RUN_ID> --json
|
|
575
591
|
|
|
@@ -608,7 +624,7 @@ Feature export notes:
|
|
|
608
624
|
- `bdd features export` writes one `.feature` file per stored BDD feature plus `manifest.json`.
|
|
609
625
|
- with `--zip`, the CLI also writes `./artifacts/features-export.zip` next to the export directory.
|
|
610
626
|
- pass `--issue-key DEV-2` to export only features visible in that Jira issue context.
|
|
611
|
-
- `getSummaryExport` remains the reporting/export path for JSON/CSV summary snapshots and is separate from feature-file round-trip export.
|
|
627
|
+
- `getSummaryExport` remains the reporting/export path for JSON/CSV summary snapshots and is separate from feature-file round-trip export/import.
|
|
612
628
|
|
|
613
629
|
Coverage and readiness report via the Forge transport:
|
|
614
630
|
```bash
|
package/dist/automatify.cjs
CHANGED
|
@@ -15339,6 +15339,138 @@ function createBddHandler(deps = {}) {
|
|
|
15339
15339
|
};
|
|
15340
15340
|
}
|
|
15341
15341
|
|
|
15342
|
+
// src/bddCommand.ts
|
|
15343
|
+
var CONFIG_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
15344
|
+
"--config",
|
|
15345
|
+
"--base-url",
|
|
15346
|
+
"--project-key",
|
|
15347
|
+
"--issue-key",
|
|
15348
|
+
"--auth-mode",
|
|
15349
|
+
"--jira-email",
|
|
15350
|
+
"--jira-api-token"
|
|
15351
|
+
]);
|
|
15352
|
+
function parseListArgs(args) {
|
|
15353
|
+
let json = false;
|
|
15354
|
+
const configArgs = [];
|
|
15355
|
+
const invalid = [];
|
|
15356
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
15357
|
+
const token = args[index];
|
|
15358
|
+
if (token === "--json") {
|
|
15359
|
+
json = true;
|
|
15360
|
+
continue;
|
|
15361
|
+
}
|
|
15362
|
+
if (!CONFIG_VALUE_FLAGS.has(token)) {
|
|
15363
|
+
invalid.push(token);
|
|
15364
|
+
continue;
|
|
15365
|
+
}
|
|
15366
|
+
const value = args[index + 1];
|
|
15367
|
+
if (!value || value.startsWith("--")) {
|
|
15368
|
+
invalid.push(token);
|
|
15369
|
+
continue;
|
|
15370
|
+
}
|
|
15371
|
+
configArgs.push(token, value);
|
|
15372
|
+
index += 1;
|
|
15373
|
+
}
|
|
15374
|
+
return { json, configArgs, invalid };
|
|
15375
|
+
}
|
|
15376
|
+
function normalizeError4(error) {
|
|
15377
|
+
if (error instanceof ForgeClientError) {
|
|
15378
|
+
return `${error.code}: ${error.message}`;
|
|
15379
|
+
}
|
|
15380
|
+
if (error instanceof Error) {
|
|
15381
|
+
return error.message;
|
|
15382
|
+
}
|
|
15383
|
+
return "Unknown BDD scenario list transport error.";
|
|
15384
|
+
}
|
|
15385
|
+
function scenarioToJson(scenario) {
|
|
15386
|
+
return {
|
|
15387
|
+
id: scenario.id,
|
|
15388
|
+
key: scenario.key ?? null,
|
|
15389
|
+
featureId: scenario.featureId,
|
|
15390
|
+
featureName: scenario.featureName,
|
|
15391
|
+
name: scenario.name,
|
|
15392
|
+
tags: [...scenario.tags],
|
|
15393
|
+
linkedIssueKeys: [...scenario.linkedIssueKeys],
|
|
15394
|
+
stepCount: scenario.steps.length,
|
|
15395
|
+
createdAt: scenario.createdAt,
|
|
15396
|
+
updatedAt: scenario.updatedAt
|
|
15397
|
+
};
|
|
15398
|
+
}
|
|
15399
|
+
function scenarioToLine(scenario) {
|
|
15400
|
+
const selector = scenario.key ?? scenario.id;
|
|
15401
|
+
const issues = scenario.linkedIssueKeys.length > 0 ? scenario.linkedIssueKeys.join(", ") : "none";
|
|
15402
|
+
return `${selector} | ${scenario.name} | Feature: ${scenario.featureName} | Steps: ${scenario.steps.length} | Issues: ${issues}`;
|
|
15403
|
+
}
|
|
15404
|
+
function createBddCommandHandler(deps = {}) {
|
|
15405
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
15406
|
+
const env = deps.env ?? process.env;
|
|
15407
|
+
const delegate = deps.delegate ?? createBddHandler({ cwd, env });
|
|
15408
|
+
return async (request, context) => {
|
|
15409
|
+
if (request.args[0] !== "scenarios" || request.args[1] !== "list") {
|
|
15410
|
+
return delegate(request, context);
|
|
15411
|
+
}
|
|
15412
|
+
const parsed = parseListArgs(request.args.slice(2));
|
|
15413
|
+
if (parsed.invalid.length > 0) {
|
|
15414
|
+
return {
|
|
15415
|
+
exitCode: ExitCode.UsageError,
|
|
15416
|
+
stderr: [`ERROR: Unknown or invalid arguments: ${parsed.invalid.join(", ")}`]
|
|
15417
|
+
};
|
|
15418
|
+
}
|
|
15419
|
+
const config = resolveCliConfig(parsed.configArgs, env, cwd).values;
|
|
15420
|
+
if (!config.projectKey) {
|
|
15421
|
+
return {
|
|
15422
|
+
exitCode: ExitCode.ValidationError,
|
|
15423
|
+
stderr: ["ERROR: Missing project context. Set JIRA_PROJECT_KEY or pass --project-key."]
|
|
15424
|
+
};
|
|
15425
|
+
}
|
|
15426
|
+
try {
|
|
15427
|
+
const result = await context.invokeForgeContract("listBddScenarios", {
|
|
15428
|
+
context: {
|
|
15429
|
+
projectKey: config.projectKey,
|
|
15430
|
+
issueKey: config.issueKey || void 0
|
|
15431
|
+
}
|
|
15432
|
+
});
|
|
15433
|
+
if (!result.ok) {
|
|
15434
|
+
return {
|
|
15435
|
+
exitCode: ExitCode.RemoteError,
|
|
15436
|
+
stderr: [`ERROR: ${result.error.code}: ${result.error.message}`]
|
|
15437
|
+
};
|
|
15438
|
+
}
|
|
15439
|
+
const scenarios = result.data;
|
|
15440
|
+
if (parsed.json) {
|
|
15441
|
+
return {
|
|
15442
|
+
exitCode: ExitCode.Success,
|
|
15443
|
+
stdout: toJsonLine({
|
|
15444
|
+
action: "bdd-scenarios-list",
|
|
15445
|
+
projectKey: config.projectKey,
|
|
15446
|
+
issueKey: config.issueKey || null,
|
|
15447
|
+
count: scenarios.length,
|
|
15448
|
+
items: scenarios.map(scenarioToJson)
|
|
15449
|
+
})
|
|
15450
|
+
};
|
|
15451
|
+
}
|
|
15452
|
+
if (scenarios.length === 0) {
|
|
15453
|
+
return {
|
|
15454
|
+
exitCode: ExitCode.Success,
|
|
15455
|
+
stdout: [`No BDD scenarios found for project ${config.projectKey}.`]
|
|
15456
|
+
};
|
|
15457
|
+
}
|
|
15458
|
+
return {
|
|
15459
|
+
exitCode: ExitCode.Success,
|
|
15460
|
+
stdout: [
|
|
15461
|
+
`BDD scenarios (${scenarios.length}) for project ${config.projectKey}:`,
|
|
15462
|
+
...scenarios.map(scenarioToLine)
|
|
15463
|
+
]
|
|
15464
|
+
};
|
|
15465
|
+
} catch (error) {
|
|
15466
|
+
return {
|
|
15467
|
+
exitCode: ExitCode.TransportError,
|
|
15468
|
+
stderr: [`ERROR: ${normalizeError4(error)}`]
|
|
15469
|
+
};
|
|
15470
|
+
}
|
|
15471
|
+
};
|
|
15472
|
+
}
|
|
15473
|
+
|
|
15342
15474
|
// src/cases.ts
|
|
15343
15475
|
var CONFIG_FLAGS4 = /* @__PURE__ */ new Set([
|
|
15344
15476
|
"--config",
|
|
@@ -15387,7 +15519,7 @@ function pickConfigArgs4(parsed) {
|
|
|
15387
15519
|
}
|
|
15388
15520
|
return args;
|
|
15389
15521
|
}
|
|
15390
|
-
function
|
|
15522
|
+
function normalizeError5(error) {
|
|
15391
15523
|
if (error instanceof ForgeClientError) {
|
|
15392
15524
|
return `${error.code}: ${error.message}`;
|
|
15393
15525
|
}
|
|
@@ -15565,7 +15697,7 @@ function createCasesHandler(deps = {}) {
|
|
|
15565
15697
|
} catch (error) {
|
|
15566
15698
|
return {
|
|
15567
15699
|
exitCode: ExitCode.TransportError,
|
|
15568
|
-
stderr: [`ERROR: ${
|
|
15700
|
+
stderr: [`ERROR: ${normalizeError5(error)}`]
|
|
15569
15701
|
};
|
|
15570
15702
|
}
|
|
15571
15703
|
}
|
|
@@ -15607,7 +15739,7 @@ function createCasesHandler(deps = {}) {
|
|
|
15607
15739
|
} catch (error) {
|
|
15608
15740
|
return {
|
|
15609
15741
|
exitCode: ExitCode.TransportError,
|
|
15610
|
-
stderr: [`ERROR: ${
|
|
15742
|
+
stderr: [`ERROR: ${normalizeError5(error)}`]
|
|
15611
15743
|
};
|
|
15612
15744
|
}
|
|
15613
15745
|
}
|
|
@@ -15670,7 +15802,7 @@ function createCasesHandler(deps = {}) {
|
|
|
15670
15802
|
} catch (error) {
|
|
15671
15803
|
return {
|
|
15672
15804
|
exitCode: ExitCode.TransportError,
|
|
15673
|
-
stderr: [`ERROR: ${
|
|
15805
|
+
stderr: [`ERROR: ${normalizeError5(error)}`]
|
|
15674
15806
|
};
|
|
15675
15807
|
}
|
|
15676
15808
|
}
|
|
@@ -15733,7 +15865,7 @@ function createCasesHandler(deps = {}) {
|
|
|
15733
15865
|
} catch (error) {
|
|
15734
15866
|
return {
|
|
15735
15867
|
exitCode: ExitCode.TransportError,
|
|
15736
|
-
stderr: [`ERROR: ${
|
|
15868
|
+
stderr: [`ERROR: ${normalizeError5(error)}`]
|
|
15737
15869
|
};
|
|
15738
15870
|
}
|
|
15739
15871
|
}
|
|
@@ -16155,7 +16287,7 @@ function summarizeSuccess(result) {
|
|
|
16155
16287
|
}
|
|
16156
16288
|
return lines;
|
|
16157
16289
|
}
|
|
16158
|
-
function
|
|
16290
|
+
function normalizeError6(error) {
|
|
16159
16291
|
if (error instanceof ForgeClientError) {
|
|
16160
16292
|
return `${error.code}: ${error.message}`;
|
|
16161
16293
|
}
|
|
@@ -16192,7 +16324,7 @@ function createIngestFeatureHandler(deps = {}) {
|
|
|
16192
16324
|
} catch (error) {
|
|
16193
16325
|
return {
|
|
16194
16326
|
exitCode: ExitCode.InternalError,
|
|
16195
|
-
stderr: [`ERROR: Failed to read feature source: ${
|
|
16327
|
+
stderr: [`ERROR: Failed to read feature source: ${normalizeError6(error)}`]
|
|
16196
16328
|
};
|
|
16197
16329
|
}
|
|
16198
16330
|
const name = (parsed.flags["--name"] ?? deriveNameFromGherkin(gherkin)).trim();
|
|
@@ -16283,14 +16415,14 @@ function createIngestFeatureHandler(deps = {}) {
|
|
|
16283
16415
|
status: "failed",
|
|
16284
16416
|
featureName: name,
|
|
16285
16417
|
source: useStdin ? "stdin" : sourceFile,
|
|
16286
|
-
errorMessage:
|
|
16418
|
+
errorMessage: normalizeError6(error)
|
|
16287
16419
|
})
|
|
16288
16420
|
};
|
|
16289
16421
|
}
|
|
16290
16422
|
return {
|
|
16291
16423
|
exitCode: ExitCode.TransportError,
|
|
16292
16424
|
stdout: ["Feature ingestion: FAILED", `Feature: ${name}`, `Source: ${useStdin ? "stdin" : sourceFile}`],
|
|
16293
|
-
stderr: [`ERROR: ${
|
|
16425
|
+
stderr: [`ERROR: ${normalizeError6(error)}`]
|
|
16294
16426
|
};
|
|
16295
16427
|
}
|
|
16296
16428
|
};
|
|
@@ -16345,7 +16477,7 @@ function pickConfigArgs7(parsed) {
|
|
|
16345
16477
|
}
|
|
16346
16478
|
return args;
|
|
16347
16479
|
}
|
|
16348
|
-
function
|
|
16480
|
+
function normalizeError7(error) {
|
|
16349
16481
|
if (error instanceof ForgeClientError) {
|
|
16350
16482
|
return `${error.code}: ${error.message}`;
|
|
16351
16483
|
}
|
|
@@ -16488,7 +16620,7 @@ function createProfilesHandler(deps = {}) {
|
|
|
16488
16620
|
} catch (error) {
|
|
16489
16621
|
return {
|
|
16490
16622
|
exitCode: ExitCode.TransportError,
|
|
16491
|
-
stderr: [`ERROR: ${
|
|
16623
|
+
stderr: [`ERROR: ${normalizeError7(error)}`]
|
|
16492
16624
|
};
|
|
16493
16625
|
}
|
|
16494
16626
|
}
|
|
@@ -16574,7 +16706,7 @@ function createProfilesHandler(deps = {}) {
|
|
|
16574
16706
|
} catch (error) {
|
|
16575
16707
|
return {
|
|
16576
16708
|
exitCode: ExitCode.TransportError,
|
|
16577
|
-
stderr: [`ERROR: ${
|
|
16709
|
+
stderr: [`ERROR: ${normalizeError7(error)}`]
|
|
16578
16710
|
};
|
|
16579
16711
|
}
|
|
16580
16712
|
}
|
|
@@ -16672,7 +16804,7 @@ function createProfilesHandler(deps = {}) {
|
|
|
16672
16804
|
} catch (error) {
|
|
16673
16805
|
return {
|
|
16674
16806
|
exitCode: ExitCode.TransportError,
|
|
16675
|
-
stderr: [`ERROR: ${
|
|
16807
|
+
stderr: [`ERROR: ${normalizeError7(error)}`]
|
|
16676
16808
|
};
|
|
16677
16809
|
}
|
|
16678
16810
|
}
|
|
@@ -16783,7 +16915,7 @@ function createProfilesHandler(deps = {}) {
|
|
|
16783
16915
|
} catch (error) {
|
|
16784
16916
|
return {
|
|
16785
16917
|
exitCode: ExitCode.TransportError,
|
|
16786
|
-
stderr: [`ERROR: ${
|
|
16918
|
+
stderr: [`ERROR: ${normalizeError7(error)}`]
|
|
16787
16919
|
};
|
|
16788
16920
|
}
|
|
16789
16921
|
}
|
|
@@ -16858,7 +16990,7 @@ function pickConfigArgs8(parsed) {
|
|
|
16858
16990
|
}
|
|
16859
16991
|
return configArgs;
|
|
16860
16992
|
}
|
|
16861
|
-
function
|
|
16993
|
+
function normalizeError8(error) {
|
|
16862
16994
|
if (error instanceof ForgeClientError) {
|
|
16863
16995
|
return `${error.code}: ${error.message}`;
|
|
16864
16996
|
}
|
|
@@ -16977,7 +17109,7 @@ function createRunUploadHandler(deps = {}) {
|
|
|
16977
17109
|
} catch (error) {
|
|
16978
17110
|
return {
|
|
16979
17111
|
exitCode: ExitCode.InternalError,
|
|
16980
|
-
stderr: [`ERROR: Failed to read run payload source: ${
|
|
17112
|
+
stderr: [`ERROR: Failed to read run payload source: ${normalizeError8(error)}`]
|
|
16981
17113
|
};
|
|
16982
17114
|
}
|
|
16983
17115
|
const payloadFromSource = parseRunPayload(raw);
|
|
@@ -17007,7 +17139,7 @@ function createRunUploadHandler(deps = {}) {
|
|
|
17007
17139
|
} catch (error) {
|
|
17008
17140
|
return {
|
|
17009
17141
|
exitCode: ExitCode.TransportError,
|
|
17010
|
-
stderr: [`ERROR: ${
|
|
17142
|
+
stderr: [`ERROR: ${normalizeError8(error)}`]
|
|
17011
17143
|
};
|
|
17012
17144
|
}
|
|
17013
17145
|
}
|
|
@@ -17087,7 +17219,7 @@ function createRunUploadHandler(deps = {}) {
|
|
|
17087
17219
|
featureName: runInput.featureName,
|
|
17088
17220
|
scenarioName: runInput.scenarioName,
|
|
17089
17221
|
executedAt: runInput.executedAt,
|
|
17090
|
-
errorMessage:
|
|
17222
|
+
errorMessage: normalizeError8(error)
|
|
17091
17223
|
})
|
|
17092
17224
|
};
|
|
17093
17225
|
}
|
|
@@ -17099,7 +17231,7 @@ function createRunUploadHandler(deps = {}) {
|
|
|
17099
17231
|
`Scenario: ${runInput.scenarioName}`,
|
|
17100
17232
|
`ExecutedAt: ${runInput.executedAt}`
|
|
17101
17233
|
],
|
|
17102
|
-
stderr: [`ERROR: ${
|
|
17234
|
+
stderr: [`ERROR: ${normalizeError8(error)}`]
|
|
17103
17235
|
};
|
|
17104
17236
|
}
|
|
17105
17237
|
};
|
|
@@ -17153,7 +17285,7 @@ function pickConfigArgs9(parsed) {
|
|
|
17153
17285
|
}
|
|
17154
17286
|
return args;
|
|
17155
17287
|
}
|
|
17156
|
-
function
|
|
17288
|
+
function normalizeError9(error) {
|
|
17157
17289
|
if (error instanceof ForgeClientError) {
|
|
17158
17290
|
return `${error.code}: ${error.message}`;
|
|
17159
17291
|
}
|
|
@@ -17271,7 +17403,7 @@ function createRunsHandler(deps = {}) {
|
|
|
17271
17403
|
} catch (error) {
|
|
17272
17404
|
return {
|
|
17273
17405
|
exitCode: ExitCode.TransportError,
|
|
17274
|
-
stderr: [`ERROR: ${
|
|
17406
|
+
stderr: [`ERROR: ${normalizeError9(error)}`]
|
|
17275
17407
|
};
|
|
17276
17408
|
}
|
|
17277
17409
|
}
|
|
@@ -19323,7 +19455,7 @@ function pickConfigArgs10(parsed) {
|
|
|
19323
19455
|
}
|
|
19324
19456
|
return args;
|
|
19325
19457
|
}
|
|
19326
|
-
function
|
|
19458
|
+
function normalizeError10(error) {
|
|
19327
19459
|
if (error instanceof ForgeClientError) {
|
|
19328
19460
|
return `${error.code}: ${error.message}`;
|
|
19329
19461
|
}
|
|
@@ -19449,7 +19581,7 @@ function createSuitesHandler(deps = {}) {
|
|
|
19449
19581
|
} catch (error) {
|
|
19450
19582
|
return {
|
|
19451
19583
|
exitCode: ExitCode.TransportError,
|
|
19452
|
-
stderr: [`ERROR: ${
|
|
19584
|
+
stderr: [`ERROR: ${normalizeError10(error)}`]
|
|
19453
19585
|
};
|
|
19454
19586
|
}
|
|
19455
19587
|
}
|
|
@@ -19490,7 +19622,7 @@ function createSuitesHandler(deps = {}) {
|
|
|
19490
19622
|
} catch (error) {
|
|
19491
19623
|
return {
|
|
19492
19624
|
exitCode: ExitCode.TransportError,
|
|
19493
|
-
stderr: [`ERROR: ${
|
|
19625
|
+
stderr: [`ERROR: ${normalizeError10(error)}`]
|
|
19494
19626
|
};
|
|
19495
19627
|
}
|
|
19496
19628
|
}
|
|
@@ -19554,7 +19686,7 @@ function createSuitesHandler(deps = {}) {
|
|
|
19554
19686
|
} catch (error) {
|
|
19555
19687
|
return {
|
|
19556
19688
|
exitCode: ExitCode.TransportError,
|
|
19557
|
-
stderr: [`ERROR: ${
|
|
19689
|
+
stderr: [`ERROR: ${normalizeError10(error)}`]
|
|
19558
19690
|
};
|
|
19559
19691
|
}
|
|
19560
19692
|
}
|
|
@@ -19614,7 +19746,7 @@ function pickConfigArgs11(parsed) {
|
|
|
19614
19746
|
}
|
|
19615
19747
|
return args;
|
|
19616
19748
|
}
|
|
19617
|
-
function
|
|
19749
|
+
function normalizeError11(error) {
|
|
19618
19750
|
if (error instanceof ForgeClientError) {
|
|
19619
19751
|
return `${error.code}: ${error.message}`;
|
|
19620
19752
|
}
|
|
@@ -19717,7 +19849,7 @@ function createSyncHandler(deps = {}) {
|
|
|
19717
19849
|
} catch (error) {
|
|
19718
19850
|
return {
|
|
19719
19851
|
exitCode: ExitCode.TransportError,
|
|
19720
|
-
stderr: [`ERROR: ${
|
|
19852
|
+
stderr: [`ERROR: ${normalizeError11(error)}`]
|
|
19721
19853
|
};
|
|
19722
19854
|
}
|
|
19723
19855
|
}
|
|
@@ -19763,7 +19895,7 @@ function createSyncHandler(deps = {}) {
|
|
|
19763
19895
|
} catch (error) {
|
|
19764
19896
|
return {
|
|
19765
19897
|
exitCode: ExitCode.TransportError,
|
|
19766
|
-
stderr: [`ERROR: ${
|
|
19898
|
+
stderr: [`ERROR: ${normalizeError11(error)}`]
|
|
19767
19899
|
};
|
|
19768
19900
|
}
|
|
19769
19901
|
}
|
|
@@ -19797,9 +19929,9 @@ var COMMAND_REGISTRY = [
|
|
|
19797
19929
|
},
|
|
19798
19930
|
{
|
|
19799
19931
|
name: "bdd",
|
|
19800
|
-
description: "BDD scenario inspection and feature export commands",
|
|
19932
|
+
description: "BDD scenario listing, inspection, and feature export commands",
|
|
19801
19933
|
subcommands: ["features", "scenarios"],
|
|
19802
|
-
handler:
|
|
19934
|
+
handler: createBddCommandHandler()
|
|
19803
19935
|
},
|
|
19804
19936
|
{
|
|
19805
19937
|
name: "cases",
|