@msalaam/xray-qe-toolkit 1.4.1 → 1.5.0
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 +102 -55
- package/bin/cli.js +35 -24
- package/commands/createPlan.js +23 -34
- package/commands/pushTests.js +62 -3
- package/lib/testCaseBuilder.js +83 -0
- package/lib/xrayClient.js +74 -0
- package/package.json +1 -1
- package/schema/tests.schema.json +106 -6
- package/templates/tests.json +200 -47
- package/commands/genTests.js +0 -138
package/README.md
CHANGED
|
@@ -55,17 +55,17 @@ openapi.yaml + business-rules.yaml
|
|
|
55
55
|
↓ (AI agent generates tests.json)
|
|
56
56
|
tests.json — structured test definitions
|
|
57
57
|
↓
|
|
58
|
-
xqt validate
|
|
58
|
+
xqt validate ← schema check
|
|
59
59
|
↓
|
|
60
|
-
xqt push
|
|
60
|
+
xqt push ← creates/updates Tests + Test Sets in Xray
|
|
61
61
|
↓
|
|
62
62
|
xray-mapping.json ← auto-populated with Jira issue keys
|
|
63
63
|
↓
|
|
64
64
|
Playwright API tests ← created by Copilot (reads tests.json + xray-mapping.json)
|
|
65
65
|
↓
|
|
66
|
-
Sprint starts
|
|
66
|
+
Sprint starts ← xqt plan → link Test Sets to Test Plan
|
|
67
67
|
↓
|
|
68
|
-
CI runs tests
|
|
68
|
+
CI runs tests ← xqt import → Test Execution in Xray
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
**Key design decisions:**
|
|
@@ -118,18 +118,18 @@ cp .env.example .env
|
|
|
118
118
|
|
|
119
119
|
# 5. Validate and push to Xray
|
|
120
120
|
npx xqt validate
|
|
121
|
-
npx xqt push
|
|
121
|
+
npx xqt push
|
|
122
122
|
# → Tests + Test Sets created in Jira
|
|
123
123
|
# → xray-mapping.json populated with issue keys
|
|
124
124
|
|
|
125
125
|
# 6. Create Playwright tests (done by Copilot skill — reads tests.json + xray-mapping.json)
|
|
126
126
|
|
|
127
127
|
# 7. When entering a sprint, create a Test Plan and link Test Sets
|
|
128
|
-
npx xqt
|
|
128
|
+
npx xqt plan --summary "Sprint 12 — My Service Regression"
|
|
129
129
|
|
|
130
130
|
# 8. Run tests and import results
|
|
131
131
|
npx playwright test
|
|
132
|
-
npx xqt import
|
|
132
|
+
npx xqt import --file test-results/results.json --env IOP-QA
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
---
|
|
@@ -167,13 +167,14 @@ npx xqt edit --port 3000
|
|
|
167
167
|
|
|
168
168
|
---
|
|
169
169
|
|
|
170
|
-
### `xqt
|
|
170
|
+
### `xqt plan`
|
|
171
171
|
|
|
172
172
|
Create a new Xray Test Plan in JIRA. Automatically saves the key to `.xrayrc` and `tests.json`.
|
|
173
|
+
`create-plan` is accepted as a legacy alias.
|
|
173
174
|
|
|
174
175
|
```bash
|
|
175
|
-
npx xqt
|
|
176
|
-
npx xqt
|
|
176
|
+
npx xqt plan --summary "My Service v2 Regression"
|
|
177
|
+
npx xqt plan --summary "Sprint 12 Smoke Tests" --version "2024.12"
|
|
177
178
|
```
|
|
178
179
|
|
|
179
180
|
| Flag | Description |
|
|
@@ -184,35 +185,43 @@ npx xqt create-plan --summary "Sprint 12 Smoke Tests" --version "2024.12"
|
|
|
184
185
|
|
|
185
186
|
---
|
|
186
187
|
|
|
187
|
-
### `xqt push
|
|
188
|
+
### `xqt push`
|
|
188
189
|
|
|
189
190
|
Create or update tests in Xray Cloud, then sync Test Plan membership and the Xray folder structure.
|
|
191
|
+
Optionally create a Test Execution linked to the plan in a single command.
|
|
192
|
+
`push-tests` is accepted as a legacy alias.
|
|
190
193
|
|
|
191
194
|
```bash
|
|
192
|
-
npx xqt push
|
|
193
|
-
npx xqt push
|
|
195
|
+
npx xqt push
|
|
196
|
+
npx xqt push --plan APIEE-1234
|
|
197
|
+
npx xqt push --plan APIEE-1234 --create-execution --execution-env IOP-QA
|
|
194
198
|
```
|
|
195
199
|
|
|
196
200
|
| Flag | Description |
|
|
197
201
|
|---|---|
|
|
198
202
|
| `--plan <key>` | Test Plan key (overrides `.xrayrc testPlanKey`) |
|
|
203
|
+
| `--create-execution` | Create a Test Execution linked to the Test Plan after pushing |
|
|
204
|
+
| `--execution-env <label>` | Environment label for the created execution (e.g. `IOP-QA`) |
|
|
205
|
+
| `--execution-summary <text>` | Custom summary for the created execution |
|
|
199
206
|
|
|
200
207
|
**Behaviour:**
|
|
201
208
|
- Tests in `xray-mapping.json` → **updated** in Xray
|
|
202
209
|
- Tests not in mapping → **created** in Xray, mapping entry added
|
|
203
210
|
- Tests with `"skip": true` → excluded entirely
|
|
204
|
-
-
|
|
211
|
+
- **Test Sets auto-created** from the `testSet` field and tests added to them (see below)
|
|
205
212
|
- Xray folder structure synced from `folder` fields
|
|
213
|
+
- With `--create-execution`, a new Test Execution is created and linked to the Test Plan
|
|
206
214
|
|
|
207
215
|
---
|
|
208
216
|
|
|
209
|
-
### `xqt pull
|
|
217
|
+
### `xqt pull`
|
|
210
218
|
|
|
211
219
|
Pull test definitions from Xray Cloud and merge them into `tests.json`. Useful for onboarding to an existing Xray project.
|
|
220
|
+
`pull-tests` is accepted as a legacy alias.
|
|
212
221
|
|
|
213
222
|
```bash
|
|
214
|
-
npx xqt pull
|
|
215
|
-
npx xqt pull
|
|
223
|
+
npx xqt pull --plan APIEE-1234
|
|
224
|
+
npx xqt pull --project APIEE --limit 200
|
|
216
225
|
```
|
|
217
226
|
|
|
218
227
|
| Flag | Description |
|
|
@@ -223,20 +232,21 @@ npx xqt pull-tests --project APIEE --limit 200
|
|
|
223
232
|
|
|
224
233
|
---
|
|
225
234
|
|
|
226
|
-
### `xqt
|
|
235
|
+
### `xqt exec`
|
|
227
236
|
|
|
228
237
|
Pre-create a Test Execution with a specific set of tests before running them.
|
|
229
|
-
Use `--quiet` to capture the key in CI for use with `import
|
|
238
|
+
Use `--quiet` to capture the key in CI for use with `import --exec`.
|
|
239
|
+
`create-execution` is accepted as a legacy alias.
|
|
230
240
|
|
|
231
241
|
```bash
|
|
232
242
|
# Standard output
|
|
233
|
-
npx xqt
|
|
243
|
+
npx xqt exec --env IOP-QA
|
|
234
244
|
|
|
235
245
|
# CI mode — prints ONLY the key
|
|
236
|
-
EXEC_KEY=$(npx xqt
|
|
246
|
+
EXEC_KEY=$(npx xqt exec --env IOP-QA --quiet)
|
|
237
247
|
|
|
238
248
|
# Specific test selection
|
|
239
|
-
npx xqt
|
|
249
|
+
npx xqt exec --env IOP-QA --plan APIEE-1234 --tests TC-001,TC-002
|
|
240
250
|
```
|
|
241
251
|
|
|
242
252
|
| Flag | Description |
|
|
@@ -247,13 +257,14 @@ npx xqt create-execution --env IOP-QA --plan APIEE-1234 --tests TC-001,TC-002
|
|
|
247
257
|
| `--summary <text>` | Custom execution title |
|
|
248
258
|
| `--quiet` | Print only the execution key |
|
|
249
259
|
|
|
250
|
-
> `import
|
|
260
|
+
> `xqt import` creates an execution automatically — this command is only needed when pre-selecting a specific subset of tests.
|
|
251
261
|
|
|
252
262
|
---
|
|
253
263
|
|
|
254
|
-
### `xqt import
|
|
264
|
+
### `xqt import`
|
|
255
265
|
|
|
256
266
|
Import test execution results into Xray Cloud.
|
|
267
|
+
`import-results` is accepted as a legacy alias.
|
|
257
268
|
|
|
258
269
|
- **Without `--exec`** — creates a **new** Test Execution linked to the Test Plan
|
|
259
270
|
- **With `--exec`** — imports results INTO a pre-created execution
|
|
@@ -262,16 +273,16 @@ Supported: Playwright JSON (`.json`) and JUnit XML (`.xml`).
|
|
|
262
273
|
|
|
263
274
|
```bash
|
|
264
275
|
# Auto-create execution (standard CI)
|
|
265
|
-
npx xqt import
|
|
276
|
+
npx xqt import --file test-results/results.json --env IOP-QA
|
|
266
277
|
|
|
267
278
|
# Import into a pre-created execution
|
|
268
|
-
npx xqt import
|
|
279
|
+
npx xqt import --file test-results/results.json --exec APIEE-9876
|
|
269
280
|
|
|
270
281
|
# JUnit XML
|
|
271
|
-
npx xqt import
|
|
282
|
+
npx xqt import --file test-results/results.xml --env IOP-PROD
|
|
272
283
|
|
|
273
284
|
# Full options
|
|
274
|
-
npx xqt import
|
|
285
|
+
npx xqt import \
|
|
275
286
|
--file test-results/results.json \
|
|
276
287
|
--env IOP-QA \
|
|
277
288
|
--plan APIEE-1234 \
|
|
@@ -284,19 +295,20 @@ npx xqt import-results \
|
|
|
284
295
|
| `--file <path>` | Path to results file **(required)** |
|
|
285
296
|
| `--env <label>` | Environment label (default: `defaultEnvironment` from `.xrayrc`) |
|
|
286
297
|
| `--plan <key>` | Test Plan key (overrides `.xrayrc`; used when no `--exec`) |
|
|
287
|
-
| `--exec <key>` | Import INTO an existing execution (from `
|
|
298
|
+
| `--exec <key>` | Import INTO an existing execution (from `xqt exec`) |
|
|
288
299
|
| `--version <ver>` | Fix version / release label |
|
|
289
300
|
| `--revision <rev>` | Build number or git SHA |
|
|
290
301
|
| `--summary <text>` | Custom execution summary |
|
|
291
302
|
|
|
292
303
|
---
|
|
293
304
|
|
|
294
|
-
### `xqt sync
|
|
305
|
+
### `xqt sync`
|
|
295
306
|
|
|
296
307
|
Sync the Xray Test Repository folder structure from `folder` fields in `tests.json` without touching test content.
|
|
308
|
+
`sync-folders` is accepted as a legacy alias.
|
|
297
309
|
|
|
298
310
|
```bash
|
|
299
|
-
npx xqt sync
|
|
311
|
+
npx xqt sync
|
|
300
312
|
```
|
|
301
313
|
|
|
302
314
|
---
|
|
@@ -327,13 +339,14 @@ npx xqt validate --file path/to/tests.json
|
|
|
327
339
|
|
|
328
340
|
---
|
|
329
341
|
|
|
330
|
-
### `xqt
|
|
342
|
+
### `xqt pipeline`
|
|
331
343
|
|
|
332
344
|
Generate an Azure Pipelines YAML template for the current project.
|
|
345
|
+
`gen-pipeline` is accepted as a legacy alias.
|
|
333
346
|
|
|
334
347
|
```bash
|
|
335
|
-
npx xqt
|
|
336
|
-
npx xqt
|
|
348
|
+
npx xqt pipeline
|
|
349
|
+
npx xqt pipeline --output .azure/ci.yml
|
|
337
350
|
```
|
|
338
351
|
|
|
339
352
|
---
|
|
@@ -440,7 +453,7 @@ JIRA_EMAIL=your.email@company.com
|
|
|
440
453
|
| `test_id` | string | Yes | Stable local ID — maps to the Xray key in `xray-mapping.json` |
|
|
441
454
|
| `type` | string | — | `api` / `ui` / `e2e` (informational) |
|
|
442
455
|
| `skip` | boolean | — | `true` to exclude from `push-tests` |
|
|
443
|
-
| `tags` | string[] | — | QE tags for categorisation and filtering |
|
|
456
|
+
| `tags` | string[] | — | QE tags for categorisation and filtering. Allowed: `regression`, `smoke`, `edge`, `critical`, `integration`, `e2e`, `security`, `performance`, `contract`, `functional`, `negative`, `positive`, `boundary`, `acceptance`, `sanity`, `data-driven`, `exploratory`, `accessibility` |
|
|
444
457
|
| `folder` | string | — | Xray repository folder path — must start with `/` |
|
|
445
458
|
| `testSet` | string | — | Test Set name in Jira — tests are grouped into Test Sets by this value |
|
|
446
459
|
| `requirementKeys` | string[] | — | JIRA keys this test covers (creates traceability links) |
|
|
@@ -457,27 +470,51 @@ JIRA_EMAIL=your.email@company.com
|
|
|
457
470
|
|
|
458
471
|
### Test Sets (persistent groupings)
|
|
459
472
|
|
|
460
|
-
Tests live in **Test Sets** in Jira. Each Test Set groups related tests
|
|
473
|
+
Tests live in **Test Sets** in Jira. Each Test Set groups related tests by feature or area — they persist across every sprint.
|
|
461
474
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
475
|
+
Set the `testSet` field on each test in `tests.json`:
|
|
476
|
+
|
|
477
|
+
```json
|
|
478
|
+
{ "test_id": "TC-001", "testSet": "Client Lookup", ... }
|
|
479
|
+
{ "test_id": "TC-002", "testSet": "Client Lookup", ... }
|
|
480
|
+
{ "test_id": "TC-003", "testSet": "Health Check", ... }
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
When you run `xqt push`:
|
|
484
|
+
1. Tests are created/updated in Xray
|
|
485
|
+
2. For each unique `testSet` value, the Test Set JIRA issue is **created automatically** if it doesn't exist yet
|
|
486
|
+
3. Tests are added to their Test Set (idempotent — Xray ignores tests already in the set)
|
|
487
|
+
4. Test Set → JIRA key mappings (e.g. `"Client Lookup" → APIEE-99`) are stored in `xray-mapping.json` under `_testSets`
|
|
488
|
+
|
|
489
|
+
```json
|
|
490
|
+
// xray-mapping.json (auto-managed)
|
|
491
|
+
{
|
|
492
|
+
"_testSets": {
|
|
493
|
+
"Client Lookup": { "key": "APIEE-99", "id": "123456" },
|
|
494
|
+
"Health Check": { "key": "APIEE-100", "id": "123457" }
|
|
495
|
+
},
|
|
496
|
+
"TC-001": { "key": "APIEE-200", "id": "234001" },
|
|
497
|
+
...
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
Test Sets are **not deleted** when tests are removed from `tests.json`. They persist in Jira as a record of all tests that have ever existed for that feature.
|
|
465
502
|
|
|
466
503
|
### Test Plans (per-sprint)
|
|
467
504
|
|
|
468
505
|
A Test Plan scopes testing work for a specific sprint or release.
|
|
469
506
|
|
|
470
|
-
- Create with `xqt
|
|
471
|
-
- Link relevant Test Sets to the Test Plan in Jira
|
|
507
|
+
- Create with `xqt plan --summary "Sprint 12 — My Service"`
|
|
508
|
+
- Link relevant Test Sets to the Test Plan in Jira (manual step in Jira UI)
|
|
472
509
|
- Key stored in `.xrayrc` (`testPlanKey`)
|
|
473
|
-
- `import
|
|
510
|
+
- `xqt import` links executions to the active plan
|
|
474
511
|
|
|
475
512
|
### Test Executions (ephemeral per run)
|
|
476
513
|
|
|
477
514
|
A Test Execution represents a single CI run.
|
|
478
515
|
|
|
479
|
-
- **Auto-created** by `xqt import
|
|
480
|
-
- **Pre-created** by `xqt
|
|
516
|
+
- **Auto-created** by `xqt import` — one new execution per run
|
|
517
|
+
- **Pre-created** by `xqt exec` for controlled test selection
|
|
481
518
|
- Tagged with environment labels (`IOP-DEV`, `IOP-QA`, `IOP-PROD`)
|
|
482
519
|
- Linked to the Test Plan automatically
|
|
483
520
|
|
|
@@ -489,18 +526,25 @@ A Test Execution represents a single CI run.
|
|
|
489
526
|
| **Test Plan** | Per-sprint | Scopes testing for a sprint — links Test Sets |
|
|
490
527
|
| **Test Execution** | Per-CI-run | Records pass/fail for one run |
|
|
491
528
|
|
|
492
|
-
###
|
|
529
|
+
### Three execution modes
|
|
493
530
|
|
|
494
531
|
**Mode A — Auto (standard CI):**
|
|
495
532
|
```bash
|
|
496
|
-
npx xqt import
|
|
533
|
+
npx xqt import --file results.json --env IOP-QA
|
|
497
534
|
```
|
|
498
535
|
|
|
499
536
|
**Mode B — Pre-create (controlled test selection):**
|
|
500
537
|
```bash
|
|
501
|
-
EXEC_KEY=$(npx xqt
|
|
538
|
+
EXEC_KEY=$(npx xqt exec --env IOP-QA --plan APIEE-1234 --quiet)
|
|
539
|
+
npx playwright test
|
|
540
|
+
npx xqt import --file results.json --exec $EXEC_KEY
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**Mode C — Push & execute (single command):**
|
|
544
|
+
```bash
|
|
545
|
+
npx xqt push --plan APIEE-1234 --create-execution --execution-env IOP-QA
|
|
502
546
|
npx playwright test
|
|
503
|
-
npx xqt import
|
|
547
|
+
npx xqt import --file results.json --env IOP-QA
|
|
504
548
|
```
|
|
505
549
|
|
|
506
550
|
---
|
|
@@ -571,7 +615,7 @@ Tests are organised in the Xray Test Repository using the `folder` field in `tes
|
|
|
571
615
|
|
|
572
616
|
- Paths must start with `/`
|
|
573
617
|
- `folderRoot` in `.xrayrc` sets the base path
|
|
574
|
-
- Folders are created automatically by `push
|
|
618
|
+
- Folders are created automatically by `xqt push` and `xqt sync`
|
|
575
619
|
|
|
576
620
|
---
|
|
577
621
|
|
|
@@ -579,7 +623,7 @@ Tests are organised in the Xray Test Repository using the `folder` field in `tes
|
|
|
579
623
|
|
|
580
624
|
### Azure DevOps pipeline
|
|
581
625
|
|
|
582
|
-
Generate a template: `npx xqt
|
|
626
|
+
Generate a template: `npx xqt pipeline`
|
|
583
627
|
|
|
584
628
|
```yaml
|
|
585
629
|
- script: npx xqt validate
|
|
@@ -590,7 +634,7 @@ Generate a template: `npx xqt gen-pipeline`
|
|
|
590
634
|
continueOnError: true
|
|
591
635
|
|
|
592
636
|
- script: |
|
|
593
|
-
npx xqt import
|
|
637
|
+
npx xqt import \
|
|
594
638
|
--file test-results/results.json \
|
|
595
639
|
--env $(XQT_ENV)
|
|
596
640
|
displayName: Import results to Xray
|
|
@@ -619,7 +663,7 @@ Generate a template: `npx xqt gen-pipeline`
|
|
|
619
663
|
|
|
620
664
|
```yaml
|
|
621
665
|
- script: |
|
|
622
|
-
EXEC_KEY=$(npx xqt
|
|
666
|
+
EXEC_KEY=$(npx xqt exec --env $(XQT_ENV) --quiet)
|
|
623
667
|
echo "##vso[task.setvariable variable=EXEC_KEY]$EXEC_KEY"
|
|
624
668
|
displayName: Pre-create Test Execution
|
|
625
669
|
|
|
@@ -627,7 +671,7 @@ Generate a template: `npx xqt gen-pipeline`
|
|
|
627
671
|
continueOnError: true
|
|
628
672
|
|
|
629
673
|
- script: |
|
|
630
|
-
npx xqt import
|
|
674
|
+
npx xqt import --file test-results/results.json --exec $(EXEC_KEY)
|
|
631
675
|
displayName: Import results into pre-created execution
|
|
632
676
|
```
|
|
633
677
|
|
|
@@ -663,7 +707,7 @@ Key exports: `authenticate`, `createIssue`, `updateIssue`, `getIssue`, `getTest`
|
|
|
663
707
|
|
|
664
708
|
## xray-mapping.json
|
|
665
709
|
|
|
666
|
-
Auto-managed by `push
|
|
710
|
+
Auto-managed by `xqt push`. Maps local `test_id` → JIRA issue key and numeric Xray ID.
|
|
667
711
|
|
|
668
712
|
```json
|
|
669
713
|
{
|
|
@@ -696,7 +740,7 @@ Ensure `.env` exists and is populated.
|
|
|
696
740
|
**Test not found in mapping after push**
|
|
697
741
|
```bash
|
|
698
742
|
npx xqt status
|
|
699
|
-
npx xqt push
|
|
743
|
+
npx xqt push --verbose
|
|
700
744
|
```
|
|
701
745
|
|
|
702
746
|
**Import results — 0 tests matched**
|
|
@@ -708,6 +752,9 @@ test.info().annotations.push({ type: 'xray', description: 'APIEE-1234' });
|
|
|
708
752
|
**Validate fails in CI**
|
|
709
753
|
Fix schema errors before pushing. Common causes: missing `testId`, invalid `priority`, malformed `folder` path (must start with `/`).
|
|
710
754
|
|
|
755
|
+
**Old command names still work**
|
|
756
|
+
All previous multi-word commands (`push-tests`, `pull-tests`, `create-plan`, `create-execution`, `import-results`, `sync-folders`, `gen-pipeline`, `mcp-server`) remain valid as aliases.
|
|
757
|
+
|
|
711
758
|
**EU region**
|
|
712
759
|
Set `XRAY_REGION=eu` in `.env` or `"xrayRegion": "eu"` in `.xrayrc`.
|
|
713
760
|
|
package/bin/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @msalaam/xray-qe-toolkit — CLI Entry Point
|
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
* npx xqt <command> [options]
|
|
8
8
|
*
|
|
9
9
|
* Commands:
|
|
10
|
-
* init
|
|
11
|
-
* edit
|
|
12
|
-
* push
|
|
13
|
-
* pull
|
|
14
|
-
*
|
|
15
|
-
* import
|
|
16
|
-
*
|
|
17
|
-
* sync
|
|
18
|
-
* status
|
|
19
|
-
* validate
|
|
20
|
-
*
|
|
21
|
-
* mcp
|
|
10
|
+
* init Scaffold project structure (tests/, playwright.config.ts, tests.json, .xrayrc)
|
|
11
|
+
* edit Launch browser-based editor for tests.json
|
|
12
|
+
* push Push/update tests in Xray Cloud + sync Test Plan + sync folders
|
|
13
|
+
* pull Pull test definitions from Xray Cloud into tests.json
|
|
14
|
+
* exec Create a new Test Execution with a specific set of tests
|
|
15
|
+
* import Import test results (JUnit XML or Playwright JSON) — new execution per run
|
|
16
|
+
* plan Create a new Xray Test Plan in JIRA
|
|
17
|
+
* sync Sync Xray repository folder structure from tests.json folder fields
|
|
18
|
+
* status Show local + remote project status summary
|
|
19
|
+
* validate Validate tests.json against its schema
|
|
20
|
+
* pipeline Generate Azure Pipelines YAML
|
|
21
|
+
* mcp Start the MCP server for GitHub Copilot agent-mode integration
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { Command } from "commander";
|
|
@@ -61,18 +61,23 @@ program
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
program
|
|
64
|
-
.command("push
|
|
64
|
+
.command("push")
|
|
65
|
+
.alias("push-tests")
|
|
65
66
|
.description(
|
|
66
67
|
"Create/update tests in Xray Cloud, sync to Test Plan, sync folder structure"
|
|
67
68
|
)
|
|
68
69
|
.option("--plan <key>", "Test Plan key (overrides .xrayrc testPlanKey)")
|
|
70
|
+
.option("--create-execution", "Create a Test Execution linked to the Test Plan after pushing")
|
|
71
|
+
.option("--execution-env <label>", "Environment label for created execution (e.g. IOP-QA)")
|
|
72
|
+
.option("--execution-summary <text>", "Custom summary for created execution")
|
|
69
73
|
.action(async (opts, cmd) => {
|
|
70
74
|
const mod = await import("../commands/pushTests.js");
|
|
71
75
|
await mod.default({ ...opts, ...cmd.optsWithGlobals() });
|
|
72
76
|
});
|
|
73
77
|
|
|
74
78
|
program
|
|
75
|
-
.command("pull
|
|
79
|
+
.command("pull")
|
|
80
|
+
.alias("pull-tests")
|
|
76
81
|
.description("Pull test definitions from Xray Cloud into tests.json")
|
|
77
82
|
.option("--plan <key>", "Fetch tests from a specific Test Plan")
|
|
78
83
|
.option("--project <key>", "Fetch all tests in a JIRA project")
|
|
@@ -83,11 +88,12 @@ program
|
|
|
83
88
|
});
|
|
84
89
|
|
|
85
90
|
program
|
|
86
|
-
.command("
|
|
91
|
+
.command("exec")
|
|
92
|
+
.alias("create-execution")
|
|
87
93
|
.description(
|
|
88
94
|
"Create a new Test Execution with a specific set of tests. " +
|
|
89
95
|
"Use --quiet to print only the execution key for CI variable capture: " +
|
|
90
|
-
"EXEC_KEY=$(xqt
|
|
96
|
+
"EXEC_KEY=$(xqt exec --env IOP-QA --quiet)"
|
|
91
97
|
)
|
|
92
98
|
.option("--env <environment>", "Environment label (e.g. IOP-QA, IOP-PROD)")
|
|
93
99
|
.option("--plan <key>", "Test Plan key to link the execution to (overrides .xrayrc)")
|
|
@@ -101,14 +107,15 @@ program
|
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
program
|
|
104
|
-
.command("import
|
|
110
|
+
.command("import")
|
|
111
|
+
.alias("import-results")
|
|
105
112
|
.description(
|
|
106
113
|
"Import test results into Xray Cloud — creates a NEW Test Execution per run (JUnit XML or Playwright JSON)"
|
|
107
114
|
)
|
|
108
115
|
.requiredOption("--file <path>", "Path to results file (.json for Playwright, .xml for JUnit)")
|
|
109
116
|
.option("--env <environment>", "Test environment label (e.g. IOP-DEV, IOP-QA, IOP-PROD)")
|
|
110
117
|
.option("--plan <key>", "Test Plan key to associate execution with (overrides .xrayrc)")
|
|
111
|
-
.option("--exec <key>", "Import INTO an existing Test Execution key (from
|
|
118
|
+
.option("--exec <key>", "Import INTO an existing Test Execution key (from xqt exec)")
|
|
112
119
|
.option("--version <version>", "Fix version / release version")
|
|
113
120
|
.option("--revision <revision>", "Revision / build number")
|
|
114
121
|
.option("--summary <text>", "Custom Test Execution summary")
|
|
@@ -119,7 +126,8 @@ program
|
|
|
119
126
|
});
|
|
120
127
|
|
|
121
128
|
program
|
|
122
|
-
.command("
|
|
129
|
+
.command("plan")
|
|
130
|
+
.alias("create-plan")
|
|
123
131
|
.description("Create a new Test Plan in JIRA and save its key to .xrayrc and tests.json")
|
|
124
132
|
.requiredOption("--summary <text>", "Test Plan summary / title")
|
|
125
133
|
.option("--version <version>", "Fix version to associate with the plan")
|
|
@@ -130,7 +138,8 @@ program
|
|
|
130
138
|
});
|
|
131
139
|
|
|
132
140
|
program
|
|
133
|
-
.command("sync
|
|
141
|
+
.command("sync")
|
|
142
|
+
.alias("sync-folders")
|
|
134
143
|
.description("Sync Xray repository folder structure from the folder field in tests.json")
|
|
135
144
|
.action(async (opts, cmd) => {
|
|
136
145
|
const mod = await import("../commands/syncFolders.js");
|
|
@@ -157,7 +166,8 @@ program
|
|
|
157
166
|
});
|
|
158
167
|
|
|
159
168
|
program
|
|
160
|
-
.command("
|
|
169
|
+
.command("pipeline")
|
|
170
|
+
.alias("gen-pipeline")
|
|
161
171
|
.description("Generate an Azure Pipelines YAML template")
|
|
162
172
|
.option("--output <path>", "Output file path", "azure-pipelines.yml")
|
|
163
173
|
.action(async (opts, cmd) => {
|
|
@@ -166,7 +176,8 @@ program
|
|
|
166
176
|
});
|
|
167
177
|
|
|
168
178
|
program
|
|
169
|
-
.command("mcp
|
|
179
|
+
.command("mcp")
|
|
180
|
+
.alias("mcp-server")
|
|
170
181
|
.description(
|
|
171
182
|
"Start the MCP server for GitHub Copilot agent-mode integration. " +
|
|
172
183
|
"Runs in stdio mode by default (for VS Code), or HTTP mode with --port."
|
|
@@ -182,4 +193,4 @@ program
|
|
|
182
193
|
program.parseAsync(process.argv).catch((err) => {
|
|
183
194
|
console.error(`\n${err.message}\n`);
|
|
184
195
|
process.exit(1);
|
|
185
|
-
});
|
|
196
|
+
});
|
package/commands/createPlan.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import logger, { setVerbose } from "../lib/logger.js";
|
|
14
14
|
import { loadConfig, validateConfig } from "../lib/config.js";
|
|
15
|
-
import { authenticate, createTestPlan } from "../lib/xrayClient.js";
|
|
15
|
+
import { authenticate, createIssue, createTestPlan, getIssue } from "../lib/xrayClient.js";
|
|
16
16
|
|
|
17
17
|
export default async function createPlan(opts = {}) {
|
|
18
18
|
if (opts.verbose) setVerbose(true);
|
|
@@ -42,47 +42,36 @@ export default async function createPlan(opts = {}) {
|
|
|
42
42
|
|
|
43
43
|
let planKey;
|
|
44
44
|
try {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fixVersions: [{ name: opts.version }],
|
|
52
|
-
}),
|
|
53
|
-
...(opts.label && {
|
|
54
|
-
labels: opts.label.split(",").map((l) => l.trim()),
|
|
55
|
-
}),
|
|
56
|
-
},
|
|
45
|
+
const fields = {
|
|
46
|
+
summary,
|
|
47
|
+
description: summary,
|
|
48
|
+
...(opts.label && {
|
|
49
|
+
labels: opts.label.split(",").map((l) => l.trim()),
|
|
50
|
+
}),
|
|
57
51
|
};
|
|
58
52
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
headers: {
|
|
62
|
-
"Content-Type": "application/json",
|
|
63
|
-
Authorization: `Basic ${Buffer.from(`${cfg.jiraEmail}:${cfg.jiraApiToken}`).toString("base64")}`,
|
|
64
|
-
},
|
|
65
|
-
body: JSON.stringify(jiraPayload),
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
if (!response.ok) {
|
|
69
|
-
const body = await response.text();
|
|
70
|
-
throw new Error(`JIRA returned ${response.status}: ${body}`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const data = await response.json();
|
|
74
|
-
planKey = data.key;
|
|
53
|
+
const issue = await createIssue(cfg, "Test Plan", fields);
|
|
54
|
+
planKey = issue.key;
|
|
75
55
|
} catch (err) {
|
|
76
56
|
// Fallback: try via Xray GraphQL createTestPlan mutation
|
|
77
57
|
logger.debug(`JIRA REST failed, trying Xray GraphQL: ${err.message}`);
|
|
78
58
|
try {
|
|
79
59
|
const result = await createTestPlan(cfg, xrayToken, {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
},
|
|
60
|
+
projectId: cfg.jiraProjectKey,
|
|
61
|
+
summary,
|
|
62
|
+
description: summary,
|
|
84
63
|
});
|
|
85
|
-
|
|
64
|
+
|
|
65
|
+
// GraphQL returns { testPlan: { issueId, projectId } } — resolve key via JIRA
|
|
66
|
+
const issueId = result?.testPlan?.issueId;
|
|
67
|
+
if (issueId) {
|
|
68
|
+
try {
|
|
69
|
+
const issue = await getIssue(cfg, issueId);
|
|
70
|
+
planKey = issue?.key;
|
|
71
|
+
} catch {
|
|
72
|
+
logger.debug(`Could not resolve JIRA key for issueId ${issueId}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
86
75
|
} catch (gqlErr) {
|
|
87
76
|
logger.error(`Could not create Test Plan: ${gqlErr.message}`);
|
|
88
77
|
process.exit(1);
|