playwright-cucumber-ts-steps 1.0.0 → 1.0.1

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 (73) hide show
  1. package/lib/actions/clickSteps.d.ts +251 -0
  2. package/lib/actions/clickSteps.js +415 -0
  3. package/lib/actions/cookieSteps.d.ts +18 -0
  4. package/lib/actions/cookieSteps.js +93 -0
  5. package/lib/actions/debugSteps.d.ts +14 -0
  6. package/lib/actions/debugSteps.js +23 -0
  7. package/lib/actions/elementFindSteps.d.ts +668 -0
  8. package/lib/actions/elementFindSteps.js +931 -0
  9. package/lib/actions/fillFormSteps.d.ts +69 -0
  10. package/lib/actions/fillFormSteps.js +237 -0
  11. package/lib/actions/index.d.ts +11 -0
  12. package/lib/actions/index.js +28 -0
  13. package/lib/actions/inputSteps.d.ts +218 -0
  14. package/lib/actions/inputSteps.js +343 -0
  15. package/lib/actions/interceptionSteps.d.ts +169 -0
  16. package/lib/actions/interceptionSteps.js +291 -0
  17. package/lib/actions/miscSteps.d.ts +645 -0
  18. package/lib/actions/miscSteps.js +1061 -0
  19. package/lib/actions/mouseSteps.d.ts +143 -0
  20. package/lib/actions/mouseSteps.js +234 -0
  21. package/lib/actions/scrollSteps.d.ts +82 -0
  22. package/lib/actions/scrollSteps.js +123 -0
  23. package/lib/actions/storageSteps.d.ts +174 -0
  24. package/lib/actions/storageSteps.js +292 -0
  25. package/lib/assertions/buttonAndTextVisibilitySteps.d.ts +245 -0
  26. package/lib/assertions/buttonAndTextVisibilitySteps.js +401 -0
  27. package/lib/assertions/cookieSteps.d.ts +75 -0
  28. package/lib/assertions/cookieSteps.js +113 -0
  29. package/lib/assertions/elementSteps.d.ts +264 -0
  30. package/lib/assertions/elementSteps.js +388 -0
  31. package/lib/assertions/formInputSteps.d.ts +248 -0
  32. package/lib/assertions/formInputSteps.js +350 -0
  33. package/lib/assertions/index.d.ts +10 -0
  34. package/lib/assertions/index.js +27 -0
  35. package/lib/assertions/interceptionRequestsSteps.d.ts +353 -0
  36. package/lib/assertions/interceptionRequestsSteps.js +593 -0
  37. package/lib/assertions/locationSteps.d.ts +217 -0
  38. package/lib/assertions/locationSteps.js +310 -0
  39. package/lib/assertions/roleTestIdSteps.d.ts +159 -0
  40. package/lib/assertions/roleTestIdSteps.js +221 -0
  41. package/lib/assertions/semanticSteps.d.ts +176 -0
  42. package/lib/assertions/semanticSteps.js +252 -0
  43. package/lib/assertions/storageSteps.d.ts +149 -0
  44. package/lib/assertions/storageSteps.js +210 -0
  45. package/lib/assertions/visualSteps.d.ts +74 -0
  46. package/lib/assertions/visualSteps.js +209 -0
  47. package/lib/custom_setups/loginHooks.d.ts +1 -0
  48. package/lib/custom_setups/loginHooks.js +130 -0
  49. package/lib/helpers/checkPeerDeps.d.ts +1 -0
  50. package/lib/helpers/checkPeerDeps.js +19 -0
  51. package/lib/helpers/compareSnapshots.d.ts +6 -0
  52. package/lib/helpers/compareSnapshots.js +20 -0
  53. package/lib/helpers/hooks.d.ts +1 -0
  54. package/lib/helpers/hooks.js +210 -0
  55. package/lib/helpers/utils/fakerUtils.d.ts +1 -0
  56. package/lib/helpers/utils/fakerUtils.js +60 -0
  57. package/lib/helpers/utils/index.d.ts +4 -0
  58. package/lib/helpers/utils/index.js +20 -0
  59. package/lib/helpers/utils/optionsUtils.d.ts +24 -0
  60. package/lib/helpers/utils/optionsUtils.js +88 -0
  61. package/lib/helpers/utils/resolveUtils.d.ts +6 -0
  62. package/lib/helpers/utils/resolveUtils.js +72 -0
  63. package/lib/helpers/utils/sessionUtils.d.ts +3 -0
  64. package/lib/helpers/utils/sessionUtils.js +40 -0
  65. package/lib/helpers/world.d.ts +34 -0
  66. package/lib/helpers/world.js +110 -0
  67. package/lib/iframes/frames.d.ts +1 -0
  68. package/lib/iframes/frames.js +11 -0
  69. package/lib/index.d.ts +10 -0
  70. package/lib/index.js +28 -0
  71. package/lib/register.d.ts +1 -0
  72. package/lib/register.js +6 -0
  73. package/package.json +1 -1
