k6-cucumber-steps 1.2.19 → 1.2.21

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,11 +24,9 @@ program
24
24
  .option("--overwrite", "Overwrite report files", false)
25
25
  .option("--cleanReports", "Clean the reports folder before running", false)
26
26
  .option("--reporter", "Enable report generation", false)
27
- .option("--clean", "Alias for --cleanReports")
27
+ .option("--clean", "Alias for --cleanReports", false)
28
28
  .option("-p, --payloadPath <dir>", "Directory for payload files")
29
29
  // Add CLI options for all config options
30
- .option("--script <file>", "k6 script file to run")
31
- .option("--k6Config <file>", "k6 config file to use")
32
30
  .action(async (argv) => {
33
31
  // Load config file
34
32
  const configFileInput =
@@ -1,5 +1,6 @@
1
1
  module.exports = function buildK6Script(config) {
2
- const { method, endpoints, endpoint, body, headers, options, baseUrl } = config;
2
+ const { method, endpoints, endpoint, body, headers, options, baseUrl } =
3
+ config;
3
4
 
4
5
  const BASE_URL =
5
6
  baseUrl ||
@@ -54,7 +55,8 @@ export default function () {
54
55
  : "JSON.stringify(body)"
55
56
  }, { headers });
56
57
  check(res${i}, {
57
- "status is 2xx": (r) => r.status >= 200 && r.status < 300
58
+ "status is 2xx": (r) => r.status >= 200 && r.status < 300,
59
+ "response body is not empty": (r) => r.body && r.body.length > 0,
58
60
  });
59
61
  `
60
62
  )
@@ -67,7 +69,8 @@ export default function () {
67
69
  : "JSON.stringify(body)"
68
70
  }, { headers });
69
71
  check(res, {
70
- "status is 2xx": (r) => r.status >= 200 && r.status < 300
72
+ "status is 2xx": (r) => r.status >= 200 && r.status < 300,
73
+ "response body is not empty": (r) => r.body && r.body.length > 0,
71
74
  });
72
75
  `
73
76
  }
@@ -0,0 +1,36 @@
1
+ const { generateK6Script, runK6Script } = require("./runner");
2
+ const buildK6Script = require("./buildK6Script");
3
+
4
+ /**
5
+ * Runs a K6 script using values from the World instance.
6
+ * Supports both single and multiple endpoints.
7
+ *
8
+ * @param {object} world - Cucumber World instance
9
+ * @param {string} method - HTTP method
10
+ * @param {boolean} isMulti - Flag to use `world.endpoints` instead of `endpoint`
11
+ */
12
+ async function runK6ScriptFromWorld(world, method, isMulti = false) {
13
+ const scriptContent = buildK6Script({
14
+ method,
15
+ endpoint: isMulti ? undefined : world.endpoint,
16
+ endpoints: isMulti ? world.endpoints : undefined,
17
+ body: world.body,
18
+ headers: world.headers,
19
+ options: world.k6Options,
20
+ baseUrl: world.baseUrl,
21
+ worldParameters: world.worldParameters,
22
+ });
23
+
24
+ const scriptPath = await generateK6Script(scriptContent, "api", true);
25
+ const { stdout, stderr, code } = await runK6Script(scriptPath, true);
26
+
27
+ console.log(stdout);
28
+ if (stderr) console.error(stderr);
29
+ if (code !== 0) {
30
+ throw new Error("❌ K6 script execution failed.");
31
+ }
32
+
33
+ console.log("✅ K6 script ran successfully.");
34
+ }
35
+
36
+ module.exports = runK6ScriptFromWorld;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k6-cucumber-steps",
3
- "version": "1.2.19",
3
+ "version": "1.2.21",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -7,9 +7,10 @@ import crypto from "crypto";
7
7
  import * as dotenv from "dotenv";
8
8
  import resolvePayloadPath from "../lib/helpers/resolvePayloadPath.js";
9
9
  import resolveBody from "../lib/helpers/resolveBody.js";
10
- import buildK6Script from "../lib/helpers/buildK6Script.js";
10
+ // import buildK6Script from "../lib/helpers/buildK6Script.js";
11
11
  import generateHeaders from "../lib/helpers/generateHeaders.js";
12
- import { runK6Script } from "../lib/utils/k6Runner.js";
12
+ // import { runK6Script } from "../lib/utils/k6Runner.js";
13
+ const runK6ScriptFromWorld = require("../../../helpers/runK6ScriptFromWorld");
13
14
 
14
15
  dotenv.config();
15
16
 
@@ -345,7 +346,10 @@ export async function When_I_set_method_body_for_endpoint(
345
346
  )}...`
346
347
  );
347
348
  }
348
-
349
+ When(
350
+ /^I set the following (\w+) body is used for "([^"]+)"$/,
351
+ When_I_set_method_body_for_endpoint
352
+ );
349
353
  /**
350
354
  * Loads a JSON payload from a file to be used as the request body for a specific
351
355
  * method and endpoint in the k6 script.
@@ -608,79 +612,95 @@ if (!fs.existsSync(reportDir)) {
608
612
  fs.mkdirSync(reportDir, { recursive: true });
609
613
  }
610
614
 
615
+ // Then(
616
+ // /^I see the API should handle the (\w+) request successfully$/,
617
+ // { timeout: 300000 },
618
+ // async function (method) {
619
+ // if (!this.config || !this.config.method) {
620
+ // throw new Error("Configuration is missing or incomplete.");
621
+ // }
622
+ // const expectedMethod = method.toUpperCase();
623
+ // const actualMethod = this.config.method.toUpperCase();
624
+ // if (actualMethod !== expectedMethod) {
625
+ // throw new Error(
626
+ // `Mismatched HTTP method: expected "${expectedMethod}", got "${actualMethod}"`
627
+ // );
628
+ // }
629
+ // try {
630
+ // const scriptContent = buildK6Script(this.config);
631
+ // const uniqueId = crypto.randomBytes(8).toString("hex");
632
+ // const scriptFileName = `k6-script-${uniqueId}.js`;
633
+ // const scriptPath = path.join(reportDir, scriptFileName);
634
+ // fs.writeFileSync(scriptPath, scriptContent, "utf-8");
635
+ // this.log?.(`✅ k6 script generated at: "${scriptPath}"`);
636
+
637
+ // this.log?.(`🚀 Running k6 script: "${scriptFileName}"...`);
638
+ // const { stdout, stderr, code } = await runK6Script(
639
+ // scriptPath,
640
+ // process.env.K6_CUCUMBER_OVERWRITE === "true"
641
+ // );
642
+ // if (stdout) this.log?.(`k6 STDOUT:\n${stdout}`);
643
+ // if (stderr) this.log?.(`k6 STDERR:\n${stderr}`);
644
+
645
+ // if (code !== 0) {
646
+ // throw new Error(
647
+ // `k6 process exited with code ${code}. Check k6 output for details.`
648
+ // );
649
+ // }
650
+ // this.log?.(
651
+ // `✅ k6 script executed successfully for ${expectedMethod} request.`
652
+ // );
653
+
654
+ // const saveK6Script =
655
+ // process.env.saveK6Script === "true" ||
656
+ // process.env.SAVE_K6_SCRIPT === "true" ||
657
+ // this.parameters?.saveK6Script === true;
658
+
659
+ // if (!saveK6Script) {
660
+ // try {
661
+ // fs.unlinkSync(scriptPath);
662
+ // this.log?.(`🧹 Temporary k6 script deleted: "${scriptPath}"`);
663
+ // } catch (cleanupErr) {
664
+ // this.log?.(
665
+ // `⚠️ Warning: Could not delete temporary k6 script file: "${scriptPath}". Error: ${
666
+ // cleanupErr instanceof Error
667
+ // ? cleanupErr.message
668
+ // : String(cleanupErr)
669
+ // }`
670
+ // );
671
+ // }
672
+ // } else {
673
+ // this.log?.(
674
+ // `ℹ️ k6 script kept at: "${scriptPath}". Set SAVE_K6_SCRIPT=false to delete automatically.`
675
+ // );
676
+ // }
677
+ // } catch (error) {
678
+ // this.log?.(
679
+ // `❌ Failed to generate or run k6 script: ${
680
+ // error instanceof Error ? error.message : String(error)
681
+ // }`
682
+ // );
683
+ // throw new Error(
684
+ // `k6 script generation or execution failed: ${
685
+ // error instanceof Error ? error.message : String(error)
686
+ // }`
687
+ // );
688
+ // }
689
+ // }
690
+ // );
691
+
692
+ // Single endpoint
611
693
  Then(
612
- /^I see the API should handle the (\w+) request successfully$/,
613
- { timeout: 300000 },
694
+ "I see the API should handle the {word} request successfully",
614
695
  async function (method) {
615
- if (!this.config || !this.config.method) {
616
- throw new Error("Configuration is missing or incomplete.");
617
- }
618
- const expectedMethod = method.toUpperCase();
619
- const actualMethod = this.config.method.toUpperCase();
620
- if (actualMethod !== expectedMethod) {
621
- throw new Error(
622
- `Mismatched HTTP method: expected "${expectedMethod}", got "${actualMethod}"`
623
- );
624
- }
625
- try {
626
- const scriptContent = buildK6Script(this.config);
627
- const uniqueId = crypto.randomBytes(8).toString("hex");
628
- const scriptFileName = `k6-script-${uniqueId}.js`;
629
- const scriptPath = path.join(reportDir, scriptFileName);
630
- fs.writeFileSync(scriptPath, scriptContent, "utf-8");
631
- this.log?.(`✅ k6 script generated at: "${scriptPath}"`);
632
-
633
- this.log?.(`🚀 Running k6 script: "${scriptFileName}"...`);
634
- const { stdout, stderr, code } = await runK6Script(
635
- scriptPath,
636
- process.env.K6_CUCUMBER_OVERWRITE === "true"
637
- );
638
- if (stdout) this.log?.(`k6 STDOUT:\n${stdout}`);
639
- if (stderr) this.log?.(`k6 STDERR:\n${stderr}`);
640
-
641
- if (code !== 0) {
642
- throw new Error(
643
- `k6 process exited with code ${code}. Check k6 output for details.`
644
- );
645
- }
646
- this.log?.(
647
- `✅ k6 script executed successfully for ${expectedMethod} request.`
648
- );
696
+ await runK6ScriptFromWorld(this, method);
697
+ }
698
+ );
649
699
 
650
- const saveK6Script =
651
- process.env.saveK6Script === "true" ||
652
- process.env.SAVE_K6_SCRIPT === "true" ||
653
- this.parameters?.saveK6Script === true;
654
-
655
- if (!saveK6Script) {
656
- try {
657
- fs.unlinkSync(scriptPath);
658
- this.log?.(`🧹 Temporary k6 script deleted: "${scriptPath}"`);
659
- } catch (cleanupErr) {
660
- this.log?.(
661
- `⚠️ Warning: Could not delete temporary k6 script file: "${scriptPath}". Error: ${
662
- cleanupErr instanceof Error
663
- ? cleanupErr.message
664
- : String(cleanupErr)
665
- }`
666
- );
667
- }
668
- } else {
669
- this.log?.(
670
- `ℹ️ k6 script kept at: "${scriptPath}". Set SAVE_K6_SCRIPT=false to delete automatically.`
671
- );
672
- }
673
- } catch (error) {
674
- this.log?.(
675
- `❌ Failed to generate or run k6 script: ${
676
- error instanceof Error ? error.message : String(error)
677
- }`
678
- );
679
- throw new Error(
680
- `k6 script generation or execution failed: ${
681
- error instanceof Error ? error.message : String(error)
682
- }`
683
- );
684
- }
700
+ // Multi-endpoint
701
+ Then(
702
+ "I run the script for multiple endpoints with method {word}",
703
+ async function (method) {
704
+ await runK6ScriptFromWorld(this, method, true);
685
705
  }
686
706
  );