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 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"
@@ -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-results";
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 = path.join(reportsDir, `${baseReportName}.json`);
139
+ let reportJsonPath = "reports/load-report.json";
115
140
  let reportHtmlPath = path.join(reportsDir, `${baseReportName}.html`);
116
141
 
117
- if (!shouldOverwrite) {
118
- reportJsonPath = path.join(reportsDir, `${baseReportName}-${timestamp}.json`);
119
- reportHtmlPath = path.join(reportsDir, `${baseReportName}-${timestamp}.html`);
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
- cucumberProcess.on("close", (code) => {
148
- console.log(`\n-----------------------------------------`);
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
- console.log(`-----------------------------------------\n`);
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:./src/examples/reports/load-report.json",
7
- "html:./src/examples/reports/report.html",
6
+ "json:./reports/load-report.json",
7
+ "html:./reports/cucumber-report.html",
8
8
  ],
9
- paths: ["./src/examples/features/*.feature"],
10
- tags: "@load",
9
+ paths: ["./features/bsp.feature"],
10
+ tags: "@rate-limit",
11
11
  worldParameters: {
12
- payloadPath: "src/examples/payloads",
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
- const resolvedUrl${i} = "${resolveEndpoint(url)}";
44
- const res${i} = http.request("${method}", resolvedUrl${i}, ${
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
- console.log(\`Response Body for \${resolvedUrl${i}}: \${res${i}.body}\`);
50
- check(res${i}, {
51
- "status is 2xx": (r) => r.status >= 200 && r.status < 300
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
- const resolvedUrl = "${resolveEndpoint(endpoint)}";
58
- const res = http.request("${method}", resolvedUrl, ${
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
- console.log(\`Response Body for \${resolvedUrl}: \${res.body}\`);
64
- check(res, {
65
- "status is 2xx": (r) => r.status >= 200 && r.status < 300
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.0.41",
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
  }