k6-cucumber-steps 1.1.3 → 1.1.4

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.
@@ -9,5 +9,6 @@
9
9
  "step_definitions/*.js",
10
10
  "src/features/stepDefinitions/*.js"
11
11
  ],
12
- "liveServer.settings.port": 5501
12
+ "liveServer.settings.port": 5501,
13
+ "git.ignoreLimitWarning": true
13
14
  }
@@ -3,11 +3,9 @@
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
5
  const { spawn } = require("child_process");
6
- const yargs = require("yargs/yargs"); // Use the correct import for yargs
7
- const { hideBin } = require("yargs/helpers"); // Helper to parse CLI arguments
6
+ const yargs = require("yargs/yargs");
7
+ const { hideBin } = require("yargs/helpers");
8
8
  require("dotenv").config();
9
- const { generateHtmlReports } = require("../scripts/generateHtmlReports");
10
- const { linkReports } = require("../scripts/linkReports");
11
9
 
12
10
  console.log(`
13
11
  -----------------------------------------
@@ -15,6 +13,7 @@ console.log(`
15
13
  -----------------------------------------
16
14
  `);
17
15
 
16
+ // Parse CLI arguments
18
17
  const argv = yargs(hideBin(process.argv))
19
18
  .usage("Usage: $0 run [options]")
20
19
  .option("feature", {
@@ -24,7 +23,7 @@ const argv = yargs(hideBin(process.argv))
24
23
  })
25
24
  .option("tags", {
26
25
  alias: "t",
27
- describe: "Cucumber tags to filter scenarios",
26
+ describe: "Cucumber tags to filter scenarios (e.g., @smoke)",
28
27
  type: "string",
29
28
  })
30
29
  .option("reporter", {
@@ -46,8 +45,10 @@ const argv = yargs(hideBin(process.argv))
46
45
  })
47
46
  .help().argv;
48
47
 
48
+ // Base Cucumber arguments
49
49
  const cucumberArgs = ["cucumber-js"];
50
50
 
51
+ // Load custom configuration file if provided
51
52
  const configFileName =
52
53
  argv.configFile || process.env.CUCUMBER_CONFIG_FILE || "cucumber.js";
53
54
  const configFilePath = path.resolve(process.cwd(), configFileName);
@@ -58,8 +59,8 @@ if (fs.existsSync(configFilePath)) {
58
59
  try {
59
60
  const loadedConfig = require(configFilePath);
60
61
  configOptions = loadedConfig.default || loadedConfig;
61
- } catch {
62
- console.warn("⚠️ Could not load config file");
62
+ } catch (err) {
63
+ console.warn("⚠️ Could not load config file:", err.message);
63
64
  }
64
65
  }
65
66
 
@@ -69,18 +70,18 @@ if (tags) {
69
70
  cucumberArgs.push("--tags", tags);
70
71
  }
71
72
 
72
- // Feature path(s)
73
+ // Feature file(s)
73
74
  let featureFiles = [];
74
75
  if (argv.feature) {
75
76
  featureFiles.push(path.resolve(argv.feature));
76
77
  } else if (configOptions.paths && configOptions.paths.length > 0) {
77
- featureFiles.push(...configOptions.paths);
78
+ featureFiles.push(...configOptions.paths.map((p) => path.resolve(p)));
78
79
  }
79
80
  if (featureFiles.length > 0) {
80
81
  cucumberArgs.push(...featureFiles);
81
82
  }
82
83
 
83
- // Require default step definitions
84
+ // Require step definitions
84
85
  const defaultStepsPath = path.resolve(
85
86
  process.cwd(),
86
87
  "node_modules",
@@ -89,15 +90,17 @@ const defaultStepsPath = path.resolve(
89
90
  );
90
91
  cucumberArgs.push("--require", defaultStepsPath);
91
92
 
92
- // Also require additional custom step definitions from config, if any
93
+ // Include additional custom step definitions from config
93
94
  if (configOptions.require && Array.isArray(configOptions.require)) {
94
95
  for (const reqPath of configOptions.require) {
95
- cucumberArgs.push("--require", reqPath);
96
+ cucumberArgs.push("--require", path.resolve(reqPath));
96
97
  }
97
98
  }
98
99
 
99
- // Determine base report name
100
+ // Reports directory setup
100
101
  const reportsDir = path.join(process.cwd(), "reports");
102
+
103
+ // Clean and prepare reports directory
101
104
  const cleanReportsDir = () => {
102
105
  if (fs.existsSync(reportsDir)) {
103
106
  try {
@@ -120,6 +123,7 @@ const cleanReportsDir = () => {
120
123
 
121
124
  cleanReportsDir();
122
125
 
126
+ // Determine base report name
123
127
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
124
128
 
125
129
  let baseReportName = "load-report";
@@ -136,10 +140,15 @@ const shouldOverwrite =
136
140
  process.env.K6_CUCUMBER_OVERWRITE === "true" ||
137
141
  configOptions.overwrite === true;
138
142
 
139
- let reportJsonPath = "reports/load-report.json";
143
+ let reportJsonPath = path.join(reportsDir, `${baseReportName}.json`);
140
144
  let reportHtmlPath = path.join(reportsDir, `${baseReportName}.html`);
141
145
 
142
- // 🆕 Respect config format path if defined
146
+ if (!shouldOverwrite) {
147
+ reportJsonPath = path.join(reportsDir, `${baseReportName}-${timestamp}.json`);
148
+ reportHtmlPath = path.join(reportsDir, `${baseReportName}-${timestamp}.html`);
149
+ }
150
+
151
+ // Respect config format path if defined
143
152
  if (Array.isArray(configOptions.format)) {
144
153
  const jsonFmt = configOptions.format.find((f) => f.startsWith("json:"));
145
154
  if (jsonFmt) {
@@ -152,8 +161,7 @@ const formatInConfig =
152
161
  Array.isArray(configOptions.format) && configOptions.format.length > 0;
153
162
 
154
163
  if (shouldGenerateReports && !formatInConfig) {
155
- fs.mkdirSync(reportsDir, { recursive: true });
156
- cucumberArgs.push("--format", `summary`);
164
+ cucumberArgs.push("--format", "summary");
157
165
  cucumberArgs.push("--format", `json:${reportJsonPath}`);
158
166
  cucumberArgs.push("--format", `html:${reportHtmlPath}`);
159
167
  }
@@ -161,6 +169,7 @@ if (shouldGenerateReports && !formatInConfig) {
161
169
  console.log("\n▶️ Final arguments passed to cucumber-js:");
162
170
  console.log(["npx", ...cucumberArgs].join(" ") + "\n");
163
171
 
172
+ // Execute Cucumber process
164
173
  const cucumberProcess = spawn("npx", cucumberArgs, {
165
174
  stdio: "inherit",
166
175
  env: {
@@ -174,9 +183,6 @@ const cucumberProcess = spawn("npx", cucumberArgs, {
174
183
  });
175
184
 
176
185
  function detectMostRecentK6Report() {
177
- const reportsDir = path.join(process.cwd(), "reports");
178
- if (!fs.existsSync(reportsDir)) return null;
179
-
180
186
  const files = fs
181
187
  .readdirSync(reportsDir)
182
188
  .filter((file) => /^k6-report.*\.html$/.test(file))
@@ -186,7 +192,7 @@ function detectMostRecentK6Report() {
186
192
  }))
187
193
  .sort((a, b) => b.time - a.time);
188
194
 
189
- return files.length > 0 ? path.join("reports", files[0].name) : null;
195
+ return files.length > 0 ? path.join(reportsDir, files[0].name) : null;
190
196
  }
191
197
 
192
198
  cucumberProcess.on("close", async (code) => {
@@ -194,17 +200,26 @@ cucumberProcess.on("close", async (code) => {
194
200
  console.log("-----------------------------------------");
195
201
  console.log("✅ k6-cucumber-steps execution completed successfully.");
196
202
 
197
- generateHtmlReports(); // 🍋 Cucumber HTML
198
-
199
- console.log(
200
- "🚀 Cucumber HTML report reports/cucumber-report.html generated successfully 👍"
201
- );
203
+ // Generate Cucumber HTML report
204
+ try {
205
+ await generateHtmlReports();
206
+ console.log(
207
+ `🚀 Cucumber HTML report generated successfully at: ${reportHtmlPath}`
208
+ );
209
+ } catch (err) {
210
+ console.error("⚠️ Failed to generate Cucumber HTML report:", err.message);
211
+ }
202
212
 
203
- await linkReports(); // 🧬 Combine and link reports
213
+ // Link reports
214
+ try {
215
+ await linkReports();
216
+ console.log(
217
+ "🔗 Combined and minified HTML report available at: reports/combined-report.html"
218
+ );
219
+ } catch (err) {
220
+ console.error("⚠️ Failed to link reports:", err.message);
221
+ }
204
222
 
205
- console.log(
206
- "📦 Combined and minified HTML report available at: reports/combined-report.html"
207
- );
208
223
  console.log("-----------------------------------------");
209
224
  } else {
210
225
  console.error("-----------------------------------------");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k6-cucumber-steps",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -49,26 +49,22 @@
49
49
  },
50
50
  "author": "qaPaschalE",
51
51
  "description": "Cucumber step definitions for running k6 performance tests.",
52
+ "peerDependencies": {
53
+ "@cucumber/cucumber": "*",
54
+ "k6": "*"
55
+ },
52
56
  "devDependencies": {
53
- "@babel/cli": "latest",
54
- "@babel/core": "latest",
55
- "@babel/preset-env": "latest",
56
- "@types/k6": "latest",
57
- "child_process": "latest",
58
- "cucumber-console-formatter": "latest",
59
- "cucumber-html-reporter": "latest",
60
- "esbuild": "latest",
61
- "form-data": "latest",
62
- "k6": "latest",
63
- "tsconfig-paths": "latest"
57
+ "@babel/cli": "^7.27.2",
58
+ "@babel/core": "^7.27.4",
59
+ "@babel/preset-env": "^7.27.2",
60
+ "@faker-js/faker": "^9.8.0",
61
+ "@types/k6": "^1.0.2",
62
+ "axios": "^1.10.0",
63
+ "dotenv": "^16.5.0",
64
+ "html-minifier-terser": "^7.2.0",
65
+ "yargs": "^18.0.0"
64
66
  },
65
67
  "dependencies": {
66
- "@babel/register": "latest",
67
- "@cucumber/cucumber": "latest",
68
- "@faker-js/faker": "latest",
69
- "axios": "^1.9.0",
70
- "dotenv": "latest",
71
- "html-minifier-terser": "^7.2.0",
72
- "yargs": "latest"
68
+ "@babel/register": "^7.27.1"
73
69
  }
74
70
  }
@@ -4,18 +4,29 @@ const path = require("path");
4
4
  const reportsDir = path.resolve("reports");
5
5
 
6
6
  /**
7
- * Adds internal cross-links between reports.
7
+ * Finds the first file that looks like a Cucumber HTML report.
8
8
  */
9
- function addLinksToReport(targetFile, otherFiles) {
9
+ function findCucumberReportFile() {
10
+ const files = fs.readdirSync(reportsDir);
11
+ return files.find((f) => f.includes("cucumber") && f.endsWith(".html"));
12
+ }
13
+
14
+ /**
15
+ * Adds a Cucumber report tab as an iframe.
16
+ */
17
+ function addLinksToReport(targetFile, cucumberFileName) {
10
18
  const content = fs.readFileSync(targetFile, "utf-8");
11
19
 
12
- // Inject the Cucumber Report tab before the Request Metrics tab
13
20
  const cucumberTab = `
14
- <input type="radio" name="tabs" id="tabcucumber">
15
- <label for="tabcucumber"><i class="fas fa-file-alt"></i> &nbsp; Cucumber Report</label>
16
- <div class="tab">
17
- <iframe src="cucumber-report.html" style="width:100%; height:600px; border:none;"></iframe>
18
- </div>
21
+ <input type="radio" name="tabs" id="tabcucumber">
22
+ <label for="tabcucumber"><i class="fas fa-file-alt"></i> &nbsp; Cucumber Report</label>
23
+ <div class="tab">
24
+ ${
25
+ cucumberFileName
26
+ ? `<iframe src="${cucumberFileName}" style="width:100%; min-height:600px; border:none;"></iframe>`
27
+ : `<p style="color:red; padding:1rem;">⚠️ Cucumber HTML report not found in <code>reports/</code> directory.</p>`
28
+ }
29
+ </div>
19
30
  `;
20
31
 
21
32
  const modifiedContent = content
@@ -23,22 +34,13 @@ function addLinksToReport(targetFile, otherFiles) {
23
34
  /<input type="radio" name="tabs" id="tabone"/,
24
35
  `${cucumberTab}\n<input type="radio" name="tabs" id="tabone"`
25
36
  )
26
- // Remove standalone links to cucumber-report.html or k6-report.html
27
- .replace(
28
- /<div style="padding:10px;margin-top:20px;text-align:center">[\s\S]*?View (Cucumber|k6).*?<\/div>/,
29
- ""
30
- );
37
+ .replace(/<div style="[^>]*margin-top:20px;[^>]*">[\s\S]*?<\/div>/g, "");
31
38
 
32
39
  fs.writeFileSync(targetFile, modifiedContent, "utf-8");
33
- console.log(
34
- `🔗 Updated ${path.basename(
35
- targetFile
36
- )} with Cucumber tab and removed standalone links.`
37
- );
38
40
  }
39
41
 
40
42
  /**
41
- * Auto-link all HTML reports in the reports directory.
43
+ * Adds a Cucumber tab to every K6 HTML report found in /reports.
42
44
  */
43
45
  function linkReports() {
44
46
  if (!fs.existsSync(reportsDir)) {
@@ -46,20 +48,22 @@ function linkReports() {
46
48
  return;
47
49
  }
48
50
 
51
+ const cucumberFile = findCucumberReportFile();
52
+
49
53
  const htmlFiles = fs
50
54
  .readdirSync(reportsDir)
51
- .filter((f) => f.endsWith(".html"))
52
- .map((f) => path.join(reportsDir, f));
55
+ .filter((f) => /^k6-report.*\.html$/.test(f));
53
56
 
54
- if (htmlFiles.length < 2) {
55
- console.warn("⚠️ Not enough HTML files to link.");
57
+ if (htmlFiles.length === 0) {
58
+ console.warn("⚠️ No K6 reports found to inject.");
56
59
  return;
57
60
  }
58
61
 
59
- for (const file of htmlFiles) {
60
- const others = htmlFiles.filter((f) => f !== file);
61
- addLinksToReport(file, others);
62
- }
62
+ htmlFiles.forEach((file) => {
63
+ const fullPath = path.join(reportsDir, file);
64
+ addLinksToReport(fullPath, cucumberFile);
65
+ console.log(`🔗 Injected Cucumber tab into: ${file}`);
66
+ });
63
67
  }
64
68
 
65
69
  module.exports = { linkReports };