k6-cucumber-steps 1.1.8 → 1.1.10

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.
@@ -24,8 +24,9 @@ program
24
24
  .option("-o, --overwrite", "Overwrite report files", false)
25
25
  .option("--cleanReports", "Clean the reports folder before running")
26
26
  .option("--clean", "Alias for --cleanReports")
27
+ .option("-p, --payloadPath <dir>", "Directory for payload files")
27
28
  .action(async (argv) => {
28
- const cucumberArgs = ["cucumber-js"];
29
+ // Load config file
29
30
  const configFileInput =
30
31
  argv.config || process.env.CUCUMBER_CONFIG_FILE || "cucumber.js";
31
32
  const configFilePath = path.isAbsolute(configFileInput)
@@ -33,73 +34,87 @@ program
33
34
  : path.resolve(process.cwd(), configFileInput);
34
35
 
35
36
  let configOptions = {};
36
-
37
37
  if (fs.existsSync(configFilePath)) {
38
- cucumberArgs.push("--config", configFileInput);
39
38
  try {
40
39
  const loadedConfig = require(configFilePath);
41
40
  configOptions = loadedConfig.default || loadedConfig;
42
41
  } catch (err) {
43
42
  console.warn("⚠️ Could not load config file:", err.message);
44
43
  }
45
- } else {
46
- console.warn(`⚠️ Config file not found at ${configFilePath}`);
47
44
  }
48
45
 
49
- // Resolve cleanReports: CLI > ENV > config file
50
- const cleanReports =
51
- typeof argv.cleanReports === "boolean"
52
- ? argv.cleanReports
53
- : typeof argv.clean === "boolean"
54
- ? argv.clean
55
- : process.env.CLEAN_REPORTS
56
- ? process.env.CLEAN_REPORTS === "true"
57
- : configOptions.cleanReports;
58
-
59
- // Clean reports directory if needed
60
- const reportsDir = path.resolve("reports");
61
- if (cleanReports) {
62
- if (fs.existsSync(reportsDir)) {
63
- fs.rmSync(reportsDir, { recursive: true, force: true });
64
- console.log("🧹 Cleaned reports directory.");
65
- }
66
- }
67
- if (!fs.existsSync(reportsDir)) {
68
- fs.mkdirSync(reportsDir, { recursive: true });
46
+ // Build the cucumber-js command from config
47
+ const cucumberConfig = configOptions.default || configOptions;
48
+ let cliParts = [];
49
+
50
+ // Add paths
51
+ if (cucumberConfig.paths && Array.isArray(cucumberConfig.paths)) {
52
+ cliParts.push(...cucumberConfig.paths);
69
53
  }
70
54
 
71
- // Build featureFiles array before using it
72
- let featureFiles = [];
73
- if (argv.feature) {
74
- featureFiles.push(path.resolve(argv.feature));
75
- } else if (Array.isArray(configOptions.paths)) {
76
- featureFiles = configOptions.paths.map((f) => path.resolve(f));
55
+ // Add require
56
+ if (cucumberConfig.require && Array.isArray(cucumberConfig.require)) {
57
+ cucumberConfig.require.forEach((req) => {
58
+ cliParts.push("--require", req);
59
+ });
77
60
  }
78
61
 
79
- let baseReportName = "load-report";
80
- if (featureFiles.length === 1) {
81
- baseReportName = path.basename(featureFiles[0], ".feature");
82
- } else if (featureFiles.length > 1) {
83
- baseReportName = "multi-feature";
62
+ // Add format
63
+ if (cucumberConfig.format && Array.isArray(cucumberConfig.format)) {
64
+ cucumberConfig.format.forEach((fmt) => {
65
+ cliParts.push("--format", fmt);
66
+ });
84
67
  }
85
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
86
- let reportHtmlPath = path.join(reportsDir, `cucumber-report.html`);
87
68
 
88
- if (argv.reporter && !Array.isArray(configOptions.format)) {
89
- cucumberArgs.push("--format", "summary");
90
- cucumberArgs.push("--format", `html:${reportHtmlPath}`);
69
+ // Add tags
70
+ if (cucumberConfig.tags) {
71
+ cliParts.push("--tags", cucumberConfig.tags);
91
72
  }
92
73
 
93
- console.log("\n▶️ Final arguments passed to cucumber-js:");
94
- console.log(["npx", ...cucumberArgs].join(" ") + "\n");
74
+ // Determine project root (where your main package.json is)
75
+ const projectRoot = path.resolve(__dirname, "..");
76
+
77
+ // Determine payload directory from CLI or config, always relative to project root
78
+ let payloadDirRaw =
79
+ argv.payloadPath ||
80
+ (cucumberConfig.worldParameters &&
81
+ cucumberConfig.worldParameters.payloadPath) ||
82
+ "payloads";
83
+ const payloadDir = path.isAbsolute(payloadDirRaw)
84
+ ? payloadDirRaw
85
+ : path.join(projectRoot, payloadDirRaw);
86
+
87
+ // Add --world-parameters to CLI args
88
+ const worldParams = {
89
+ ...(cucumberConfig.worldParameters || {}),
90
+ payloadPath: payloadDir,
91
+ };
92
+ cliParts.push("--world-parameters", JSON.stringify(worldParams));
93
+
94
+ // Add other options as needed...
95
+
96
+ const finalCommand = ["npx", "cucumber-js", ...cliParts].join(" ");
97
+ console.log("▶️ Final arguments passed to cucumber-js:", finalCommand);
98
+
99
+ // Clean reports directory if requested
100
+ const shouldCleanReports =
101
+ argv.cleanReports ||
102
+ argv.clean ||
103
+ process.env.CLEAN_REPORTS === "true" ||
104
+ cucumberConfig.cleanReports;
105
+
106
+ if (shouldCleanReports) {
107
+ const reportsDir = path.join(projectRoot, "reports");
108
+ if (fs.existsSync(reportsDir)) {
109
+ fs.rmSync(reportsDir, { recursive: true, force: true });
110
+ fs.mkdirSync(reportsDir, { recursive: true });
111
+ console.log("🧹 Cleaned reports directory.");
112
+ }
113
+ }
95
114
 
96
- const cucumberProcess = spawn("npx", cucumberArgs, {
115
+ // Now spawn the process
116
+ const cucumberProcess = spawn("npx", ["cucumber-js", ...cliParts], {
97
117
  stdio: "inherit",
98
- env: {
99
- ...process.env,
100
- REPORT_HTML_PATH: reportHtmlPath,
101
- K6_CUCUMBER_OVERWRITE: argv.overwrite ? "true" : "false",
102
- },
103
118
  });
104
119
 
105
120
  cucumberProcess.on("close", async (code) => {
@@ -108,7 +123,9 @@ program
108
123
  console.log("✅ k6-cucumber-steps execution completed successfully.");
109
124
  try {
110
125
  await linkReports();
111
- console.log("🔗 Reports linked successfully with embedded Cucumber tab.");
126
+ console.log(
127
+ "🔗 Reports linked successfully with embedded Cucumber tab."
128
+ );
112
129
  } catch (err) {
113
130
  console.error("⚠️ Failed to link reports:", err.message);
114
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k6-cucumber-steps",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,38 +10,58 @@ async function linkReports() {
10
10
  return;
11
11
  }
12
12
 
13
+ // Get all HTML files in the reports directory
13
14
  const htmlFiles = fs
14
15
  .readdirSync(reportsDir)
15
- .filter((f) => f.endsWith(".html"));
16
- const k6ReportFile = htmlFiles.find(
17
- (f) => f.startsWith("k6-report") && f.endsWith(".html")
18
- );
19
- const cucumberReportFile = htmlFiles.find((f) =>
20
- f.includes("cucumber-report")
21
- );
16
+ .filter((f) => f.endsWith(".html"))
17
+ .map((f) => ({
18
+ name: f,
19
+ path: path.join(reportsDir, f),
20
+ mtime: fs.statSync(path.join(reportsDir, f)).mtime.getTime(),
21
+ }));
22
+
23
+ if (htmlFiles.length === 0) {
24
+ console.warn("⚠️ No HTML reports found.");
25
+ return;
26
+ }
27
+
28
+ // Find k6 report: file starting with "k6-" or fallback to most recent
29
+ let k6Report = htmlFiles.find((f) => f.name.startsWith("k6-"));
30
+ if (!k6Report) {
31
+ k6Report = htmlFiles.reduce((a, b) => (a.mtime > b.mtime ? a : b));
32
+ }
33
+
34
+ // Find all other HTML reports (excluding k6 report)
35
+ const otherReports = htmlFiles.filter((f) => f.name !== k6Report.name);
22
36
 
23
- if (!k6ReportFile || !cucumberReportFile) {
24
- console.warn("⚠️ K6 or Cucumber HTML report not found.");
37
+ if (!k6Report || otherReports.length === 0) {
38
+ console.warn("⚠️ K6 or any other HTML report not found.");
25
39
  return;
26
40
  }
27
41
 
28
- const k6Path = path.join(reportsDir, k6ReportFile);
29
- const cucumberPath = path.basename(cucumberReportFile);
30
- let content = fs.readFileSync(k6Path, "utf8");
42
+ // Read k6 report content
43
+ let content = fs.readFileSync(k6Report.path, "utf8");
31
44
 
32
- const cucumberTab = `
33
- <input type="radio" name="tabs" id="tabcucumber">
34
- <label for="tabcucumber"><i class="fas fa-file-alt"></i> &nbsp; Cucumber Report</label>
45
+ // Build tabs for each other report
46
+ const tabs = otherReports
47
+ .map(
48
+ (report, idx) => `
49
+ <input type="radio" name="tabs" id="tab${idx + 2}">
50
+ <label for="tab${idx + 2}"><i class="fas fa-file-alt"></i> &nbsp; ${report.name}</label>
35
51
  <div class="tab">
36
- <iframe src="${cucumberPath}" style="width:100%; height:600px; border:none;"></iframe>
52
+ <iframe src="${report.name}" style="width:100%; height:600px; border:none;"></iframe>
37
53
  </div>
38
- `;
54
+ `
55
+ )
56
+ .join("\n");
39
57
 
58
+ // Insert tabs after the first tab (assumes k6 report has a tab structure)
40
59
  content = content.replace(
41
60
  /<input type="radio" name="tabs" id="tabone"/,
42
- `${cucumberTab}\n<input type="radio" name="tabs" id="tabone"`
61
+ `${tabs}\n<input type="radio" name="tabs" id="tabone"`
43
62
  );
44
63
 
64
+ // Remove any existing footer
45
65
  content = content.replace(
46
66
  /<div style="padding:10px;margin-top:20px;text-align:center">[\s\S]*?<\/div>/,
47
67
  ""
@@ -184,9 +184,11 @@ When(
184
184
  );
185
185
  }
186
186
 
187
- const basePayloadPath =
188
- this.parameters?.payloadPath || path.resolve(__dirname, "../../payloads");
189
- const payloadPath = path.resolve(basePayloadPath, fileName);
187
+ const projectRoot = path.resolve(__dirname, "..", "..");
188
+ const payloadDir = this.parameters?.payloadPath || "payloads";
189
+ const payloadPath = path.isAbsolute(payloadDir)
190
+ ? path.join(payloadDir, fileName)
191
+ : path.join(__dirname, "..", "..", payloadDir, fileName);
190
192
 
191
193
  if (!fs.existsSync(payloadPath)) {
192
194
  throw new Error(`Payload file not found: ${payloadPath}`);
@@ -261,9 +263,10 @@ Then(
261
263
  When(
262
264
  "I login via POST to {string} with payload from {string}",
263
265
  async function (endpoint, fileName) {
264
- const basePayloadPath =
265
- this.parameters?.payloadPath || path.resolve(__dirname, "../../payloads");
266
- const payloadPath = path.resolve(basePayloadPath, fileName);
266
+ const payloadDir = this.parameters?.payloadPath || "payloads";
267
+ const payloadPath = path.isAbsolute(payloadDir)
268
+ ? path.join(payloadDir, fileName)
269
+ : path.join(__dirname, "..", "..", payloadDir, fileName);
267
270
 
268
271
  if (!fs.existsSync(payloadPath)) {
269
272
  throw new Error(`Payload file not found: ${payloadPath}`);