@ai-testing-tool/forge-cypress 2.0.0 → 2.1.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 +2 -2
- package/dist/__fixtures__/saucedemo-13.json +131 -0
- package/dist/metadata.js +24 -0
- package/dist/mocha.d.ts +8 -0
- package/dist/mocha.js +48 -0
- package/dist/report-builder.d.ts +1 -1
- package/dist/report-builder.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Cypress reporter + plugin for **AI Testing Tool** (Jira Forge quality hub).
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -D @ai-testing-tool/forge-cypress@2.
|
|
8
|
+
npm install -D @ai-testing-tool/forge-cypress@2.1.0 @ai-testing-tool/forge-commons@2.1.0 cypress-multi-reporters
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
The pinned versions above track the latest release; `npm run release:bump` keeps them in sync.
|
|
@@ -73,7 +73,7 @@ it('AUTH-101 login', () => {
|
|
|
73
73
|
});
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
All helpers: `qa.title(value)`, `qa.comment(value)`, `qa.suite(value)`, `qa.parameters({ key: value })`, `qa.ignore()`, `qa.step(name, syncFn)`. `qa.step()` throws if the callback returns a Promise — keep it synchronous and let Cypress commands queue as usual.
|
|
76
|
+
All helpers: `qa.title(value)`, `qa.comment(value)`, `qa.suite(value)`, `qa.suiteId(value)`, `qa.planId(value)`, `qa.plan(value)`, `qa.fixVersion(value)`, `qa.sprintName(value)`, `qa.labels(value)`, `qa.parameters({ key: value })`, `qa.ignore()`, `qa.step(name, syncFn)`. `qa.step()` throws if the callback returns a Promise — keep it synchronous and let Cypress commands queue as usual.
|
|
77
77
|
|
|
78
78
|
Prefer **Jira issue keys in test titles**. Requires `@ai-testing-tool/forge-cypress/metadata` so `cy.task` bridges metadata to the Node reporter. Step hierarchy lands on `assertionResults[].meta.qa.steps`.
|
|
79
79
|
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"suite": "saucedemo-reference-13",
|
|
3
|
+
"source": "saucedemo e-commerce suite (login/inventory/cart/checkout) — titles use FR43 AUTH-* keys",
|
|
4
|
+
"specs": [
|
|
5
|
+
{
|
|
6
|
+
"name": "cypress/e2e/login.cy.js",
|
|
7
|
+
"assertions": [
|
|
8
|
+
{
|
|
9
|
+
"ancestorTitles": ["Login Scenarios"],
|
|
10
|
+
"title": "AUTH-101 User can login with valid credentials",
|
|
11
|
+
"status": "passed",
|
|
12
|
+
"duration": 1200,
|
|
13
|
+
"steps": [
|
|
14
|
+
"Fill in username",
|
|
15
|
+
"Fill in password",
|
|
16
|
+
"Submit login form",
|
|
17
|
+
"Verify successful login"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"ancestorTitles": ["Login Scenarios"],
|
|
22
|
+
"title": "AUTH-102 User cannot login with invalid password",
|
|
23
|
+
"status": "passed",
|
|
24
|
+
"duration": 800,
|
|
25
|
+
"steps": [
|
|
26
|
+
"Attempt login with invalid credentials",
|
|
27
|
+
"Verify error message is shown",
|
|
28
|
+
"Verify still on login page"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"ancestorTitles": ["Login Scenarios"],
|
|
33
|
+
"title": "AUTH-103 Locked user cannot login",
|
|
34
|
+
"status": "passed",
|
|
35
|
+
"duration": 700,
|
|
36
|
+
"steps": [
|
|
37
|
+
"Attempt login with locked user",
|
|
38
|
+
"Verify locked out error message",
|
|
39
|
+
"Verify cannot access inventory"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "cypress/e2e/inventory.cy.js",
|
|
46
|
+
"assertions": [
|
|
47
|
+
{
|
|
48
|
+
"ancestorTitles": ["Inventory Scenarios"],
|
|
49
|
+
"title": "AUTH-104 User can browse all products",
|
|
50
|
+
"status": "passed",
|
|
51
|
+
"duration": 900,
|
|
52
|
+
"steps": ["Open inventory", "Verify product list"]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"ancestorTitles": ["Inventory Scenarios"],
|
|
56
|
+
"title": "AUTH-105 User can sort products by price",
|
|
57
|
+
"status": "passed",
|
|
58
|
+
"duration": 850,
|
|
59
|
+
"steps": ["Sort by price", "Verify order"]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"ancestorTitles": ["Inventory Scenarios"],
|
|
63
|
+
"title": "AUTH-106 User can view product details",
|
|
64
|
+
"status": "passed",
|
|
65
|
+
"duration": 750,
|
|
66
|
+
"steps": ["Open product", "Verify details"]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "cypress/e2e/cart.cy.js",
|
|
72
|
+
"assertions": [
|
|
73
|
+
{
|
|
74
|
+
"ancestorTitles": ["Cart Scenarios"],
|
|
75
|
+
"title": "AUTH-107 User can add product to cart",
|
|
76
|
+
"status": "passed",
|
|
77
|
+
"duration": 1000,
|
|
78
|
+
"steps": ["Add to cart", "Verify cart badge"]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"ancestorTitles": ["Cart Scenarios"],
|
|
82
|
+
"title": "AUTH-108 User can remove product from cart",
|
|
83
|
+
"status": "passed",
|
|
84
|
+
"duration": 950,
|
|
85
|
+
"steps": ["Remove from cart", "Verify empty"]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"ancestorTitles": ["Cart Scenarios"],
|
|
89
|
+
"title": "AUTH-109 User can add multiple products to cart",
|
|
90
|
+
"status": "passed",
|
|
91
|
+
"duration": 1100,
|
|
92
|
+
"steps": ["Add products", "Verify count"]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "cypress/e2e/checkout.cy.js",
|
|
98
|
+
"assertions": [
|
|
99
|
+
{
|
|
100
|
+
"ancestorTitles": ["Checkout Scenarios"],
|
|
101
|
+
"title": "AUTH-110 User can complete checkout with valid information",
|
|
102
|
+
"status": "passed",
|
|
103
|
+
"duration": 1500,
|
|
104
|
+
"steps": ["Fill checkout", "Finish", "Verify confirmation"]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"ancestorTitles": ["Checkout Scenarios"],
|
|
108
|
+
"title": "AUTH-111 Checkout fails without required information",
|
|
109
|
+
"status": "passed",
|
|
110
|
+
"duration": 600,
|
|
111
|
+
"steps": ["Submit empty", "Verify validation"]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"ancestorTitles": ["Checkout Scenarios"],
|
|
115
|
+
"title": "AUTH-112 User can cancel checkout",
|
|
116
|
+
"status": "passed",
|
|
117
|
+
"duration": 700,
|
|
118
|
+
"steps": ["Cancel", "Verify cart"]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"ancestorTitles": ["Checkout Scenarios"],
|
|
122
|
+
"title": "AUTH-113 Demo test that will be ignored in reporting",
|
|
123
|
+
"status": "pending",
|
|
124
|
+
"duration": 0,
|
|
125
|
+
"steps": [],
|
|
126
|
+
"ignore": true
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
package/dist/metadata.js
CHANGED
|
@@ -10,6 +10,30 @@ function metadata(on) {
|
|
|
10
10
|
metadata_manager_1.MetadataManager.push('qa-suite', value);
|
|
11
11
|
return null;
|
|
12
12
|
},
|
|
13
|
+
qaSuiteId(value) {
|
|
14
|
+
metadata_manager_1.MetadataManager.push('qa-suite-id', value);
|
|
15
|
+
return null;
|
|
16
|
+
},
|
|
17
|
+
qaPlanId(value) {
|
|
18
|
+
metadata_manager_1.MetadataManager.push('qa-plan-id', value);
|
|
19
|
+
return null;
|
|
20
|
+
},
|
|
21
|
+
qaPlan(value) {
|
|
22
|
+
metadata_manager_1.MetadataManager.push('qa-plan', value);
|
|
23
|
+
return null;
|
|
24
|
+
},
|
|
25
|
+
qaFixVersion(value) {
|
|
26
|
+
metadata_manager_1.MetadataManager.push('qa-fix-version', value);
|
|
27
|
+
return null;
|
|
28
|
+
},
|
|
29
|
+
qaSprintName(value) {
|
|
30
|
+
metadata_manager_1.MetadataManager.push('qa-sprint-name', value);
|
|
31
|
+
return null;
|
|
32
|
+
},
|
|
33
|
+
qaLabels(value) {
|
|
34
|
+
metadata_manager_1.MetadataManager.push('qa-labels', value);
|
|
35
|
+
return null;
|
|
36
|
+
},
|
|
13
37
|
qaComment(value) {
|
|
14
38
|
metadata_manager_1.MetadataManager.push('qa-comment', value);
|
|
15
39
|
return null;
|
package/dist/mocha.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ export type QaHelpers = {
|
|
|
14
14
|
title(value: string): void;
|
|
15
15
|
comment(value: string): void;
|
|
16
16
|
suite(value: string): void;
|
|
17
|
+
suiteId(value: string): void;
|
|
18
|
+
planId(value: string): void;
|
|
19
|
+
/** Plan display name → `meta.qa.planName`. */
|
|
20
|
+
plan(value: string): void;
|
|
21
|
+
fixVersion(value: string): void;
|
|
22
|
+
sprintName(value: string): void;
|
|
23
|
+
/** Comma-separated string or array → `meta.qa.labels`. */
|
|
24
|
+
labels(value: string | string[]): void;
|
|
17
25
|
parameters(values: Record<string, string>): void;
|
|
18
26
|
/** Explicit FR43 issue key (preferred over embedding in titles). */
|
|
19
27
|
issueKey(key: string): void;
|
package/dist/mocha.js
CHANGED
|
@@ -53,6 +53,54 @@ exports.qa = {
|
|
|
53
53
|
}
|
|
54
54
|
pushLocal('qa-suite', value);
|
|
55
55
|
},
|
|
56
|
+
suiteId(value) {
|
|
57
|
+
const cy = cyRef();
|
|
58
|
+
if (cy) {
|
|
59
|
+
pushTask('qaSuiteId', value);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
pushLocal('qa-suite-id', value);
|
|
63
|
+
},
|
|
64
|
+
planId(value) {
|
|
65
|
+
const cy = cyRef();
|
|
66
|
+
if (cy) {
|
|
67
|
+
pushTask('qaPlanId', value);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
pushLocal('qa-plan-id', value);
|
|
71
|
+
},
|
|
72
|
+
plan(value) {
|
|
73
|
+
const cy = cyRef();
|
|
74
|
+
if (cy) {
|
|
75
|
+
pushTask('qaPlan', value);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
pushLocal('qa-plan', value);
|
|
79
|
+
},
|
|
80
|
+
fixVersion(value) {
|
|
81
|
+
const cy = cyRef();
|
|
82
|
+
if (cy) {
|
|
83
|
+
pushTask('qaFixVersion', value);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
pushLocal('qa-fix-version', value);
|
|
87
|
+
},
|
|
88
|
+
sprintName(value) {
|
|
89
|
+
const cy = cyRef();
|
|
90
|
+
if (cy) {
|
|
91
|
+
pushTask('qaSprintName', value);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
pushLocal('qa-sprint-name', value);
|
|
95
|
+
},
|
|
96
|
+
labels(value) {
|
|
97
|
+
const cy = cyRef();
|
|
98
|
+
if (cy) {
|
|
99
|
+
pushTask('qaLabels', value);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
pushLocal('qa-labels', value);
|
|
103
|
+
},
|
|
56
104
|
parameters(values) {
|
|
57
105
|
const cy = cyRef();
|
|
58
106
|
if (cy) {
|
package/dist/report-builder.d.ts
CHANGED
package/dist/report-builder.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toJestJsonReport = toJestJsonReport;
|
|
4
|
+
const forge_commons_1 = require("@ai-testing-tool/forge-commons");
|
|
4
5
|
function mapAssertion(a) {
|
|
5
6
|
const fullName = a.fullName ??
|
|
6
7
|
(a.ancestorTitles.length > 0
|
|
@@ -29,7 +30,7 @@ function toJestJsonReport(specs, startTime) {
|
|
|
29
30
|
const testResults = specs.map((spec) => {
|
|
30
31
|
const assertionResults = spec.assertions.map(mapAssertion);
|
|
31
32
|
return {
|
|
32
|
-
name: spec.name,
|
|
33
|
+
name: (0, forge_commons_1.normalizeReportFilePath)(spec.name),
|
|
33
34
|
status: fileStatus(assertionResults),
|
|
34
35
|
startTime: spec.startTime,
|
|
35
36
|
endTime: spec.endTime,
|
package/package.json
CHANGED