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.
- package/LICENSE +21 -0
- package/dist/backend/actions/click.d.ts +133 -0
- package/dist/backend/actions/click.d.ts.map +1 -0
- package/dist/backend/actions/click.js +248 -0
- package/dist/backend/actions/find.d.ts +244 -0
- package/dist/backend/actions/find.d.ts.map +1 -0
- package/dist/backend/actions/find.js +415 -0
- package/dist/backend/actions/form.d.ts +38 -0
- package/dist/backend/actions/form.d.ts.map +1 -0
- package/dist/backend/actions/form.js +237 -0
- package/dist/backend/actions/formTable.d.ts +25 -1
- package/dist/backend/actions/formTable.d.ts.map +1 -1
- package/dist/backend/actions/formTable.js +27 -5
- package/dist/backend/actions/frames.d.ts +54 -0
- package/dist/backend/actions/frames.d.ts.map +1 -0
- package/dist/backend/actions/frames.js +97 -0
- package/dist/backend/actions/index.d.ts +10 -0
- package/dist/backend/actions/index.d.ts.map +1 -1
- package/dist/backend/actions/index.js +10 -0
- package/dist/backend/actions/inputs.d.ts +140 -0
- package/dist/backend/actions/inputs.d.ts.map +1 -0
- package/dist/backend/actions/inputs.js +247 -0
- package/dist/backend/actions/interactions.d.ts +61 -1
- package/dist/backend/actions/interactions.d.ts.map +1 -1
- package/dist/backend/actions/interactions.js +65 -10
- package/dist/backend/actions/keyboard.d.ts +71 -0
- package/dist/backend/actions/keyboard.d.ts.map +1 -0
- package/dist/backend/actions/keyboard.js +98 -0
- package/dist/backend/actions/misc.d.ts +135 -0
- package/dist/backend/actions/misc.d.ts.map +1 -0
- package/dist/backend/actions/misc.js +208 -0
- package/dist/backend/actions/mobile.d.ts +75 -0
- package/dist/backend/actions/mobile.d.ts.map +1 -0
- package/dist/backend/actions/mobile.js +148 -0
- package/dist/backend/actions/mouse.d.ts +80 -0
- package/dist/backend/actions/mouse.d.ts.map +1 -0
- package/dist/backend/actions/mouse.js +150 -0
- package/dist/backend/actions/navigation.d.ts +48 -1
- package/dist/backend/actions/navigation.d.ts.map +1 -1
- package/dist/backend/actions/navigation.js +61 -10
- package/dist/backend/actions/waits.d.ts +56 -0
- package/dist/backend/actions/waits.d.ts.map +1 -0
- package/dist/backend/actions/waits.js +83 -0
- package/dist/backend/api/assertions.d.ts +32 -1
- package/dist/backend/api/assertions.d.ts.map +1 -1
- package/dist/backend/api/assertions.js +37 -9
- package/dist/backend/api/index.d.ts +1 -0
- package/dist/backend/api/index.d.ts.map +1 -1
- package/dist/backend/api/index.js +1 -0
- package/dist/backend/api/mock.d.ts +34 -1
- package/dist/backend/api/mock.d.ts.map +1 -1
- package/dist/backend/api/mock.js +37 -10
- package/dist/backend/api/network.d.ts +61 -0
- package/dist/backend/api/network.d.ts.map +1 -0
- package/dist/backend/api/network.js +177 -0
- package/dist/backend/api/requests.d.ts +43 -1
- package/dist/backend/api/requests.d.ts.map +1 -1
- package/dist/backend/api/requests.js +49 -17
- package/dist/backend/assertions/pageState.d.ts +40 -1
- package/dist/backend/assertions/pageState.d.ts.map +1 -1
- package/dist/backend/assertions/pageState.js +48 -16
- package/dist/backend/assertions/text.d.ts +46 -1
- package/dist/backend/assertions/text.d.ts.map +1 -1
- package/dist/backend/assertions/text.js +51 -8
- package/dist/backend/assertions/visibility.d.ts +102 -1
- package/dist/backend/assertions/visibility.d.ts.map +1 -1
- package/dist/backend/assertions/visibility.js +166 -12
- package/dist/backend/auth/index.js +2 -2
- package/dist/backend/db/steps.d.ts +35 -1
- package/dist/backend/db/steps.d.ts.map +1 -1
- package/dist/backend/db/steps.js +48 -15
- package/dist/backend/elements/alerts.d.ts +35 -1
- package/dist/backend/elements/alerts.d.ts.map +1 -1
- package/dist/backend/elements/alerts.js +39 -6
- package/dist/backend/elements/forms.d.ts +44 -1
- package/dist/backend/elements/forms.d.ts.map +1 -1
- package/dist/backend/elements/forms.js +50 -11
- package/dist/backend/elements/frames.d.ts +36 -1
- package/dist/backend/elements/frames.d.ts.map +1 -1
- package/dist/backend/elements/frames.js +43 -13
- package/dist/backend/utils/state.d.ts +18 -0
- package/dist/backend/utils/state.d.ts.map +1 -0
- package/dist/backend/utils/state.js +84 -0
- package/dist/core/registry.d.ts +14 -14
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +13 -4
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +91 -38
- package/package.json +52 -12
|
@@ -1,2 +1,26 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
3
|
+
exports.FillTestFormData = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
|
-
|
|
6
|
-
|
|
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
|
+
});
|