k6-cucumber-steps 1.0.41 โ 1.1.2
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/.env +38 -0
- package/bin/k6-cucumber-steps.js +71 -11
- package/cucumber.js +5 -5
- package/lib/helpers/buildK6Script.js +39 -18
- package/package.json +2 -1
- package/reports/cucumber-report.html +50 -0
- package/reports/k6-report-2025-06-03T12-54-18-512Z.html +582 -0
- package/reports/k6-report-2025-06-03T12-54-33-806Z.html +582 -0
- package/reports/load-report.json +283 -0
- package/scripts/generateHtmlReports.js +53 -0
- package/scripts/linkReports.js +122 -0
- package/.env.example +0 -17
- package/generateReport.js +0 -24
package/.env
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
NODE_ENV=sandbox
|
|
2
|
+
POSTMAN_ENV=test
|
|
3
|
+
APP_ENVIRONMENT=development
|
|
4
|
+
|
|
5
|
+
POSTMAN_COLLECTION_URL='https://api.getpostman.com/collections/21022247-5a73af48-e8b9-4aa3-a55d-a352517404bf'
|
|
6
|
+
POSTMAN_ENVIRONMENT_URL='https://api.getpostman.com/environments/21022247-fdb96b14-4bd7-4e5b-8bec-c39f95c8fa0d'
|
|
7
|
+
POSTMAN_ENVIRONMENT_URL_STAGE='https://api.getpostman.com/environments/21022247-fdb96b14-4bd7-4e5b-8bec-c39f95c8fa0d'
|
|
8
|
+
POSTMAN_ENVIRONMENT_URL_SANDBOX=https://api.getpostman.com/environments/26431315-6e705dea-3f42-4fda-a8a0-cdea63dac91d
|
|
9
|
+
POSTMAN_ENVIRONMENT_URL_PROD=https://api.getpostman.com/environments/26431315-6e705dea-3f42-4fda-a8a0-cdea63dac91d
|
|
10
|
+
# SLACK_WEBHOOK_URL-stage=https://hooks.slack.com/services/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
|
|
11
|
+
# SLACK_WEBHOOK_URL='https://hooks.slack.com/services/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'
|
|
12
|
+
POSTMAN_API_KEY='PMAK-655f12ee88ca96002a53ce0e-f91a566c91b8b88e9f17cb460347cd6a47'
|
|
13
|
+
21022247-5a73af48-e8b9-4aa3-a55d-a352517404bf
|
|
14
|
+
21022247-fdb96b14-4bd7-4e5b-8bec-c39f95c8fa0d
|
|
15
|
+
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/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
|
|
16
|
+
WEB_URL='https://sandbox-decide.indicina.net/'
|
|
17
|
+
# WEB_URL=https://decide.indicina.co/
|
|
18
|
+
# CYPRESS_TAGS='@regression'
|
|
19
|
+
# CYPRESS_TAGS='@sanity'
|
|
20
|
+
|
|
21
|
+
# API_BASE_URL=https://sandbox-decide-api.indicina.net
|
|
22
|
+
BASE_URL=https://sandbox-decide-api.indicina.net
|
|
23
|
+
USER_EMAIL=product.indicina@yopmail.com
|
|
24
|
+
USER_PASSWORD=1Password@
|
|
25
|
+
# USER_EMAIL= product.tester@indicina.co
|
|
26
|
+
# USER_PASSWORD=?Indicina123
|
|
27
|
+
CLIENT_SECRET_PROD=AHP84J7-KJJMSJ3-NAH3NWE-JEWSEA0
|
|
28
|
+
SLUG=indicina
|
|
29
|
+
ACCOUNT_TYPE=ACCOUNT_TYPE_MERCHANT
|
|
30
|
+
CLIENT_SECRET=MD5Y106-RYG4STY-H3B33FS-CRS5AMG
|
|
31
|
+
CLIENT_ID=indicina
|
|
32
|
+
CUSTOMER_ID_PROD=3a39b1c0-a725-48cf-8c44-1298d3c399a6
|
|
33
|
+
CUSTOMER_ID_SANDBOX=f7cbfe40-2330-11ef-8a77-025b06f85973
|
|
34
|
+
|
|
35
|
+
TEAMS_WEBHOOK_URL= https://seamlesshrsuite.webhook.office.com/webhookb2/51bb6663-5d8e-4c68-bfc6-f01e24999c3a@45908be8-ba32-466d-ac1f-8fb319a24cba/IncomingWebhook/ef5fd5b0a6be4e05a2b0943968c40429/04c7e600-d01e-41f8-9298-d38d80577410/V28Cgsd2MwRXM7LxjM-cLtSMm0QuwZm27DPq7sXeK2q9c1
|
|
36
|
+
# GITHUB_RUN_ID= tests_webhook
|
|
37
|
+
# TEAMS_WEBHOOK_URL=https://seamlesshrsuite.webhook.office.com/webhookb2/58ab15f8-c6a7-44ec-b1ad-e437c707ed73@45908be8-ba32-466d-ac1f-8fb319a24cba/IncomingWebhook/59a3b2b15f254f24a822ec6b0452f670/04c7e600-d01e-41f8-9298-d38d80577410/V2idCGcJwnS_VqKep-2Hmx5rZosVRByQrvMV2Yxh22lM81
|
|
38
|
+
REPORT_URL="http://localhost:5500/cypress-ms-teams-reporter/cypress/reports/html/index.html"
|
package/bin/k6-cucumber-steps.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
//bin/k6-cucumber-steps.js
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const { spawn } = require("child_process");
|
|
6
|
-
const yargs = require("yargs");
|
|
6
|
+
const yargs = require("yargs/yargs"); // Use the correct import for yargs
|
|
7
|
+
const { hideBin } = require("yargs/helpers"); // Helper to parse CLI arguments
|
|
7
8
|
require("dotenv").config();
|
|
9
|
+
const { generateHtmlReports } = require("../scripts/generateHtmlReports");
|
|
10
|
+
const { linkReports } = require("../scripts/linkReports");
|
|
8
11
|
|
|
9
12
|
console.log(`
|
|
10
13
|
-----------------------------------------
|
|
@@ -12,7 +15,7 @@ console.log(`
|
|
|
12
15
|
-----------------------------------------
|
|
13
16
|
`);
|
|
14
17
|
|
|
15
|
-
const argv = yargs
|
|
18
|
+
const argv = yargs(hideBin(process.argv))
|
|
16
19
|
.usage("Usage: $0 run [options]")
|
|
17
20
|
.option("feature", {
|
|
18
21
|
alias: "f",
|
|
@@ -95,9 +98,31 @@ if (configOptions.require && Array.isArray(configOptions.require)) {
|
|
|
95
98
|
|
|
96
99
|
// Determine base report name
|
|
97
100
|
const reportsDir = path.join(process.cwd(), "reports");
|
|
101
|
+
const cleanReportsDir = () => {
|
|
102
|
+
if (fs.existsSync(reportsDir)) {
|
|
103
|
+
try {
|
|
104
|
+
fs.rmSync(reportsDir, { recursive: true, force: true });
|
|
105
|
+
console.log("๐งน Cleaned existing reports directory.");
|
|
106
|
+
} catch (err) {
|
|
107
|
+
console.error("โ Failed to clean reports directory:", err.message);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
fs.mkdirSync(reportsDir, { recursive: true });
|
|
114
|
+
console.log("๐ Created fresh reports directory.");
|
|
115
|
+
} catch (err) {
|
|
116
|
+
console.error("โ Failed to create reports directory:", err.message);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
cleanReportsDir();
|
|
122
|
+
|
|
98
123
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
99
124
|
|
|
100
|
-
let baseReportName = "load-
|
|
125
|
+
let baseReportName = "load-report";
|
|
101
126
|
if (featureFiles.length === 1) {
|
|
102
127
|
const nameFromFeature = path.basename(featureFiles[0], ".feature");
|
|
103
128
|
baseReportName = nameFromFeature || baseReportName;
|
|
@@ -111,12 +136,16 @@ const shouldOverwrite =
|
|
|
111
136
|
process.env.K6_CUCUMBER_OVERWRITE === "true" ||
|
|
112
137
|
configOptions.overwrite === true;
|
|
113
138
|
|
|
114
|
-
let reportJsonPath =
|
|
139
|
+
let reportJsonPath = "reports/load-report.json";
|
|
115
140
|
let reportHtmlPath = path.join(reportsDir, `${baseReportName}.html`);
|
|
116
141
|
|
|
117
|
-
if
|
|
118
|
-
|
|
119
|
-
|
|
142
|
+
// ๐ Respect config format path if defined
|
|
143
|
+
if (Array.isArray(configOptions.format)) {
|
|
144
|
+
const jsonFmt = configOptions.format.find((f) => f.startsWith("json:"));
|
|
145
|
+
if (jsonFmt) {
|
|
146
|
+
reportJsonPath = jsonFmt.split("json:")[1];
|
|
147
|
+
console.log(`๐ Using report path from config: ${reportJsonPath}`);
|
|
148
|
+
}
|
|
120
149
|
}
|
|
121
150
|
|
|
122
151
|
const formatInConfig =
|
|
@@ -144,13 +173,44 @@ const cucumberProcess = spawn("npx", cucumberArgs, {
|
|
|
144
173
|
},
|
|
145
174
|
});
|
|
146
175
|
|
|
147
|
-
|
|
148
|
-
|
|
176
|
+
function detectMostRecentK6Report() {
|
|
177
|
+
const reportsDir = path.join(process.cwd(), "reports");
|
|
178
|
+
if (!fs.existsSync(reportsDir)) return null;
|
|
179
|
+
|
|
180
|
+
const files = fs
|
|
181
|
+
.readdirSync(reportsDir)
|
|
182
|
+
.filter((file) => /^k6-report.*\.html$/.test(file))
|
|
183
|
+
.map((file) => ({
|
|
184
|
+
name: file,
|
|
185
|
+
time: fs.statSync(path.join(reportsDir, file)).mtime.getTime(),
|
|
186
|
+
}))
|
|
187
|
+
.sort((a, b) => b.time - a.time);
|
|
188
|
+
|
|
189
|
+
return files.length > 0 ? path.join("reports", files[0].name) : null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
cucumberProcess.on("close", async (code) => {
|
|
149
193
|
if (code === 0) {
|
|
194
|
+
console.log("-----------------------------------------");
|
|
150
195
|
console.log("โ
k6-cucumber-steps execution completed successfully.");
|
|
196
|
+
|
|
197
|
+
generateHtmlReports(); // ๐ Cucumber HTML
|
|
198
|
+
|
|
199
|
+
console.log(
|
|
200
|
+
"๐ Cucumber HTML report reports/cucumber-report.html generated successfully ๐"
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
await linkReports(); // ๐งฌ Combine and link reports
|
|
204
|
+
|
|
205
|
+
console.log(
|
|
206
|
+
"๐ฆ Combined and minified HTML report available at: reports/combined-report.html"
|
|
207
|
+
);
|
|
208
|
+
console.log("-----------------------------------------");
|
|
151
209
|
} else {
|
|
210
|
+
console.error("-----------------------------------------");
|
|
152
211
|
console.error("โ k6-cucumber-steps execution failed.");
|
|
212
|
+
console.error("-----------------------------------------");
|
|
153
213
|
}
|
|
154
|
-
|
|
214
|
+
|
|
155
215
|
process.exit(code);
|
|
156
216
|
});
|
package/cucumber.js
CHANGED
|
@@ -3,13 +3,13 @@ module.exports = {
|
|
|
3
3
|
require: ["./step_definitions/**/*.js"],
|
|
4
4
|
format: [
|
|
5
5
|
"summary",
|
|
6
|
-
"json:./
|
|
7
|
-
"html:./
|
|
6
|
+
"json:./reports/load-report.json",
|
|
7
|
+
"html:./reports/cucumber-report.html",
|
|
8
8
|
],
|
|
9
|
-
paths: ["./
|
|
10
|
-
tags: "@
|
|
9
|
+
paths: ["./features/bsp.feature"],
|
|
10
|
+
tags: "@rate-limit",
|
|
11
11
|
worldParameters: {
|
|
12
|
-
payloadPath: "
|
|
12
|
+
payloadPath: "payloads",
|
|
13
13
|
},
|
|
14
14
|
overwrite: true,
|
|
15
15
|
reporter: true,
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
module.exports = function buildK6Script(config) {
|
|
2
2
|
const { method, endpoints, endpoint, body, headers, options } = config;
|
|
3
3
|
|
|
4
|
-
// Ensure at least one of `endpoints` or `endpoint` is defined
|
|
5
4
|
if (!endpoints?.length && !endpoint) {
|
|
6
5
|
throw new Error(
|
|
7
6
|
'Either "endpoints" or "endpoint" must be defined in the configuration.'
|
|
8
7
|
);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
// Prefer API_BASE_URL, fallback to BASE_URL
|
|
12
10
|
const BASE_URL = process.env.API_BASE_URL || process.env.BASE_URL;
|
|
13
11
|
if (!BASE_URL) {
|
|
14
12
|
throw new Error(
|
|
@@ -16,18 +14,18 @@ module.exports = function buildK6Script(config) {
|
|
|
16
14
|
);
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
// Resolve relative endpoints by prepending BASE_URL
|
|
20
17
|
const resolveEndpoint = (url) => {
|
|
21
18
|
return url.startsWith("/") ? `${BASE_URL}${url}` : url;
|
|
22
19
|
};
|
|
23
20
|
|
|
24
|
-
// Convert to inline JS object (not stringified) so K6 can call JSON.stringify() itself
|
|
25
21
|
const stringifiedHeaders = JSON.stringify(headers, null, 2);
|
|
26
22
|
const stringifiedBody = JSON.stringify(body, null, 2);
|
|
27
23
|
|
|
28
24
|
return `
|
|
29
25
|
import http from 'k6/http';
|
|
30
26
|
import { check } from 'k6';
|
|
27
|
+
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";
|
|
28
|
+
import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js";
|
|
31
29
|
|
|
32
30
|
export const options = ${JSON.stringify(options, null, 2)};
|
|
33
31
|
|
|
@@ -40,32 +38,55 @@ export default function () {
|
|
|
40
38
|
? endpoints
|
|
41
39
|
.map(
|
|
42
40
|
(url, i) => `
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
const resolvedUrl${i} = "${resolveEndpoint(url)}";
|
|
42
|
+
const res${i} = http.request("${method}", resolvedUrl${i}, ${
|
|
45
43
|
method === "GET" || method === "DELETE"
|
|
46
44
|
? "null"
|
|
47
45
|
: "JSON.stringify(body)"
|
|
48
46
|
}, { headers });
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
console.log(\`Response Body for \${resolvedUrl${i}}: \${res${i}.body}\`);
|
|
48
|
+
check(res${i}, {
|
|
49
|
+
"status is 2xx": (r) => r.status >= 200 && r.status < 300
|
|
50
|
+
});
|
|
51
|
+
`
|
|
54
52
|
)
|
|
55
53
|
.join("\n")
|
|
56
54
|
: `
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const resolvedUrl = "${resolveEndpoint(endpoint)}";
|
|
56
|
+
const res = http.request("${method}", resolvedUrl, ${
|
|
59
57
|
method === "GET" || method === "DELETE"
|
|
60
58
|
? "null"
|
|
61
59
|
: "JSON.stringify(body)"
|
|
62
60
|
}, { headers });
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
console.log(\`Response Body for \${resolvedUrl}: \${res.body}\`);
|
|
62
|
+
check(res, {
|
|
63
|
+
"status is 2xx": (r) => r.status >= 200 && r.status < 300
|
|
64
|
+
});
|
|
67
65
|
`
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
|
-
|
|
68
|
+
|
|
69
|
+
export function handleSummary(data) {
|
|
70
|
+
const outputDir = __ENV.REPORT_OUTPUT_DIR || "reports";
|
|
71
|
+
const html = htmlReport(data);
|
|
72
|
+
const cucumberReportFile = "cucumber-report.html";
|
|
73
|
+
const cucumberLink = \`
|
|
74
|
+
<div style="text-align:center; margin-top:20px;">
|
|
75
|
+
<a href="\${cucumberReportFile}" style="font-size:18px; color:#0066cc;">
|
|
76
|
+
๐ View Cucumber Test Report
|
|
77
|
+
</a>
|
|
78
|
+
</div>
|
|
79
|
+
\`;
|
|
80
|
+
|
|
81
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
82
|
+
const k6ReportFilename = \`\${outputDir}/k6-report-\${timestamp}.html\`;
|
|
83
|
+
|
|
84
|
+
console.log(\`๐ K6 HTML report \${k6ReportFilename} generated successfully ๐\`);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
[k6ReportFilename]: html.replace("</body>", \`\${cucumberLink}</body>\`),
|
|
88
|
+
stdout: textSummary(data, { indent: " ", enableColors: true }),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
71
92
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "k6-cucumber-steps",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"@faker-js/faker": "latest",
|
|
69
69
|
"axios": "^1.9.0",
|
|
70
70
|
"dotenv": "latest",
|
|
71
|
+
"html-minifier-terser": "^7.2.0",
|
|
71
72
|
"yargs": "latest"
|
|
72
73
|
}
|
|
73
74
|
}
|