playwright-cucumber-ts-steps 1.1.12 → 1.2.0
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.
- package/README.md +1697 -2
- package/dist/backend/actions/click.d.ts +55 -77
- package/dist/backend/actions/click.d.ts.map +1 -1
- package/dist/backend/actions/click.js +125 -103
- package/dist/backend/actions/find.d.ts +48 -121
- package/dist/backend/actions/find.d.ts.map +1 -1
- package/dist/backend/actions/find.js +126 -172
- package/dist/backend/actions/form.d.ts +18 -26
- package/dist/backend/actions/form.d.ts.map +1 -1
- package/dist/backend/actions/form.js +30 -35
- package/dist/backend/actions/formTable.d.ts +4 -9
- package/dist/backend/actions/formTable.d.ts.map +1 -1
- package/dist/backend/actions/formTable.js +13 -11
- package/dist/backend/actions/frames.d.ts +7 -35
- package/dist/backend/actions/frames.d.ts.map +1 -1
- package/dist/backend/actions/frames.js +22 -61
- package/dist/backend/actions/index.d.ts +0 -1
- package/dist/backend/actions/index.d.ts.map +1 -1
- package/dist/backend/actions/index.js +0 -1
- package/dist/backend/actions/inputs.d.ts +33 -77
- package/dist/backend/actions/inputs.d.ts.map +1 -1
- package/dist/backend/actions/inputs.js +92 -116
- package/dist/backend/actions/interactions.d.ts +10 -32
- package/dist/backend/actions/interactions.d.ts.map +1 -1
- package/dist/backend/actions/interactions.js +31 -41
- package/dist/backend/actions/keyboard.d.ts +13 -37
- package/dist/backend/actions/keyboard.d.ts.map +1 -1
- package/dist/backend/actions/keyboard.js +35 -46
- package/dist/backend/actions/misc.d.ts +29 -69
- package/dist/backend/actions/misc.d.ts.map +1 -1
- package/dist/backend/actions/misc.js +77 -98
- package/dist/backend/actions/mobile.d.ts +14 -36
- package/dist/backend/actions/mobile.d.ts.map +1 -1
- package/dist/backend/actions/mobile.js +42 -55
- package/dist/backend/actions/mouse.d.ts +29 -36
- package/dist/backend/actions/mouse.d.ts.map +1 -1
- package/dist/backend/actions/mouse.js +76 -51
- package/dist/backend/actions/navigation.d.ts +11 -23
- package/dist/backend/actions/navigation.d.ts.map +1 -1
- package/dist/backend/actions/navigation.js +32 -32
- package/dist/backend/actions/waits.d.ts +11 -30
- package/dist/backend/actions/waits.d.ts.map +1 -1
- package/dist/backend/actions/waits.js +32 -39
- package/dist/backend/api/assertions.d.ts +6 -15
- package/dist/backend/api/assertions.d.ts.map +1 -1
- package/dist/backend/api/assertions.js +21 -23
- package/dist/backend/api/mock.d.ts +9 -18
- package/dist/backend/api/mock.d.ts.map +1 -1
- package/dist/backend/api/mock.js +24 -22
- package/dist/backend/api/network.d.ts +13 -25
- package/dist/backend/api/network.d.ts.map +1 -1
- package/dist/backend/api/network.js +40 -39
- package/dist/backend/api/requests.d.ts +13 -24
- package/dist/backend/api/requests.d.ts.map +1 -1
- package/dist/backend/api/requests.js +31 -30
- package/dist/backend/assertions/pageState.d.ts +13 -24
- package/dist/backend/assertions/pageState.d.ts.map +1 -1
- package/dist/backend/assertions/pageState.js +31 -29
- package/dist/backend/assertions/text.d.ts +12 -23
- package/dist/backend/assertions/text.d.ts.map +1 -1
- package/dist/backend/assertions/text.js +30 -28
- package/dist/backend/assertions/visibility.d.ts +24 -51
- package/dist/backend/assertions/visibility.d.ts.map +1 -1
- package/dist/backend/assertions/visibility.js +74 -79
- package/dist/backend/auth/index.d.ts +14 -1
- package/dist/backend/auth/index.d.ts.map +1 -1
- package/dist/backend/auth/index.js +26 -8
- package/dist/backend/db/steps.d.ts +58 -18
- package/dist/backend/db/steps.d.ts.map +1 -1
- package/dist/backend/db/steps.js +180 -26
- package/dist/backend/elements/alerts.d.ts +10 -19
- package/dist/backend/elements/alerts.d.ts.map +1 -1
- package/dist/backend/elements/alerts.js +25 -23
- package/dist/backend/elements/forms.d.ts +12 -23
- package/dist/backend/elements/forms.d.ts.map +1 -1
- package/dist/backend/elements/forms.js +30 -29
- package/dist/backend/elements/frames.d.ts +9 -18
- package/dist/backend/elements/frames.d.ts.map +1 -1
- package/dist/backend/elements/frames.js +24 -23
- package/dist/backend/index.d.ts +14 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +31 -0
- package/dist/metadata.json +1016 -0
- package/package.json +8 -4
|
@@ -33,19 +33,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.fillFormData = fillFormData;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const test_1 = require("@playwright/test");
|
|
40
40
|
const registry_1 = require("../../core/registry");
|
|
41
41
|
const state_1 = require("../utils/state");
|
|
42
|
+
// ==================================================
|
|
43
|
+
// HELPER FUNCTIONS (Internal)
|
|
44
|
+
// ==================================================
|
|
42
45
|
/**
|
|
43
46
|
* Helper to convert raw runner table into Objects (ActionRow[]).
|
|
44
47
|
* Handles whitespace in headers (e.g., "| Target |" -> "Target").
|
|
45
48
|
* Supports both Cucumber DataTables (hashes) and Raw Arrays (Custom Runner).
|
|
46
|
-
*
|
|
47
|
-
* @param table - The raw table object from the test runner.
|
|
48
|
-
* @returns An array of ActionRow objects.
|
|
49
49
|
*/
|
|
50
50
|
function parseDataTable(table) {
|
|
51
51
|
// Debug Log: See exactly what the runner is passing
|
|
@@ -73,10 +73,6 @@ function parseDataTable(table) {
|
|
|
73
73
|
/**
|
|
74
74
|
* Helper to resolve values, handling variable aliases.
|
|
75
75
|
* If a value starts with "@", it retrieves it from the global state.
|
|
76
|
-
*
|
|
77
|
-
* @param page - The Playwright Page object (for context).
|
|
78
|
-
* @param rawValue - The value string from the Gherkin table.
|
|
79
|
-
* @returns The resolved string value.
|
|
80
76
|
*/
|
|
81
77
|
function resolveValue(page, rawValue) {
|
|
82
78
|
if (!rawValue)
|
|
@@ -94,32 +90,12 @@ function resolveValue(page, rawValue) {
|
|
|
94
90
|
}
|
|
95
91
|
return trimmed;
|
|
96
92
|
}
|
|
93
|
+
// ==================================================
|
|
94
|
+
// CORE FUNCTIONS
|
|
95
|
+
// ==================================================
|
|
97
96
|
/**
|
|
98
|
-
* A "Swiss Army Knife"
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* ```gherkin
|
|
102
|
-
* When I fill the following {string} form data
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* @remarks
|
|
106
|
-
* **Columns:**
|
|
107
|
-
* - `Target`: The CSS selector, or a special keyword (request:, set:localStorage:, wait).
|
|
108
|
-
* - `Value`: The value to input, the action (click, check), or assertion pattern.
|
|
109
|
-
*
|
|
110
|
-
* **Supported UI Actions:**
|
|
111
|
-
* - **Fill:** Default behavior. Types `Value` into `Target`.
|
|
112
|
-
* - **Click:** Set `Value` to "click".
|
|
113
|
-
* - **Check:** Set `Value` to "check".
|
|
114
|
-
* - **Select:** Set `Value` to "select" (selects first option).
|
|
115
|
-
* - **Assert Visible:** Set `Value` to "assert:visible".
|
|
116
|
-
* - **Assert Text:** Set `Value` to "assert:text:Expected Text".
|
|
117
|
-
*
|
|
118
|
-
* **Supported Special Actions:**
|
|
119
|
-
* - **API Request:** Target = `request:METHOD:URL`, Value = `payload_filename.json`.
|
|
120
|
-
* - **Local Storage:** Target = `set:localStorage:key`, Value = `value`.
|
|
121
|
-
* - **Wait:** Target = `wait`, Value = `wait:1000` (ms).
|
|
122
|
-
*
|
|
97
|
+
* A "Swiss Army Knife" function for filling forms, performing assertions, and executing mixed workflows.
|
|
98
|
+
* Iterates through a Data Table and performs actions based on the Target and Value columns.
|
|
123
99
|
* @example
|
|
124
100
|
* When I fill the following "Login Flow" form data:
|
|
125
101
|
* | Target | Value |
|
|
@@ -129,8 +105,23 @@ function resolveValue(page, rawValue) {
|
|
|
129
105
|
* | wait | wait:500 |
|
|
130
106
|
* | .error-msg | assert:visible |
|
|
131
107
|
* | request:GET:/api/status | body: {} |
|
|
108
|
+
* @remarks
|
|
109
|
+
* **Columns:**
|
|
110
|
+
* - Target: The CSS selector, or a special keyword (request:, set:localStorage:, wait).
|
|
111
|
+
* - Value: The value to input, the action (click, check), or assertion pattern.
|
|
112
|
+
* **Supported UI Actions:**
|
|
113
|
+
* - Fill: Default behavior. Types Value into Target.
|
|
114
|
+
* - Click: Set Value to "click".
|
|
115
|
+
* - Check: Set Value to "check".
|
|
116
|
+
* - Select: Set Value to "select".
|
|
117
|
+
* - Assert Visible: Set Value to "assert:visible".
|
|
118
|
+
* - Assert Text: Set Value to "assert:text:Expected Text".
|
|
119
|
+
* **Supported Special Actions:**
|
|
120
|
+
* - API Request: Target = "request:METHOD:URL", Value = "payload_filename.json".
|
|
121
|
+
* - Local Storage: Target = "set:localStorage:key", Value = "value".
|
|
122
|
+
* - Wait: Target = "wait", Value = "wait:1000" (ms).
|
|
132
123
|
*/
|
|
133
|
-
|
|
124
|
+
async function fillFormData(page, formName, table) {
|
|
134
125
|
console.log(`📝 Processing Form: "${formName}"`);
|
|
135
126
|
// Parse the table
|
|
136
127
|
const rows = parseDataTable(table);
|
|
@@ -234,4 +225,8 @@ exports.FillFormData = (0, registry_1.Step)("I fill the following {string} form
|
|
|
234
225
|
await locator.fill(resolvedValue);
|
|
235
226
|
console.log(`✍️ Filled ${target} with "${resolvedValue}"`);
|
|
236
227
|
}
|
|
237
|
-
}
|
|
228
|
+
}
|
|
229
|
+
// ==================================================
|
|
230
|
+
// GLUE STEPS
|
|
231
|
+
// ==================================================
|
|
232
|
+
(0, registry_1.Step)("I fill the following {string} form data", fillFormData);
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Iterates through a provided Data Table to fill inputs, click elements, or perform assertions.
|
|
3
|
-
* This
|
|
4
|
-
*
|
|
5
|
-
* ```gherkin
|
|
3
|
+
* This function is designed for bulk form interaction without writing repetitive "When I..." steps.
|
|
4
|
+
* @example
|
|
6
5
|
* When I fill the following "Login" test form data
|
|
7
6
|
* | #username | tomsmith |
|
|
8
7
|
* | #password | SuperSecretPassword! |
|
|
9
8
|
* | #login | click |
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
9
|
* @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
|
|
14
|
-
*
|
|
10
|
+
* @param tableData - A 2D array representing the data table rows.
|
|
15
11
|
* @remarks
|
|
16
12
|
* **Supported Values in Column 2:**
|
|
17
13
|
* - `Any String`: Fills the input found by the selector in Column 1.
|
|
@@ -19,8 +15,7 @@
|
|
|
19
15
|
* - `"check"`: Checks a checkbox or radio button.
|
|
20
16
|
* - `"assert:visible"`: Asserts that the element is visible.
|
|
21
17
|
* - `"assert:text:EXPECTED"`: Asserts that the element contains the specific text.
|
|
22
|
-
*
|
|
23
18
|
* @throws {Error} If the Data Table is missing or invalid.
|
|
24
19
|
*/
|
|
25
|
-
export declare
|
|
20
|
+
export declare function fillTestFormData(page: any, formName: string, tableData: string[][]): Promise<void>;
|
|
26
21
|
//# 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":"AAOA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.fillTestFormData = fillTestFormData;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const registry_1 = require("../../core/registry");
|
|
6
|
+
// ==================================================
|
|
7
|
+
// CORE FUNCTIONS
|
|
8
|
+
// ==================================================
|
|
6
9
|
/**
|
|
7
10
|
* Iterates through a provided Data Table to fill inputs, click elements, or perform assertions.
|
|
8
|
-
* This
|
|
9
|
-
*
|
|
10
|
-
* ```gherkin
|
|
11
|
+
* This function is designed for bulk form interaction without writing repetitive "When I..." steps.
|
|
12
|
+
* @example
|
|
11
13
|
* When I fill the following "Login" test form data
|
|
12
14
|
* | #username | tomsmith |
|
|
13
15
|
* | #password | SuperSecretPassword! |
|
|
14
16
|
* | #login | click |
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
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
|
|
19
|
-
*
|
|
18
|
+
* @param tableData - A 2D array representing the data table rows.
|
|
20
19
|
* @remarks
|
|
21
20
|
* **Supported Values in Column 2:**
|
|
22
21
|
* - `Any String`: Fills the input found by the selector in Column 1.
|
|
@@ -24,10 +23,9 @@ const registry_1 = require("../../core/registry");
|
|
|
24
23
|
* - `"check"`: Checks a checkbox or radio button.
|
|
25
24
|
* - `"assert:visible"`: Asserts that the element is visible.
|
|
26
25
|
* - `"assert:text:EXPECTED"`: Asserts that the element contains the specific text.
|
|
27
|
-
*
|
|
28
26
|
* @throws {Error} If the Data Table is missing or invalid.
|
|
29
27
|
*/
|
|
30
|
-
|
|
28
|
+
async function fillTestFormData(page, formName, tableData) {
|
|
31
29
|
console.log(`📝 Processing Form: ${formName}`);
|
|
32
30
|
// Guard clause: Ensure tableData exists to prevent crashes if user forgets the table
|
|
33
31
|
if (!tableData || !Array.isArray(tableData)) {
|
|
@@ -53,4 +51,8 @@ exports.FillTestFormData = (0, registry_1.Step)("I fill the following {string} t
|
|
|
53
51
|
await page.fill(selector, value);
|
|
54
52
|
}
|
|
55
53
|
}
|
|
56
|
-
}
|
|
54
|
+
}
|
|
55
|
+
// ==================================================
|
|
56
|
+
// GLUE STEPS
|
|
57
|
+
// ==================================================
|
|
58
|
+
(0, registry_1.Step)("I fill the following {string} test form data", fillTestFormData);
|
|
@@ -1,54 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Attempts to switch the logical context to a specific iframe.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Verifies the frame exists and logs a warning about frame scope limitations.
|
|
4
|
+
* @example
|
|
5
5
|
* When I switch to frame "#payment-iframe"
|
|
6
|
-
* ```
|
|
7
|
-
*
|
|
8
6
|
* @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
7
|
*/
|
|
18
|
-
export declare
|
|
8
|
+
export declare function switchToFrame(page: any, selector: string): Promise<void>;
|
|
19
9
|
/**
|
|
20
10
|
* Finds an element inside a specific iframe and sets it as the active element.
|
|
21
11
|
* 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
12
|
* @example
|
|
31
13
|
* When I find element "#card-number" in frame "#stripe-element"
|
|
32
|
-
*
|
|
14
|
+
* @param elementSelector - The selector of the element INSIDE the iframe.
|
|
15
|
+
* @param frameSelector - The selector of the iframe element itself.
|
|
33
16
|
*/
|
|
34
|
-
export declare
|
|
17
|
+
export declare function findElementInFrame(page: any, elementSelector: string, frameSelector: string): Promise<void>;
|
|
35
18
|
/**
|
|
36
19
|
* Waits for a new browser tab (popup) to open.
|
|
37
20
|
* 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
21
|
* @example
|
|
49
22
|
* When I click on link "Open Dashboard"
|
|
50
23
|
* And I switch to new tab
|
|
51
|
-
* # (Implicitly validates the tab opened successfully)
|
|
52
24
|
*/
|
|
53
|
-
export declare
|
|
25
|
+
export declare function switchToNewTab(page: any): Promise<void>;
|
|
54
26
|
//# sourceMappingURL=frames.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/frames.ts"],"names":[],"mappings":"AAOA
|
|
1
|
+
{"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/frames.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9E;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,GAAG,EACT,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7D"}
|
|
@@ -1,97 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.switchToFrame = switchToFrame;
|
|
4
|
+
exports.findElementInFrame = findElementInFrame;
|
|
5
|
+
exports.switchToNewTab = switchToNewTab;
|
|
4
6
|
const registry_1 = require("../../core/registry");
|
|
5
7
|
const state_1 = require("../utils/state");
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
8
|
+
// ==================================================
|
|
9
|
+
// CORE FUNCTIONS
|
|
10
|
+
// ==================================================
|
|
9
11
|
/**
|
|
10
12
|
* Attempts to switch the logical context to a specific iframe.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
+
* Verifies the frame exists and logs a warning about frame scope limitations.
|
|
14
|
+
* @example
|
|
13
15
|
* When I switch to frame "#payment-iframe"
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
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
17
|
*/
|
|
26
|
-
|
|
18
|
+
async function switchToFrame(page, selector) {
|
|
27
19
|
const frameElement = page.locator(selector);
|
|
28
20
|
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
21
|
if (!frame)
|
|
36
22
|
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
23
|
console.log(`⚠️ Switching Frames requires a Scope manager. For now, use 'I find element ... in frame ...'`);
|
|
42
|
-
}
|
|
24
|
+
}
|
|
43
25
|
/**
|
|
44
26
|
* Finds an element inside a specific iframe and sets it as the active element.
|
|
45
27
|
* 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
28
|
* @example
|
|
55
29
|
* When I find element "#card-number" in frame "#stripe-element"
|
|
56
|
-
*
|
|
30
|
+
* @param elementSelector - The selector of the element INSIDE the iframe.
|
|
31
|
+
* @param frameSelector - The selector of the iframe element itself.
|
|
57
32
|
*/
|
|
58
|
-
|
|
33
|
+
async function findElementInFrame(page, elementSelector, frameSelector) {
|
|
59
34
|
const frame = page.frameLocator(frameSelector);
|
|
60
35
|
const element = frame.locator(elementSelector).first();
|
|
61
36
|
await element.waitFor();
|
|
62
37
|
(0, state_1.setActiveElement)(page, element);
|
|
63
38
|
console.log(`🔍 Found element "${elementSelector}" inside frame "${frameSelector}"`);
|
|
64
|
-
}
|
|
65
|
-
// =============================
|
|
66
|
-
// TAB / WINDOW HANDLING
|
|
67
|
-
// =============================
|
|
39
|
+
}
|
|
68
40
|
/**
|
|
69
41
|
* Waits for a new browser tab (popup) to open.
|
|
70
42
|
* 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
43
|
* @example
|
|
82
44
|
* When I click on link "Open Dashboard"
|
|
83
45
|
* And I switch to new tab
|
|
84
|
-
* # (Implicitly validates the tab opened successfully)
|
|
85
46
|
*/
|
|
86
|
-
|
|
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:
|
|
47
|
+
async function switchToNewTab(page) {
|
|
91
48
|
console.log("⚠️ Multi-tab support requires Runner updates. Verifying popup event only.");
|
|
92
49
|
const popup = await page.waitForEvent("popup");
|
|
93
50
|
await popup.waitForLoadState();
|
|
94
51
|
console.log(`📑 New tab opened: ${await popup.title()}`);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
52
|
+
}
|
|
53
|
+
// ==================================================
|
|
54
|
+
// GLUE STEPS
|
|
55
|
+
// ==================================================
|
|
56
|
+
(0, registry_1.Step)("I switch to frame {string}", switchToFrame);
|
|
57
|
+
(0, registry_1.Step)("I find element {string} in frame {string}", findElementInFrame);
|
|
58
|
+
(0, registry_1.Step)("I switch to new tab", switchToNewTab);
|
|
@@ -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;AACrB,OAAO,SAAS,CAAC;AACjB,OAAO,
|
|
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,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"}
|
|
@@ -1,140 +1,96 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fills the currently stored (active) input element with specific text.
|
|
3
3
|
* Supports variable aliases using the "@" prefix.
|
|
4
|
-
*
|
|
5
|
-
* ```gherkin
|
|
4
|
+
* @example
|
|
6
5
|
* When I type "hello world"
|
|
7
6
|
* When I type "@storedPassword"
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* @param page - Playwright page object
|
|
10
8
|
* @param textOrAlias - The text to type OR a variable key prefixed with "@".
|
|
11
9
|
* @param table - Optional data table for options (e.g., force: true).
|
|
12
10
|
*/
|
|
13
|
-
export declare
|
|
11
|
+
export declare function typeText(page: any, textOrAlias: string, table?: any): Promise<void>;
|
|
14
12
|
/**
|
|
15
13
|
* Fills the active input with a value explicitly retrieved from the variable store.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* ```gherkin
|
|
14
|
+
* @example
|
|
19
15
|
* When I type stored "userEmail"
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
16
|
* @param alias - The key of the stored variable.
|
|
23
17
|
*/
|
|
24
|
-
export declare
|
|
18
|
+
export declare function typeStoredText(page: any, alias: string, table?: any): Promise<void>;
|
|
25
19
|
/**
|
|
26
20
|
* Types text character-by-character with a 100ms delay.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* ```gherkin
|
|
21
|
+
* @example
|
|
30
22
|
* When I slowly type "Playwright"
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
23
|
* @param text - The text to type sequentially.
|
|
34
24
|
*/
|
|
35
|
-
export declare
|
|
25
|
+
export declare function typeSlowly(page: any, text: string): Promise<void>;
|
|
36
26
|
/**
|
|
37
27
|
* Sets the value of an input directly (alias for filling).
|
|
38
|
-
*
|
|
39
|
-
* ```gherkin
|
|
28
|
+
* @example
|
|
40
29
|
* When I set value "12345"
|
|
41
|
-
* ```
|
|
42
|
-
*
|
|
43
30
|
* @param value - The value to set.
|
|
44
31
|
*/
|
|
45
|
-
export declare
|
|
32
|
+
export declare function setInputValue(page: any, value: string, table?: any): Promise<void>;
|
|
46
33
|
/**
|
|
47
34
|
* Clears the text content of the active input field.
|
|
48
|
-
*
|
|
49
|
-
* ```gherkin
|
|
35
|
+
* @example
|
|
50
36
|
* When I clear
|
|
51
|
-
* ```
|
|
52
37
|
*/
|
|
53
|
-
export declare
|
|
38
|
+
export declare function clearInput(page: any): Promise<void>;
|
|
54
39
|
/**
|
|
55
40
|
* Simulates pressing a specific keyboard key on the active element.
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* ```gherkin
|
|
41
|
+
* @example
|
|
59
42
|
* When I press "Enter"
|
|
60
43
|
* When I press "Tab"
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
44
|
* @param key - The key name (e.g., "Enter", "Escape", "ArrowDown").
|
|
64
45
|
*/
|
|
65
|
-
export declare
|
|
46
|
+
export declare function pressKeyOnInput(page: any, key: string): Promise<void>;
|
|
66
47
|
/**
|
|
67
48
|
* Checks the currently active checkbox or radio button.
|
|
68
|
-
*
|
|
69
|
-
* ```gherkin
|
|
49
|
+
* @example
|
|
70
50
|
* When I check
|
|
71
|
-
* ```
|
|
72
51
|
*/
|
|
73
|
-
export declare
|
|
52
|
+
export declare function checkElement(page: any, table?: any): Promise<void>;
|
|
74
53
|
/**
|
|
75
54
|
* Unchecks the currently active checkbox.
|
|
76
|
-
*
|
|
77
|
-
* ```gherkin
|
|
55
|
+
* @example
|
|
78
56
|
* When I uncheck
|
|
79
|
-
* ```
|
|
80
57
|
*/
|
|
81
|
-
export declare
|
|
58
|
+
export declare function uncheckElement(page: any, table?: any): Promise<void>;
|
|
82
59
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* When I check
|
|
87
|
-
* ```
|
|
60
|
+
* Checks/Unchecks the Nth checkbox or radio button matching a selector.
|
|
61
|
+
* @example
|
|
62
|
+
* When I check 1st selector "input[type='checkbox']"
|
|
63
|
+
* When I uncheck 2nd selector ".terms-check"
|
|
88
64
|
*/
|
|
89
|
-
export declare
|
|
90
|
-
/**
|
|
91
|
-
* Legacy alias for `I uncheck`.
|
|
92
|
-
*
|
|
93
|
-
* ```gherkin
|
|
94
|
-
* When I uncheck input
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
export declare const UncheckInputAlias: void;
|
|
65
|
+
export declare function checkNthElementBySelector(page: any, action: string, indexStr: string, selector: string, table?: any): Promise<void>;
|
|
98
66
|
/**
|
|
99
67
|
* Selects an option in a `<select>` dropdown by its visible label.
|
|
100
|
-
*
|
|
101
|
-
* ```gherkin
|
|
68
|
+
* @example
|
|
102
69
|
* When I select option "California"
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
70
|
* @param option - The visible text label of the option to select.
|
|
106
71
|
*/
|
|
107
|
-
export declare
|
|
72
|
+
export declare function selectOption(page: any, option: string, table?: any): Promise<void>;
|
|
108
73
|
/**
|
|
109
74
|
* Submits the form related to the active element.
|
|
110
|
-
*
|
|
111
|
-
* **Logic:**
|
|
75
|
+
* Logic:
|
|
112
76
|
* 1. Tries to find the parent `<form>` of the currently stored element.
|
|
113
|
-
* 2. If no parent form is found
|
|
114
|
-
*
|
|
115
|
-
* ```gherkin
|
|
77
|
+
* 2. If no parent form is found, finds the first form on the page.
|
|
78
|
+
* @example
|
|
116
79
|
* When I submit
|
|
117
|
-
* ```
|
|
118
80
|
*/
|
|
119
|
-
export declare
|
|
81
|
+
export declare function submitForm(page: any): Promise<void>;
|
|
120
82
|
/**
|
|
121
83
|
* Uploads a file to the active file input element.
|
|
122
|
-
*
|
|
123
|
-
* ```gherkin
|
|
84
|
+
* @example
|
|
124
85
|
* When I select file "data/invoice.pdf"
|
|
125
|
-
* ```
|
|
126
|
-
*
|
|
127
86
|
* @param filePath - The path to the file (relative to the project root).
|
|
128
87
|
*/
|
|
129
|
-
export declare
|
|
88
|
+
export declare function selectFile(page: any, filePath: string): Promise<void>;
|
|
130
89
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* ```gherkin
|
|
90
|
+
* Uploads a file to the active file input element (alias for selectFile).
|
|
91
|
+
* @example
|
|
134
92
|
* When I upload file "images/logo.png"
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
93
|
* @param filePath - The path to the file.
|
|
138
94
|
*/
|
|
139
|
-
export declare
|
|
95
|
+
export declare function uploadFile(page: any, filePath: string): Promise<void>;
|
|
140
96
|
//# sourceMappingURL=inputs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/inputs.ts"],"names":[],"mappings":"AAOA
|
|
1
|
+
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../../src/backend/actions/inputs.ts"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBzF;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CASzF;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxF;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzD;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1E;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,GAAG,GACV,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBzD;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E"}
|