playwright-cucumber-ts-steps 1.1.7 → 1.1.9

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/dist/backend/actions/click.d.ts +133 -0
  3. package/dist/backend/actions/click.d.ts.map +1 -0
  4. package/dist/backend/actions/click.js +248 -0
  5. package/dist/backend/actions/find.d.ts +244 -0
  6. package/dist/backend/actions/find.d.ts.map +1 -0
  7. package/dist/backend/actions/find.js +415 -0
  8. package/dist/backend/actions/form.d.ts +38 -0
  9. package/dist/backend/actions/form.d.ts.map +1 -0
  10. package/dist/backend/actions/form.js +237 -0
  11. package/dist/backend/actions/formTable.d.ts +25 -1
  12. package/dist/backend/actions/formTable.d.ts.map +1 -1
  13. package/dist/backend/actions/formTable.js +27 -5
  14. package/dist/backend/actions/frames.d.ts +54 -0
  15. package/dist/backend/actions/frames.d.ts.map +1 -0
  16. package/dist/backend/actions/frames.js +97 -0
  17. package/dist/backend/actions/index.d.ts +10 -0
  18. package/dist/backend/actions/index.d.ts.map +1 -1
  19. package/dist/backend/actions/index.js +10 -0
  20. package/dist/backend/actions/inputs.d.ts +140 -0
  21. package/dist/backend/actions/inputs.d.ts.map +1 -0
  22. package/dist/backend/actions/inputs.js +247 -0
  23. package/dist/backend/actions/interactions.d.ts +61 -1
  24. package/dist/backend/actions/interactions.d.ts.map +1 -1
  25. package/dist/backend/actions/interactions.js +65 -10
  26. package/dist/backend/actions/keyboard.d.ts +71 -0
  27. package/dist/backend/actions/keyboard.d.ts.map +1 -0
  28. package/dist/backend/actions/keyboard.js +98 -0
  29. package/dist/backend/actions/misc.d.ts +135 -0
  30. package/dist/backend/actions/misc.d.ts.map +1 -0
  31. package/dist/backend/actions/misc.js +208 -0
  32. package/dist/backend/actions/mobile.d.ts +75 -0
  33. package/dist/backend/actions/mobile.d.ts.map +1 -0
  34. package/dist/backend/actions/mobile.js +148 -0
  35. package/dist/backend/actions/mouse.d.ts +80 -0
  36. package/dist/backend/actions/mouse.d.ts.map +1 -0
  37. package/dist/backend/actions/mouse.js +150 -0
  38. package/dist/backend/actions/navigation.d.ts +48 -1
  39. package/dist/backend/actions/navigation.d.ts.map +1 -1
  40. package/dist/backend/actions/navigation.js +61 -10
  41. package/dist/backend/actions/waits.d.ts +56 -0
  42. package/dist/backend/actions/waits.d.ts.map +1 -0
  43. package/dist/backend/actions/waits.js +83 -0
  44. package/dist/backend/api/assertions.d.ts +32 -1
  45. package/dist/backend/api/assertions.d.ts.map +1 -1
  46. package/dist/backend/api/assertions.js +37 -9
  47. package/dist/backend/api/index.d.ts +1 -0
  48. package/dist/backend/api/index.d.ts.map +1 -1
  49. package/dist/backend/api/index.js +1 -0
  50. package/dist/backend/api/mock.d.ts +34 -1
  51. package/dist/backend/api/mock.d.ts.map +1 -1
  52. package/dist/backend/api/mock.js +37 -10
  53. package/dist/backend/api/network.d.ts +61 -0
  54. package/dist/backend/api/network.d.ts.map +1 -0
  55. package/dist/backend/api/network.js +177 -0
  56. package/dist/backend/api/requests.d.ts +43 -1
  57. package/dist/backend/api/requests.d.ts.map +1 -1
  58. package/dist/backend/api/requests.js +49 -17
  59. package/dist/backend/assertions/pageState.d.ts +40 -1
  60. package/dist/backend/assertions/pageState.d.ts.map +1 -1
  61. package/dist/backend/assertions/pageState.js +48 -16
  62. package/dist/backend/assertions/text.d.ts +46 -1
  63. package/dist/backend/assertions/text.d.ts.map +1 -1
  64. package/dist/backend/assertions/text.js +51 -8
  65. package/dist/backend/assertions/visibility.d.ts +102 -1
  66. package/dist/backend/assertions/visibility.d.ts.map +1 -1
  67. package/dist/backend/assertions/visibility.js +166 -12
  68. package/dist/backend/auth/index.js +2 -2
  69. package/dist/backend/db/steps.d.ts +35 -1
  70. package/dist/backend/db/steps.d.ts.map +1 -1
  71. package/dist/backend/db/steps.js +48 -15
  72. package/dist/backend/elements/alerts.d.ts +35 -1
  73. package/dist/backend/elements/alerts.d.ts.map +1 -1
  74. package/dist/backend/elements/alerts.js +39 -6
  75. package/dist/backend/elements/forms.d.ts +44 -1
  76. package/dist/backend/elements/forms.d.ts.map +1 -1
  77. package/dist/backend/elements/forms.js +50 -11
  78. package/dist/backend/elements/frames.d.ts +36 -1
  79. package/dist/backend/elements/frames.d.ts.map +1 -1
  80. package/dist/backend/elements/frames.js +43 -13
  81. package/dist/backend/utils/state.d.ts +18 -0
  82. package/dist/backend/utils/state.d.ts.map +1 -0
  83. package/dist/backend/utils/state.js +84 -0
  84. package/dist/core/registry.d.ts +14 -14
  85. package/dist/core/registry.d.ts.map +1 -1
  86. package/dist/core/registry.js +13 -4
  87. package/dist/core/runner.d.ts.map +1 -1
  88. package/dist/core/runner.js +91 -38
  89. package/package.json +52 -12
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaitForUrlContain = exports.WaitForElementHidden = exports.WaitForElementVisible = exports.WaitForLoadState = exports.WaitForNetworkIdle = void 0;
4
+ const registry_1 = require("../../core/registry");
5
+ const state_1 = require("../utils/state");
6
+ // =============================
7
+ // WAIT STRATEGIES
8
+ // =============================
9
+ /**
10
+ * Waits for the network to reach an "idle" state.
11
+ * In Playwright terms, this means there are no new network connections for at least 500ms.
12
+ *
13
+ * ```gherkin
14
+ * When I wait for network idle
15
+ * ```
16
+ *
17
+ * @remarks
18
+ * **Warning:** This can be flaky on pages that have constant background polling (e.g., real-time chats, analytics).
19
+ * If the test times out here, consider using `I wait for element to be visible` instead.
20
+ */
21
+ exports.WaitForNetworkIdle = (0, registry_1.Step)("I wait for network idle", async (page) => {
22
+ await page.waitForLoadState("networkidle");
23
+ console.log("⏳ Network is idle");
24
+ });
25
+ /**
26
+ * Waits for the page to reach a specific load lifecycle event.
27
+ *
28
+ * ```gherkin
29
+ * When I wait for load state "domcontentloaded"
30
+ * ```
31
+ *
32
+ * @param state - The state to wait for. Options:
33
+ * - `"load"`: Window load event fired.
34
+ * - `"domcontentloaded"`: DOM is ready (scripts might still be loading).
35
+ * - `"networkidle"`: No network connections for 500ms.
36
+ */
37
+ exports.WaitForLoadState = (0, registry_1.Step)("I wait for load state {string}", async (page, state) => {
38
+ if (!["load", "domcontentloaded", "networkidle"].includes(state)) {
39
+ throw new Error(`❌ Invalid load state: "${state}". Use load, domcontentloaded, or networkidle.`);
40
+ }
41
+ await page.waitForLoadState(state);
42
+ console.log(`⏳ Reached load state: "${state}"`);
43
+ });
44
+ /**
45
+ * Explicitly waits for the currently stored (active) element to become visible.
46
+ * Useful for ensuring animations complete or modals appear before proceeding.
47
+ *
48
+ * ```gherkin
49
+ * When I wait for element to be visible
50
+ * ```
51
+ */
52
+ exports.WaitForElementVisible = (0, registry_1.Step)("I wait for element to be visible", async (page) => {
53
+ const element = (0, state_1.getActiveElement)(page);
54
+ await element.waitFor({ state: "visible" });
55
+ console.log("⏳ Element is now visible");
56
+ });
57
+ /**
58
+ * Explicitly waits for the currently stored (active) element to become hidden or detached from the DOM.
59
+ * Useful for verifying that loading spinners have disappeared.
60
+ *
61
+ * ```gherkin
62
+ * When I wait for element to be hidden
63
+ * ```
64
+ */
65
+ exports.WaitForElementHidden = (0, registry_1.Step)("I wait for element to be hidden", async (page) => {
66
+ const element = (0, state_1.getActiveElement)(page);
67
+ await element.waitFor({ state: "hidden" });
68
+ console.log("⏳ Element is now hidden");
69
+ });
70
+ /**
71
+ * Waits until the page URL contains the specified substring (Regex match).
72
+ * Useful for verifying redirects (e.g., after login).
73
+ *
74
+ * ```gherkin
75
+ * When I wait for URL to contain "dashboard"
76
+ * ```
77
+ *
78
+ * @param urlPart - The substring to look for in the current URL.
79
+ */
80
+ exports.WaitForUrlContain = (0, registry_1.Step)("I wait for URL to contain {string}", async (page, urlPart) => {
81
+ await page.waitForURL(new RegExp(urlPart));
82
+ console.log(`⏳ URL now contains: "${urlPart}"`);
83
+ });
@@ -1,2 +1,33 @@
1
- export {};
1
+ /**
2
+ * Asserts that the HTTP status code of the last API response matches the expected integer.
3
+ *
4
+ * ```gherkin
5
+ * Then I expect the response status to be 200
6
+ * ```
7
+ *
8
+ * @param statusCode - The expected HTTP status code (e.g., 200, 404, 500).
9
+ */
10
+ export declare const ExpectResponseStatus: void;
11
+ /**
12
+ * Asserts that the body text of the last API response contains a specific substring.
13
+ *
14
+ * ```gherkin
15
+ * Then I expect the response body to contain "success"
16
+ * ```
17
+ *
18
+ * @param text - The text substring to look for in the response body.
19
+ */
20
+ export declare const ExpectResponseBodyContain: void;
21
+ /**
22
+ * Asserts that a specific property in the JSON response matches a string value.
23
+ * Supports dot notation for nested properties.
24
+ *
25
+ * ```gherkin
26
+ * Then I expect the response property "user.id" to be "12345"
27
+ * ```
28
+ *
29
+ * @param jsonPath - The dot-notation path to the JSON property (e.g., "data.user.name").
30
+ * @param value - The expected string value of the property.
31
+ */
32
+ export declare const ExpectResponseProperty: void;
2
33
  //# sourceMappingURL=assertions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../../src/backend/api/assertions.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../../src/backend/api/assertions.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,MAMhC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,MAOrC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,MAWlC,CAAC"}
