@msalaam/xray-qe-toolkit 1.1.0 → 1.2.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 +249 -16
- package/bin/cli.js +6 -4
- package/commands/importResults.js +44 -10
- package/lib/playwrightConverter.js +297 -0
- package/lib/postmanGenerator.js +1 -2
- package/lib/xrayClient.js +24 -1
- package/package.json +1 -1
- package/templates/tests.json +564 -33
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
- [Jira/Xray Project Setup](#jiraxray-project-setup)
|
|
32
32
|
- [QE Workflow](#qe-workflow)
|
|
33
33
|
- [Building Regression Packs](#building-regression-packs)
|
|
34
|
+
- [Working with Existing Xray Tests](#working-with-existing-xray-tests)
|
|
34
35
|
- [Idempotent Push](#idempotent-push)
|
|
35
36
|
- [Programmatic API](#programmatic-api)
|
|
36
37
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -46,8 +47,9 @@
|
|
|
46
47
|
3. **Idempotent push** — updates existing tests, creates new ones, skips duplicates
|
|
47
48
|
4. **Postman collection generation** from test definitions
|
|
48
49
|
5. **CI pipeline template** for Azure DevOps (Newman + Xray import)
|
|
49
|
-
6. **
|
|
50
|
-
7. **
|
|
50
|
+
6. **Playwright integration** — import Playwright JSON results with automatic test mapping
|
|
51
|
+
7. **Modular architecture** — every function is importable for programmatic use
|
|
52
|
+
8. **AI-ready scaffolds** — optional AI assistance for test generation (manual workflow fully supported)
|
|
51
53
|
|
|
52
54
|
### QE Review Gate Philosophy
|
|
53
55
|
|
|
@@ -242,7 +244,7 @@ All commands support these global options:
|
|
|
242
244
|
|
|
243
245
|
---
|
|
244
246
|
|
|
245
|
-
### `
|
|
247
|
+
### `xqt init`
|
|
246
248
|
|
|
247
249
|
Scaffold a new project with starter templates.
|
|
248
250
|
|
|
@@ -261,7 +263,7 @@ Existing files are **never overwritten** — the command skips them with a warni
|
|
|
261
263
|
|
|
262
264
|
---
|
|
263
265
|
|
|
264
|
-
### `
|
|
266
|
+
### `xqt gen-tests`
|
|
265
267
|
|
|
266
268
|
Generate test cases from `knowledge/` folder documentation (AI-assisted or manual guidance).
|
|
267
269
|
|
|
@@ -300,7 +302,7 @@ Existing files are **never overwritten** — the command skips them with a warni
|
|
|
300
302
|
|
|
301
303
|
---
|
|
302
304
|
|
|
303
|
-
### `
|
|
305
|
+
### `xqt edit-json`
|
|
304
306
|
|
|
305
307
|
Launch the browser-based QE review gate editor.
|
|
306
308
|
|
|
@@ -325,7 +327,7 @@ npx xqt edit-json --port 3000
|
|
|
325
327
|
|
|
326
328
|
---
|
|
327
329
|
|
|
328
|
-
### `
|
|
330
|
+
### `xqt push-tests`
|
|
329
331
|
|
|
330
332
|
Push or update tests in Xray Cloud from `tests.json`.
|
|
331
333
|
|
|
@@ -354,7 +356,7 @@ npx xqt push-tests --skip-exec
|
|
|
354
356
|
|
|
355
357
|
---
|
|
356
358
|
|
|
357
|
-
### `
|
|
359
|
+
### `xqt gen-postman`
|
|
358
360
|
|
|
359
361
|
Generate a Postman Collection v2.1 JSON from `tests.json` (works with or without AI).
|
|
360
362
|
|
|
@@ -398,7 +400,7 @@ npx xqt gen-postman --knowledge ./docs
|
|
|
398
400
|
|
|
399
401
|
---
|
|
400
402
|
|
|
401
|
-
### `
|
|
403
|
+
### `xqt create-execution`
|
|
402
404
|
|
|
403
405
|
Create a standalone Test Execution issue in JIRA.
|
|
404
406
|
|
|
@@ -415,22 +417,58 @@ npx xqt create-execution --summary "Feature XYZ" --issue QE-123
|
|
|
415
417
|
|
|
416
418
|
---
|
|
417
419
|
|
|
418
|
-
### `
|
|
420
|
+
### `xqt import-results`
|
|
419
421
|
|
|
420
|
-
Import
|
|
422
|
+
Import test results into Xray Cloud. Supports JUnit XML and Playwright JSON formats. Designed for CI — no human interaction.
|
|
421
423
|
|
|
424
|
+
**JUnit XML (JUnit, Newman, etc.):**
|
|
422
425
|
```bash
|
|
423
426
|
npx xqt import-results --file results.xml --testExecKey QE-123
|
|
424
427
|
```
|
|
425
428
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
429
|
+
**Playwright JSON:**
|
|
430
|
+
```bash
|
|
431
|
+
# Generate JSON report in Playwright
|
|
432
|
+
npx playwright test --reporter=json > playwright-results.json
|
|
433
|
+
|
|
434
|
+
# Import to Xray (links to existing tests or creates new ones)
|
|
435
|
+
npx xqt import-results --file playwright-results.json --testExecKey QE-123
|
|
436
|
+
|
|
437
|
+
# Create new Test Execution automatically
|
|
438
|
+
npx xqt import-results --file playwright-results.json --summary "Regression Suite"
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
| Option | Description | Required |
|
|
442
|
+
|-----------------------------|---------------------------------------------------|----------|
|
|
443
|
+
| `--file <path>` | Path to results file (.xml or .json) | Yes |
|
|
444
|
+
| `--testExecKey <key>` | Test Execution to link results to | No* |
|
|
445
|
+
| `--summary <text>` | Summary for new Test Execution (if no testExecKey) | No |
|
|
446
|
+
| `--description <text>` | Description for new Test Execution | No |
|
|
447
|
+
|
|
448
|
+
\* If `--testExecKey` is omitted, a new Test Execution will be created automatically.
|
|
449
|
+
|
|
450
|
+
**Mapping Playwright Tests to Xray:**
|
|
451
|
+
|
|
452
|
+
To link Playwright test results to existing Xray test cases, use annotations or include test keys in titles:
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
// Option 1: Using annotations (recommended)
|
|
456
|
+
test('User login flow', async ({ page }) => {
|
|
457
|
+
test.info().annotations.push({ type: 'xray', description: 'PROJ-123' });
|
|
458
|
+
// ... test code
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// Option 2: Include test key in title
|
|
462
|
+
test('[PROJ-456] User registration validates email', async ({ page }) => {
|
|
463
|
+
// ... test code
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
If no test key is found, a new test will be created in Xray with the test title as the summary.
|
|
430
468
|
|
|
431
469
|
---
|
|
432
470
|
|
|
433
|
-
### `
|
|
471
|
+
### `xqt gen-pipeline`
|
|
434
472
|
|
|
435
473
|
Generate an Azure Pipelines YAML template.
|
|
436
474
|
|
|
@@ -453,7 +491,7 @@ The generated pipeline:
|
|
|
453
491
|
|
|
454
492
|
---
|
|
455
493
|
|
|
456
|
-
### `
|
|
494
|
+
### `xqt mcp-server`
|
|
457
495
|
|
|
458
496
|
Start a Model Context Protocol server for GitHub Copilot agent-mode integration.
|
|
459
497
|
|
|
@@ -682,6 +720,34 @@ Use this checklist to align a new team's board and Xray configuration with the t
|
|
|
682
720
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
683
721
|
```
|
|
684
722
|
|
|
723
|
+
### Playwright Integration Workflow
|
|
724
|
+
|
|
725
|
+
For teams using Playwright for API or E2E testing:
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# 1. Write Playwright tests with Xray annotations
|
|
729
|
+
# tests/login.spec.ts
|
|
730
|
+
test('User login with valid credentials', async ({ page }) => {
|
|
731
|
+
test.info().annotations.push({ type: 'xray', description: 'PROJ-123' });
|
|
732
|
+
// ... test implementation
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
# 2. Run tests and generate JSON report
|
|
736
|
+
npx playwright test --reporter=json > playwright-results.json
|
|
737
|
+
|
|
738
|
+
# 3. Import results to Xray (links to existing tests or creates new)
|
|
739
|
+
npx xqt import-results --file playwright-results.json --testExecKey PROJ-456
|
|
740
|
+
|
|
741
|
+
# Or create new execution automatically
|
|
742
|
+
npx xqt import-results --file playwright-results.json --summary "Playwright Regression"
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Benefits:**
|
|
746
|
+
- Automatically maps Playwright tests to Xray test cases using annotations or `[TEST-123]` in titles
|
|
747
|
+
- Creates new test cases in Xray if no mapping found
|
|
748
|
+
- Supports Playwright retries, worker info, and detailed error reporting
|
|
749
|
+
- Works in CI/CD pipelines for continuous test reporting
|
|
750
|
+
|
|
685
751
|
---
|
|
686
752
|
|
|
687
753
|
## Building Regression Packs
|
|
@@ -823,6 +889,173 @@ newman run collection.postman.json # Full regression weekly
|
|
|
823
889
|
|
|
824
890
|
---
|
|
825
891
|
|
|
892
|
+
## Working with Existing Xray Tests
|
|
893
|
+
|
|
894
|
+
If your team already has test cases in Xray Cloud that were created manually or by another tool, you can set up this toolkit to manage and update those existing tests.
|
|
895
|
+
|
|
896
|
+
### Step 1: Query Existing Tests from Xray
|
|
897
|
+
|
|
898
|
+
Use the Xray GraphQL API to fetch your existing tests. Here's a script to generate the mapping file:
|
|
899
|
+
|
|
900
|
+
**fetch-existing-tests.js:**
|
|
901
|
+
```javascript
|
|
902
|
+
import { authenticate, loadConfig } from "@msalaam/xray-qe-toolkit";
|
|
903
|
+
import fs from "fs";
|
|
904
|
+
|
|
905
|
+
const cfg = loadConfig();
|
|
906
|
+
const token = await authenticate(cfg);
|
|
907
|
+
|
|
908
|
+
// GraphQL query to fetch all tests in your project
|
|
909
|
+
const query = `
|
|
910
|
+
query {
|
|
911
|
+
getTests(jql: "project = ${cfg.jiraProjectKey} AND issuetype = Test", limit: 1000) {
|
|
912
|
+
total
|
|
913
|
+
results {
|
|
914
|
+
issueId
|
|
915
|
+
jira(fields: ["key", "summary", "description", "priority", "labels"])
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
`;
|
|
920
|
+
|
|
921
|
+
const response = await fetch(cfg.xrayGraphQLUrl || "https://us.xray.cloud.getxray.app/api/v2/graphql", {
|
|
922
|
+
method: "POST",
|
|
923
|
+
headers: {
|
|
924
|
+
"Content-Type": "application/json",
|
|
925
|
+
Authorization: `Bearer ${token}`,
|
|
926
|
+
},
|
|
927
|
+
body: JSON.stringify({ query }),
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
const data = await response.json();
|
|
931
|
+
const tests = data.data.getTests.results;
|
|
932
|
+
|
|
933
|
+
// Generate xray-mapping.json
|
|
934
|
+
const mapping = {};
|
|
935
|
+
tests.forEach((test) => {
|
|
936
|
+
const testId = test.jira.key; // Use JIRA key as test_id initially
|
|
937
|
+
mapping[testId] = {
|
|
938
|
+
key: test.jira.key,
|
|
939
|
+
id: test.issueId,
|
|
940
|
+
};
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
fs.writeFileSync("xray-mapping.json", JSON.stringify(mapping, null, 2));
|
|
944
|
+
console.log(`✓ Created xray-mapping.json with ${tests.length} tests`);
|
|
945
|
+
|
|
946
|
+
// Generate tests.json scaffold
|
|
947
|
+
const testsJson = {
|
|
948
|
+
testExecution: {
|
|
949
|
+
summary: "Existing Tests - Managed by Toolkit",
|
|
950
|
+
description: "Imported from existing Xray tests",
|
|
951
|
+
},
|
|
952
|
+
tests: tests.map((test) => ({
|
|
953
|
+
test_id: test.jira.key,
|
|
954
|
+
skip: false,
|
|
955
|
+
tags: [],
|
|
956
|
+
xray: {
|
|
957
|
+
summary: test.jira.summary,
|
|
958
|
+
description: test.jira.description || "",
|
|
959
|
+
priority: test.jira.priority?.name || "Medium",
|
|
960
|
+
labels: test.jira.labels || [],
|
|
961
|
+
steps: [
|
|
962
|
+
// You'll need to fetch test steps separately via another API call
|
|
963
|
+
{
|
|
964
|
+
action: "PLACEHOLDER - Edit this in npx xqt edit-json",
|
|
965
|
+
data: "",
|
|
966
|
+
expected_result: "PLACEHOLDER",
|
|
967
|
+
},
|
|
968
|
+
],
|
|
969
|
+
},
|
|
970
|
+
})),
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
fs.writeFileSync("tests.json", JSON.stringify(testsJson, null, 2));
|
|
974
|
+
console.log(`✓ Created tests.json with ${tests.length} test scaffolds`);
|
|
975
|
+
console.log("\nNext steps:");
|
|
976
|
+
console.log("1. Run 'npx xqt edit-json' to review and complete test steps");
|
|
977
|
+
console.log("2. Run 'npx xqt push-tests' to update tests in Xray");
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
### Step 2: Run the Script
|
|
981
|
+
|
|
982
|
+
```bash
|
|
983
|
+
# Save the script above as fetch-existing-tests.js
|
|
984
|
+
node fetch-existing-tests.js
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
This generates:
|
|
988
|
+
- `xray-mapping.json` — maps your existing JIRA test keys to their IDs
|
|
989
|
+
- `tests.json` — scaffold with summaries, descriptions, priorities, labels
|
|
990
|
+
|
|
991
|
+
### Step 3: Complete Test Steps
|
|
992
|
+
|
|
993
|
+
The script can't fetch test steps automatically (requires additional API calls). Complete them in the editor:
|
|
994
|
+
|
|
995
|
+
```bash
|
|
996
|
+
npx xqt edit-json
|
|
997
|
+
# Edit each test to add proper steps
|
|
998
|
+
# Save when done
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
### Step 4: Update Existing Tests
|
|
1002
|
+
|
|
1003
|
+
Now you can update your existing Xray tests:
|
|
1004
|
+
|
|
1005
|
+
```bash
|
|
1006
|
+
npx xqt push-tests
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
Because the tests are in `xray-mapping.json`, they'll be **updated** (not duplicated).
|
|
1010
|
+
|
|
1011
|
+
### Alternative: Manual Mapping Creation
|
|
1012
|
+
|
|
1013
|
+
If you have a small number of tests, create the mapping manually:
|
|
1014
|
+
|
|
1015
|
+
**xray-mapping.json:**
|
|
1016
|
+
```json
|
|
1017
|
+
{
|
|
1018
|
+
"APIEE-6933": { "key": "APIEE-6933", "id": "1865623" },
|
|
1019
|
+
"APIEE-6934": { "key": "APIEE-6934", "id": "1865627" },
|
|
1020
|
+
"APIEE-6935": { "key": "APIEE-6935", "id": "1865628" }
|
|
1021
|
+
}
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
**tests.json:**
|
|
1025
|
+
```json
|
|
1026
|
+
{
|
|
1027
|
+
"tests": [
|
|
1028
|
+
{
|
|
1029
|
+
"test_id": "APIEE-6933",
|
|
1030
|
+
"xray": {
|
|
1031
|
+
"summary": "Test User Login",
|
|
1032
|
+
"steps": [
|
|
1033
|
+
{ "action": "...", "expected_result": "..." }
|
|
1034
|
+
]
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
]
|
|
1038
|
+
}
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
Then run `npx xqt push-tests` to update.
|
|
1042
|
+
|
|
1043
|
+
### Future Enhancement: Pull Command
|
|
1044
|
+
|
|
1045
|
+
A `pull-tests` command to automatically fetch and sync existing tests is planned:
|
|
1046
|
+
|
|
1047
|
+
```bash
|
|
1048
|
+
# Future feature (not yet implemented)
|
|
1049
|
+
npx xqt pull-tests --project APIEE
|
|
1050
|
+
npx xqt pull-tests --jql "project = APIEE AND labels = regression"
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
This would automatically generate both `tests.json` and `xray-mapping.json` from Xray.
|
|
1054
|
+
|
|
1055
|
+
**Want this feature?** [Open an issue on GitHub](https://github.com/Muhammad-Salaam_omit/xray-qe-toolkit/issues) or contribute via PR.
|
|
1056
|
+
|
|
1057
|
+
---
|
|
1058
|
+
|
|
826
1059
|
## Idempotent Push
|
|
827
1060
|
|
|
828
1061
|
`push-tests` checks `xray-mapping.json` before each operation:
|
package/bin/cli.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* push-tests Push / update tests in Xray Cloud
|
|
14
14
|
* gen-postman Generate Postman collection from tests.json (with optional AI)
|
|
15
15
|
* create-execution Create a new Test Execution in JIRA
|
|
16
|
-
* import-results Import
|
|
16
|
+
* import-results Import test results (JUnit XML or Playwright JSON) into Xray
|
|
17
17
|
* gen-pipeline Generate an Azure Pipelines YAML template
|
|
18
18
|
* mcp-server Start Model Context Protocol server for agent integration
|
|
19
19
|
*/
|
|
@@ -103,9 +103,11 @@ program
|
|
|
103
103
|
|
|
104
104
|
program
|
|
105
105
|
.command("import-results")
|
|
106
|
-
.description("Import
|
|
107
|
-
.requiredOption("--file <path>", "Path to the results
|
|
108
|
-
.
|
|
106
|
+
.description("Import test results into Xray Cloud (JUnit XML or Playwright JSON)")
|
|
107
|
+
.requiredOption("--file <path>", "Path to the results file (.xml for JUnit, .json for Playwright)")
|
|
108
|
+
.option("--testExecKey <key>", "Test Execution key to associate results with (creates new if omitted)")
|
|
109
|
+
.option("--summary <text>", "Test Execution summary (for new executions)")
|
|
110
|
+
.option("--description <text>", "Test Execution description (for new executions)")
|
|
109
111
|
.action(async (opts, cmd) => {
|
|
110
112
|
const mod = await import("../commands/importResults.js");
|
|
111
113
|
await mod.default({ ...opts, ...cmd.optsWithGlobals() });
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Command:
|
|
2
|
+
* Command: xqt import-results --file <path> [--testExecKey <key>]
|
|
3
3
|
*
|
|
4
|
-
* Imports
|
|
5
|
-
*
|
|
4
|
+
* Imports test results into Xray Cloud and associates them with a Test Execution.
|
|
5
|
+
*
|
|
6
|
+
* Supported formats:
|
|
7
|
+
* - JUnit XML (.xml) - Standard JUnit or XUnit format
|
|
8
|
+
* - Playwright JSON (.json) - Playwright JSON reporter output
|
|
6
9
|
*
|
|
7
10
|
* Designed to run in CI — no human interaction required.
|
|
8
11
|
*/
|
|
@@ -11,7 +14,8 @@ import fs from "node:fs";
|
|
|
11
14
|
import path from "node:path";
|
|
12
15
|
import logger, { setVerbose } from "../lib/logger.js";
|
|
13
16
|
import { loadConfig, validateConfig } from "../lib/config.js";
|
|
14
|
-
import { authenticate, importResults as
|
|
17
|
+
import { authenticate, importResults as importResultsXml, importResultsXrayJson } from "../lib/xrayClient.js";
|
|
18
|
+
import { convertPlaywrightToXray } from "../lib/playwrightConverter.js";
|
|
15
19
|
|
|
16
20
|
export default async function importResults(opts = {}) {
|
|
17
21
|
if (opts.verbose) setVerbose(true);
|
|
@@ -27,23 +31,53 @@ export default async function importResults(opts = {}) {
|
|
|
27
31
|
process.exit(1);
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const fileName = path.basename(filePath);
|
|
35
|
+
const fileExt = path.extname(filePath).toLowerCase();
|
|
36
|
+
|
|
37
|
+
logger.info(`File: ${fileName}`);
|
|
38
|
+
if (opts.testExecKey) {
|
|
39
|
+
logger.info(`Test Execution: ${opts.testExecKey}`);
|
|
40
|
+
}
|
|
32
41
|
logger.blank();
|
|
33
42
|
|
|
34
43
|
// Authenticate
|
|
35
44
|
const xrayToken = await authenticate(cfg);
|
|
36
45
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
// Detect format and import
|
|
47
|
+
let result;
|
|
48
|
+
|
|
49
|
+
if (fileExt === '.json') {
|
|
50
|
+
// Playwright JSON format
|
|
51
|
+
logger.send(`Importing Playwright JSON results...`);
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
const playwrightJson = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
54
|
+
|
|
55
|
+
// Convert to Xray format
|
|
56
|
+
const xrayJson = convertPlaywrightToXray(playwrightJson, {
|
|
57
|
+
testExecutionKey: opts.testExecKey,
|
|
58
|
+
projectKey: cfg.jiraProjectKey,
|
|
59
|
+
summary: opts.summary || `Playwright Test Execution - ${new Date().toLocaleString()}`,
|
|
60
|
+
description: opts.description,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
logger.step(`Converted ${xrayJson.tests.length} test results to Xray format`);
|
|
64
|
+
|
|
65
|
+
// Import to Xray
|
|
66
|
+
result = await importResultsXrayJson(cfg, xrayToken, xrayJson);
|
|
67
|
+
} else {
|
|
68
|
+
// JUnit XML format (default)
|
|
69
|
+
logger.send(`Importing JUnit XML results...`);
|
|
70
|
+
|
|
71
|
+
const xmlBuffer = fs.readFileSync(filePath);
|
|
72
|
+
result = await importResultsXml(cfg, xrayToken, xmlBuffer, opts.testExecKey);
|
|
73
|
+
}
|
|
42
74
|
|
|
43
75
|
logger.success("Results imported successfully");
|
|
44
76
|
|
|
45
77
|
if (result?.key) {
|
|
46
78
|
logger.link(`View: ${cfg.jiraUrl}/browse/${result.key}`);
|
|
79
|
+
} else if (result?.testExecIssue?.key) {
|
|
80
|
+
logger.link(`View: ${cfg.jiraUrl}/browse/${result.testExecIssue.key}`);
|
|
47
81
|
}
|
|
48
82
|
|
|
49
83
|
logger.blank();
|