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
@@ -1,2 +1,26 @@
1
- export {};
1
+ /**
2
+ * Iterates through a provided Data Table to fill inputs, click elements, or perform assertions.
3
+ * This step is designed for bulk form interaction without writing repetitive "When I..." steps.
4
+ *
5
+ * ```gherkin
6
+ * When I fill the following "Login" test form data
7
+ * | #username | tomsmith |
8
+ * | #password | SuperSecretPassword! |
9
+ * | #login | click |
10
+ * ```
11
+ *
12
+ * @param formName - A descriptive name for the form being filled (used for logging only).
13
+ * @param tableData - A 2D array representing the data table rows (automatically passed by the runner).
14
+ *
15
+ * @remarks
16
+ * **Supported Values in Column 2:**
17
+ * - `Any String`: Fills the input found by the selector in Column 1.
18
+ * - `"click"`: Clicks the element.
19
+ * - `"check"`: Checks a checkbox or radio button.
20
+ * - `"assert:visible"`: Asserts that the element is visible.
21
+ * - `"assert:text:EXPECTED"`: Asserts that the element contains the specific text.
22
+ *
23
+ * @throws {Error} If the Data Table is missing or invalid.
24
+ */
25
+ export declare const FillTestFormData: void;
2
26
  //# sourceMappingURL=formTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formTable.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/formTable.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"formTable.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/formTable.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,MA8B5B,CAAC"}
@@ -1,12 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const registry_1 = require("../../core/registry");
3
+ exports.FillTestFormData = void 0;
4
4
  const test_1 = require("@playwright/test");
