jiradc-cli 1.0.29 → 1.0.31
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 +24 -24
- package/dist/index.js +233 -149
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -119,52 +119,52 @@ Search and list commands accept `--limit` to control page size (Jira DC caps at
|
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
121
|
# Get an issue with default fields
|
|
122
|
-
jiradc issue get
|
|
122
|
+
jiradc issue get PROJ-123
|
|
123
123
|
|
|
124
124
|
# Get an issue with specific fields
|
|
125
|
-
jiradc issue get
|
|
125
|
+
jiradc issue get PROJ-123 --fields summary,status,assignee,customfield_10100
|
|
126
126
|
|
|
127
127
|
# Search with JQL
|
|
128
128
|
jiradc issue search 'project = AI AND status = "In Development" ORDER BY updated DESC'
|
|
129
129
|
|
|
130
130
|
# Create an issue
|
|
131
|
-
jiradc issue create --project
|
|
131
|
+
jiradc issue create --project PROJ --type Task --summary "Implement feature X" --description "Details here"
|
|
132
132
|
|
|
133
133
|
# Create with custom fields
|
|
134
|
-
jiradc issue create --project
|
|
134
|
+
jiradc issue create --project PROJ --type Story --summary "User login" --custom-fields '{"customfield_10100": "value"}'
|
|
135
135
|
|
|
136
136
|
# Transition by ID or by status name
|
|
137
|
-
jiradc issue transitions
|
|
138
|
-
jiradc issue transition
|
|
139
|
-
jiradc issue transition
|
|
137
|
+
jiradc issue transitions PROJ-123
|
|
138
|
+
jiradc issue transition PROJ-123 --to 31
|
|
139
|
+
jiradc issue transition PROJ-123 --to "In Review" --comment "Ready for review"
|
|
140
140
|
|
|
141
141
|
# Assign
|
|
142
|
-
jiradc issue assign
|
|
143
|
-
jiradc issue assign
|
|
144
|
-
jiradc issue assign
|
|
142
|
+
jiradc issue assign PROJ-123 me
|
|
143
|
+
jiradc issue assign PROJ-123 jsmith
|
|
144
|
+
jiradc issue assign PROJ-123 none
|
|
145
145
|
|
|
146
146
|
# Update with shortcuts (instead of --fields JSON)
|
|
147
|
-
jiradc issue update
|
|
148
|
-
jiradc issue update
|
|
149
|
-
jiradc issue update
|
|
150
|
-
jiradc issue update
|
|
151
|
-
jiradc issue update
|
|
152
|
-
jiradc issue update
|
|
147
|
+
jiradc issue update PROJ-123 --summary "New title" --priority High
|
|
148
|
+
jiradc issue update PROJ-123 --assignee me
|
|
149
|
+
jiradc issue update PROJ-123 --labels backend,urgent # set mode
|
|
150
|
+
jiradc issue update PROJ-123 --labels +urgent,-backend # mutate mode
|
|
151
|
+
jiradc issue update PROJ-123 --components +Frontend
|
|
152
|
+
jiradc issue update PROJ-123 --fix-versions 1.0,2.0
|
|
153
153
|
|
|
154
154
|
# Link multiple issues to an epic in one call
|
|
155
|
-
jiradc issue link-epic
|
|
155
|
+
jiradc issue link-epic PROJ-456 PROJ-457 PROJ-458 --epic PROJ-100
|
|
156
156
|
|
|
157
157
|
# Add a comment
|
|
158
|
-
jiradc issue comment add
|
|
158
|
+
jiradc issue comment add PROJ-123 --body "Fixed in commit abc123"
|
|
159
159
|
|
|
160
160
|
# Delete a comment
|
|
161
|
-
jiradc issue comment delete
|
|
161
|
+
jiradc issue comment delete PROJ-123 --id 12345
|
|
162
162
|
|
|
163
163
|
# Link two issues
|
|
164
|
-
jiradc issue link
|
|
164
|
+
jiradc issue link PROJ-123 PROJ-456 --type "blocks"
|
|
165
165
|
|
|
166
166
|
# Log work
|
|
167
|
-
jiradc issue worklog add
|
|
167
|
+
jiradc issue worklog add PROJ-123 --time "2h 30m" --comment "Code review"
|
|
168
168
|
|
|
169
169
|
# List active sprints
|
|
170
170
|
jiradc sprint list 42 --state active
|
|
@@ -176,11 +176,11 @@ jiradc sprint issues 42 100
|
|
|
176
176
|
jiradc field search --query "story points"
|
|
177
177
|
|
|
178
178
|
# Clone an issue with subtasks
|
|
179
|
-
jiradc issue clone
|
|
179
|
+
jiradc issue clone PROJ-123
|
|
180
180
|
|
|
181
181
|
# Get dev status (linked branches, PRs)
|
|
182
|
-
jiradc issue dev-status
|
|
182
|
+
jiradc issue dev-status PROJ-123
|
|
183
183
|
|
|
184
184
|
# List components for a project
|
|
185
|
-
jiradc component list --project
|
|
185
|
+
jiradc component list --project PROJ
|
|
186
186
|
```
|
package/dist/index.js
CHANGED
|
@@ -237,6 +237,24 @@ var CliAuthError = class extends Error {
|
|
|
237
237
|
this.name = "CliAuthError";
|
|
238
238
|
}
|
|
239
239
|
};
|
|
240
|
+
var NOT_FOUND_RECOVERY = "Verify the id/key, then check your access.";
|
|
241
|
+
var NOT_FOUND_MESSAGE = "Not found: it may not exist, or you may not have permission to see it";
|
|
242
|
+
var CliNotFoundError = class extends Error {
|
|
243
|
+
recovery;
|
|
244
|
+
constructor(message, recovery = NOT_FOUND_RECOVERY) {
|
|
245
|
+
super(message);
|
|
246
|
+
this.name = "CliNotFoundError";
|
|
247
|
+
this.recovery = recovery;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var SubcommandRequiredError = class extends Error {
|
|
251
|
+
subcommands;
|
|
252
|
+
constructor(commandPath3, subcommands) {
|
|
253
|
+
super(`'${commandPath3}' requires a subcommand`);
|
|
254
|
+
this.name = "SubcommandRequiredError";
|
|
255
|
+
this.subcommands = subcommands;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
240
258
|
var TYPE_EXIT = {
|
|
241
259
|
usage: EXIT.USAGE,
|
|
242
260
|
not_found: EXIT.NOT_FOUND,
|
|
@@ -285,9 +303,21 @@ function normalize(err, opts) {
|
|
|
285
303
|
retryable: false
|
|
286
304
|
};
|
|
287
305
|
}
|
|
306
|
+
if (err instanceof SubcommandRequiredError) {
|
|
307
|
+
return {
|
|
308
|
+
type: "usage",
|
|
309
|
+
message,
|
|
310
|
+
recovery: `Re-run with one of these subcommands: ${err.subcommands.join(", ")}.`,
|
|
311
|
+
retryable: false,
|
|
312
|
+
detail: { subcommands: err.subcommands }
|
|
313
|
+
};
|
|
314
|
+
}
|
|
288
315
|
if (err instanceof CliAuthError) {
|
|
289
316
|
return { type: "auth", message: message || "Missing credentials", recovery: opts.authRecovery, retryable: false };
|
|
290
317
|
}
|
|
318
|
+
if (err instanceof CliNotFoundError) {
|
|
319
|
+
return { type: "not_found", message, recovery: err.recovery, retryable: false };
|
|
320
|
+
}
|
|
291
321
|
const status = httpStatus(err);
|
|
292
322
|
const detail = responseDetail(err);
|
|
293
323
|
if (status !== void 0) {
|
|
@@ -296,7 +326,7 @@ function normalize(err, opts) {
|
|
|
296
326
|
return {
|
|
297
327
|
type: "usage",
|
|
298
328
|
status,
|
|
299
|
-
message: "Bad request
|
|
329
|
+
message: "Bad request",
|
|
300
330
|
recovery: "Check parameter values (ids, keys, query syntax) against the API.",
|
|
301
331
|
retryable: false,
|
|
302
332
|
detail
|
|
@@ -305,7 +335,7 @@ function normalize(err, opts) {
|
|
|
305
335
|
return {
|
|
306
336
|
type: "auth",
|
|
307
337
|
status,
|
|
308
|
-
message: "Authentication failed
|
|
338
|
+
message: "Authentication failed",
|
|
309
339
|
recovery: opts.authRecovery,
|
|
310
340
|
retryable: false
|
|
311
341
|
};
|
|
@@ -313,7 +343,7 @@ function normalize(err, opts) {
|
|
|
313
343
|
return {
|
|
314
344
|
type: "forbidden",
|
|
315
345
|
status,
|
|
316
|
-
message: "Forbidden
|
|
346
|
+
message: "Forbidden",
|
|
317
347
|
recovery: `Your ${opts.service} account lacks permission for this operation; check token scope and resource permissions.`,
|
|
318
348
|
retryable: false,
|
|
319
349
|
detail
|
|
@@ -322,8 +352,8 @@ function normalize(err, opts) {
|
|
|
322
352
|
return {
|
|
323
353
|
type: "not_found",
|
|
324
354
|
status,
|
|
325
|
-
message:
|
|
326
|
-
recovery:
|
|
355
|
+
message: NOT_FOUND_MESSAGE,
|
|
356
|
+
recovery: NOT_FOUND_RECOVERY,
|
|
327
357
|
retryable: false,
|
|
328
358
|
detail
|
|
329
359
|
};
|
|
@@ -331,7 +361,7 @@ function normalize(err, opts) {
|
|
|
331
361
|
return {
|
|
332
362
|
type: "conflict",
|
|
333
363
|
status,
|
|
334
|
-
message: "Conflict
|
|
364
|
+
message: "Conflict",
|
|
335
365
|
recovery: "The resource changed or already exists; re-fetch current state and retry.",
|
|
336
366
|
retryable: false,
|
|
337
367
|
detail
|
|
@@ -340,7 +370,7 @@ function normalize(err, opts) {
|
|
|
340
370
|
return {
|
|
341
371
|
type: "rate_limited",
|
|
342
372
|
status,
|
|
343
|
-
message: "Rate limited
|
|
373
|
+
message: "Rate limited",
|
|
344
374
|
recovery: "Wait and retry the request.",
|
|
345
375
|
retryable: true
|
|
346
376
|
};
|
|
@@ -410,8 +440,30 @@ function routeErrors(cmd) {
|
|
|
410
440
|
cmd.configureOutput({ writeErr: () => void 0 });
|
|
411
441
|
cmd.commands.forEach(routeErrors);
|
|
412
442
|
}
|
|
443
|
+
function commandPath2(cmd) {
|
|
444
|
+
const parts = [];
|
|
445
|
+
let cur = cmd;
|
|
446
|
+
while (cur) {
|
|
447
|
+
parts.unshift(cur.name());
|
|
448
|
+
cur = cur.parent;
|
|
449
|
+
}
|
|
450
|
+
return parts.join(" ");
|
|
451
|
+
}
|
|
452
|
+
function attachSubcommandGuards(cmd) {
|
|
453
|
+
cmd.commands.forEach(attachSubcommandGuards);
|
|
454
|
+
if (cmd.commands.length === 0)
|
|
455
|
+
return;
|
|
456
|
+
const hasAction = Boolean(cmd._actionHandler);
|
|
457
|
+
if (hasAction)
|
|
458
|
+
return;
|
|
459
|
+
cmd.action(() => {
|
|
460
|
+
const names = cmd.commands.map((c) => c.name()).filter((name) => name !== "help");
|
|
461
|
+
throw new SubcommandRequiredError(commandPath2(cmd), names);
|
|
462
|
+
});
|
|
463
|
+
}
|
|
413
464
|
async function runCli(program, opts) {
|
|
414
465
|
routeErrors(program);
|
|
466
|
+
attachSubcommandGuards(program);
|
|
415
467
|
try {
|
|
416
468
|
await program.parseAsync();
|
|
417
469
|
} catch (err) {
|
|
@@ -962,9 +1014,9 @@ function create(parent) {
|
|
|
962
1014
|
const cmd = parent.command("create").description("Create a new component in a project").requiredOption("--project <key>", "Project key (e.g., AI)", text).requiredOption("--name <name>", "Component name", text).option("--lead <username>", "Username of the component lead", text).addOption(new Option3("--assignee-type <type>", "Assignee strategy").choices(ASSIGNEE_TYPES));
|
|
963
1015
|
textOrFileOption(cmd, "description", { description: "Component description" });
|
|
964
1016
|
examples(cmd, [
|
|
965
|
-
"--project
|
|
966
|
-
'--project
|
|
967
|
-
"--project
|
|
1017
|
+
"--project PROJ --name Backend",
|
|
1018
|
+
'--project PROJ --name Frontend --description "UI work" --lead jsmith',
|
|
1019
|
+
"--project PROJ --name Infra --assignee-type COMPONENT_LEAD --lead jsmith"
|
|
968
1020
|
]);
|
|
969
1021
|
cmd.action(
|
|
970
1022
|
async (opts) => {
|
|
@@ -1018,7 +1070,7 @@ function issueCount(parent) {
|
|
|
1018
1070
|
// src/commands/component/list.ts
|
|
1019
1071
|
function list2(parent) {
|
|
1020
1072
|
const cmd = parent.command("list").description("List all components for a project").requiredOption("--project <key>", "Project key (e.g., AI)", text);
|
|
1021
|
-
examples(cmd, ["--project
|
|
1073
|
+
examples(cmd, ["--project PROJ"]);
|
|
1022
1074
|
cmd.action(async (opts) => {
|
|
1023
1075
|
const client = getClient();
|
|
1024
1076
|
const result = await client.components.list({ projectKeyOrId: opts.project });
|
|
@@ -1065,9 +1117,9 @@ function update(parent) {
|
|
|
1065
1117
|
function registerComponentCommands(program) {
|
|
1066
1118
|
const component = program.command("component").description("Project component operations");
|
|
1067
1119
|
examples(component, [
|
|
1068
|
-
"list --project
|
|
1120
|
+
"list --project PROJ",
|
|
1069
1121
|
"get 11289",
|
|
1070
|
-
"create --project
|
|
1122
|
+
"create --project PROJ --name Backend",
|
|
1071
1123
|
"update 11289 --name Backend",
|
|
1072
1124
|
"delete 11289 --move-issues-to 11290",
|
|
1073
1125
|
"issue-count 11289"
|
|
@@ -1737,7 +1789,7 @@ function link(parent) {
|
|
|
1737
1789
|
const cmd = parent.command("link").description("Link two issues together").requiredOption("--type <name>", "Link type name (e.g., 'Blocks', 'Duplicate', 'Relates')", text).requiredOption("--from <key>", 'Source issue key (e.g., the issue that "blocks")', issueKey).requiredOption("--to <key>", 'Target issue key (e.g., the issue that "is blocked by")', issueKey);
|
|
1738
1790
|
commentOption(cmd, { description: "Optional comment" });
|
|
1739
1791
|
examples(cmd, [
|
|
1740
|
-
"--type Relates --from
|
|
1792
|
+
"--type Relates --from PROJ-154 --to PROJ-149",
|
|
1741
1793
|
["--type Blocks --from PROJ-456 --to PROJ-123", "PROJ-456 blocks PROJ-123"]
|
|
1742
1794
|
]);
|
|
1743
1795
|
cmd.action(async (opts) => {
|
|
@@ -2397,14 +2449,50 @@ function registerUserCommands(program) {
|
|
|
2397
2449
|
search3(user);
|
|
2398
2450
|
}
|
|
2399
2451
|
|
|
2452
|
+
// src/utils/xray/guards.ts
|
|
2453
|
+
function assertExactlyOne(opts, keys, label) {
|
|
2454
|
+
const present = keys.filter((k) => opts[k] !== void 0);
|
|
2455
|
+
if (present.length !== 1)
|
|
2456
|
+
throw new Error(`Provide exactly one of ${keys.map((k) => `--${k}`).join(", ")} (${label}).`);
|
|
2457
|
+
return present[0];
|
|
2458
|
+
}
|
|
2459
|
+
function assertAtLeastOne(opts, keys) {
|
|
2460
|
+
if (!keys.some((k) => opts[k] !== void 0))
|
|
2461
|
+
throw new Error(`Provide at least one of ${keys.map((k) => `--${k}`).join(", ")}.`);
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2400
2464
|
// src/commands/xray/execution/add.ts
|
|
2401
2465
|
function add(parent) {
|
|
2402
|
-
const cmd = parent.command("add").description("Add tests to a Test Execution").argument("<execKey>", "Test Execution issue key (e.g.
|
|
2403
|
-
|
|
2466
|
+
const cmd = parent.command("add").description("Add tests to a Test Execution, directly (--test) and/or by expanding Test Sets (--set)").argument("<execKey>", "Test Execution issue key (e.g. PROJ-200)", issueKey).option("--test <keys>", "Comma-separated test issue keys to add (e.g. PROJ-1,PROJ-2)", keyList).option(
|
|
2467
|
+
"--set <keys>",
|
|
2468
|
+
"Comma-separated Test Set keys; each set's current tests are added to the execution (e.g. PROJ-300)",
|
|
2469
|
+
keyList
|
|
2470
|
+
);
|
|
2471
|
+
examples(cmd, [
|
|
2472
|
+
"PROJ-200 --test PROJ-1",
|
|
2473
|
+
"PROJ-200 --test PROJ-1,PROJ-2",
|
|
2474
|
+
"PROJ-200 --set PROJ-300",
|
|
2475
|
+
"PROJ-200 --test PROJ-1 --set PROJ-300"
|
|
2476
|
+
]);
|
|
2404
2477
|
cmd.action(async (execKey, opts) => {
|
|
2405
|
-
|
|
2406
|
-
const
|
|
2407
|
-
|
|
2478
|
+
assertAtLeastOne(opts, ["test", "set"]);
|
|
2479
|
+
const client = getClient();
|
|
2480
|
+
const keys = new Set(opts.test ?? []);
|
|
2481
|
+
if (opts.set) {
|
|
2482
|
+
const lists = await Promise.all(opts.set.map((setKey) => client.testSets.listTests({ setKey })));
|
|
2483
|
+
for (const list20 of lists) {
|
|
2484
|
+
const tests = Array.isArray(list20) ? list20 : list20.tests ?? [];
|
|
2485
|
+
for (const t of tests) {
|
|
2486
|
+
if (t.key) keys.add(String(t.key));
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
const allKeys = [...keys];
|
|
2491
|
+
if (allKeys.length === 0) {
|
|
2492
|
+
throw new Error("No tests to add \u2014 the given --set(s) contain no tests and no --test keys were provided.");
|
|
2493
|
+
}
|
|
2494
|
+
const result = await client.testExecutions.addTests({ execKey, keys: allKeys });
|
|
2495
|
+
output(result ?? { added: allKeys });
|
|
2408
2496
|
});
|
|
2409
2497
|
}
|
|
2410
2498
|
|
|
@@ -2441,8 +2529,8 @@ function create7(parent) {
|
|
|
2441
2529
|
const cmd = parent.command("create").description("Create a new Xray Test Execution issue").requiredOption("--project <key>", "Project key (e.g. AI)", text).requiredOption("--summary <text>", "Test Execution summary (title)", text);
|
|
2442
2530
|
textOrFileOption(cmd, "description", { description: "Test Execution description" });
|
|
2443
2531
|
examples(cmd, [
|
|
2444
|
-
'--project
|
|
2445
|
-
'--project
|
|
2532
|
+
'--project PROJ --summary "Sprint 42 regression run"',
|
|
2533
|
+
'--project PROJ --summary "Smoke run" --description "Post-deploy smoke"'
|
|
2446
2534
|
]);
|
|
2447
2535
|
cmd.action(async (opts) => {
|
|
2448
2536
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
@@ -2459,8 +2547,8 @@ function create7(parent) {
|
|
|
2459
2547
|
|
|
2460
2548
|
// src/commands/xray/execution/delete.ts
|
|
2461
2549
|
function deleteExecution(parent) {
|
|
2462
|
-
const cmd = parent.command("delete").description("Delete an Xray Test Execution issue").argument("<execKey>", "Test Execution issue key (e.g.
|
|
2463
|
-
examples(cmd, ["
|
|
2550
|
+
const cmd = parent.command("delete").description("Delete an Xray Test Execution issue").argument("<execKey>", "Test Execution issue key (e.g. PROJ-200)", issueKey);
|
|
2551
|
+
examples(cmd, ["PROJ-200"]);
|
|
2464
2552
|
cmd.action(async (execKey) => {
|
|
2465
2553
|
const client = getClient();
|
|
2466
2554
|
await deleteXrayIssue(client, execKey);
|
|
@@ -2472,8 +2560,8 @@ function deleteExecution(parent) {
|
|
|
2472
2560
|
function list8(parent) {
|
|
2473
2561
|
const cmd = parent.command("list").description(
|
|
2474
2562
|
"List Test Executions that contain a given test (inverse view). For the tests inside an execution, use: xray test list --execution <key>."
|
|
2475
|
-
).requiredOption("--test <key>", "Test issue key whose executions to list (e.g.
|
|
2476
|
-
examples(cmd, ["--test
|
|
2563
|
+
).requiredOption("--test <key>", "Test issue key whose executions to list (e.g. PROJ-584)", issueKey);
|
|
2564
|
+
examples(cmd, ["--test PROJ-584"]);
|
|
2477
2565
|
cmd.action(async (opts) => {
|
|
2478
2566
|
const client = getClient();
|
|
2479
2567
|
const executions = await client.xrayTests.getTestExecutions({ testKey: opts.test });
|
|
@@ -2483,8 +2571,8 @@ function list8(parent) {
|
|
|
2483
2571
|
|
|
2484
2572
|
// src/commands/xray/execution/remove.ts
|
|
2485
2573
|
function remove(parent) {
|
|
2486
|
-
const cmd = parent.command("remove").description("Remove tests from a Test Execution").argument("<execKey>", "Test Execution issue key (e.g.
|
|
2487
|
-
examples(cmd, ["
|
|
2574
|
+
const cmd = parent.command("remove").description("Remove tests from a Test Execution").argument("<execKey>", "Test Execution issue key (e.g. PROJ-200)", issueKey).requiredOption("--test <keys>", "Comma-separated test issue keys to remove (e.g. PROJ-1,PROJ-2)", keyList);
|
|
2575
|
+
examples(cmd, ["PROJ-200 --test PROJ-1", "PROJ-200 --test PROJ-1,PROJ-2"]);
|
|
2488
2576
|
cmd.action(async (execKey, opts) => {
|
|
2489
2577
|
const client = getClient();
|
|
2490
2578
|
const result = await client.testExecutions.removeTests({ execKey, keys: opts.test });
|
|
@@ -2494,9 +2582,9 @@ function remove(parent) {
|
|
|
2494
2582
|
|
|
2495
2583
|
// src/commands/xray/execution/update.ts
|
|
2496
2584
|
function update6(parent) {
|
|
2497
|
-
const cmd = parent.command("update").description("Update an Xray Test Execution issue").argument("<execKey>", "Test Execution issue key (e.g.
|
|
2585
|
+
const cmd = parent.command("update").description("Update an Xray Test Execution issue").argument("<execKey>", "Test Execution issue key (e.g. PROJ-200)", issueKey).option("--summary <text>", "New summary (title)", text);
|
|
2498
2586
|
textOrFileOption(cmd, "description", { description: "New Test Execution description" });
|
|
2499
|
-
examples(cmd, ['
|
|
2587
|
+
examples(cmd, ['PROJ-200 --summary "Updated execution title"', 'PROJ-200 --description "Post-hotfix run"']);
|
|
2500
2588
|
cmd.action(async (execKey, opts) => {
|
|
2501
2589
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
2502
2590
|
const client = getClient();
|
|
@@ -2511,9 +2599,9 @@ function registerExecutionCommands(xray) {
|
|
|
2511
2599
|
"Xray Test Execution issue management (CRUD, membership). To list tests inside an execution, use: xray test list --execution <key>."
|
|
2512
2600
|
);
|
|
2513
2601
|
examples(execution2, [
|
|
2514
|
-
'create --project
|
|
2515
|
-
"add
|
|
2516
|
-
"list --test
|
|
2602
|
+
'create --project PROJ --summary "Sprint 42 regression run"',
|
|
2603
|
+
"add PROJ-200 --test PROJ-1,PROJ-2",
|
|
2604
|
+
"list --test PROJ-584"
|
|
2517
2605
|
]);
|
|
2518
2606
|
create7(execution2);
|
|
2519
2607
|
update6(execution2);
|
|
@@ -2528,7 +2616,7 @@ import { writeFileSync as writeFileSync2 } from "fs";
|
|
|
2528
2616
|
import { basename, join as join5 } from "path";
|
|
2529
2617
|
function feature(parent) {
|
|
2530
2618
|
const cmd = parent.command("feature").description("Export Gherkin .feature files for the given test keys").requiredOption("--test <keys>", "Comma-separated Test, Set, Plan, or Execution issue keys", keyList).option("--output <path>", "Write the exported file to this path (default: ./<filename> from response)", text).option("--zip", "Request a zip archive instead of a single .feature file");
|
|
2531
|
-
examples(cmd, ["--test
|
|
2619
|
+
examples(cmd, ["--test PROJ-584 --output ai-584.feature"]);
|
|
2532
2620
|
cmd.action(async (opts) => {
|
|
2533
2621
|
const client = getClient();
|
|
2534
2622
|
const { data, filename } = await client.xrayExport.exportFeature({
|
|
@@ -2566,8 +2654,8 @@ function registerFieldCommands2(xray) {
|
|
|
2566
2654
|
|
|
2567
2655
|
// src/commands/xray/folder/add.ts
|
|
2568
2656
|
function add2(parent) {
|
|
2569
|
-
const cmd = parent.command("add").description("Add tests to a folder in the test repository").argument("<folderId>", "Folder id (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text).requiredOption("--test <keys>", "Comma-separated test issue keys to add (e.g.
|
|
2570
|
-
examples(cmd, ["818 --project
|
|
2657
|
+
const cmd = parent.command("add").description("Add tests to a folder in the test repository").argument("<folderId>", "Folder id (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text).requiredOption("--test <keys>", "Comma-separated test issue keys to add (e.g. PROJ-1,PROJ-2)", keyList);
|
|
2658
|
+
examples(cmd, ["818 --project PROJ --test PROJ-1", "818 --project PROJ --test PROJ-1,PROJ-2,PROJ-3"]);
|
|
2571
2659
|
cmd.action(async (folderId, opts) => {
|
|
2572
2660
|
const client = getClient();
|
|
2573
2661
|
const result = await client.testRepository.updateFolderTests({
|
|
@@ -2583,9 +2671,9 @@ function add2(parent) {
|
|
|
2583
2671
|
function create8(parent) {
|
|
2584
2672
|
const cmd = parent.command("create").description("Create a new folder in the test repository").requiredOption("--project <key>", "Project key (e.g. QA)", text).option("--parent-id <id>", "Parent folder id (-1 = root)", integer, -1).requiredOption("--name <text>", "Folder name", text);
|
|
2585
2673
|
examples(cmd, [
|
|
2586
|
-
"--project
|
|
2587
|
-
'--project
|
|
2588
|
-
'--project
|
|
2674
|
+
"--project PROJ --name Smoke",
|
|
2675
|
+
'--project PROJ --parent-id -1 --name "Regression Suite"',
|
|
2676
|
+
'--project PROJ --parent-id 818 --name "Sub-folder"'
|
|
2589
2677
|
]);
|
|
2590
2678
|
cmd.action(async (opts) => {
|
|
2591
2679
|
const client = getClient();
|
|
@@ -2601,7 +2689,7 @@ function create8(parent) {
|
|
|
2601
2689
|
// src/commands/xray/folder/delete.ts
|
|
2602
2690
|
function deleteFolder(parent) {
|
|
2603
2691
|
const cmd = parent.command("delete").description("Delete a folder from the test repository").argument("<folderId>", "Folder id to delete (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text);
|
|
2604
|
-
examples(cmd, ["818 --project
|
|
2692
|
+
examples(cmd, ["818 --project PROJ", "42 --project PROJ"]);
|
|
2605
2693
|
cmd.action(async (folderId, opts) => {
|
|
2606
2694
|
const client = getClient();
|
|
2607
2695
|
await client.testRepository.deleteFolder({ projectKey: opts.project, folderId });
|
|
@@ -2612,7 +2700,7 @@ function deleteFolder(parent) {
|
|
|
2612
2700
|
// src/commands/xray/folder/list.ts
|
|
2613
2701
|
function list10(parent) {
|
|
2614
2702
|
const cmd = parent.command("list").description("List the test repository folder tree for a project").requiredOption("--project <key>", "Project key (e.g. QA)", text);
|
|
2615
|
-
examples(cmd, ["--project
|
|
2703
|
+
examples(cmd, ["--project PROJ", "--project PROJ"]);
|
|
2616
2704
|
cmd.action(async (opts) => {
|
|
2617
2705
|
const client = getClient();
|
|
2618
2706
|
const tree = await client.testRepository.getFolders({ projectKey: opts.project });
|
|
@@ -2622,8 +2710,8 @@ function list10(parent) {
|
|
|
2622
2710
|
|
|
2623
2711
|
// src/commands/xray/folder/remove.ts
|
|
2624
2712
|
function remove2(parent) {
|
|
2625
|
-
const cmd = parent.command("remove").description("Remove tests from a folder in the test repository").argument("<folderId>", "Folder id (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text).requiredOption("--test <keys>", "Comma-separated test issue keys to remove (e.g.
|
|
2626
|
-
examples(cmd, ["818 --project
|
|
2713
|
+
const cmd = parent.command("remove").description("Remove tests from a folder in the test repository").argument("<folderId>", "Folder id (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text).requiredOption("--test <keys>", "Comma-separated test issue keys to remove (e.g. PROJ-1,PROJ-2)", keyList);
|
|
2714
|
+
examples(cmd, ["818 --project PROJ --test PROJ-1", "818 --project PROJ --test PROJ-1,PROJ-2"]);
|
|
2627
2715
|
cmd.action(async (folderId, opts) => {
|
|
2628
2716
|
const client = getClient();
|
|
2629
2717
|
const result = await client.testRepository.updateFolderTests({
|
|
@@ -2639,9 +2727,9 @@ function remove2(parent) {
|
|
|
2639
2727
|
function update7(parent) {
|
|
2640
2728
|
const cmd = parent.command("update").description("Rename or reorder a folder in the test repository").argument("<folderId>", "Folder id (from folder list)", positiveInt).requiredOption("--project <key>", "Project key (e.g. QA)", text).option("--name <text>", "New folder name", text).option("--rank <id>", "New folder rank/position", positiveInt);
|
|
2641
2729
|
examples(cmd, [
|
|
2642
|
-
'818 --project
|
|
2643
|
-
"818 --project
|
|
2644
|
-
"818 --project
|
|
2730
|
+
'818 --project PROJ --name "New Name"',
|
|
2731
|
+
"818 --project PROJ --rank 2",
|
|
2732
|
+
"818 --project PROJ --name Smoke --rank 1"
|
|
2645
2733
|
]);
|
|
2646
2734
|
cmd.action(async (folderId, opts) => {
|
|
2647
2735
|
if (opts.name === void 0 && opts.rank === void 0) {
|
|
@@ -2663,7 +2751,7 @@ function registerFolderCommands(xray) {
|
|
|
2663
2751
|
const folder = xray.command("folder").description(
|
|
2664
2752
|
"Xray Test Repository folder management (rename/reorder within parent only \u2014 cross-parent moves are UI-only, not supported by the API). To list tests in a folder use: xray test list --folder <id> --project <key>"
|
|
2665
2753
|
);
|
|
2666
|
-
examples(folder, ["list --project
|
|
2754
|
+
examples(folder, ["list --project PROJ", "create --project PROJ --parent-id -1 --name Smoke"]);
|
|
2667
2755
|
list10(folder);
|
|
2668
2756
|
create8(folder);
|
|
2669
2757
|
update7(folder);
|
|
@@ -2694,8 +2782,8 @@ function execution(parent) {
|
|
|
2694
2782
|
issueKey
|
|
2695
2783
|
).option("--plan <key>", "Associate with a Test Plan issue key", issueKey).option("--fix-version <text>", "Fix version to set on the Test Execution", text).option("--revision <text>", "Source control revision", text).option("--environments <text>", "Comma-separated test environment names", text);
|
|
2696
2784
|
examples(cmd, [
|
|
2697
|
-
"--file results.xml --format junit --project
|
|
2698
|
-
"--file results.xml --format junit --execution
|
|
2785
|
+
"--file results.xml --format junit --project PROJ",
|
|
2786
|
+
"--file results.xml --format junit --execution PROJ-100",
|
|
2699
2787
|
"--file results.json --format xray"
|
|
2700
2788
|
]);
|
|
2701
2789
|
cmd.action(
|
|
@@ -2730,7 +2818,7 @@ import { readFileSync as readFileSync5 } from "fs";
|
|
|
2730
2818
|
import { basename as basename3 } from "path";
|
|
2731
2819
|
function feature2(parent) {
|
|
2732
2820
|
const cmd = parent.command("feature").description("Import a Gherkin .feature file into the Xray test repository (multipart)").requiredOption("--file <path>", "Path to the .feature file", filePath).requiredOption("--project <text>", "Project key to import the feature into", text);
|
|
2733
|
-
examples(cmd, ["--file login.feature --project
|
|
2821
|
+
examples(cmd, ["--file login.feature --project PROJ"]);
|
|
2734
2822
|
cmd.action(async (opts) => {
|
|
2735
2823
|
const fileBuffer = readFileSync5(opts.file);
|
|
2736
2824
|
const filename = basename3(opts.file);
|
|
@@ -2751,22 +2839,14 @@ function registerImportCommands(xray) {
|
|
|
2751
2839
|
feature2(importGroup);
|
|
2752
2840
|
}
|
|
2753
2841
|
|
|
2754
|
-
// src/utils/xray/guards.ts
|
|
2755
|
-
function assertExactlyOne(opts, keys, label) {
|
|
2756
|
-
const present = keys.filter((k) => opts[k] !== void 0);
|
|
2757
|
-
if (present.length !== 1)
|
|
2758
|
-
throw new Error(`Provide exactly one of ${keys.map((k) => `--${k}`).join(", ")} (${label}).`);
|
|
2759
|
-
return present[0];
|
|
2760
|
-
}
|
|
2761
|
-
function assertAtLeastOne(opts, keys) {
|
|
2762
|
-
if (!keys.some((k) => opts[k] !== void 0))
|
|
2763
|
-
throw new Error(`Provide at least one of ${keys.map((k) => `--${k}`).join(", ")}.`);
|
|
2764
|
-
}
|
|
2765
|
-
|
|
2766
2842
|
// src/commands/xray/plan/add.ts
|
|
2767
2843
|
function add3(parent) {
|
|
2768
|
-
const cmd = parent.command("add").description("Add tests and/or executions to a Test Plan").argument("<planKey>", "Test Plan issue key (e.g.
|
|
2769
|
-
examples(cmd, [
|
|
2844
|
+
const cmd = parent.command("add").description("Add tests and/or executions to a Test Plan").argument("<planKey>", "Test Plan issue key (e.g. PROJ-573)", issueKey).option("--test <keys>", "Comma-separated test issue keys to add (e.g. PROJ-1,PROJ-2)", keyList).option("--execution <keys>", "Comma-separated test execution keys to add (e.g. PROJ-200,PROJ-201)", keyList);
|
|
2845
|
+
examples(cmd, [
|
|
2846
|
+
"PROJ-573 --test PROJ-1,PROJ-2",
|
|
2847
|
+
"PROJ-573 --execution PROJ-200",
|
|
2848
|
+
"PROJ-573 --test PROJ-1 --execution PROJ-200"
|
|
2849
|
+
]);
|
|
2770
2850
|
cmd.action(async (planKey, opts) => {
|
|
2771
2851
|
assertAtLeastOne(opts, ["test", "execution"]);
|
|
2772
2852
|
const client = getClient();
|
|
@@ -2783,8 +2863,8 @@ function create9(parent) {
|
|
|
2783
2863
|
const cmd = parent.command("create").description("Create a new Xray Test Plan issue").requiredOption("--project <key>", "Project key (e.g. QA)", text).requiredOption("--summary <text>", "Test Plan summary (title)", text);
|
|
2784
2864
|
textOrFileOption(cmd, "description", { description: "Test Plan description" });
|
|
2785
2865
|
examples(cmd, [
|
|
2786
|
-
'--project
|
|
2787
|
-
'--project
|
|
2866
|
+
'--project PROJ --summary "Q3 regression plan"',
|
|
2867
|
+
'--project PROJ --summary "Sprint 42 plan" --description "Covers all sprint stories"'
|
|
2788
2868
|
]);
|
|
2789
2869
|
cmd.action(async (opts) => {
|
|
2790
2870
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
@@ -2801,8 +2881,8 @@ function create9(parent) {
|
|
|
2801
2881
|
|
|
2802
2882
|
// src/commands/xray/plan/delete.ts
|
|
2803
2883
|
function deletePlan(parent) {
|
|
2804
|
-
const cmd = parent.command("delete").description("Delete an Xray Test Plan issue").argument("<planKey>", "Test Plan issue key (e.g.
|
|
2805
|
-
examples(cmd, ["
|
|
2884
|
+
const cmd = parent.command("delete").description("Delete an Xray Test Plan issue").argument("<planKey>", "Test Plan issue key (e.g. PROJ-573)", issueKey);
|
|
2885
|
+
examples(cmd, ["PROJ-573"]);
|
|
2806
2886
|
cmd.action(async (planKey) => {
|
|
2807
2887
|
const client = getClient();
|
|
2808
2888
|
await deleteXrayIssue(client, planKey);
|
|
@@ -2814,8 +2894,8 @@ function deletePlan(parent) {
|
|
|
2814
2894
|
function list11(parent) {
|
|
2815
2895
|
const cmd = parent.command("list").description(
|
|
2816
2896
|
"List Test Plans that contain a given test (inverse view). For the tests inside a plan, use: xray test list --plan <key>. For executions in a plan, use: xray execution list --plan <key>."
|
|
2817
|
-
).requiredOption("--test <key>", "Test issue key whose plans to list (e.g.
|
|
2818
|
-
examples(cmd, ["--test
|
|
2897
|
+
).requiredOption("--test <key>", "Test issue key whose plans to list (e.g. PROJ-574)", issueKey);
|
|
2898
|
+
examples(cmd, ["--test PROJ-574"]);
|
|
2819
2899
|
cmd.action(async (opts) => {
|
|
2820
2900
|
const client = getClient();
|
|
2821
2901
|
const plans = await client.xrayTests.getTestPlans({ testKey: opts.test });
|
|
@@ -2825,8 +2905,12 @@ function list11(parent) {
|
|
|
2825
2905
|
|
|
2826
2906
|
// src/commands/xray/plan/remove.ts
|
|
2827
2907
|
function remove3(parent) {
|
|
2828
|
-
const cmd = parent.command("remove").description("Remove tests and/or executions from a Test Plan").argument("<planKey>", "Test Plan issue key (e.g.
|
|
2829
|
-
examples(cmd, [
|
|
2908
|
+
const cmd = parent.command("remove").description("Remove tests and/or executions from a Test Plan").argument("<planKey>", "Test Plan issue key (e.g. PROJ-573)", issueKey).option("--test <keys>", "Comma-separated test issue keys to remove (e.g. PROJ-1,PROJ-2)", keyList).option("--execution <keys>", "Comma-separated test execution keys to remove (e.g. PROJ-200)", keyList);
|
|
2909
|
+
examples(cmd, [
|
|
2910
|
+
"PROJ-573 --test PROJ-1",
|
|
2911
|
+
"PROJ-573 --execution PROJ-200",
|
|
2912
|
+
"PROJ-573 --test PROJ-1 --execution PROJ-200"
|
|
2913
|
+
]);
|
|
2830
2914
|
cmd.action(async (planKey, opts) => {
|
|
2831
2915
|
assertAtLeastOne(opts, ["test", "execution"]);
|
|
2832
2916
|
const client = getClient();
|
|
@@ -2840,9 +2924,9 @@ function remove3(parent) {
|
|
|
2840
2924
|
|
|
2841
2925
|
// src/commands/xray/plan/update.ts
|
|
2842
2926
|
function update8(parent) {
|
|
2843
|
-
const cmd = parent.command("update").description("Update an Xray Test Plan issue").argument("<planKey>", "Test Plan issue key (e.g.
|
|
2927
|
+
const cmd = parent.command("update").description("Update an Xray Test Plan issue").argument("<planKey>", "Test Plan issue key (e.g. PROJ-573)", issueKey).option("--summary <text>", "New summary (title)", text);
|
|
2844
2928
|
textOrFileOption(cmd, "description", { description: "New Test Plan description" });
|
|
2845
|
-
examples(cmd, ['
|
|
2929
|
+
examples(cmd, ['PROJ-573 --summary "Updated plan title"', 'PROJ-573 --description "Revised scope"']);
|
|
2846
2930
|
cmd.action(async (planKey, opts) => {
|
|
2847
2931
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
2848
2932
|
const client = getClient();
|
|
@@ -2857,10 +2941,10 @@ function registerPlanCommands(xray) {
|
|
|
2857
2941
|
"Xray Test Plan issue management (CRUD, membership). To list tests inside a plan, use: xray test list --plan <key>."
|
|
2858
2942
|
);
|
|
2859
2943
|
examples(plan, [
|
|
2860
|
-
'create --project
|
|
2861
|
-
"add
|
|
2862
|
-
"add
|
|
2863
|
-
"list --test
|
|
2944
|
+
'create --project PROJ --summary "Q3 regression plan"',
|
|
2945
|
+
"add PROJ-573 --test PROJ-1,PROJ-2",
|
|
2946
|
+
"add PROJ-573 --test PROJ-1 --execution PROJ-200",
|
|
2947
|
+
"list --test PROJ-574"
|
|
2864
2948
|
]);
|
|
2865
2949
|
create9(plan);
|
|
2866
2950
|
update8(plan);
|
|
@@ -2872,8 +2956,8 @@ function registerPlanCommands(xray) {
|
|
|
2872
2956
|
|
|
2873
2957
|
// src/commands/xray/precondition/add.ts
|
|
2874
2958
|
function add4(parent) {
|
|
2875
|
-
const cmd = parent.command("add").description("Add tests to a Pre-Condition").argument("<preKey>", "Pre-Condition issue key (e.g.
|
|
2876
|
-
examples(cmd, ["
|
|
2959
|
+
const cmd = parent.command("add").description("Add tests to a Pre-Condition").argument("<preKey>", "Pre-Condition issue key (e.g. PROJ-50)", issueKey).requiredOption("--test <keys>", "Comma-separated test issue keys to add (e.g. PROJ-1,PROJ-2)", keyList);
|
|
2960
|
+
examples(cmd, ["PROJ-50 --test PROJ-1", "PROJ-50 --test PROJ-1,PROJ-2,PROJ-3"]);
|
|
2877
2961
|
cmd.action(async (preKey, opts) => {
|
|
2878
2962
|
const client = getClient();
|
|
2879
2963
|
const result = await client.preconditions.addTests({ preKey, keys: opts.test });
|
|
@@ -2981,7 +3065,7 @@ function buildPreconditionCustomFields(map, opts) {
|
|
|
2981
3065
|
// src/commands/xray/precondition/create.ts
|
|
2982
3066
|
function create10(parent) {
|
|
2983
3067
|
const cmd = parent.command("create").description(
|
|
2984
|
-
"Create a new Xray Pre-Condition issue. Note: the Pre-Condition issue type is only available in projects that have it configured (e.g. BD); it is not on
|
|
3068
|
+
"Create a new Xray Pre-Condition issue. Note: the Pre-Condition issue type is only available in projects that have it configured (e.g. BD); it is not on your project scheme."
|
|
2985
3069
|
).requiredOption("--project <key>", "Project key (e.g. BD)", text).requiredOption("--summary <text>", "Pre-Condition summary (title)", text).addOption(
|
|
2986
3070
|
new Option10("--type <type>", "Pre-Condition type").choices(["manual", "generic", "cucumber"]).default("manual")
|
|
2987
3071
|
);
|
|
@@ -3020,8 +3104,8 @@ function create10(parent) {
|
|
|
3020
3104
|
|
|
3021
3105
|
// src/commands/xray/precondition/delete.ts
|
|
3022
3106
|
function deletePrecondition(parent) {
|
|
3023
|
-
const cmd = parent.command("delete").description("Delete an Xray Pre-Condition issue").argument("<preKey>", "Pre-Condition issue key (e.g.
|
|
3024
|
-
examples(cmd, ["
|
|
3107
|
+
const cmd = parent.command("delete").description("Delete an Xray Pre-Condition issue").argument("<preKey>", "Pre-Condition issue key (e.g. PROJ-50)", issueKey);
|
|
3108
|
+
examples(cmd, ["PROJ-50"]);
|
|
3025
3109
|
cmd.action(async (preKey) => {
|
|
3026
3110
|
const client = getClient();
|
|
3027
3111
|
await deleteXrayIssue(client, preKey);
|
|
@@ -3033,8 +3117,8 @@ function deletePrecondition(parent) {
|
|
|
3033
3117
|
function list12(parent) {
|
|
3034
3118
|
const cmd = parent.command("list").description(
|
|
3035
3119
|
"List Pre-Conditions that apply to a given test (inverse view). For the forward view (tests covered by a precondition), use: xray precondition add/remove."
|
|
3036
|
-
).requiredOption("--test <key>", "Test issue key whose pre-conditions to list (e.g.
|
|
3037
|
-
examples(cmd, ["--test
|
|
3120
|
+
).requiredOption("--test <key>", "Test issue key whose pre-conditions to list (e.g. PROJ-584)", issueKey);
|
|
3121
|
+
examples(cmd, ["--test PROJ-584"]);
|
|
3038
3122
|
cmd.action(async (opts) => {
|
|
3039
3123
|
const client = getClient();
|
|
3040
3124
|
const preconditions = await client.xrayTests.getPreconditions({ testKey: opts.test });
|
|
@@ -3044,8 +3128,8 @@ function list12(parent) {
|
|
|
3044
3128
|
|
|
3045
3129
|
// src/commands/xray/precondition/remove.ts
|
|
3046
3130
|
function remove4(parent) {
|
|
3047
|
-
const cmd = parent.command("remove").description("Remove tests from a Pre-Condition").argument("<preKey>", "Pre-Condition issue key (e.g.
|
|
3048
|
-
examples(cmd, ["
|
|
3131
|
+
const cmd = parent.command("remove").description("Remove tests from a Pre-Condition").argument("<preKey>", "Pre-Condition issue key (e.g. PROJ-50)", issueKey).requiredOption("--test <keys>", "Comma-separated test issue keys to remove (e.g. PROJ-1,PROJ-2)", keyList);
|
|
3132
|
+
examples(cmd, ["PROJ-50 --test PROJ-1", "PROJ-50 --test PROJ-1,PROJ-2"]);
|
|
3049
3133
|
cmd.action(async (preKey, opts) => {
|
|
3050
3134
|
const client = getClient();
|
|
3051
3135
|
const result = await client.preconditions.removeTests({ preKey, keys: opts.test });
|
|
@@ -3056,10 +3140,10 @@ function remove4(parent) {
|
|
|
3056
3140
|
// src/commands/xray/precondition/update.ts
|
|
3057
3141
|
import { Option as Option11 } from "commander";
|
|
3058
3142
|
function update9(parent) {
|
|
3059
|
-
const cmd = parent.command("update").description("Update an Xray Pre-Condition issue").argument("<preKey>", "Pre-Condition issue key (e.g.
|
|
3143
|
+
const cmd = parent.command("update").description("Update an Xray Pre-Condition issue").argument("<preKey>", "Pre-Condition issue key (e.g. PROJ-50)", issueKey).option("--summary <text>", "New summary (title)", text).addOption(new Option11("--type <type>", "New Pre-Condition type").choices(["manual", "generic", "cucumber"]));
|
|
3060
3144
|
textOrFileOption(cmd, "condition", { description: "New pre-condition body / definition text" });
|
|
3061
3145
|
textOrFileOption(cmd, "description", { description: "New Pre-Condition issue description" });
|
|
3062
|
-
examples(cmd, ['
|
|
3146
|
+
examples(cmd, ['PROJ-50 --summary "Updated precondition"', 'PROJ-50 --type generic --condition "apiKey != null"']);
|
|
3063
3147
|
cmd.action(
|
|
3064
3148
|
async (preKey, opts) => {
|
|
3065
3149
|
const condition = resolveTextOrFile(opts, "condition", { required: false });
|
|
@@ -3097,12 +3181,12 @@ function update9(parent) {
|
|
|
3097
3181
|
// src/commands/xray/precondition/index.ts
|
|
3098
3182
|
function registerPreconditionCommands(xray) {
|
|
3099
3183
|
const precondition = xray.command("precondition").description(
|
|
3100
|
-
"Xray Pre-Condition issue management (CRUD, membership). Note: Pre-Condition issue type is only available in projects where it is configured (not
|
|
3184
|
+
"Xray Pre-Condition issue management (CRUD, membership). Note: Pre-Condition issue type is only available in projects where it is configured (not your project). To list tests covered by a precondition, use: xray test list --precondition <key>."
|
|
3101
3185
|
);
|
|
3102
3186
|
examples(precondition, [
|
|
3103
3187
|
'create --project BD --summary "User is logged in"',
|
|
3104
|
-
"add
|
|
3105
|
-
"list --test
|
|
3188
|
+
"add PROJ-50 --test PROJ-1,PROJ-2",
|
|
3189
|
+
"list --test PROJ-584"
|
|
3106
3190
|
]);
|
|
3107
3191
|
create10(precondition);
|
|
3108
3192
|
update9(precondition);
|
|
@@ -3124,7 +3208,7 @@ async function resolveRunId(client, o) {
|
|
|
3124
3208
|
// src/commands/xray/run/defect/add.ts
|
|
3125
3209
|
function add5(parent) {
|
|
3126
3210
|
const cmd = parent.command("add").description("Link defect issues to a test run").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--defect <keys>", "Comma-separated defect issue keys to link", keyList).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3127
|
-
examples(cmd, ["42 --defect BUG-1", "--execution
|
|
3211
|
+
examples(cmd, ["42 --defect BUG-1", "--execution PROJ-1 --test PROJ-2 --defect BUG-1,BUG-2"]);
|
|
3128
3212
|
cmd.action(async (runId, opts) => {
|
|
3129
3213
|
const client = getClient();
|
|
3130
3214
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3136,7 +3220,7 @@ function add5(parent) {
|
|
|
3136
3220
|
// src/commands/xray/run/defect/remove.ts
|
|
3137
3221
|
function remove5(parent) {
|
|
3138
3222
|
const cmd = parent.command("remove").description("Unlink defect issues from a test run (per-key, reports failures without aborting)").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--defect <keys>", "Comma-separated defect issue keys to unlink", keyList).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3139
|
-
examples(cmd, ["42 --defect BUG-1", "--execution
|
|
3223
|
+
examples(cmd, ["42 --defect BUG-1", "--execution PROJ-1 --test PROJ-2 --defect BUG-1,BUG-2"]);
|
|
3140
3224
|
cmd.action(async (runId, opts) => {
|
|
3141
3225
|
const client = getClient();
|
|
3142
3226
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3170,7 +3254,7 @@ function registerDefectCommands(run) {
|
|
|
3170
3254
|
const defect = run.command("defect").description(
|
|
3171
3255
|
"Manage defects linked to a test run. See also: run update --defect for the one-command fail+link loop."
|
|
3172
3256
|
);
|
|
3173
|
-
examples(defect, ["add --execution
|
|
3257
|
+
examples(defect, ["add --execution PROJ-1 --test PROJ-2 --defect BUG-1", "remove 42 --defect BUG-1"]);
|
|
3174
3258
|
add5(defect);
|
|
3175
3259
|
remove5(defect);
|
|
3176
3260
|
}
|
|
@@ -3196,7 +3280,7 @@ function inferContentType(fp) {
|
|
|
3196
3280
|
}
|
|
3197
3281
|
function add6(parent) {
|
|
3198
3282
|
const cmd = parent.command("add").description("Attach a file as evidence to a test run").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--file <path>", "Path to the file to attach", filePath).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3199
|
-
examples(cmd, ["42 --file screenshot.png", "--execution
|
|
3283
|
+
examples(cmd, ["42 --file screenshot.png", "--execution PROJ-1 --test PROJ-2 --file report.pdf"]);
|
|
3200
3284
|
cmd.action(async (runId, opts) => {
|
|
3201
3285
|
const client = getClient();
|
|
3202
3286
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3212,7 +3296,7 @@ function add6(parent) {
|
|
|
3212
3296
|
// src/commands/xray/run/evidence/delete.ts
|
|
3213
3297
|
function deleteEvidence(parent) {
|
|
3214
3298
|
const cmd = parent.command("delete").description("Delete an evidence attachment from a test run").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--evidence-id <id>", "Id of the evidence attachment (from evidence list)", positiveInt).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3215
|
-
examples(cmd, ["42 --evidence-id 7", "--execution
|
|
3299
|
+
examples(cmd, ["42 --evidence-id 7", "--execution PROJ-1 --test PROJ-2 --evidence-id 7"]);
|
|
3216
3300
|
cmd.action(async (runId, opts) => {
|
|
3217
3301
|
const client = getClient();
|
|
3218
3302
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3224,7 +3308,7 @@ function deleteEvidence(parent) {
|
|
|
3224
3308
|
// src/commands/xray/run/evidence/list.ts
|
|
3225
3309
|
function list13(parent) {
|
|
3226
3310
|
const cmd = parent.command("list").description("List evidence (attachments) on a test run").argument("[runId]", "Test run id (from run list)", positiveInt).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3227
|
-
examples(cmd, ["42", "--execution
|
|
3311
|
+
examples(cmd, ["42", "--execution PROJ-1 --test PROJ-2"]);
|
|
3228
3312
|
cmd.action(async (runId, opts) => {
|
|
3229
3313
|
const client = getClient();
|
|
3230
3314
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3237,7 +3321,7 @@ function list13(parent) {
|
|
|
3237
3321
|
function registerEvidenceCommands(run) {
|
|
3238
3322
|
const evidence = run.command("evidence").description("Manage evidence (file attachments) on a test run");
|
|
3239
3323
|
examples(evidence, [
|
|
3240
|
-
"add --execution
|
|
3324
|
+
"add --execution PROJ-1 --test PROJ-2 --file screenshot.png",
|
|
3241
3325
|
"list 42",
|
|
3242
3326
|
"delete 42 --evidence-id 7"
|
|
3243
3327
|
]);
|
|
@@ -3249,7 +3333,7 @@ function registerEvidenceCommands(run) {
|
|
|
3249
3333
|
// src/commands/xray/run/field/get.ts
|
|
3250
3334
|
function get4(parent) {
|
|
3251
3335
|
const cmd = parent.command("get").description("Get a custom field value on a test run").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--field-id <id>", "Custom field id (from xray field list)", text).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3252
|
-
examples(cmd, ["42 --field-id customfield_10100", "--execution
|
|
3336
|
+
examples(cmd, ["42 --field-id customfield_10100", "--execution PROJ-1 --test PROJ-2 --field-id customfield_10100"]);
|
|
3253
3337
|
cmd.action(async (runId, opts) => {
|
|
3254
3338
|
const client = getClient();
|
|
3255
3339
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3263,7 +3347,7 @@ function set(parent) {
|
|
|
3263
3347
|
const cmd = parent.command("set").description("Set a custom field value on a test run").argument("[runId]", "Test run id (from run list)", positiveInt).requiredOption("--field-id <id>", "Custom field id (from xray field list)", text).requiredOption("--value <text>", "Value to set for the field", text).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3264
3348
|
examples(cmd, [
|
|
3265
3349
|
'42 --field-id customfield_10100 --value "approved"',
|
|
3266
|
-
'--execution
|
|
3350
|
+
'--execution PROJ-1 --test PROJ-2 --field-id customfield_10100 --value "reviewed"'
|
|
3267
3351
|
]);
|
|
3268
3352
|
cmd.action(
|
|
3269
3353
|
async (runId, opts) => {
|
|
@@ -3286,7 +3370,7 @@ function registerRunFieldCommands(run) {
|
|
|
3286
3370
|
// src/commands/xray/run/get.ts
|
|
3287
3371
|
function get5(parent) {
|
|
3288
3372
|
const cmd = parent.command("get").description("Get a test run by id or by execution + test key").argument("[runId]", "Test run id (from run list)", positiveInt).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3289
|
-
examples(cmd, ["42", "--execution
|
|
3373
|
+
examples(cmd, ["42", "--execution PROJ-1 --test PROJ-2"]);
|
|
3290
3374
|
cmd.action(async (runId, opts) => {
|
|
3291
3375
|
const client = getClient();
|
|
3292
3376
|
const id = await resolveRunId(client, { runId, ...opts });
|
|
@@ -3298,7 +3382,7 @@ function get5(parent) {
|
|
|
3298
3382
|
// src/commands/xray/run/list.ts
|
|
3299
3383
|
function list14(parent) {
|
|
3300
3384
|
const cmd = parent.command("list").description("List test runs for a test execution (CLI-side slice with --limit/--start)").requiredOption("--execution <key>", "Test execution issue key", issueKey).option("--limit <number>", "Max results to return (1-200)", intInRange(1, 200), 50).option("--start <number>", "Starting index for pagination", nonNegativeInt);
|
|
3301
|
-
examples(cmd, ["--execution
|
|
3385
|
+
examples(cmd, ["--execution PROJ-1", "--execution PROJ-1 --limit 10", "--execution PROJ-1 --limit 10 --start 10"]);
|
|
3302
3386
|
cmd.action(async (opts) => {
|
|
3303
3387
|
const client = getClient();
|
|
3304
3388
|
const runs = await client.testRuns.listByExecution({ execKey: opts.execution });
|
|
@@ -3311,7 +3395,7 @@ function list14(parent) {
|
|
|
3311
3395
|
// src/commands/xray/run/step/list.ts
|
|
3312
3396
|
function list15(parent) {
|
|
3313
3397
|
const cmd = parent.command("list").description("List step results for a test run").argument("[runId]", "Test run id (from run list)", positiveInt).option("--execution <key>", "Test execution issue key (used with --test to resolve run id)", issueKey).option("--test <key>", "Test issue key (used with --execution to resolve run id)", issueKey);
|
|
3314
|
-
examples(cmd, ["42", "--execution
|
|
3398
|
+
examples(cmd, ["42", "--execution PROJ-1 --test PROJ-2"]);
|
|
3315
3399
|
cmd.action(async (runId, opts) => {
|
|
3316
3400
|
const client = getClient();
|
|
3317
3401
|
const id = await resolveRunId(client, { runId, execution: opts.execution, test: opts.test });
|
|
@@ -3331,7 +3415,7 @@ function update10(parent) {
|
|
|
3331
3415
|
textOrFileOption(cmd, "actual-result", { description: "Actual result text for this step" });
|
|
3332
3416
|
examples(cmd, [
|
|
3333
3417
|
"42 --step-id 1 --status PASS",
|
|
3334
|
-
'--execution
|
|
3418
|
+
'--execution PROJ-1 --test PROJ-2 --step-id 2 --status FAIL --comment "button missing"',
|
|
3335
3419
|
'42 --step-id 1 --status PASS --actual-result "Form submitted successfully"'
|
|
3336
3420
|
]);
|
|
3337
3421
|
cmd.action(
|
|
@@ -3355,7 +3439,7 @@ function update10(parent) {
|
|
|
3355
3439
|
// src/commands/xray/run/step/index.ts
|
|
3356
3440
|
function registerRunStepCommands(run) {
|
|
3357
3441
|
const step = run.command("step").description("Manage step results within a test run. See also: xray step for test step definitions.");
|
|
3358
|
-
examples(step, ["list --execution
|
|
3442
|
+
examples(step, ["list --execution PROJ-1 --test PROJ-2", "update 42 --step-id 1 --status PASS"]);
|
|
3359
3443
|
list15(step);
|
|
3360
3444
|
update10(step);
|
|
3361
3445
|
}
|
|
@@ -3366,8 +3450,8 @@ function update11(parent) {
|
|
|
3366
3450
|
textOrFileOption(cmd, "comment", { description: "Comment text for this run" });
|
|
3367
3451
|
examples(cmd, [
|
|
3368
3452
|
"42 --status PASS",
|
|
3369
|
-
'--execution
|
|
3370
|
-
'--execution
|
|
3453
|
+
'--execution PROJ-1 --test PROJ-2 --status FAIL --comment "broken"',
|
|
3454
|
+
'--execution PROJ-1 --test PROJ-2 --status FAIL --comment "broken" --defect BUG-1'
|
|
3371
3455
|
]);
|
|
3372
3456
|
cmd.action(
|
|
3373
3457
|
async (runId, opts) => {
|
|
@@ -3394,12 +3478,12 @@ function registerRunCommands(xray) {
|
|
|
3394
3478
|
"Manage test run results (status, comments, defects, evidence, steps). Every command accepts [runId] or --execution + --test."
|
|
3395
3479
|
);
|
|
3396
3480
|
examples(run, [
|
|
3397
|
-
"get --execution
|
|
3398
|
-
"list --execution
|
|
3399
|
-
'update --execution
|
|
3481
|
+
"get --execution PROJ-1 --test PROJ-2",
|
|
3482
|
+
"list --execution PROJ-1",
|
|
3483
|
+
'update --execution PROJ-1 --test PROJ-2 --status FAIL --comment "broken" --defect BUG-1',
|
|
3400
3484
|
"defect add 42 --defect BUG-1,BUG-2",
|
|
3401
|
-
"evidence add --execution
|
|
3402
|
-
"step list --execution
|
|
3485
|
+
"evidence add --execution PROJ-1 --test PROJ-2 --file screenshot.png",
|
|
3486
|
+
"step list --execution PROJ-1 --test PROJ-2",
|
|
3403
3487
|
"field get 42 --field-id customfield_10100"
|
|
3404
3488
|
]);
|
|
3405
3489
|
get5(run);
|
|
@@ -3431,13 +3515,13 @@ function registerStatusCommands(xray) {
|
|
|
3431
3515
|
|
|
3432
3516
|
// src/commands/xray/step/add.ts
|
|
3433
3517
|
function add7(parent) {
|
|
3434
|
-
const cmd = parent.command("add").description("Add a manual test step to a Test issue").requiredOption("--test <key>", "Test issue key (e.g.
|
|
3518
|
+
const cmd = parent.command("add").description("Add a manual test step to a Test issue").requiredOption("--test <key>", "Test issue key (e.g. PROJ-584)", issueKey);
|
|
3435
3519
|
textOrFileOption(cmd, "action", { description: "Step action text (required: provide --action or --action-file)" });
|
|
3436
3520
|
textOrFileOption(cmd, "data", { description: "Step test data text" });
|
|
3437
3521
|
textOrFileOption(cmd, "result", { description: "Expected result text" });
|
|
3438
3522
|
examples(cmd, [
|
|
3439
|
-
'--test
|
|
3440
|
-
'--test
|
|
3523
|
+
'--test PROJ-584 --action "Open login page" --result "Login form is shown"',
|
|
3524
|
+
'--test PROJ-584 --action "Submit form" --data "user=admin" --result "Dashboard loads"'
|
|
3441
3525
|
]);
|
|
3442
3526
|
cmd.action(
|
|
3443
3527
|
async (opts) => {
|
|
@@ -3453,8 +3537,8 @@ function add7(parent) {
|
|
|
3453
3537
|
|
|
3454
3538
|
// src/commands/xray/step/delete.ts
|
|
3455
3539
|
function deleteStep(parent) {
|
|
3456
|
-
const cmd = parent.command("delete").description("Delete a manual test step by ID").argument("<stepId>", "Step ID to delete (from step list)", positiveInt).requiredOption("--test <key>", "Test issue key (e.g.
|
|
3457
|
-
examples(cmd, ["3 --test
|
|
3540
|
+
const cmd = parent.command("delete").description("Delete a manual test step by ID").argument("<stepId>", "Step ID to delete (from step list)", positiveInt).requiredOption("--test <key>", "Test issue key (e.g. PROJ-584)", issueKey);
|
|
3541
|
+
examples(cmd, ["3 --test PROJ-584"]);
|
|
3458
3542
|
cmd.action(async (stepId, opts) => {
|
|
3459
3543
|
const client = getClient();
|
|
3460
3544
|
await client.testSteps.delete({ testKey: opts.test, stepId });
|
|
@@ -3464,8 +3548,8 @@ function deleteStep(parent) {
|
|
|
3464
3548
|
|
|
3465
3549
|
// src/commands/xray/step/list.ts
|
|
3466
3550
|
function list17(parent) {
|
|
3467
|
-
const cmd = parent.command("list").description("List manual test steps for a Test issue").requiredOption("--test <key>", "Test issue key (e.g.
|
|
3468
|
-
examples(cmd, ["--test
|
|
3551
|
+
const cmd = parent.command("list").description("List manual test steps for a Test issue").requiredOption("--test <key>", "Test issue key (e.g. PROJ-584)", issueKey);
|
|
3552
|
+
examples(cmd, ["--test PROJ-584"]);
|
|
3469
3553
|
cmd.action(async (opts) => {
|
|
3470
3554
|
const client = getClient();
|
|
3471
3555
|
const steps = await client.testSteps.list({ testKey: opts.test });
|
|
@@ -3475,13 +3559,13 @@ function list17(parent) {
|
|
|
3475
3559
|
|
|
3476
3560
|
// src/commands/xray/step/update.ts
|
|
3477
3561
|
function update12(parent) {
|
|
3478
|
-
const cmd = parent.command("update").description("Update a manual test step by ID").argument("<stepId>", "Step ID to update (from step list)", positiveInt).requiredOption("--test <key>", "Test issue key (e.g.
|
|
3562
|
+
const cmd = parent.command("update").description("Update a manual test step by ID").argument("<stepId>", "Step ID to update (from step list)", positiveInt).requiredOption("--test <key>", "Test issue key (e.g. PROJ-584)", issueKey);
|
|
3479
3563
|
textOrFileOption(cmd, "action", { description: "New step action text" });
|
|
3480
3564
|
textOrFileOption(cmd, "data", { description: "New step test data text" });
|
|
3481
3565
|
textOrFileOption(cmd, "result", { description: "New expected result text" });
|
|
3482
3566
|
examples(cmd, [
|
|
3483
|
-
'3 --test
|
|
3484
|
-
'3 --test
|
|
3567
|
+
'3 --test PROJ-584 --action "Click submit button"',
|
|
3568
|
+
'3 --test PROJ-584 --result "Confirmation email sent"'
|
|
3485
3569
|
]);
|
|
3486
3570
|
cmd.action(
|
|
3487
3571
|
async (stepId, opts) => {
|
|
@@ -3505,7 +3589,7 @@ function registerStepCommands(xray) {
|
|
|
3505
3589
|
const step = xray.command("step").description(
|
|
3506
3590
|
"Manage manual test steps for a Test issue (scope: --test). Steps are ordered by insertion; use step list to see current ids."
|
|
3507
3591
|
);
|
|
3508
|
-
examples(step, ['add --test
|
|
3592
|
+
examples(step, ['add --test PROJ-584 --action "Open login" --result "Form shows"', "list --test PROJ-584"]);
|
|
3509
3593
|
list17(step);
|
|
3510
3594
|
add7(step);
|
|
3511
3595
|
update12(step);
|
|
@@ -3532,15 +3616,15 @@ function create11(parent) {
|
|
|
3532
3616
|
textOrFileOption(cmd, "description", { description: "Test description" });
|
|
3533
3617
|
examples(cmd, [
|
|
3534
3618
|
[
|
|
3535
|
-
`--project
|
|
3619
|
+
`--project PROJ --summary "Login test" --type manual --steps '[{"action":"Open browser","result":"Browser opens"}]'`,
|
|
3536
3620
|
"Create manual test with step seed"
|
|
3537
3621
|
],
|
|
3538
3622
|
[
|
|
3539
|
-
'--project
|
|
3623
|
+
'--project PROJ --summary "Login scenario" --type cucumber --cucumber-type scenario --gherkin "Given I am on login page\\nWhen I enter credentials\\nThen I am logged in"',
|
|
3540
3624
|
"Create cucumber test"
|
|
3541
3625
|
],
|
|
3542
3626
|
[
|
|
3543
|
-
'--project
|
|
3627
|
+
'--project PROJ --summary "Perf baseline" --type generic --definition "Run k6 script and assert p95 < 500ms"',
|
|
3544
3628
|
"Create generic test"
|
|
3545
3629
|
]
|
|
3546
3630
|
]);
|
|
@@ -3597,8 +3681,8 @@ function create11(parent) {
|
|
|
3597
3681
|
|
|
3598
3682
|
// src/commands/xray/test/delete.ts
|
|
3599
3683
|
function deleteTest(parent) {
|
|
3600
|
-
const cmd = parent.command("delete").description("Delete an Xray Test issue").argument("<testKey>", "Test issue key (e.g.
|
|
3601
|
-
examples(cmd, ["
|
|
3684
|
+
const cmd = parent.command("delete").description("Delete an Xray Test issue").argument("<testKey>", "Test issue key (e.g. PROJ-584)", issueKey);
|
|
3685
|
+
examples(cmd, ["PROJ-584"]);
|
|
3602
3686
|
cmd.action(async (testKey) => {
|
|
3603
3687
|
const client = getClient();
|
|
3604
3688
|
await client.issues.delete({ issueKeyOrId: testKey });
|
|
@@ -3608,8 +3692,8 @@ function deleteTest(parent) {
|
|
|
3608
3692
|
|
|
3609
3693
|
// src/commands/xray/test/get.ts
|
|
3610
3694
|
function get6(parent) {
|
|
3611
|
-
const cmd = parent.command("get").description("Get one or more Xray test issues by key").argument("<testKey...>", "One or more test issue keys (e.g.
|
|
3612
|
-
examples(cmd, ["
|
|
3695
|
+
const cmd = parent.command("get").description("Get one or more Xray test issues by key").argument("<testKey...>", "One or more test issue keys (e.g. PROJ-584)", listOf(issueKey));
|
|
3696
|
+
examples(cmd, ["PROJ-584", "PROJ-584 PROJ-585"]);
|
|
3613
3697
|
cmd.action(async (testKeys) => {
|
|
3614
3698
|
const client = getClient();
|
|
3615
3699
|
const tests = await client.xrayTests.getTests({ keys: testKeys });
|
|
@@ -3622,7 +3706,7 @@ function list18(parent) {
|
|
|
3622
3706
|
const cmd = parent.command("list").description(
|
|
3623
3707
|
"List Xray Test issues by scope: all tests in a project, or tests belonging to a set, plan, execution, precondition, or folder. Note: use `jiradc issue search` for richer JQL when scoping by project."
|
|
3624
3708
|
).option("--project <text>", "Project key \u2014 list all tests in the project (or companion to --folder)", text).option("--set <key>", "Test Set issue key \u2014 list tests in this set", issueKey).option("--plan <key>", "Test Plan issue key \u2014 list tests in this plan", issueKey).option("--execution <key>", "Test Execution issue key \u2014 list tests in this execution", issueKey).option("--precondition <key>", "Precondition issue key \u2014 list tests with this precondition", issueKey).option("--folder <id>", "Folder id \u2014 list tests in this folder (requires --project)", positiveInt).option("--limit <number>", "Max results (1-50, applies to --project scope)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination (applies to --project scope)", nonNegativeInt);
|
|
3625
|
-
examples(cmd, ["--project
|
|
3709
|
+
examples(cmd, ["--project PROJ", "--set PROJ-100", "--folder 818 --project PROJ"]);
|
|
3626
3710
|
cmd.action(
|
|
3627
3711
|
async (opts) => {
|
|
3628
3712
|
const client = getClient();
|
|
@@ -3694,7 +3778,7 @@ function list18(parent) {
|
|
|
3694
3778
|
// src/commands/xray/test/update.ts
|
|
3695
3779
|
import { Option as Option13 } from "commander";
|
|
3696
3780
|
function update13(parent) {
|
|
3697
|
-
const cmd = parent.command("update").description("Update an Xray Test issue").argument("<testKey>", "Test issue key (e.g.
|
|
3781
|
+
const cmd = parent.command("update").description("Update an Xray Test issue").argument("<testKey>", "Test issue key (e.g. PROJ-584)", issueKey).option("--summary <text>", "New summary (title)", text).addOption(new Option13("--type <type>", "Test type").choices(["manual", "cucumber", "generic"])).addOption(
|
|
3698
3782
|
new Option13("--cucumber-type <cucumberType>", "Cucumber scenario type (required when --type cucumber)").choices([
|
|
3699
3783
|
"scenario",
|
|
3700
3784
|
"scenario-outline"
|
|
@@ -3704,8 +3788,8 @@ function update13(parent) {
|
|
|
3704
3788
|
textOrFileOption(cmd, "definition", { description: "Generic test definition (required when --type generic)" });
|
|
3705
3789
|
textOrFileOption(cmd, "description", { description: "Test description" });
|
|
3706
3790
|
examples(cmd, [
|
|
3707
|
-
'
|
|
3708
|
-
'
|
|
3791
|
+
'PROJ-584 --summary "Updated title"',
|
|
3792
|
+
'PROJ-584 --type cucumber --cucumber-type scenario --gherkin "Given I open the app"'
|
|
3709
3793
|
]);
|
|
3710
3794
|
cmd.action(
|
|
3711
3795
|
async (testKey, opts) => {
|
|
@@ -3759,7 +3843,7 @@ function update13(parent) {
|
|
|
3759
3843
|
// src/commands/xray/test/index.ts
|
|
3760
3844
|
function registerTestCommands(xray) {
|
|
3761
3845
|
const test = xray.command("test").description("Xray Test issue management (CRUD)");
|
|
3762
|
-
examples(test, ["get
|
|
3846
|
+
examples(test, ["get PROJ-584", 'create --project PROJ --summary "Login" --type manual']);
|
|
3763
3847
|
get6(test);
|
|
3764
3848
|
create11(test);
|
|
3765
3849
|
update13(test);
|
|
@@ -3769,8 +3853,8 @@ function registerTestCommands(xray) {
|
|
|
3769
3853
|
|
|
3770
3854
|
// src/commands/xray/testset/add.ts
|
|
3771
3855
|
function add8(parent) {
|
|
3772
|
-
const cmd = parent.command("add").description("Add tests to a Test Set").argument("<setKey>", "Test Set issue key (e.g.
|
|
3773
|
-
examples(cmd, ["
|
|
3856
|
+
const cmd = parent.command("add").description("Add tests to a Test Set").argument("<setKey>", "Test Set issue key (e.g. PROJ-100)", issueKey).requiredOption("--test <keys>", "Comma-separated test issue keys to add (e.g. PROJ-1,PROJ-2)", keyList);
|
|
3857
|
+
examples(cmd, ["PROJ-100 --test PROJ-1", "PROJ-100 --test PROJ-1,PROJ-2,PROJ-3"]);
|
|
3774
3858
|
cmd.action(async (setKey, opts) => {
|
|
3775
3859
|
const client = getClient();
|
|
3776
3860
|
const result = await client.testSets.addTests({ setKey, keys: opts.test });
|
|
@@ -3783,8 +3867,8 @@ function create12(parent) {
|
|
|
3783
3867
|
const cmd = parent.command("create").description("Create a new Xray Test Set issue").requiredOption("--project <key>", "Project key (e.g. AI)", text).requiredOption("--summary <text>", "Test Set summary (title)", text);
|
|
3784
3868
|
textOrFileOption(cmd, "description", { description: "Test Set description" });
|
|
3785
3869
|
examples(cmd, [
|
|
3786
|
-
'--project
|
|
3787
|
-
'--project
|
|
3870
|
+
'--project PROJ --summary "Smoke Test Set"',
|
|
3871
|
+
'--project PROJ --summary "Regression Set" --description "All regression tests"'
|
|
3788
3872
|
]);
|
|
3789
3873
|
cmd.action(async (opts) => {
|
|
3790
3874
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
@@ -3801,8 +3885,8 @@ function create12(parent) {
|
|
|
3801
3885
|
|
|
3802
3886
|
// src/commands/xray/testset/delete.ts
|
|
3803
3887
|
function deleteTestset(parent) {
|
|
3804
|
-
const cmd = parent.command("delete").description("Delete an Xray Test Set issue").argument("<setKey>", "Test Set issue key (e.g.
|
|
3805
|
-
examples(cmd, ["
|
|
3888
|
+
const cmd = parent.command("delete").description("Delete an Xray Test Set issue").argument("<setKey>", "Test Set issue key (e.g. PROJ-100)", issueKey);
|
|
3889
|
+
examples(cmd, ["PROJ-100"]);
|
|
3806
3890
|
cmd.action(async (setKey) => {
|
|
3807
3891
|
const client = getClient();
|
|
3808
3892
|
await deleteXrayIssue(client, setKey);
|
|
@@ -3814,8 +3898,8 @@ function deleteTestset(parent) {
|
|
|
3814
3898
|
function list19(parent) {
|
|
3815
3899
|
const cmd = parent.command("list").description(
|
|
3816
3900
|
"List Test Sets that contain a given test (inverse view). For the forward view (tests inside a set), use: xray test list --set <key>"
|
|
3817
|
-
).requiredOption("--test <key>", "Test issue key whose sets to list (e.g.
|
|
3818
|
-
examples(cmd, ["--test
|
|
3901
|
+
).requiredOption("--test <key>", "Test issue key whose sets to list (e.g. PROJ-584)", issueKey);
|
|
3902
|
+
examples(cmd, ["--test PROJ-584"]);
|
|
3819
3903
|
cmd.action(async (opts) => {
|
|
3820
3904
|
const client = getClient();
|
|
3821
3905
|
const sets = await client.xrayTests.getTestSets({ testKey: opts.test });
|
|
@@ -3825,8 +3909,8 @@ function list19(parent) {
|
|
|
3825
3909
|
|
|
3826
3910
|
// src/commands/xray/testset/remove.ts
|
|
3827
3911
|
function remove6(parent) {
|
|
3828
|
-
const cmd = parent.command("remove").description("Remove tests from a Test Set").argument("<setKey>", "Test Set issue key (e.g.
|
|
3829
|
-
examples(cmd, ["
|
|
3912
|
+
const cmd = parent.command("remove").description("Remove tests from a Test Set").argument("<setKey>", "Test Set issue key (e.g. PROJ-100)", issueKey).requiredOption("--test <keys>", "Comma-separated test issue keys to remove (e.g. PROJ-1,PROJ-2)", keyList);
|
|
3913
|
+
examples(cmd, ["PROJ-100 --test PROJ-1", "PROJ-100 --test PROJ-1,PROJ-2"]);
|
|
3830
3914
|
cmd.action(async (setKey, opts) => {
|
|
3831
3915
|
const client = getClient();
|
|
3832
3916
|
const result = await client.testSets.removeTests({ setKey, keys: opts.test });
|
|
@@ -3836,9 +3920,9 @@ function remove6(parent) {
|
|
|
3836
3920
|
|
|
3837
3921
|
// src/commands/xray/testset/update.ts
|
|
3838
3922
|
function update14(parent) {
|
|
3839
|
-
const cmd = parent.command("update").description("Update an Xray Test Set issue").argument("<setKey>", "Test Set issue key (e.g.
|
|
3923
|
+
const cmd = parent.command("update").description("Update an Xray Test Set issue").argument("<setKey>", "Test Set issue key (e.g. PROJ-100)", issueKey).option("--summary <text>", "New summary (title)", text);
|
|
3840
3924
|
textOrFileOption(cmd, "description", { description: "New Test Set description" });
|
|
3841
|
-
examples(cmd, ['
|
|
3925
|
+
examples(cmd, ['PROJ-100 --summary "Updated smoke set"', 'PROJ-100 --description "New description"']);
|
|
3842
3926
|
cmd.action(async (setKey, opts) => {
|
|
3843
3927
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
3844
3928
|
const client = getClient();
|
|
@@ -3852,7 +3936,7 @@ function registerTestsetCommands(xray) {
|
|
|
3852
3936
|
const testset = xray.command("testset").description(
|
|
3853
3937
|
"Xray Test Set issue management (CRUD, membership). To list tests inside a set, use: xray test list --set <key>"
|
|
3854
3938
|
);
|
|
3855
|
-
examples(testset, ['create --project
|
|
3939
|
+
examples(testset, ['create --project PROJ --summary "Smoke tests"', "add PROJ-100 --test PROJ-1,PROJ-2"]);
|
|
3856
3940
|
create12(testset);
|
|
3857
3941
|
update14(testset);
|
|
3858
3942
|
deleteTestset(testset);
|
|
@@ -3864,7 +3948,7 @@ function registerTestsetCommands(xray) {
|
|
|
3864
3948
|
// src/commands/xray/index.ts
|
|
3865
3949
|
function registerXrayCommands(program) {
|
|
3866
3950
|
const xray = program.command("xray").description("Xray test management (tests, runs, repository, import/export)");
|
|
3867
|
-
examples(xray, ["test get
|
|
3951
|
+
examples(xray, ["test get PROJ-584"]);
|
|
3868
3952
|
registerStatusCommands(xray);
|
|
3869
3953
|
registerFieldCommands2(xray);
|
|
3870
3954
|
registerTestCommands(xray);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jiradc-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.31",
|
|
4
4
|
"publish": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"tsx": "^4.19.2",
|
|
24
24
|
"typescript": "^5.7.2",
|
|
25
25
|
"vitest": "^4.0.16",
|
|
26
|
+
"cli-utils": "1.0.0",
|
|
26
27
|
"config-eslint": "0.0.0",
|
|
27
|
-
"config-typescript": "0.0.0"
|
|
28
|
-
"cli-utils": "1.0.0"
|
|
28
|
+
"config-typescript": "0.0.0"
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=22.0.0"
|