@@ -1,26 +1,54 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExpectResponseProperty = exports.ExpectResponseBodyContain = exports.ExpectResponseStatus = void 0;
3
4
  const test_1 = require("@playwright/test");
4
5
  const registry_1 = require("../../core/registry");
5
6
  const state_1 = require("./state");
6
- // Check Status Code
7
- (0, registry_1.Step)("I expect the response status to be {int}", async (page, statusCode) => {
7
+ // =============================
8
+ // API ASSERTIONS
9
+ // =============================
10
+ /**
11
+ * Asserts that the HTTP status code of the last API response matches the expected integer.
12
+ *
13
+ * ```gherkin
14
+ * Then I expect the response status to be 200
15
+ * ```
16
+ *
17
+ * @param statusCode - The expected HTTP status code (e.g., 200, 404, 500).
18
+ */
19
+ exports.ExpectResponseStatus = (0, registry_1.Step)("I expect the response status to be {int}", async (page, statusCode) => {
8
20
  const response = state_1.apiState.getResponse();
9
21
  (0, test_1.expect)(response.status()).toBe(statusCode);
10
22
  });
11
- // Check entire Body Text
12
- (0, registry_1.Step)("I expect the response body to contain {string}", async (page, text) => {
23
+ /**
24
+ * Asserts that the body text of the last API response contains a specific substring.
25
+ *
26
+ * ```gherkin
27
+ * Then I expect the response body to contain "success"
28
+ * ```
29
+ *
30
+ * @param text - The text substring to look for in the response body.
31
+ */
32
+ exports.ExpectResponseBodyContain = (0, registry_1.Step)("I expect the response body to contain {string}", async (page, text) => {
13
33
  const response = state_1.apiState.getResponse();
14
34
  const body = await response.text();
15
35
  (0, test_1.expect)(body).toContain(text);
16
36
  });
17
- // Check JSON Property
18
- (0, registry_1.Step)("I expect the response property {string} to be {string}", async (page, jsonPath, value) => {
37
+ /**
38
+ * Asserts that a specific property in the JSON response matches a string value.
39
+ * Supports dot notation for nested properties.
40
+ *
41
+ * ```gherkin
42
+ * Then I expect the response property "user.id" to be "12345"
43
+ * ```
44
+ *
45
+ * @param jsonPath - The dot-notation path to the JSON property (e.g., "data.user.name").
46
+ * @param value - The expected string value of the property.
47
+ */
48
+ exports.ExpectResponseProperty = (0, registry_1.Step)("I expect the response property {string} to be {string}", async (page, jsonPath, value) => {
19
49
  const response = state_1.apiState.getResponse();
20
50
  const json = await response.json();
21
51
  // FIX: Added ': string' to the 'i' parameter
22
- const actualValue = jsonPath
23
- .split(".")
24
- .reduce((o, i) => o[i], json);
52
+ const actualValue = jsonPath.split(".").reduce((o, i) => o[i], json);
25
53
  (0, test_1.expect)(String(actualValue)).toBe(value);
26
54
  });
@@ -1,4 +1,5 @@
1
1
  import "./requests";
2
2
  import "./assertions";
3
3
  import "./mock";
4
+ import "./network";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AACpB,OAAO,cAAc,CAAC;AACtB,OAAO,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AACpB,OAAO,cAAc,CAAC;AACtB,OAAO,QAAQ,CAAC;AAChB,OAAO,WAAW,CAAC"}
@@ -3,3 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("./requests");
4
4
  require("./assertions");
5
5
  require("./mock");
6
+ require("./network");
@@ -1,2 +1,35 @@
1
- export {};
1
+ /**
2
+ * @module NetworkMocking
3
+ */
4
+ /**
5
+ * Mocks a specific API endpoint with a hardcoded inline JSON response body.
6
+ * * @example
7
+ * ```gherkin
8
+ * Given I mock the API endpoint "/api/users" with body '{"id": 1, "name": "Fake"}'
9
+ * ```
10
+ * * @param urlPattern - The URL or glob pattern to intercept.
11
+ * @param jsonBody - The raw JSON string to return as the response.
12
+ */
13
+ export declare const MockApiWithInlineJson: void;
14
+ /**
15
+ * Mocks an API endpoint using the contents of a local JSON file.
16
+ * * @example
17
+ * ```gherkin
18
+ * Given I mock the API endpoint "/api/users" with response from "mocks/users.json"
19
+ * ```
20
+ * * @param urlPattern - The URL pattern to intercept.
21
+ * @param filePath - Path to the JSON file relative to the project root.
22
+ */
23
+ export declare const MockApiWithFile: void;
24
+ /**
25
+ * Mocks an API endpoint to return a specific HTTP status code only.
26
+ * Useful for simulating server errors like 500 or 404.
27
+ * * @example
28
+ * ```gherkin
29
+ * Given I mock the API endpoint "/api/broken" with status 500
30
+ * ```
31
+ * * @param urlPattern - The URL pattern to intercept.
32
+ * @param statusCode - The HTTP status code to return.
33
+ */
34
+ export declare const MockApiStatus: void;
2
35
  //# sourceMappingURL=mock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/backend/api/mock.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/backend/api/mock.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,MAajC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,MAoB3B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,MAQzB,CAAC"}
@@ -33,12 +33,23 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- const registry_1 = require("../../core/registry");
36
+ exports.MockApiStatus = exports.MockApiWithFile = exports.MockApiWithInlineJson = void 0;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
- // 1. Mock with Inline JSON
40
- // Usage: Given I mock the API endpoint "/api/users" with body '{"id": 1, "name": "Fake"}'
41
- (0, registry_1.Step)("I mock the API endpoint {string} with body {string}", async (page, urlPattern, jsonBody) => {
39
+ const registry_1 = require("../../core/registry");
40
+ /**
41
+ * @module NetworkMocking
42
+ */
43
+ /**
44
+ * Mocks a specific API endpoint with a hardcoded inline JSON response body.
45
+ * * @example
46
+ * ```gherkin
47
+ * Given I mock the API endpoint "/api/users" with body '{"id": 1, "name": "Fake"}'
48
+ * ```
49
+ * * @param urlPattern - The URL or glob pattern to intercept.
50
+ * @param jsonBody - The raw JSON string to return as the response.
51
+ */
52
+ exports.MockApiWithInlineJson = (0, registry_1.Step)("I mock the API endpoint {string} with body {string}", async (page, urlPattern, jsonBody) => {
42
53
  await page.route(urlPattern, async (route) => {
43
54
  const json = JSON.parse(jsonBody);
44
55
  await route.fulfill({
@@ -49,9 +60,16 @@ const path = __importStar(require("path"));
49
60
  });
50
61
  console.log(`🎭 Mocked ${urlPattern} with inline JSON`);
51
62
  });
52
- // 2. Mock with File
53
- // Usage: Given I mock the API endpoint "/api/users" with response from "mocks/users.json"
54
- (0, registry_1.Step)("I mock the API endpoint {string} with response from {string}", async (page, urlPattern, filePath) => {
63
+ /**
64
+ * Mocks an API endpoint using the contents of a local JSON file.
65
+ * * @example
66
+ * ```gherkin
67
+ * Given I mock the API endpoint "/api/users" with response from "mocks/users.json"
68
+ * ```
69
+ * * @param urlPattern - The URL pattern to intercept.
70
+ * @param filePath - Path to the JSON file relative to the project root.
71
+ */
72
+ exports.MockApiWithFile = (0, registry_1.Step)("I mock the API endpoint {string} with response from {string}", async (page, urlPattern, filePath) => {
55
73
  const fullPath = path.resolve(process.cwd(), filePath);
56
74
  if (!fs.existsSync(fullPath)) {
57
75
  throw new Error(`❌ Mock file not found at: ${fullPath}`);
@@ -66,10 +84,19 @@ const path = __importStar(require("path"));
66
84
  });
67
85
  console.log(`🎭 Mocked ${urlPattern} with file: ${filePath}`);
68
86
  });
69
- // 3. Mock Status Code Only (Simulate Errors)
70
- // Usage: Given I mock the API endpoint "/api/broken" with status 500
71
- (0, registry_1.Step)("I mock the API endpoint {string} with status {int}", async (page, urlPattern, statusCode) => {
87
+ /**
88
+ * Mocks an API endpoint to return a specific HTTP status code only.
89
+ * Useful for simulating server errors like 500 or 404.
90
+ * * @example
91
+ * ```gherkin
92
+ * Given I mock the API endpoint "/api/broken" with status 500
93
+ * ```
94
+ * * @param urlPattern - The URL pattern to intercept.
95
+ * @param statusCode - The HTTP status code to return.
96
+ */
97
+ exports.MockApiStatus = (0, registry_1.Step)("I mock the API endpoint {string} with status {int}", async (page, urlPattern, statusCode) => {
72
98
  await page.route(urlPattern, async (route) => {
73
99
  await route.fulfill({ status: statusCode });
74
100
  });
101
+ console.log(`🎭 Mocked ${urlPattern} with status ${statusCode}`);
75
102
  });
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Intercepts a network URL and returns a stubbed JSON response.
3
+ * Supports Gherkin DocStrings for the body content.
4
+ * * @example
5
+ * ```gherkin
6
+ * When I intercept URL "/api/user" and stub body:
7
+ * """
8
+ * { "id": 101, "status": "active" }
9
+ * """
10
+ * ```
11
+ */
12
+ export declare const InterceptStubJson: void;
13
+ /**
14
+ * Intercepts a URL and stubs it with a raw string (non-JSON).
15
+ * * @example
16
+ * ```gherkin
17
+ * When I intercept URL "/health" and stub body "OK"
18
+ * ```
19
+ */
20
+ export declare const InterceptStubRaw: void;
21
+ /**
22
+ * Intercepts a URL but allows it to continue (Network Spying).
23
+ * Useful for monitoring traffic without changing the response.
24
+ * * @example
25
+ * ```gherkin
26
+ * When I intercept URL "/api/*"
27
+ * ```
28
+ */
29
+ export declare const InterceptSpy: void;
30
+ /**
31
+ * Makes a GET request and stores the response in the test state.
32
+ * Stores values in `lastResponse` and `lastStatusCode`.
33
+ * * @example
34
+ * ```gherkin
35
+ * When I make request to "[https://api.example.com/v1/users](https://api.example.com/v1/users)"
36
+ * ```
37
+ */
38
+ export declare const ApiGetRequest: void;
39
+ /**
40
+ * Makes a POST request with a JSON body provided via DocString.
41
+ * * @example
42
+ * ```gherkin
43
+ * When I make a POST request to "/api/login" with JSON body:
44
+ * """
45
+ * { "username": "admin", "password": "password123" }
46
+ * """
47
+ * ```
48
+ */
49
+ export declare const ApiPostRequest: void;
50
+ /**
51
+ * Makes a generic HTTP request using the browser's `fetch` API.
52
+ * Supports a data table for headers and an optional body.
53
+ * * @example
54
+ * ```gherkin
55
+ * When I make a "PUT" request to "/api/settings"
56
+ * | Authorization | Bearer my-token |
57
+ * | body | {"theme": "dark"} |
58
+ * ```
59
+ */
60
+ export declare const BrowserFetchRequest: void;
61
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../src/backend/api/network.ts"],"names":[],"mappings":"AAkCA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,MAe7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,MAY5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,MAKvB,CAAC;AAMH;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,MAexB,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,MAoB1B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,MA+C/B,CAAC"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserFetchRequest = exports.ApiPostRequest = exports.ApiGetRequest = exports.InterceptSpy = exports.InterceptStubRaw = exports.InterceptStubJson = void 0;
4
+ const registry_1 = require("../../core/registry");
5
+ const state_1 = require("../utils/state");
6
+ /**
7
+ * Helper: Safely parse JSON even if it comes with DocString quotes or is undefined.
8
+ * Used internally by API steps to process Gherkin DocStrings.
9
+ */
10
+ function safeJsonParse(input, context) {
11
+ if (!input) {
12
+ throw new Error(`❌ Missing JSON input for ${context}. Did you forget the DocString?`);
13
+ }
14
+ let text = typeof input === "string" ? input : JSON.stringify(input);
15
+ // Clean up DocString artifacts
16
+ text = text.replace(/^"""/g, "").replace(/"""$/g, "");
17
+ text = text.trim();
18
+ try {
19
+ return JSON.parse(text);
20
+ }
21
+ catch (e) {
22
+ throw new Error(`❌ Invalid JSON for ${context}.\nReceived: ${text.slice(0, 50)}...\nError: ${e.message}`);
23
+ }
24
+ }
25
+ // =============================
26
+ // 1. INTERCEPTION / MOCKING
27
+ // =============================
28
+ /**
29
+ * Intercepts a network URL and returns a stubbed JSON response.
30
+ * Supports Gherkin DocStrings for the body content.
31
+ * * @example
32
+ * ```gherkin
33
+ * When I intercept URL "/api/user" and stub body:
34
+ * """
35
+ * { "id": 101, "status": "active" }
36
+ * """
37
+ * ```
38
+ */
39
+ exports.InterceptStubJson = (0, registry_1.Step)(/^I intercept URL "([^"]+)" and stub body:?$/, async (page, url, body) => {
40
+ const parsedBody = safeJsonParse(body, `stubbing "${url}"`);
41
+ await page.route(url, (route) => {
42
+ route.fulfill({
43
+ status: 200,
44
+ contentType: "application/json",
45
+ body: JSON.stringify(parsedBody),
46
+ });
47
+ });
48
+ console.log(`📡 Stubbed "${url}" with JSON response.`);
49
+ });
50
+ /**
51
+ * Intercepts a URL and stubs it with a raw string (non-JSON).
52
+ * * @example
53
+ * ```gherkin
54
+ * When I intercept URL "/health" and stub body "OK"
55
+ * ```
56
+ */
57
+ exports.InterceptStubRaw = (0, registry_1.Step)("I intercept URL {string} and stub body {string}", async (page, url, body) => {
58
+ await page.route(url, (route) => {
59
+ route.fulfill({
60
+ status: 200,
61
+ contentType: "text/plain",
62
+ body: body,
63
+ });
64
+ });
65
+ console.log(`📡 Stubbed "${url}" with raw text: "${body}"`);
66
+ });
67
+ /**
68
+ * Intercepts a URL but allows it to continue (Network Spying).
69
+ * Useful for monitoring traffic without changing the response.
70
+ * * @example
71
+ * ```gherkin
72
+ * When I intercept URL "/api/*"
73
+ * ```
74
+ */
75
+ exports.InterceptSpy = (0, registry_1.Step)("I intercept URL {string}", async (page, url) => {
76
+ await page.route(url, async (route) => {
77
+ await route.continue();
78
+ });
79
+ console.log(`📡 Spying on URL "${url}" (allowed to continue).`);
80
+ });
81
+ // =============================
82
+ // 2. MAKING API REQUESTS
83
+ // =============================
84
+ /**
85
+ * Makes a GET request and stores the response in the test state.
86
+ * Stores values in `lastResponse` and `lastStatusCode`.
87
+ * * @example
88
+ * ```gherkin
89
+ * When I make request to "[https://api.example.com/v1/users](https://api.example.com/v1/users)"
90
+ * ```
91
+ */
92
+ exports.ApiGetRequest = (0, registry_1.Step)("I make request to {string}", async (page, url) => {
93
+ console.log(`⚡ GET request to: ${url}`);
94
+ const response = await page.request.get(url);
95
+ const status = response.status();
96
+ const body = await response.text();
97
+ let jsonBody;
98
+ try {
99
+ jsonBody = JSON.parse(body);
100
+ }
101
+ catch { }
102
+ (0, state_1.setVariable)(page, "lastResponse", { status, body, json: jsonBody });
103
+ (0, state_1.setVariable)(page, "lastStatusCode", status);
104
+ console.log(`✅ Status: ${status}`);
105
+ });
106
+ /**
107
+ * Makes a POST request with a JSON body provided via DocString.
108
+ * * @example
109
+ * ```gherkin
110
+ * When I make a POST request to "/api/login" with JSON body:
111
+ * """
112
+ * { "username": "admin", "password": "password123" }
113
+ * """
114
+ * ```
115
+ */
116
+ exports.ApiPostRequest = (0, registry_1.Step)(/^I make a POST request to "([^"]+)" with JSON body:?$/, async (page, url, docString) => {
117
+ const payload = safeJsonParse(docString, `POST to "${url}"`);
118
+ console.log(`⚡ POST request to: ${url}`);
119
+ const response = await page.request.post(url, { data: payload });
120
+ const status = response.status();
121
+ const body = await response.text();
122
+ let jsonBody;
123
+ try {
124
+ jsonBody = JSON.parse(body);
125
+ }
126
+ catch { }
127
+ (0, state_1.setVariable)(page, "lastResponse", { status, body, json: jsonBody });
128
+ (0, state_1.setVariable)(page, "lastStatusCode", status);
129
+ console.log(`✅ Status: ${status}`);
130
+ });
131
+ /**
132
+ * Makes a generic HTTP request using the browser's `fetch` API.
133
+ * Supports a data table for headers and an optional body.
134
+ * * @example
135
+ * ```gherkin
136
+ * When I make a "PUT" request to "/api/settings"
137
+ * | Authorization | Bearer my-token |
138
+ * | body | {"theme": "dark"} |
139
+ * ```
140
+ */
141
+ exports.BrowserFetchRequest = (0, registry_1.Step)('I make a "{word}" request to {string}', async (page, method, url, table) => {
142
+ const options = { method: method.toUpperCase() };
143
+ const rows = table && typeof table.rows === "function" ? table.rows() : table || [];
144
+ if (Array.isArray(rows)) {
145
+ rows.forEach((row) => {
146
+ const key = Array.isArray(row) ? row[0] : row.header || row.key;
147
+ const val = Array.isArray(row) ? row[1] : row.value;
148
+ if (!key)
149
+ return;
150
+ if (key.toLowerCase() === "body") {
151
+ options.body = val;
152
+ }
153
+ else {
154
+ if (!options.headers)
155
+ options.headers = {};
156
+ options.headers[key] = val;
157
+ }
158
+ });
159
+ }
160
+ console.log(`⚡ Browser Fetch: ${method} ${url}`);
161
+ const res = await page.evaluate(async ({ url, options }) => {
162
+ const response = await fetch(url, options);
163
+ return {
164
+ status: response.status,
165
+ body: await response.text(),
166
+ headers: Object.fromEntries(response.headers.entries()),
167
+ };
168
+ }, { url, options });
169
+ let jsonBody;
170
+ try {
171
+ jsonBody = JSON.parse(res.body);
172
+ }
173
+ catch { }
174
+ (0, state_1.setVariable)(page, "lastResponse", { ...res, json: jsonBody });
175
+ (0, state_1.setVariable)(page, "lastStatusCode", res.status);
176
+ console.log(`✅ Status: ${res.status}`);
177
+ });
@@ -1,2 +1,44 @@
1
- export {};
1
+ /**
2
+ * @module ApiActions
3
+ */
4
+ /**
5
+ * Performs a standard HTTP GET request and stores the response in the global API state.
6
+ * * @example
7
+ * ```gherkin
8
+ * When I make a GET request to "[https://api.example.com/users](https://api.example.com/users)"
9
+ * ```
10
+ * * @param url - The full URL or endpoint path.
11
+ */
12
+ export declare const MakeGetRequest: void;
13
+ /**
14
+ * Performs a standard HTTP DELETE request and stores the response in the global API state.
15
+ * * @example
16
+ * ```gherkin
17
+ * When I make a DELETE request to "/api/users/1"
18
+ * ```
19
+ * * @param url - The endpoint path to delete.
20
+ */
21
+ export declare const MakeDeleteRequest: void;
22
+ /**
23
+ * Performs an HTTP POST request using a Gherkin Data Table as the JSON payload.
24
+ * * @example
25
+ * ```gherkin
26
+ * When I make a POST request to "/api/users" with data
27
+ * | name | John |
28
+ * | job | Dev |
29
+ * ```
30
+ * * @param url - The target endpoint.
31
+ * @param tableData - The Gherkin Data Table (automatically converted to a JSON object).
32
+ */
33
+ export declare const MakePostRequestWithTable: void;
34
+ /**
35
+ * Performs an HTTP POST request using the contents of a local JSON file as the payload.
36
+ * * @example
37
+ * ```gherkin
38
+ * When I make a POST request to "/api/users" with payload from "data/user.json"
39
+ * ```
40
+ * * @param url - The target endpoint.
41
+ * @param filePath - Path to the JSON file relative to the project root.
42
+ */
43
+ export declare const MakePostRequestWithFile: void;
2
44
  //# sourceMappingURL=requests.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/backend/api/requests.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/backend/api/requests.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAIzB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,MAI5B,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,MAmBpC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,MAoBnC,CAAC"}