5
- // CHANGE: Removed the ':' at the end of the string below
6
- (0, registry_1.Step)("I fill the following {string} form data", async (page, formName, tableData) => {
5
+ const registry_1 = require("../../core/registry");
6
+ /**
7
+ * Iterates through a provided Data Table to fill inputs, click elements, or perform assertions.
8
+ * This step is designed for bulk form interaction without writing repetitive "When I..." steps.
9
+ *
10
+ * ```gherkin
11
+ * When I fill the following "Login" test form data
12
+ * | #username | tomsmith |
13
+ * | #password | SuperSecretPassword! |
14
+ * | #login | click |
15
+ * ```
16
+ *
17
+ * @param formName - A descriptive name for the form being filled (used for logging only).
18
+ * @param tableData - A 2D array representing the data table rows (automatically passed by the runner).
19
+ *
20
+ * @remarks
21
+ * **Supported Values in Column 2:**
22
+ * - `Any String`: Fills the input found by the selector in Column 1.
23
+ * - `"click"`: Clicks the element.
24
+ * - `"check"`: Checks a checkbox or radio button.
25
+ * - `"assert:visible"`: Asserts that the element is visible.
26
+ * - `"assert:text:EXPECTED"`: Asserts that the element contains the specific text.
27
+ *
28
+ * @throws {Error} If the Data Table is missing or invalid.
29
+ */
30
+ exports.FillTestFormData = (0, registry_1.Step)("I fill the following {string} test form data", async (page, formName, tableData) => {
7
31
  console.log(`๐Ÿ“ Processing Form: ${formName}`);
8
- // The runner passes the table data as the last argument
9
- // tableData = [ ['#username', 'tomsmith'], ['#password', '...'] ]
10
32
  // Guard clause: Ensure tableData exists to prevent crashes if user forgets the table
11
33
  if (!tableData || !Array.isArray(tableData)) {
12
34
  throw new Error(`โŒ The step "I fill the following '${formName}' form data" requires a Data Table below it.`);
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Attempts to switch the logical context to a specific iframe.
3
+ *
4
+ * ```gherkin
5
+ * When I switch to frame "#payment-iframe"
6
+ * ```
7
+ *
8
+ * @param selector - The CSS selector of the iframe element.
9
+ * @remarks
10
+ * **Limitation:** In the current architecture, "switching" the global page context permanently
11
+ * is complex. This step currently verifies the frame exists but logs a warning
12
+ * that subsequent steps might not automatically target this frame unless you use
13
+ * the specific `I find element ... in frame ...` step.
14
+ *
15
+ * @example
16
+ * When I switch to frame "iframe[name='payment']"
17
+ */
18
+ export declare const SwitchToFrame: void;
19
+ /**
20
+ * Finds an element inside a specific iframe and sets it as the active element.
21
+ * This is the robust way to interact with iframe content (e.g., Stripe forms, embedded videos).
22
+ *
23
+ * ```gherkin
24
+ * When I find element {string} in frame {string}
25
+ * ```
26
+ *
27
+ * @param elementSelector - The selector of the element INSIDE the iframe.
28
+ * @param frameSelector - The selector of the iframe element itself.
29
+ *
30
+ * @example
31
+ * When I find element "#card-number" in frame "#stripe-element"
32
+ * Then I type "4242 4242..."
33
+ */
34
+ export declare const FindElementInFrame: void;
35
+ /**
36
+ * Waits for a new browser tab (popup) to open.
37
+ * Useful for validating `target="_blank"` links.
38
+ *
39
+ * ```gherkin
40
+ * When I switch to new tab
41
+ * ```
42
+ *
43
+ * @remarks
44
+ * **Limitation:** This step verifies that a new tab was opened (e.g., after a click),
45
+ * but it does **not** swap the global `page` variable for subsequent steps due to runner limitations.
46
+ * It is primarily used for verification (ensuring a popup appeared).
47
+ *
48
+ * @example
49
+ * When I click on link "Open Dashboard"
50
+ * And I switch to new tab
51
+ * # (Implicitly validates the tab opened successfully)
52
+ */
53
+ export declare const SwitchToNewTab: void;
54
+ //# sourceMappingURL=frames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/frames.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,MAoBxB,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB,MAU9B,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,MAazB,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SwitchToNewTab = exports.FindElementInFrame = exports.SwitchToFrame = void 0;
4
+ const registry_1 = require("../../core/registry");
5
+ const state_1 = require("../utils/state");
6
+ // =============================
7
+ // IFRAME HANDLING
8
+ // =============================
9
+ /**
10
+ * Attempts to switch the logical context to a specific iframe.
11
+ *
12
+ * ```gherkin
13
+ * When I switch to frame "#payment-iframe"
14
+ * ```
15
+ *
16
+ * @param selector - The CSS selector of the iframe element.
17
+ * @remarks
18
+ * **Limitation:** In the current architecture, "switching" the global page context permanently
19
+ * is complex. This step currently verifies the frame exists but logs a warning
20
+ * that subsequent steps might not automatically target this frame unless you use
21
+ * the specific `I find element ... in frame ...` step.
22
+ *
23
+ * @example
24
+ * When I switch to frame "iframe[name='payment']"
25
+ */
26
+ exports.SwitchToFrame = (0, registry_1.Step)("I switch to frame {string}", async (page, selector) => {
27
+ const frameElement = page.locator(selector);
28
+ const frame = frameElement.contentFrame();
29
+ // We can't actually "switch" the global 'page' object easily in this architecture,
30
+ // BUT we can store the frame as the "Active Scope" if we extended our state management.
31
+ //
32
+ // SIMPLER APPROACH: We just store the frame locator as the "Active Element"
33
+ // and update our `find` steps to look inside it if it's a frame.
34
+ // However, for strict BDD, it's often easier to just interact with the frame directly here:
35
+ if (!frame)
36
+ throw new Error(`โŒ Iframe "${selector}" not found or has no content.`);
37
+ // Set the frame as the active context for future actions?
38
+ // This requires updating `src/backend/utils/state.ts` to support `scope`.
39
+ //
40
+ // For now, let's just Log it. Frame handling usually requires a dedicated `find inside frame` step.
41
+ console.log(`โš ๏ธ Switching Frames requires a Scope manager. For now, use 'I find element ... in frame ...'`);
42
+ });
43
+ /**
44
+ * Finds an element inside a specific iframe and sets it as the active element.
45
+ * This is the robust way to interact with iframe content (e.g., Stripe forms, embedded videos).
46
+ *
47
+ * ```gherkin
48
+ * When I find element {string} in frame {string}
49
+ * ```
50
+ *
51
+ * @param elementSelector - The selector of the element INSIDE the iframe.
52
+ * @param frameSelector - The selector of the iframe element itself.
53
+ *
54
+ * @example
55
+ * When I find element "#card-number" in frame "#stripe-element"
56
+ * Then I type "4242 4242..."
57
+ */
58
+ exports.FindElementInFrame = (0, registry_1.Step)("I find element {string} in frame {string}", async (page, elementSelector, frameSelector) => {
59
+ const frame = page.frameLocator(frameSelector);
60
+ const element = frame.locator(elementSelector).first();
61
+ await element.waitFor();
62
+ (0, state_1.setActiveElement)(page, element);
63
+ console.log(`๐Ÿ” Found element "${elementSelector}" inside frame "${frameSelector}"`);
64
+ });
65
+ // =============================
66
+ // TAB / WINDOW HANDLING
67
+ // =============================
68
+ /**
69
+ * Waits for a new browser tab (popup) to open.
70
+ * Useful for validating `target="_blank"` links.
71
+ *
72
+ * ```gherkin
73
+ * When I switch to new tab
74
+ * ```
75
+ *
76
+ * @remarks
77
+ * **Limitation:** This step verifies that a new tab was opened (e.g., after a click),
78
+ * but it does **not** swap the global `page` variable for subsequent steps due to runner limitations.
79
+ * It is primarily used for verification (ensuring a popup appeared).
80
+ *
81
+ * @example
82
+ * When I click on link "Open Dashboard"
83
+ * And I switch to new tab
84
+ * # (Implicitly validates the tab opened successfully)
85
+ */
86
+ exports.SwitchToNewTab = (0, registry_1.Step)("I switch to new tab", async (page) => {
87
+ // This is tricky: Playwright 'page' object passed to steps is usually fixed.
88
+ // To support multi-tab, we'd need to update the Runner to allow swapping the 'page' reference.
89
+ //
90
+ // For a library like this, checking the popup existence is usually enough:
91
+ console.log("โš ๏ธ Multi-tab support requires Runner updates. Verifying popup event only.");
92
+ const popup = await page.waitForEvent("popup");
93
+ await popup.waitForLoadState();
94
+ console.log(`๐Ÿ“‘ New tab opened: ${await popup.title()}`);
95
+ // Note: We cannot easily "swap" the 'page' variable for subsequent steps
96
+ // without a more complex Global State object.
97
+ });
@@ -1,4 +1,14 @@
1
1
  import "./navigation";
2
2
  import "./interactions";
3
3
  import "./formTable";
4
+ import "./click";
5
+ import "./find";
6
+ import "./inputs";
7
+ import "./form";
8
+ import "./mouse";
9
+ import "./misc";
10
+ import "./mobile";
11
+ import "./waits";
12
+ import "./frames";
13
+ import "./keyboard";
4
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC;AACrB,OAAO,SAAS,CAAC;AACjB,OAAO,QAAQ,CAAC;AAChB,OAAO,UAAU,CAAC;AAClB,OAAO,QAAQ,CAAC;AAChB,OAAO,SAAS,CAAC;AACjB,OAAO,QAAQ,CAAC;AAChB,OAAO,UAAU,CAAC;AAClB,OAAO,SAAS,CAAC;AACjB,OAAO,UAAU,CAAC;AAClB,OAAO,YAAY,CAAC"}
@@ -3,3 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("./navigation");
4
4
  require("./interactions");
5
5
  require("./formTable");
6
+ require("./click");
7
+ require("./find");
8
+ require("./inputs");
9
+ require("./form");
10
+ require("./mouse");
11
+ require("./misc");
12
+ require("./mobile");
13
+ require("./waits");
14
+ require("./frames");
15
+ require("./keyboard");
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Fills the currently stored (active) input element with specific text.
3
+ * Supports variable aliases using the "@" prefix.
4
+ *
5
+ * ```gherkin
6
+ * When I type "hello world"
7
+ * When I type "@storedPassword"
8
+ * ```
9
+ *
10
+ * @param textOrAlias - The text to type OR a variable key prefixed with "@".
11
+ * @param table - Optional data table for options (e.g., force: true).
12
+ */
13
+ export declare const TypeText: void;
14
+ /**
15
+ * Fills the active input with a value explicitly retrieved from the variable store.
16
+ * Unlike `I type`, this does not require the "@" prefix in the step text.
17
+ *
18
+ * ```gherkin
19
+ * When I type stored "userEmail"
20
+ * ```
21
+ *
22
+ * @param alias - The key of the stored variable.
23
+ */
24
+ export declare const TypeStoredText: void;
25
+ /**
26
+ * Types text character-by-character with a 100ms delay.
27
+ * Useful for testing auto-complete fields or search bars that listen for keystrokes.
28
+ *
29
+ * ```gherkin
30
+ * When I slowly type "Playwright"
31
+ * ```
32
+ *
33
+ * @param text - The text to type sequentially.
34
+ */
35
+ export declare const TypeSlowly: void;
36
+ /**
37
+ * Sets the value of an input directly (alias for filling).
38
+ *
39
+ * ```gherkin
40
+ * When I set value "12345"
41
+ * ```
42
+ *
43
+ * @param value - The value to set.
44
+ */
45
+ export declare const SetInputValue: void;
46
+ /**
47
+ * Clears the text content of the active input field.
48
+ *
49
+ * ```gherkin
50
+ * When I clear
51
+ * ```
52
+ */
53
+ export declare const ClearInput: void;
54
+ /**
55
+ * Simulates pressing a specific keyboard key on the active element.
56
+ * Useful for "Enter" to submit, or "ArrowDown" for dropdowns.
57
+ *
58
+ * ```gherkin
59
+ * When I press "Enter"
60
+ * When I press "Tab"
61
+ * ```
62
+ *
63
+ * @param key - The key name (e.g., "Enter", "Escape", "ArrowDown").
64
+ */
65
+ export declare const PressKeyOnInput: void;
66
+ /**
67
+ * Checks the currently active checkbox or radio button.
68
+ *
69
+ * ```gherkin
70
+ * When I check
71
+ * ```
72
+ */
73
+ export declare const CheckElement: void;
74
+ /**
75
+ * Unchecks the currently active checkbox.
76
+ *
77
+ * ```gherkin
78
+ * When I uncheck
79
+ * ```
80
+ */
81
+ export declare const UncheckElement: void;
82
+ /**
83
+ * Legacy alias for `I check`.
84
+ *
85
+ * ```gherkin
86
+ * When I check input
87
+ * ```
88
+ */
89
+ export declare const CheckInputAlias: void;
90
+ /**
91
+ * Legacy alias for `I uncheck`.
92
+ *
93
+ * ```gherkin
94
+ * When I uncheck input
95
+ * ```
96
+ */
97
+ export declare const UncheckInputAlias: void;
98
+ /**
99
+ * Selects an option in a `<select>` dropdown by its visible label.
100
+ *
101
+ * ```gherkin
102
+ * When I select option "California"
103
+ * ```
104
+ *
105
+ * @param option - The visible text label of the option to select.
106
+ */
107
+ export declare const SelectOption: void;
108
+ /**
109
+ * Submits the form related to the active element.
110
+ *
111
+ * **Logic:**
112
+ * 1. Tries to find the parent `<form>` of the currently stored element.
113
+ * 2. If no parent form is found (or no element is active), it finds the *first* form on the page.
114
+ *
115
+ * ```gherkin
116
+ * When I submit
117
+ * ```
118
+ */
119
+ export declare const SubmitForm: void;
120
+ /**
121
+ * Uploads a file to the active file input element.
122
+ *
123
+ * ```gherkin
124
+ * When I select file "data/invoice.pdf"
125
+ * ```
126
+ *
127
+ * @param filePath - The path to the file (relative to the project root).
128
+ */
129
+ export declare const SelectFile: void;
130
+ /**
131
+ * Alias for `I select file`.
132
+ *
133
+ * ```gherkin
134
+ * When I upload file "images/logo.png"
135
+ * ```
136
+ *
137
+ * @param filePath - The path to the file.
138
+ */
139
+ export declare const UploadFileAlias: void;
140
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/inputs.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,MAgBnB,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,MASzB,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,MAIrB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,MAKxB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,MAIrB,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,MAI1B,CAAC;AAMH;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,MAKvB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,MAKzB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,MAK1B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAK5B,CAAC;AAMH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,MAOvB,CAAC;AAMH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,MAoBrB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,MAIrB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,MAI1B,CAAC"}
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UploadFileAlias = exports.SelectFile = exports.SubmitForm = exports.SelectOption = exports.UncheckInputAlias = exports.CheckInputAlias = exports.UncheckElement = exports.CheckElement = exports.PressKeyOnInput = exports.ClearInput = exports.SetInputValue = exports.TypeSlowly = exports.TypeStoredText = exports.TypeText = void 0;
4
+ const registry_1 = require("../../core/registry");
5
+ const state_1 = require("../utils/state");
6
+ // =============================
7
+ // 1. TYPING & FILLING
8
+ // =============================
9
+ /**
10
+ * Fills the currently stored (active) input element with specific text.
11
+ * Supports variable aliases using the "@" prefix.
12
+ *
13
+ * ```gherkin
14
+ * When I type "hello world"
15
+ * When I type "@storedPassword"
16
+ * ```
17
+ *
18
+ * @param textOrAlias - The text to type OR a variable key prefixed with "@".
19
+ * @param table - Optional data table for options (e.g., force: true).
20
+ */
21
+ exports.TypeText = (0, registry_1.Step)("I type {string}", async (page, textOrAlias, table) => {
22
+ const element = (0, state_1.getActiveElement)(page);
23
+ const options = (0, state_1.parseClickOptions)(table); // Reusing generic options parser
24
+ let text = textOrAlias;
25
+ // Handle Alias
26
+ if (textOrAlias.startsWith("@")) {
27
+ const alias = textOrAlias.slice(1);
28
+ const val = (0, state_1.getVariable)(page, alias);
29
+ if (!val)
30
+ throw new Error(`โŒ Alias @${alias} not found.`);
31
+ text = val;
32
+ }
33
+ await element.fill(text, options);
34
+ console.log(`โŒจ๏ธ Filled element with: "${text}"`);
35
+ });
36
+ /**
37
+ * Fills the active input with a value explicitly retrieved from the variable store.
38
+ * Unlike `I type`, this does not require the "@" prefix in the step text.
39
+ *
40
+ * ```gherkin
41
+ * When I type stored "userEmail"
42
+ * ```
43
+ *
44
+ * @param alias - The key of the stored variable.
45
+ */
46
+ exports.TypeStoredText = (0, registry_1.Step)("I type stored {string}", async (page, alias, table) => {
47
+ const element = (0, state_1.getActiveElement)(page);
48
+ const options = (0, state_1.parseClickOptions)(table);
49
+ const val = (0, state_1.getVariable)(page, alias);
50
+ if (!val)
51
+ throw new Error(`โŒ Alias "${alias}" not found.`);
52
+ await element.fill(val, options);
53
+ console.log(`โŒจ๏ธ Typed stored value from "${alias}"`);
54
+ });
55
+ /**
56
+ * Types text character-by-character with a 100ms delay.
57
+ * Useful for testing auto-complete fields or search bars that listen for keystrokes.
58
+ *
59
+ * ```gherkin
60
+ * When I slowly type "Playwright"
61
+ * ```
62
+ *
63
+ * @param text - The text to type sequentially.
64
+ */
65
+ exports.TypeSlowly = (0, registry_1.Step)("I slowly type {string}", async (page, text) => {
66
+ const element = (0, state_1.getActiveElement)(page);
67
+ await element.pressSequentially(text, { delay: 100 });
68
+ console.log(`โŒจ๏ธ Slowly typed: "${text}"`);
69
+ });
70
+ /**
71
+ * Sets the value of an input directly (alias for filling).
72
+ *
73
+ * ```gherkin
74
+ * When I set value "12345"
75
+ * ```
76
+ *
77
+ * @param value - The value to set.
78
+ */
79
+ exports.SetInputValue = (0, registry_1.Step)("I set value {string}", async (page, value, table) => {
80
+ const element = (0, state_1.getActiveElement)(page);
81
+ const options = (0, state_1.parseClickOptions)(table);
82
+ await element.fill(value, options);
83
+ console.log(`๐Ÿ“ Set value to: "${value}"`);
84
+ });
85
+ /**
86
+ * Clears the text content of the active input field.
87
+ *
88
+ * ```gherkin
89
+ * When I clear
90
+ * ```
91
+ */
92
+ exports.ClearInput = (0, registry_1.Step)("I clear", async (page) => {
93
+ const element = (0, state_1.getActiveElement)(page);
94
+ await element.fill("");
95
+ console.log("๐Ÿงน Cleared input");
96
+ });
97
+ /**
98
+ * Simulates pressing a specific keyboard key on the active element.
99
+ * Useful for "Enter" to submit, or "ArrowDown" for dropdowns.
100
+ *
101
+ * ```gherkin
102
+ * When I press "Enter"
103
+ * When I press "Tab"
104
+ * ```
105
+ *
106
+ * @param key - The key name (e.g., "Enter", "Escape", "ArrowDown").
107
+ */
108
+ exports.PressKeyOnInput = (0, registry_1.Step)("I press {string}", async (page, key) => {
109
+ const element = (0, state_1.getActiveElement)(page);
110
+ await element.press(key);
111
+ console.log(`๐ŸŽน Pressed key: "${key}"`);
112
+ });
113
+ // =============================
114
+ // 2. CHECKBOXES & RADIOS
115
+ // =============================
116
+ /**
117
+ * Checks the currently active checkbox or radio button.
118
+ *
119
+ * ```gherkin
120
+ * When I check
121
+ * ```
122
+ */
123
+ exports.CheckElement = (0, registry_1.Step)("I check", async (page, table) => {
124
+ const element = (0, state_1.getActiveElement)(page);
125
+ const options = (0, state_1.parseClickOptions)(table);
126
+ await element.check(options);
127
+ console.log("โœ… Checked element");
128
+ });
129
+ /**
130
+ * Unchecks the currently active checkbox.
131
+ *
132
+ * ```gherkin
133
+ * When I uncheck
134
+ * ```
135
+ */
136
+ exports.UncheckElement = (0, registry_1.Step)("I uncheck", async (page, table) => {
137
+ const element = (0, state_1.getActiveElement)(page);
138
+ const options = (0, state_1.parseClickOptions)(table);
139
+ await element.uncheck(options);
140
+ console.log("โฌœ Unchecked element");
141
+ });
142
+ /**
143
+ * Legacy alias for `I check`.
144
+ *
145
+ * ```gherkin
146
+ * When I check input
147
+ * ```
148
+ */
149
+ exports.CheckInputAlias = (0, registry_1.Step)("I check input", async (page, table) => {
150
+ const element = (0, state_1.getActiveElement)(page);
151
+ const options = (0, state_1.parseClickOptions)(table);
152
+ await element.check(options);
153
+ console.log("โœ… Checked input");
154
+ });
155
+ /**
156
+ * Legacy alias for `I uncheck`.
157
+ *
158
+ * ```gherkin
159
+ * When I uncheck input
160
+ * ```
161
+ */
162
+ exports.UncheckInputAlias = (0, registry_1.Step)("I uncheck input", async (page, table) => {
163
+ const element = (0, state_1.getActiveElement)(page);
164
+ const options = (0, state_1.parseClickOptions)(table);
165
+ await element.uncheck(options);
166
+ console.log("โฌœ Unchecked input");
167
+ });
168
+ // =============================
169
+ // 3. DROPDOWNS & SELECTS
170
+ // =============================
171
+ /**
172
+ * Selects an option in a `<select>` dropdown by its visible label.
173
+ *
174
+ * ```gherkin
175
+ * When I select option "California"
176
+ * ```
177
+ *
178
+ * @param option - The visible text label of the option to select.
179
+ */
180
+ exports.SelectOption = (0, registry_1.Step)("I select option {string}", async (page, option, table) => {
181
+ const element = (0, state_1.getActiveElement)(page);
182
+ const options = (0, state_1.parseClickOptions)(table);
183
+ // Playwright selects by value or label automatically
184
+ await element.selectOption({ label: option }, options);
185
+ console.log(`๐Ÿ”ฝ Selected option: "${option}"`);
186
+ });
187
+ // =============================
188
+ // 4. FORMS & FILES
189
+ // =============================
190
+ /**
191
+ * Submits the form related to the active element.
192
+ *
193
+ * **Logic:**
194
+ * 1. Tries to find the parent `<form>` of the currently stored element.
195
+ * 2. If no parent form is found (or no element is active), it finds the *first* form on the page.
196
+ *
197
+ * ```gherkin
198
+ * When I submit
199
+ * ```
200
+ */
201
+ exports.SubmitForm = (0, registry_1.Step)("I submit", async (page) => {
202
+ let formLocator;
203
+ try {
204
+ const element = (0, state_1.getActiveElement)(page);
205
+ // Try to find the parent form of the stored element
206
+ formLocator = element.locator("xpath=ancestor-or-self::form");
207
+ }
208
+ catch (_e) {
209
+ // If no element stored, find first form on page
210
+ formLocator = page.locator("form").first();
211
+ }
212
+ const count = await formLocator.count();
213
+ if (count === 0) {
214
+ throw new Error("โŒ No form found to submit.");
215
+ }
216
+ // Native HTML submit (bypasses some validation, extremely reliable)
217
+ await formLocator.evaluate((f) => f.submit());
218
+ console.log("๐Ÿ“จ Submitted form");
219
+ });
220
+ /**
221
+ * Uploads a file to the active file input element.
222
+ *
223
+ * ```gherkin
224
+ * When I select file "data/invoice.pdf"
225
+ * ```
226
+ *
227
+ * @param filePath - The path to the file (relative to the project root).
228
+ */
229
+ exports.SelectFile = (0, registry_1.Step)("I select file {string}", async (page, filePath) => {
230
+ const element = (0, state_1.getActiveElement)(page);
231
+ await element.setInputFiles(filePath);
232
+ console.log(`๐Ÿ“‚ Selected file: "${filePath}"`);
233
+ });
234
+ /**
235
+ * Alias for `I select file`.
236
+ *
237
+ * ```gherkin
238
+ * When I upload file "images/logo.png"
239
+ * ```
240
+ *
241
+ * @param filePath - The path to the file.
242
+ */
243
+ exports.UploadFileAlias = (0, registry_1.Step)("I upload file {string}", async (page, filePath) => {
244
+ const element = (0, state_1.getActiveElement)(page);
245
+ await element.setInputFiles(filePath);
246
+ console.log(`๐Ÿ“‚ Uploaded file: "${filePath}"`);
247
+ });