@@ -0,0 +1,931 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.When_I_find_element_by_selector = When_I_find_element_by_selector;
4
+ exports.When_I_find_link_by_text = When_I_find_link_by_text;
5
+ exports.When_I_find_heading_by_text = When_I_find_heading_by_text;
6
+ exports.When_I_find_headings_by_text = When_I_find_headings_by_text;
7
+ exports.When_I_find_elements_by_selector = When_I_find_elements_by_selector;
8
+ exports.When_I_find_element_by_text = When_I_find_element_by_text;
9
+ exports.When_I_find_element_by_title = When_I_find_element_by_title;
10
+ exports.When_I_find_element_by_testid = When_I_find_element_by_testid;
11
+ exports.When_I_find_element_by_role = When_I_find_element_by_role;
12
+ exports.When_I_find_element_by_placeholder_text = When_I_find_element_by_placeholder_text;
13
+ exports.When_I_find_element_by_label_text = When_I_find_element_by_label_text;
14
+ exports.When_I_find_elements_by_label_text = When_I_find_elements_by_label_text;
15
+ exports.When_I_find_element_by_alt_text = When_I_find_element_by_alt_text;
16
+ exports.When_I_find_element_by_name = When_I_find_element_by_name;
17
+ exports.When_I_find_elements_by_name = When_I_find_elements_by_name;
18
+ exports.When_I_find_buttons_by_text = When_I_find_buttons_by_text;
19
+ exports.When_I_get_element_by_selector = When_I_get_element_by_selector;
20
+ exports.When_I_get_elements_by_selector = When_I_get_elements_by_selector;
21
+ exports.When_I_get_first_element = When_I_get_first_element;
22
+ exports.When_I_get_last_element = When_I_get_last_element;
23
+ exports.When_I_get_nth_element = When_I_get_nth_element;
24
+ exports.When_I_find_elements_by_role = When_I_find_elements_by_role;
25
+ exports.When_I_get_int_rd_element = When_I_get_int_rd_element;
26
+ exports.When_I_get_focused_element = When_I_get_focused_element;
27
+ exports.When_I_store_element_text_as = When_I_store_element_text_as;
28
+ exports.When_I_find_textarea_by_label_text = When_I_find_textarea_by_label_text;
29
+ exports.When_I_find_textarea_by_placeholder_text = When_I_find_textarea_by_placeholder_text;
30
+ exports.When_I_find_textareas_by_label_text = When_I_find_textareas_by_label_text;
31
+ exports.When_I_find_textarea_by_name = When_I_find_textarea_by_name;
32
+ exports.When_I_find_textareas_by_ID = When_I_find_textareas_by_ID;
33
+ exports.When_I_find_textareas_by_placeholder_text_multiple = When_I_find_textareas_by_placeholder_text_multiple;
34
+ exports.When_I_find_input_by_ID = When_I_find_input_by_ID;
35
+ exports.When_I_find_inputs_by_ID = When_I_find_inputs_by_ID;
36
+ exports.When_I_find_input_by_label_text = When_I_find_input_by_label_text;
37
+ exports.When_I_find_input_by_name = When_I_find_input_by_name;
38
+ exports.When_I_find_input_by_placeholder_text = When_I_find_input_by_placeholder_text;
39
+ exports.When_I_find_inputs_by_name_multiple = When_I_find_inputs_by_name_multiple;
40
+ exports.When_I_find_inputs_by_placeholder_text_multiple = When_I_find_inputs_by_placeholder_text_multiple;
41
+ exports.When_I_find_inputs_by_label_text_multiple = When_I_find_inputs_by_label_text_multiple;
42
+ exports.When_I_find_inputs_by_display_value_multiple = When_I_find_inputs_by_display_value_multiple;
43
+ exports.When_I_find_input_by_display_value = When_I_find_input_by_display_value;
44
+ const cucumber_1 = require("@cucumber/cucumber");
45
+ const test_1 = require("@playwright/test");
46
+ // =============================
47
+ // WHEN I FIND ELEMENT(S)
48
+ // =============================
49
+ /**
50
+ * Finds an element by CSS selector and stores it as the current element.
51
+ *
52
+ * ```gherkin
53
+ * When I find element by selector {string}
54
+ * ```
55
+ *
56
+ * @example
57
+ * When I find element by selector ".my-class"
58
+ *
59
+ * @remarks
60
+ * This step sets the {@link CustomWorld.element | current element} in the test context.
61
+ * Subsequent steps can then interact with this single element. An `expect` assertion is included
62
+ * to ensure exactly one element is found.
63
+ */
64
+ async function When_I_find_element_by_selector(selector) {
65
+ this.element = this.page.locator(selector);
66
+ await (0, test_1.expect)(this.element).toHaveCount(1);
67
+ }
68
+ (0, cucumber_1.When)("I find element by selector {string}", When_I_find_element_by_selector);
69
+ /**
70
+ * Finds a link by its text and stores it as the current locator.
71
+ *
72
+ * ```gherkin
73
+ * When I find link by text {string}
74
+ * ```
75
+ *
76
+ * @example
77
+ * When I find link by text "Home"
78
+ *
79
+ * @remarks
80
+ * This step sets the {@link CustomWorld.currentLocator | currentLocator} in the test context,
81
+ * allowing subsequent steps to operate on the found link. For example:
82
+ *
83
+ * ```gherkin
84
+ * When I find link by text "Products"
85
+ * And I click current element
86
+ * ```
87
+ */
88
+ async function When_I_find_link_by_text(text) {
89
+ this.currentLocator = this.getScope().getByRole("link", { name: text });
90
+ }
91
+ (0, cucumber_1.When)("I find link by text {string}", When_I_find_link_by_text);
92
+ /**
93
+ * Finds a heading by its text and stores it as the current locator.
94
+ *
95
+ * ```gherkin
96
+ * When I find heading by text {string}
97
+ * ```
98
+ *
99
+ * @example
100
+ * When I find heading by text "Welcome"
101
+ *
102
+ * @remarks
103
+ * This step sets the {@link CustomWorld.currentLocator | currentLocator} in the test context,
104
+ * allowing subsequent steps to operate on the found heading.
105
+ */
106
+ async function When_I_find_heading_by_text(text) {
107
+ this.currentLocator = this.getScope().getByRole("heading", { name: text });
108
+ }
109
+ (0, cucumber_1.When)("I find heading by text {string}", When_I_find_heading_by_text);
110
+ /**
111
+ * Finds all headings by text and stores them as the current locator.
112
+ *
113
+ * ```gherkin
114
+ * When I find headings by text {string}
115
+ * ```
116
+ *
117
+ * @example
118
+ * When I find headings by text "Section"
119
+ *
120
+ * @remarks
121
+ * This step sets the {@link CustomWorld.currentLocator | currentLocator} in the test context
122
+ * to a locator that matches *all* headings with the specified text. This is useful for
123
+ * verifying multiple instances or iterating.
124
+ */
125
+ async function When_I_find_headings_by_text(text) {
126
+ this.currentLocator = this.getScope().getByRole("heading", { name: text });
127
+ }
128
+ (0, cucumber_1.When)("I find headings by text {string}", When_I_find_headings_by_text);
129
+ /**
130
+ * Finds all elements by CSS selector and stores them.
131
+ *
132
+ * ```gherkin
133
+ * When I find elements by selector {string}
134
+ * ```
135
+ *
136
+ * @example
137
+ * When I find elements by selector ".item"
138
+ *
139
+ * @remarks
140
+ * This step sets the {@link CustomWorld.elements | elements} property in the test context
141
+ * to a Playwright `Locator` representing all matching elements. You can then use steps like
142
+ * "When I get first element" to pick a specific one.
143
+ */
144
+ async function When_I_find_elements_by_selector(selector) {
145
+ this.elements = this.page.locator(selector);
146
+ const count = await this.elements.count();
147
+ this.log?.(`Found ${count} elements with selector ${selector}`);
148
+ }
149
+ (0, cucumber_1.When)("I find elements by selector {string}", When_I_find_elements_by_selector);
150
+ /**
151
+ * Finds an element by its exact text and stores it as the current element.
152
+ *
153
+ * ```gherkin
154
+ * When I find element by text {string}
155
+ * ```
156
+ *
157
+ * @example
158
+ * When I find element by text "Submit"
159
+ *
160
+ * @remarks
161
+ * This step uses `page.getByText` with `exact: true` to find an element
162
+ * that matches the text precisely. It stores the result in {@link CustomWorld.element | this.element}.
163
+ * An `expect` assertion is included to ensure exactly one element is found.
164
+ */
165
+ async function When_I_find_element_by_text(text) {
166
+ this.element = this.page.getByText(text, { exact: true });
167
+ await (0, test_1.expect)(this.element).toHaveCount(1);
168
+ }
169
+ (0, cucumber_1.When)("I find element by text {string}", When_I_find_element_by_text);
170
+ /**
171
+ * Finds an element by its title attribute and stores it as the current element.
172
+ *
173
+ * ```gherkin
174
+ * When I find element by title {string}
175
+ * ```
176
+ *
177
+ * @example
178
+ * When I find element by title "Tooltip"
179
+ *
180
+ * @remarks
181
+ * This step uses `page.getByTitle` to find an element with the specified `title` attribute.
182
+ * It stores the result in {@link CustomWorld.element | this.element}.
183
+ * An `expect` assertion is included to ensure exactly one element is found.
184
+ */
185
+ async function When_I_find_element_by_title(title) {
186
+ this.element = this.page.getByTitle(title);
187
+ await (0, test_1.expect)(this.element).toHaveCount(1);
188
+ }
189
+ (0, cucumber_1.When)("I find element by title {string}", When_I_find_element_by_title);
190
+ /**
191
+ * Finds an element by its test id and stores it as the current element.
192
+ *
193
+ * ```gherkin
194
+ * When I find element by testid {string}
195
+ * ```
196
+ *
197
+ * @example
198
+ * When I find element by testid "main-content"
199
+ *
200
+ * @remarks
201
+ * This step uses `page.getByTestId` to find an element based on its
202
+ * `data-testid` attribute (or configured test ID attribute).
203
+ * It stores the result in {@link CustomWorld.element | this.element}.
204
+ * An `expect` assertion is included to ensure exactly one element is found.
205
+ */
206
+ async function When_I_find_element_by_testid(testid) {
207
+ this.element = this.page.getByTestId(testid);
208
+ await (0, test_1.expect)(this.element).toHaveCount(1);
209
+ }
210
+ (0, cucumber_1.When)("I find element by testid {string}", When_I_find_element_by_testid);
211
+ /**
212
+ * Finds an element by its role and stores it as the current element.
213
+ *
214
+ * ```gherkin
215
+ * When I find element by role {string}
216
+ * ```
217
+ *
218
+ * @example
219
+ * When I find element by role "button"
220
+ *
221
+ * @remarks
222
+ * This step uses `page.getByRole` to find an element based on its
223
+ * ARIA role. It stores the result in {@link CustomWorld.element | this.element}.
224
+ * An `expect` assertion is included to ensure exactly one element is found.
225
+ */
226
+ async function When_I_find_element_by_role(role) {
227
+ this.element = this.page.getByRole(role);
228
+ await (0, test_1.expect)(this.element).toHaveCount(1);
229
+ }
230
+ (0, cucumber_1.When)("I find element by role {string}", When_I_find_element_by_role);
231
+ /**
232
+ * Finds an element by its placeholder text and stores it as the current element.
233
+ *
234
+ * ```gherkin
235
+ * When I find element by placeholder text {string}
236
+ * ```
237
+ *
238
+ * @example
239
+ * When I find element by placeholder text "Enter your name"
240
+ *
241
+ * @remarks
242
+ * This step uses `page.getByPlaceholder` to find an input or textarea element
243
+ * based on its `placeholder` attribute. It stores the result in {@link CustomWorld.element | this.element}.
244
+ * An `expect` assertion is included to ensure exactly one element is found.
245
+ */
246
+ async function When_I_find_element_by_placeholder_text(text) {
247
+ this.element = this.page.getByPlaceholder(text);
248
+ await (0, test_1.expect)(this.element).toHaveCount(1);
249
+ }
250
+ (0, cucumber_1.When)("I find element by placeholder text {string}", When_I_find_element_by_placeholder_text);
251
+ /**
252
+ * Finds an element by its label text and stores it as the current element.
253
+ *
254
+ * ```gherkin
255
+ * When I find element by label text {string}
256
+ * ```
257
+ *
258
+ * @example
259
+ * When I find element by label text "Username"
260
+ *
261
+ * @remarks
262
+ * This step uses `page.getByLabel` to find an element associated with a given
263
+ * label text (e.g., using a `<label for="...">` or wrapping the input).
264
+ * It stores the result in {@link CustomWorld.element | this.element}.
265
+ * An `expect` assertion is included to ensure exactly one element is found.
266
+ */
267
+ async function When_I_find_element_by_label_text(label) {
268
+ this.element = this.page.getByLabel(label);
269
+ await (0, test_1.expect)(this.element).toHaveCount(1);
270
+ }
271
+ (0, cucumber_1.When)("I find element by label text {string}", When_I_find_element_by_label_text);
272
+ /**
273
+ * Finds all elements by label text and stores them as the current locator.
274
+ *
275
+ * ```gherkin
276
+ * When I find elements by label text {string}
277
+ * ```
278
+ *
279
+ * @example
280
+ * When I find elements by label text "Username"
281
+ *
282
+ * @remarks
283
+ * This step sets the {@link CustomWorld.currentLocator | currentLocator} to a locator
284
+ * representing all elements associated with the given label text. This is useful
285
+ * for scenarios where multiple inputs might share a similar label.
286
+ */
287
+ async function When_I_find_elements_by_label_text(label) {
288
+ this.currentLocator = this.getScope().getByLabel(label);
289
+ }
290
+ (0, cucumber_1.When)("I find elements by label text {string}", When_I_find_elements_by_label_text);
291
+ /**
292
+ * Finds an element by its alt text and stores it as the current element.
293
+ *
294
+ * ```gherkin
295
+ * When I find element by alt text {string}
296
+ * ```
297
+ *
298
+ * @example
299
+ * When I find element by alt text "Logo"
300
+ *
301
+ * @remarks
302
+ * This step uses `page.getByAltText` to find elements, typically images,
303
+ * based on their `alt` attribute. It stores the result in {@link CustomWorld.element | this.element}.
304
+ * An `expect` assertion is included to ensure exactly one element is found.
305
+ */
306
+ async function When_I_find_element_by_alt_text(alt) {
307
+ this.element = this.page.getByAltText(alt);
308
+ await (0, test_1.expect)(this.element).toHaveCount(1);
309
+ }
310
+ (0, cucumber_1.When)("I find element by alt text {string}", When_I_find_element_by_alt_text);
311
+ /**
312
+ * Finds an input element by its name attribute and stores it as the current element.
313
+ *
314
+ * ```gherkin
315
+ * When I find element by name {string}
316
+ * ```
317
+ *
318
+ * @example
319
+ * When I find element by name "email"
320
+ *
321
+ * @remarks
322
+ * This step uses `page.getByRole("textbox", { name })` to specifically find an input
323
+ * element (or similar interactive element) with the given `name` attribute.
324
+ * It stores the result in {@link CustomWorld.element | this.element}.
325
+ * An `expect` assertion is included to ensure exactly one element is found.
326
+ */
327
+ async function When_I_find_element_by_name(name) {
328
+ this.element = this.page.getByRole("textbox", { name });
329
+ await (0, test_1.expect)(this.element).toHaveCount(1);
330
+ }
331
+ (0, cucumber_1.When)("I find element by name {string}", When_I_find_element_by_name);
332
+ /**
333
+ * Finds all elements by name attribute and stores them as the current locator.
334
+ *
335
+ * ```gherkin
336
+ * When I find elements by name {string}
337
+ * ```
338
+ *
339
+ * @example
340
+ * When I find elements by name "email"
341
+ *
342
+ * @remarks
343
+ * This step sets the {@link CustomWorld.currentLocator | currentLocator} to a CSS locator
344
+ * targeting all elements with the specified `name` attribute.
345
+ */
346
+ async function When_I_find_elements_by_name(name) {
347
+ this.currentLocator = this.getScope().locator(`[name="${name}"]`);
348
+ }
349
+ (0, cucumber_1.When)("I find elements by name {string}", When_I_find_elements_by_name);
350
+ /**
351
+ * Finds all buttons by text (supports alias) and stores them as elements.
352
+ *
353
+ * ```gherkin
354
+ * When I find buttons by text {string}
355
+ * ```
356
+ *
357
+ * @example
358
+ * When I find buttons by text "Save"
359
+ * When I find buttons by text "@buttonAlias"
360
+ *
361
+ * @remarks
362
+ * This step uses `page.getByRole("button", { name })` to find all buttons
363
+ * matching the provided text. It supports resolving an alias from `this.data`.
364
+ * The result is stored in {@link CustomWorld.elements | this.elements}.
365
+ */
366
+ async function When_I_find_buttons_by_text(buttonText) {
367
+ // 🧠 Resolve alias
368
+ if (buttonText.startsWith("@")) {
369
+ const alias = buttonText.slice(1);
370
+ buttonText = this.data?.[alias];
371
+ if (!buttonText) {
372
+ throw new Error(`No value found for alias "@${alias}"`);
373
+ }
374
+ }
375
+ // 🔍 Locate all matching buttons
376
+ this.elements = this.page.getByRole("button", {
377
+ name: buttonText,
378
+ exact: false,
379
+ });
380
+ this.log?.(`🔘 Stored all buttons matching text "${buttonText}"`);
381
+ }
382
+ (0, cucumber_1.When)("I find buttons by text {string}", When_I_find_buttons_by_text);
383
+ // =============================
384
+ // WHEN I GET ELEMENT(S)
385
+ // =============================
386
+ /**
387
+ * Gets the first element matching the selector and stores it as the current element.
388
+ *
389
+ * ```gherkin
390
+ * When I get element by selector {string}
391
+ * ```
392
+ *
393
+ * @example
394
+ * When I get element by selector ".item"
395
+ *
396
+ * @remarks
397
+ * This step targets a single element using a CSS selector and sets it as the
398
+ * {@link CustomWorld.element | current element}. It's useful when you expect only
399
+ * one element to match or you only need the first one.
400
+ */
401
+ async function When_I_get_element_by_selector(selector) {
402
+ this.element = this.page.locator(selector).first();
403
+ }
404
+ (0, cucumber_1.When)("I get element by selector {string}", When_I_get_element_by_selector);
405
+ /**
406
+ * Gets all elements matching the selector and stores them.
407
+ *
408
+ * ```gherkin
409
+ * When I get elements by selector {string}
410
+ * ```
411
+ *
412
+ * @example
413
+ * When I get elements by selector ".item"
414
+ *
415
+ * @remarks
416
+ * This step sets the {@link CustomWorld.elements | elements} property to a
417
+ * Playwright `Locator` representing all elements that match the given CSS selector.
418
+ * You can then use other steps like "When I get first element" to work with specific items.
419
+ */
420
+ async function When_I_get_elements_by_selector(selector) {
421
+ this.elements = this.page.locator(selector);
422
+ }
423
+ (0, cucumber_1.When)("I get elements by selector {string}", When_I_get_elements_by_selector);
424
+ /**
425
+ * Gets the first element from the stored elements collection.
426
+ *
427
+ * ```gherkin
428
+ * When I get first element
429
+ * ```
430
+ *
431
+ * @example
432
+ * When I get first element
433
+ *
434
+ * @remarks
435
+ * This step requires a preceding step that populates {@link CustomWorld.elements | this.elements}
436
+ * (e.g., "When I find elements by selector"). It then selects the very first
437
+ * element from that collection and sets it as the {@link CustomWorld.element | current element}.
438
+ */
439
+ async function When_I_get_first_element() {
440
+ if (!this.elements)
441
+ throw new Error("No element collection found. Use a 'find elements' step first.");
442
+ this.element = this.elements.first();
443
+ }
444
+ (0, cucumber_1.When)("I get first element", When_I_get_first_element);
445
+ /**
446
+ * Gets the last element from the stored elements collection.
447
+ *
448
+ * ```gherkin
449
+ * When I get last element
450
+ * ```
451
+ *
452
+ * @example
453
+ * When I get last element
454
+ *
455
+ * @remarks
456
+ * This step requires a preceding step that populates {@link CustomWorld.elements | this.elements}
457
+ * (e.g., "When I find elements by selector"). It then selects the very last
458
+ * element from that collection and sets it as the {@link CustomWorld.element | current element}.
459
+ */
460
+ async function When_I_get_last_element() {
461
+ if (!this.elements)
462
+ throw new Error("No element collection found. Use a 'find elements' step first.");
463
+ this.element = this.elements.last();
464
+ }
465
+ (0, cucumber_1.When)("I get last element", When_I_get_last_element);
466
+ /**
467
+ * Gets the nth element (1-based index) from the stored elements.
468
+ *
469
+ * ```gherkin
470
+ * When I get {int}st element
471
+ * When I get {int}nd element
472
+ * When I get {int}rd element
473
+ * When I get {int}th element
474
+ * ```
475
+ *
476
+ * @example
477
+ * When I get 2nd element
478
+ *
479
+ * @remarks
480
+ * This step requires a preceding step that populates {@link CustomWorld.elements | this.elements}
481
+ * (e.g., "When I find elements by selector"). It then selects the element at the
482
+ * specified 1-based index from that collection and sets it as the {@link CustomWorld.element | current element}.
483
+ * Error handling is included for out-of-bounds indices.
484
+ */
485
+ async function When_I_get_nth_element(index) {
486
+ if (!this.elements)
487
+ throw new Error("No elements stored to pick from. Use a 'find elements' step first.");
488
+ const count = await this.elements.count();
489
+ if (index < 1 || index > count) {
490
+ throw new Error(`Cannot get element ${index} — only ${count} found.`);
491
+ }
492
+ this.element = this.elements.nth(index - 1); // Playwright is 0-based
493
+ this.log?.(`Selected ${index} element from stored elements`);
494
+ }
495
+ (0, cucumber_1.When)(/^I get (\d+)(?:st|nd|rd|th) element$/, When_I_get_nth_element);
496
+ /**
497
+ * Finds all elements by role and stores them in the elements collection.
498
+ *
499
+ * ```gherkin
500
+ * When I find elements by role {string}
501
+ * ```
502
+ *
503
+ * @example
504
+ * When I find elements by role "button"
505
+ *
506
+ * @remarks
507
+ * This step uses `page.getByRole` to find all elements with a specific ARIA role
508
+ * and stores them in {@link CustomWorld.elements | this.elements}.
509
+ * It includes a check to ensure at least one element is found.
510
+ */
511
+ async function When_I_find_elements_by_role(role) {
512
+ const locator = this.page.getByRole(role);
513
+ const count = await locator.count();
514
+ if (count === 0) {
515
+ throw new Error(`No elements found with role "${role}".`);
516
+ }
517
+ this.elements = locator;
518
+ this.log?.(`Stored ${count} elements with role "${role}"`);
519
+ }
520
+ (0, cucumber_1.When)("I find elements by role {string}", When_I_find_elements_by_role);
521
+ /**
522
+ * Gets the nth element (0-based index) from the stored elements.
523
+ *
524
+ * ```gherkin
525
+ * When I get {int}rd element
526
+ * ```
527
+ *
528
+ * @example
529
+ * When I get 3rd element
530
+ *
531
+ * @remarks
532
+ * This step requires a preceding step that populates {@link CustomWorld.elements | this.elements}.
533
+ * It selects the element at the specified **0-based index** from the collection
534
+ * and sets it as the {@link CustomWorld.element | current element}.
535
+ *
536
+ * **Note:** Consider using `When I get {int}(?:st|nd|rd|th) element` for a 1-based index
537
+ * which is often more user-friendly in Gherkin.
538
+ */
539
+ async function When_I_get_int_rd_element(index) {
540
+ if (!this.elements)
541
+ throw new Error("No element collection found. Use a 'find elements' step first.");
542
+ this.element = this.elements.nth(index);
543
+ }
544
+ (0, cucumber_1.When)("I get {int}rd element", When_I_get_int_rd_element); // This step pattern is a bit specific; the regex-based one is more general.
545
+ /**
546
+ * Gets the currently focused element and stores it as the current element.
547
+ *
548
+ * ```gherkin
549
+ * When I get focused element
550
+ * ```
551
+ *
552
+ * @example
553
+ * When I get focused element
554
+ *
555
+ * @remarks
556
+ * This step uses `page.evaluateHandle` to find the `document.activeElement`
557
+ * (the currently focused element in the browser DOM) and sets it as the
558
+ * {@link CustomWorld.element | current element}. This is useful for testing focus management.
559
+ */
560
+ async function When_I_get_focused_element() {
561
+ this.element = (await this.page.evaluateHandle(() => document.activeElement));
562
+ }
563
+ (0, cucumber_1.When)("I get focused element", When_I_get_focused_element);
564
+ /**
565
+ * Stores the text content of the current element as an alias in the test data.
566
+ *
567
+ * ```gherkin
568
+ * When I store element text as {string}
569
+ * ```
570
+ *
571
+ * @example
572
+ * When I store element text as "greeting"
573
+ *
574
+ * @remarks
575
+ * This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
576
+ * It retrieves the `textContent` of that element and stores it in
577
+ * {@link CustomWorld.data | this.data} under the provided alias, allowing it to be
578
+ * reused in subsequent steps (e.g., in assertions or input fields).
579
+ */
580
+ async function When_I_store_element_text_as(alias) {
581
+ const element = this.element;
582
+ if (!element)
583
+ throw new Error("No element selected. Use a 'find element' step first.");
584
+ const text = await element.textContent();
585
+ this.data[alias] = text?.trim();
586
+ this.log?.(`Stored text "${text}" as "${alias}"`);
587
+ }
588
+ (0, cucumber_1.When)("I store element text as {string}", When_I_store_element_text_as);
589
+ // =============================
590
+ // WHEN I FIND TEXTAREA(S)
591
+ // =============================
592
+ /**
593
+ * Finds a textarea by its label text and stores it as the current element.
594
+ *
595
+ * ```gherkin
596
+ * When I find textarea by label text {string}
597
+ * ```
598
+ *
599
+ * @example
600
+ * When I find textarea by label text "Description"
601
+ *
602
+ * @remarks
603
+ * This step uses Playwright's `getByLabel` to locate a textarea associated
604
+ * with the given label text. It sets the found textarea as the
605
+ * {@link CustomWorld.element | current element}.
606
+ */
607
+ async function When_I_find_textarea_by_label_text(label) {
608
+ this.element = this.page.getByLabel(label);
609
+ this.log?.(`Stored textarea with label "${label}"`);
610
+ }
611
+ (0, cucumber_1.When)("I find textarea by label text {string}", When_I_find_textarea_by_label_text);
612
+ /**
613
+ * Finds a textarea by its placeholder text and stores it as the current element.
614
+ *
615
+ * ```gherkin
616
+ * When I find textarea by placeholder text {string}
617
+ * ```
618
+ *
619
+ * @example
620
+ * When I find textarea by placeholder text "Type here"
621
+ *
622
+ * @remarks
623
+ * This step uses Playwright's `getByPlaceholder` to locate a textarea
624
+ * based on its `placeholder` attribute. It sets the found textarea as the
625
+ * {@link CustomWorld.element | current element}.
626
+ */
627
+ async function When_I_find_textarea_by_placeholder_text(placeholder) {
628
+ this.element = this.page.getByPlaceholder(placeholder);
629
+ this.log?.(`Stored textarea with placeholder "${placeholder}"`);
630
+ }
631
+ (0, cucumber_1.When)("I find textarea by placeholder text {string}", When_I_find_textarea_by_placeholder_text);
632
+ /**
633
+ * Finds all textareas by label text and stores them as elements.
634
+ *
635
+ * ```gherkin
636
+ * When I find textareas by label text {string}
637
+ * ```
638
+ *
639
+ * @example
640
+ * When I find textareas by label text "Comment"
641
+ *
642
+ * @remarks
643
+ * This step uses a CSS selector to find all textareas associated with the
644
+ * given label text and stores them in the {@link CustomWorld.elements | elements}
645
+ * collection.
646
+ */
647
+ async function When_I_find_textareas_by_label_text(label) {
648
+ this.elements = this.page.locator(`label:has-text("${label}") + textarea`);
649
+ this.log?.(`Stored multiple textareas with label "${label}"`);
650
+ }
651
+ (0, cucumber_1.When)("I find textareas by label text {string}", When_I_find_textareas_by_label_text);
652
+ /**
653
+ * Finds a textarea by its name attribute and stores it as the current element.
654
+ *
655
+ * ```gherkin
656
+ * When I find textarea by name {string}
657
+ * ```
658
+ *
659
+ * @example
660
+ * When I find textarea by name "bio"
661
+ *
662
+ * @remarks
663
+ * This step uses a CSS selector to locate a textarea based on its `name` attribute.
664
+ * It sets the found textarea as the {@link CustomWorld.element | current element}.
665
+ */
666
+ async function When_I_find_textarea_by_name(name) {
667
+ this.element = this.page.locator(`textarea[name="${name}"]`);
668
+ this.log?.(`Stored textarea with name "${name}"`);
669
+ }
670
+ (0, cucumber_1.When)("I find textarea by name {string}", When_I_find_textarea_by_name);
671
+ /**
672
+ * Finds all textareas by ID and stores them as elements.
673
+ *
674
+ * ```gherkin
675
+ * When I find textareas by ID {string}
676
+ * ```
677
+ *
678
+ * @example
679
+ * When I find textareas by ID "my-textarea"
680
+ *
681
+ * @remarks
682
+ * This step uses a CSS selector to find all textareas with the specified ID
683
+ * and stores them in the {@link CustomWorld.elements | elements} collection.
684
+ */
685
+ async function When_I_find_textareas_by_ID(id) {
686
+ this.elements = this.page.locator(`textarea#${id}`);
687
+ this.log?.(`Stored multiple textareas with ID "${id}"`);
688
+ }
689
+ (0, cucumber_1.When)("I find textareas by ID {string}", When_I_find_textareas_by_ID);
690
+ /**
691
+ * Finds all textareas by placeholder text and stores them as elements.
692
+ *
693
+ * ```gherkin
694
+ * When I find textareas by placeholder text {string}
695
+ * ```
696
+ *
697
+ * @example
698
+ * When I find textareas by placeholder text "Type here"
699
+ *
700
+ * @remarks
701
+ * This step uses a CSS selector to find all textareas with the specified
702
+ * `placeholder` attribute and stores them in the {@link CustomWorld.elements | elements}
703
+ * collection.
704
+ */
705
+ async function When_I_find_textareas_by_placeholder_text_multiple(placeholder) {
706
+ this.elements = this.page.locator(`textarea[placeholder="${placeholder}"]`);
707
+ this.log?.(`Stored multiple textareas with placeholder "${placeholder}"`);
708
+ }
709
+ (0, cucumber_1.When)("I find textareas by placeholder text {string}", When_I_find_textareas_by_placeholder_text_multiple);
710
+ // =============================
711
+ // WHEN I FIND INPUT(S)
712
+ // =============================
713
+ /**
714
+ * Finds an input by its ID and stores it as the current element.
715
+ *
716
+ * ```gherkin
717
+ * When I find input by ID {string}
718
+ * ```
719
+ *
720
+ * @example
721
+ * When I find input by ID "email"
722
+ *
723
+ * @remarks
724
+ * This step uses a CSS selector to locate an input element by its ID.
725
+ * It sets the found input as the {@link CustomWorld.element | current element}.
726
+ */
727
+ async function When_I_find_input_by_ID(id) {
728
+ this.element = this.page.locator(`input#${id}`);
729
+ this.log?.(`Stored input with ID "${id}"`);
730
+ }
731
+ (0, cucumber_1.When)("I find input by ID {string}", When_I_find_input_by_ID);
732
+ /**
733
+ * Finds all inputs by ID and stores them as elements.
734
+ *
735
+ * ```gherkin
736
+ * When I find inputs by ID {string}
737
+ * ```
738
+ *
739
+ * @example
740
+ * When I find inputs by ID "email"
741
+ *
742
+ * @remarks
743
+ * This step uses a CSS selector to find all input elements with the specified ID
744
+ * and stores them in the {@link CustomWorld.elements | elements} collection.
745
+ */
746
+ async function When_I_find_inputs_by_ID(id) {
747
+ this.elements = this.page.locator(`input#${id}`);
748
+ this.log?.(`Stored multiple inputs with ID "${id}"`);
749
+ }
750
+ (0, cucumber_1.When)("I find inputs by ID {string}", When_I_find_inputs_by_ID);
751
+ /**
752
+ * Finds an input by its label text and stores it as the current element.
753
+ *
754
+ * ```gherkin
755
+ * When I find input by label text {string}
756
+ * ```
757
+ *
758
+ * @example
759
+ * When I find input by label text "Email"
760
+ *
761
+ * @remarks
762
+ * This step uses Playwright's `getByLabel` to locate an input associated
763
+ * with the given label text. It sets the found input as the
764
+ * {@link CustomWorld.element | current element}.
765
+ */
766
+ async function When_I_find_input_by_label_text(label) {
767
+ this.element = this.page.getByLabel(label);
768
+ this.log?.(`Stored input with label "${label}"`);
769
+ }
770
+ (0, cucumber_1.When)("I find input by label text {string}", When_I_find_input_by_label_text);
771
+ /**
772
+ * Finds an input by its name attribute and stores it as the current element.
773
+ *
774
+ * ```gherkin
775
+ * When I find input by name {string}
776
+ * ```
777
+ * * @example
778
+ * When I find input by name "username"
779
+ *
780
+ * @remarks
781
+ * This step uses a CSS selector to locate an input element based on its `name` attribute.
782
+ * It sets the found input as the {@link CustomWorld.element | current element}.
783
+ */
784
+ async function When_I_find_input_by_name(name) {
785
+ this.element = this.page.locator(`input[name="${name}"]`);
786
+ this.log?.(`Stored input with name "${name}"`);
787
+ }
788
+ (0, cucumber_1.When)("I find input by name {string}", When_I_find_input_by_name);
789
+ /**
790
+ * Finds an input by its placeholder text and stores it as the current element.
791
+ *
792
+ * ```gherkin
793
+ * When I find input by placeholder text {string}
794
+ * ```
795
+ *
796
+ * @example
797
+ * When I find input by placeholder text "Enter your email"
798
+ *
799
+ * @remarks
800
+ * This step uses Playwright's `getByPlaceholder` to locate an input
801
+ * based on its `placeholder` attribute. It sets the found input as the
802
+ * {@link CustomWorld.element | current element}.
803
+ */
804
+ async function When_I_find_input_by_placeholder_text(placeholder) {
805
+ this.element = this.page.getByPlaceholder(placeholder);
806
+ this.log?.(`Stored input with placeholder "${placeholder}"`);
807
+ }
808
+ (0, cucumber_1.When)("I find input by placeholder text {string}", When_I_find_input_by_placeholder_text);
809
+ /**
810
+ * Finds all inputs by name attribute and stores them as elements.
811
+ *
812
+ * ```gherkin
813
+ * When I find inputs by name {string}
814
+ * ```
815
+ *
816
+ * @example
817
+ * When I find inputs by name "username"
818
+ *
819
+ * @remarks
820
+ * This step uses a CSS selector to find all input elements with the specified
821
+ * `name` attribute and stores them in the {@link CustomWorld.elements | elements}
822
+ * collection.
823
+ */
824
+ async function When_I_find_inputs_by_name_multiple(name) {
825
+ this.elements = this.page.locator(`input[name="${name}"]`);
826
+ this.log?.(`Stored multiple inputs with name "${name}"`);
827
+ }
828
+ (0, cucumber_1.When)("I find inputs by name {string}", When_I_find_inputs_by_name_multiple);
829
+ /**
830
+ * Finds all inputs by placeholder text and stores them as elements.
831
+ *
832
+ * ```gherkin
833
+ * When I find inputs by placeholder text {string}
834
+ * ```
835
+ *
836
+ * @example
837
+ * When I find inputs by placeholder text "Search"
838
+ *
839
+ * @remarks
840
+ * This step uses a CSS selector to find all input elements with the specified
841
+ * `placeholder` attribute and stores them in the {@link CustomWorld.elements | elements}
842
+ * collection.
843
+ */
844
+ async function When_I_find_inputs_by_placeholder_text_multiple(placeholder) {
845
+ this.elements = this.page.locator(`input[placeholder="${placeholder}"]`);
846
+ this.log?.(`Stored multiple inputs with placeholder "${placeholder}"`);
847
+ }
848
+ (0, cucumber_1.When)("I find inputs by placeholder text {string}", When_I_find_inputs_by_placeholder_text_multiple);
849
+ /**
850
+ * Finds all inputs by label text and stores them as elements.
851
+ *
852
+ * ```gherkin
853
+ * When I find inputs by label text {string}
854
+ * ```
855
+ *
856
+ * @example
857
+ * When I find inputs by label text "Email"
858
+ *
859
+ * @remarks
860
+ * This step uses a CSS selector to find all input elements associated with the
861
+ * given label text and stores them in the {@link CustomWorld.elements | elements}
862
+ * collection.
863
+ */
864
+ async function When_I_find_inputs_by_label_text_multiple(label) {
865
+ this.elements = this.page.locator(`label:has-text("${label}") + input`);
866
+ this.log?.(`Stored multiple inputs with label "${label}"`);
867
+ }
868
+ (0, cucumber_1.When)("I find inputs by label text {string}", When_I_find_inputs_by_label_text_multiple);
869
+ /**
870
+ * Finds all inputs by display value (supports alias) and stores them as elements.
871
+ *
872
+ * ```gherkin
873
+ * When I find inputs by display value {string}
874
+ * ```
875
+ *
876
+ * @example
877
+ * When I find inputs by display value "John"
878
+ * When I find inputs by display value "@userName"
879
+ *
880
+ * @remarks
881
+ * This step searches for all input elements whose `value` attribute matches
882
+ * the provided text or resolved alias. The matching inputs are stored in the
883
+ * {@link CustomWorld.elements | elements} collection.
884
+ */
885
+ async function When_I_find_inputs_by_display_value_multiple(value) {
886
+ // 🧠 Handle alias
887
+ if (value.startsWith("@")) {
888
+ const alias = value.slice(1);
889
+ value = this.data?.[alias];
890
+ if (!value) {
891
+ throw new Error(`No value found for alias "@${alias}".`);
892
+ }
893
+ }
894
+ // 🔍 Find all matching inputs
895
+ this.elements = this.page.locator(`input[value="${value}"]`);
896
+ this.log?.(`📦 Stored multiple inputs with display value "${value}"`);
897
+ }
898
+ (0, cucumber_1.When)("I find inputs by display value {string}", When_I_find_inputs_by_display_value_multiple);
899
+ /**
900
+ * Finds an input by display value (supports alias) and stores it as the current element.
901
+ *
902
+ * ```gherkin
903
+ * When I find input by display value {string}
904
+ * ```
905
+ *
906
+ * @example
907
+ * When I find input by display value "John"
908
+ * When I find input by display value "@userName"
909
+ *
910
+ * @remarks
911
+ * This step searches for a single input element whose `value` attribute matches
912
+ * the provided text or resolved alias. It sets the found input as the
913
+ * {@link CustomWorld.element | current element}. An `expect` assertion
914
+ * is included to ensure the element is visible.
915
+ */
916
+ async function When_I_find_input_by_display_value(value) {
917
+ // 🧠 Handle alias
918
+ if (value.startsWith("@")) {
919
+ const alias = value.slice(1);
920
+ value = this.data?.[alias];
921
+ if (!value) {
922
+ throw new Error(`No value found for alias "@${alias}".`);
923
+ }
924
+ }
925
+ // 🎯 Try to find input element with matching display value
926
+ const locator = this.page.locator(`input[value="${value}"]`);
927
+ await (0, test_1.expect)(locator).toBeVisible({ timeout: 5000 });
928
+ this.element = locator;
929
+ this.log?.(`🔍 Found input with value: "${value}"`);
930
+ }
931
+ (0, cucumber_1.When)("I find input by display value {string}", When_I_find_input_by_display_value);