@playq/core 0.2.77

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 (225) hide show
  1. package/README.md +41 -0
  2. package/bin/playq.js +175 -0
  3. package/cucumber.js +10 -0
  4. package/dist/exec/featureFileCache.d.ts +21 -0
  5. package/dist/exec/featureFileCache.js +124 -0
  6. package/dist/exec/featureFilePreProcess.d.ts +12 -0
  7. package/dist/exec/featureFilePreProcess.js +208 -0
  8. package/dist/exec/preLoader.d.ts +1 -0
  9. package/dist/exec/preLoader.js +72 -0
  10. package/dist/exec/preProcessEntry.d.ts +1 -0
  11. package/dist/exec/preProcessEntry.js +83 -0
  12. package/dist/exec/preProcess_old_todelete.d.ts +1 -0
  13. package/dist/exec/preProcess_old_todelete.js +258 -0
  14. package/dist/exec/runner.d.ts +1 -0
  15. package/dist/exec/runner.js +221 -0
  16. package/dist/exec/runner_orchestrator.d.ts +1 -0
  17. package/dist/exec/runner_orchestrator.js +85 -0
  18. package/dist/exec/sgGenerator.d.ts +11 -0
  19. package/dist/exec/sgGenerator.js +310 -0
  20. package/dist/global.d.ts +15 -0
  21. package/dist/global.js +185 -0
  22. package/dist/helper/actions/api/apiRequestActions.d.ts +117 -0
  23. package/dist/helper/actions/api/apiRequestActions.js +374 -0
  24. package/dist/helper/actions/api/apiValidationActions.d.ts +119 -0
  25. package/dist/helper/actions/api/apiValidationActions.js +615 -0
  26. package/dist/helper/actions/apiActions.d.ts +18 -0
  27. package/dist/helper/actions/apiActions.js +34 -0
  28. package/dist/helper/actions/apiStepDefs.d.ts +1 -0
  29. package/dist/helper/actions/apiStepDefs.js +64 -0
  30. package/dist/helper/actions/comm/commonActions.d.ts +58 -0
  31. package/dist/helper/actions/comm/commonActions.js +198 -0
  32. package/dist/helper/actions/comm/utilityActions.d.ts +131 -0
  33. package/dist/helper/actions/comm/utilityActions.js +351 -0
  34. package/dist/helper/actions/commActions.d.ts +18 -0
  35. package/dist/helper/actions/commActions.js +34 -0
  36. package/dist/helper/actions/commStepDefs.d.ts +1 -0
  37. package/dist/helper/actions/commStepDefs.js +57 -0
  38. package/dist/helper/actions/stepGroupStepDefs.d.ts +1 -0
  39. package/dist/helper/actions/stepGroupStepDefs.js +15 -0
  40. package/dist/helper/actions/web/alertActions.d.ts +61 -0
  41. package/dist/helper/actions/web/alertActions.js +224 -0
  42. package/dist/helper/actions/web/cookieActions.d.ts +45 -0
  43. package/dist/helper/actions/web/cookieActions.js +186 -0
  44. package/dist/helper/actions/web/downloadActions.d.ts +40 -0
  45. package/dist/helper/actions/web/downloadActions.js +153 -0
  46. package/dist/helper/actions/web/elementReaderActions.d.ts +95 -0
  47. package/dist/helper/actions/web/elementReaderActions.js +326 -0
  48. package/dist/helper/actions/web/formActions.d.ts +122 -0
  49. package/dist/helper/actions/web/formActions.js +423 -0
  50. package/dist/helper/actions/web/iframeActions.d.ts +23 -0
  51. package/dist/helper/actions/web/iframeActions.js +108 -0
  52. package/dist/helper/actions/web/javascriptActions.d.ts +14 -0
  53. package/dist/helper/actions/web/javascriptActions.js +77 -0
  54. package/dist/helper/actions/web/keyboardActions.d.ts +35 -0
  55. package/dist/helper/actions/web/keyboardActions.js +118 -0
  56. package/dist/helper/actions/web/localStorageActions.d.ts +51 -0
  57. package/dist/helper/actions/web/localStorageActions.js +163 -0
  58. package/dist/helper/actions/web/mouseActions.d.ts +240 -0
  59. package/dist/helper/actions/web/mouseActions.js +609 -0
  60. package/dist/helper/actions/web/reportingActions.d.ts +34 -0
  61. package/dist/helper/actions/web/reportingActions.js +58 -0
  62. package/dist/helper/actions/web/screenshotActions.d.ts +34 -0
  63. package/dist/helper/actions/web/screenshotActions.js +151 -0
  64. package/dist/helper/actions/web/testDataActions.d.ts +21 -0
  65. package/dist/helper/actions/web/testDataActions.js +211 -0
  66. package/dist/helper/actions/web/validationActions.d.ts +547 -0
  67. package/dist/helper/actions/web/validationActions.js +1754 -0
  68. package/dist/helper/actions/web/waitActions.d.ts +191 -0
  69. package/dist/helper/actions/web/waitActions.js +589 -0
  70. package/dist/helper/actions/web/webNavigation.d.ts +104 -0
  71. package/dist/helper/actions/web/webNavigation.js +288 -0
  72. package/dist/helper/actions/webActions.d.ts +32 -0
  73. package/dist/helper/actions/webActions.js +48 -0
  74. package/dist/helper/actions/webStepDefs.d.ts +1 -0
  75. package/dist/helper/actions/webStepDefs.js +455 -0
  76. package/dist/helper/browsers/browserManager.d.ts +1 -0
  77. package/dist/helper/browsers/browserManager.js +56 -0
  78. package/dist/helper/bundle/defaultEntries.d.ts +6 -0
  79. package/dist/helper/bundle/defaultEntries.js +200 -0
  80. package/dist/helper/bundle/env.d.ts +1 -0
  81. package/dist/helper/bundle/env.js +157 -0
  82. package/dist/helper/bundle/vars.d.ts +9 -0
  83. package/dist/helper/bundle/vars.js +375 -0
  84. package/dist/helper/faker/customFaker.d.ts +55 -0
  85. package/dist/helper/faker/customFaker.js +45 -0
  86. package/dist/helper/faker/modules/data/postcodes_valid_sg.json +17 -0
  87. package/dist/helper/faker/modules/dateTime.d.ts +18 -0
  88. package/dist/helper/faker/modules/dateTime.js +106 -0
  89. package/dist/helper/faker/modules/mobile.d.ts +4 -0
  90. package/dist/helper/faker/modules/mobile.js +59 -0
  91. package/dist/helper/faker/modules/nric.d.ts +32 -0
  92. package/dist/helper/faker/modules/nric.js +84 -0
  93. package/dist/helper/faker/modules/passport.d.ts +3 -0
  94. package/dist/helper/faker/modules/passport.js +36 -0
  95. package/dist/helper/faker/modules/person.d.ts +14 -0
  96. package/dist/helper/faker/modules/person.js +73 -0
  97. package/dist/helper/faker/modules/postcode.d.ts +6 -0
  98. package/dist/helper/faker/modules/postcode.js +47 -0
  99. package/dist/helper/fixtures/locAggregate.d.ts +7 -0
  100. package/dist/helper/fixtures/locAggregate.js +94 -0
  101. package/dist/helper/fixtures/logFixture.d.ts +8 -0
  102. package/dist/helper/fixtures/logFixture.js +56 -0
  103. package/dist/helper/fixtures/webFixture.d.ts +19 -0
  104. package/dist/helper/fixtures/webFixture.js +186 -0
  105. package/dist/helper/fixtures/webLocFixture.d.ts +2 -0
  106. package/dist/helper/fixtures/webLocFixture.js +144 -0
  107. package/dist/helper/report/allureStepLogger.d.ts +0 -0
  108. package/dist/helper/report/allureStepLogger.js +25 -0
  109. package/dist/helper/report/customiseReport.d.ts +1 -0
  110. package/dist/helper/report/customiseReport.js +55 -0
  111. package/dist/helper/report/init.d.ts +1 -0
  112. package/dist/helper/report/init.js +14 -0
  113. package/dist/helper/report/report.d.ts +1 -0
  114. package/dist/helper/report/report.js +102 -0
  115. package/dist/helper/util/dataLoader.d.ts +10 -0
  116. package/dist/helper/util/dataLoader.js +73 -0
  117. package/dist/helper/util/logger.d.ts +4 -0
  118. package/dist/helper/util/logger.js +61 -0
  119. package/dist/helper/util/session/sessionUtil.d.ts +26 -0
  120. package/dist/helper/util/session/sessionUtil.js +729 -0
  121. package/dist/helper/util/stepHelpers.d.ts +2 -0
  122. package/dist/helper/util/stepHelpers.js +16 -0
  123. package/dist/helper/util/test-data/dataLoader.d.ts +7 -0
  124. package/dist/helper/util/test-data/dataLoader.js +145 -0
  125. package/dist/helper/util/test-data/dataTest.d.ts +10 -0
  126. package/dist/helper/util/test-data/dataTest.js +216 -0
  127. package/dist/helper/util/totp/totpHelper.d.ts +38 -0
  128. package/dist/helper/util/totp/totpHelper.js +117 -0
  129. package/dist/helper/util/utilities/cryptoUtil.d.ts +2 -0
  130. package/dist/helper/util/utilities/cryptoUtil.js +53 -0
  131. package/dist/helper/util/utilities/schemaGeneratorUtil.d.ts +2 -0
  132. package/dist/helper/util/utilities/schemaGeneratorUtil.js +129 -0
  133. package/dist/helper/util/utils.d.ts +2 -0
  134. package/dist/helper/util/utils.js +22 -0
  135. package/dist/helper/wrapper/PlaywrightWrappers.d.ts +8 -0
  136. package/dist/helper/wrapper/PlaywrightWrappers.js +26 -0
  137. package/dist/helper/wrapper/assert.d.ts +9 -0
  138. package/dist/helper/wrapper/assert.js +23 -0
  139. package/dist/index.d.ts +7 -0
  140. package/dist/index.js +57 -0
  141. package/dist/scripts/get-versions.d.ts +1 -0
  142. package/dist/scripts/get-versions.js +98 -0
  143. package/dist/scripts/posttest.d.ts +1 -0
  144. package/dist/scripts/posttest.js +29 -0
  145. package/dist/scripts/pretest.d.ts +1 -0
  146. package/dist/scripts/pretest.js +57 -0
  147. package/dist/scripts/util.d.ts +1 -0
  148. package/dist/scripts/util.js +376 -0
  149. package/package.json +68 -0
  150. package/src/exec/featureFileCache.ts +80 -0
  151. package/src/exec/featureFilePreProcess.ts +239 -0
  152. package/src/exec/preLoader.ts +72 -0
  153. package/src/exec/preProcessEntry.ts +59 -0
  154. package/src/exec/preProcess_old_todelete.ts +289 -0
  155. package/src/exec/runner.ts +241 -0
  156. package/src/exec/runnerCuke.js +90 -0
  157. package/src/exec/runner_orchestrator.ts +91 -0
  158. package/src/exec/sgGenerator.ts +373 -0
  159. package/src/global.ts +130 -0
  160. package/src/helper/actions/api/apiRequestActions.ts +362 -0
  161. package/src/helper/actions/api/apiValidationActions.ts +594 -0
  162. package/src/helper/actions/apiActions.ts +18 -0
  163. package/src/helper/actions/apiStepDefs.ts +80 -0
  164. package/src/helper/actions/comm/commonActions.ts +165 -0
  165. package/src/helper/actions/comm/utilityActions.ts +344 -0
  166. package/src/helper/actions/commActions.ts +18 -0
  167. package/src/helper/actions/commStepDefs.ts +72 -0
  168. package/src/helper/actions/stepGroupStepDefs.ts +17 -0
  169. package/src/helper/actions/web/alertActions.ts +179 -0
  170. package/src/helper/actions/web/cookieActions.ts +124 -0
  171. package/src/helper/actions/web/downloadActions.ts +129 -0
  172. package/src/helper/actions/web/elementReaderActions.ts +323 -0
  173. package/src/helper/actions/web/formActions.ts +469 -0
  174. package/src/helper/actions/web/iframeActions.ts +67 -0
  175. package/src/helper/actions/web/javascriptActions.ts +38 -0
  176. package/src/helper/actions/web/keyboardActions.ts +101 -0
  177. package/src/helper/actions/web/localStorageActions.ts +109 -0
  178. package/src/helper/actions/web/mouseActions.ts +864 -0
  179. package/src/helper/actions/web/reportingActions.ts +53 -0
  180. package/src/helper/actions/web/screenshotActions.ts +124 -0
  181. package/src/helper/actions/web/testDataActions.ts +162 -0
  182. package/src/helper/actions/web/validationActions.ts +2287 -0
  183. package/src/helper/actions/web/waitActions.ts +757 -0
  184. package/src/helper/actions/web/webNavigation.ts +313 -0
  185. package/src/helper/actions/webActions.ts +33 -0
  186. package/src/helper/actions/webStepDefs.ts +505 -0
  187. package/src/helper/browsers/browserManager.ts +23 -0
  188. package/src/helper/bundle/defaultEntries.ts +208 -0
  189. package/src/helper/bundle/env.ts +119 -0
  190. package/src/helper/bundle/vars.ts +368 -0
  191. package/src/helper/faker/customFaker.ts +107 -0
  192. package/src/helper/faker/modules/data/postcodes_valid_sg.json +17 -0
  193. package/src/helper/faker/modules/dateTime.ts +121 -0
  194. package/src/helper/faker/modules/mobile.ts +58 -0
  195. package/src/helper/faker/modules/nric.ts +109 -0
  196. package/src/helper/faker/modules/passport.ts +34 -0
  197. package/src/helper/faker/modules/person.ts +93 -0
  198. package/src/helper/faker/modules/postcode.ts +57 -0
  199. package/src/helper/fixtures/locAggregate.ts +61 -0
  200. package/src/helper/fixtures/logFixture.ts +57 -0
  201. package/src/helper/fixtures/webFixture.ts +206 -0
  202. package/src/helper/fixtures/webLocFixture.ts +143 -0
  203. package/src/helper/report/allureStepLogger.ts +26 -0
  204. package/src/helper/report/customiseReport.ts +61 -0
  205. package/src/helper/report/init.ts +18 -0
  206. package/src/helper/report/report.ts +72 -0
  207. package/src/helper/util/dataLoader.ts +42 -0
  208. package/src/helper/util/logger.ts +32 -0
  209. package/src/helper/util/session/sessionUtil.ts +839 -0
  210. package/src/helper/util/stepHelpers.ts +14 -0
  211. package/src/helper/util/test-data/dataLoader.ts +108 -0
  212. package/src/helper/util/test-data/dataTest.ts +191 -0
  213. package/src/helper/util/test-data/registerUser.json +7 -0
  214. package/src/helper/util/totp/totpHelper.ts +102 -0
  215. package/src/helper/util/utilities/cryptoUtil.ts +53 -0
  216. package/src/helper/util/utilities/schemaGeneratorUtil.ts +143 -0
  217. package/src/helper/util/utils.ts +28 -0
  218. package/src/helper/wrapper/PlaywrightWrappers.ts +28 -0
  219. package/src/helper/wrapper/assert.ts +25 -0
  220. package/src/index.ts +17 -0
  221. package/src/scripts/get-versions.ts +68 -0
  222. package/src/scripts/posttest.ts +32 -0
  223. package/src/scripts/pretest.ts +48 -0
  224. package/src/scripts/util.ts +406 -0
  225. package/tsconfig.json +30 -0
@@ -0,0 +1,864 @@
1
+ /**
2
+ * @file mouseActions.ts
3
+ *
4
+ * Mouse interaction helpers for PlayQ web actions.
5
+ * Provides click/hover/drag/scroll utilities with runner-aware step wrappers,
6
+ * locator resolution, and screenshot options.
7
+ *
8
+ * Authors: PlayQ Team
9
+ * Version: v1.0.0
10
+ */
11
+ import * as allure from "allure-js-commons";
12
+ import { Page, Locator, BrowserContext } from "@playwright/test";
13
+ import { vars, webLocResolver } from "../../../global";
14
+ // no fs/path usage required in this module
15
+ import { waitForPageToLoad } from "./waitActions";
16
+ import { processScreenshot } from "./screenshotActions";
17
+ import { parseLooseJson } from '../../bundle/vars';
18
+ import { attachLog } from '../commActions';
19
+ // wait helpers provided via waitActions where needed
20
+ const config: any = {};
21
+ function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
22
+ const __allureAny_mouse: any = allure as any;
23
+ if (typeof __allureAny_mouse.step !== 'function') {
24
+ __allureAny_mouse.step = async (_name: string, fn: any) => await fn();
25
+ }
26
+ // Allure compatibility shim: if step is unavailable, just run the body
27
+ const __allureAny_web: any = allure as any;
28
+ if (typeof __allureAny_web.step !== 'function') {
29
+ __allureAny_web.step = async (_name: string, fn: any) => await fn();
30
+ }
31
+
32
+
33
+ /**
34
+ * Web: Click Element -field: {param} -options: {param}
35
+ *
36
+ * Clicks an element on the page using the given fieldType.
37
+ *
38
+ * @param page - Playwright Page instance
39
+ * @param field - Label, text, selector, or Locator
40
+ * @param options - Optional JSON string or object:
41
+ * - fieldType: [string] Field type to resolve (button | action | div | text | link etc.)
42
+ * - actionTimeout: [number] Timeout in ms
43
+ * - pattern: [string] PatternIQ config override
44
+ * - isDoubleClick: [boolean]
45
+ * - screenshot: [boolean]
46
+ * - screenshotBefore: [boolean]
47
+ * - screenshotText: [string]
48
+ * - screenshotFullPage: [boolean]
49
+ */
50
+ export async function click(
51
+ page: Page,
52
+ field: string | Locator,
53
+ options?: string | Record<string, any>
54
+ ) {
55
+ const options_json =
56
+ typeof options === "string" ? parseLooseJson(options) : options || {};
57
+
58
+ const {
59
+ fieldType = "button",
60
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
61
+ pattern,
62
+ isDoubleClick = false,
63
+ screenshot = false,
64
+ screenshotBefore = false,
65
+ screenshotText = "",
66
+ screenshotFullPage = true,
67
+ } = options_json;
68
+
69
+ if (isPlaywrightRunner()) {
70
+ await __allureAny_mouse.step(
71
+ `Web: Click -field: ${field} -fieldType: ${fieldType} -options: ${JSON.stringify(options_json)}`,
72
+ async () => {
73
+ await doClick();
74
+ }
75
+ );
76
+ } else {
77
+ await doClick();
78
+ }
79
+
80
+ async function doClick() {
81
+ if (!page) throw new Error("Page not initialized");
82
+
83
+ const target =
84
+ typeof field === "string"
85
+ ? await webLocResolver(
86
+ fieldType,
87
+ field,
88
+ page,
89
+ pattern,
90
+ actionTimeout,
91
+ "after"
92
+ )
93
+ : field;
94
+
95
+ await processScreenshot(
96
+ page,
97
+ screenshotBefore,
98
+ screenshotText,
99
+ screenshotFullPage
100
+ );
101
+
102
+ if (isDoubleClick) {
103
+ await target.dblclick();
104
+ } else {
105
+ await target.click();
106
+ }
107
+
108
+ await page.waitForLoadState("load");
109
+
110
+ await processScreenshot(
111
+ page,
112
+ screenshot,
113
+ screenshotText,
114
+ screenshotFullPage
115
+ );
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Web: Mouseover on link -field: {param} -options: {param}
121
+ *
122
+ * Performs a mouse hover over a link element on the page, identified by text, label, id, name, or pattern.
123
+ *
124
+ * @param field - The text, label, id, name, or selector of the link to hover over (e.g., "Account", "Login", "Help").
125
+ * @param options - Optional JSON string or object:
126
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
127
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
128
+ * - screenshot: [boolean] Capture a screenshot after hovering over the link. Default: false.
129
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
130
+ * - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
131
+ *
132
+ * @example
133
+ * Web: Mouseover on link -field: "{{top_menu}} My account" -options: "{screenshot: true, screenshotText: 'Hovered on My Account'}"
134
+ */
135
+ export async function mouseoverOnLink(
136
+ page: Page,
137
+ field: string | Locator,
138
+ options?: string | Record<string, any>
139
+ ) {
140
+ const resolvedField =
141
+ typeof field === "string" ? vars.replaceVariables(field) : undefined;
142
+ const options_json =
143
+ typeof options === "string" ? parseLooseJson(options) : options || {};
144
+ const {
145
+ actionTimeout,
146
+ pattern,
147
+ screenshot = false,
148
+ screenshotText = "",
149
+ screenshotFullPage = true,
150
+ } = options_json || {};
151
+
152
+ if (isPlaywrightRunner()) {
153
+ await __allureAny_mouse.step(
154
+ `Web: Mouseover on link -field: ${resolvedField || field
155
+ } -options: ${JSON.stringify(options_json)}`,
156
+ async () => {
157
+ await doMouseoverOnLink();
158
+ }
159
+ );
160
+ } else {
161
+ await doMouseoverOnLink();
162
+ }
163
+
164
+ async function doMouseoverOnLink() { }
165
+
166
+ if (!page) throw new Error("Page not initialized");
167
+
168
+ const target =
169
+ typeof field === "string"
170
+ ? await webLocResolver(
171
+ "link",
172
+ resolvedField,
173
+ page,
174
+ pattern,
175
+ actionTimeout
176
+ )
177
+ : field;
178
+
179
+ await target.hover();
180
+ await page.waitForLoadState("networkidle");
181
+
182
+ await processScreenshot(page, screenshot, screenshotText, screenshotFullPage);
183
+ }
184
+
185
+ /**
186
+ * Web: Mouseover on text -text: {param} -options: {param}
187
+ *
188
+ * Performs a mouse hover over an element identified by its visible text.
189
+ *
190
+ * @param page - Playwright Page instance
191
+ * @param text - The visible text of the element to hover over
192
+ * @param options - Optional string or object:
193
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
194
+ * - pattern: [string] Optional pattern to refine element search.
195
+ * - screenshot: [boolean] Capture a screenshot after hovering. Default: false.
196
+ * - screenshotText: [string] Description for the screenshot.
197
+ * - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
198
+ *
199
+ * @example
200
+ * Web: Mouseover on text -text: "Menu" -options: "{screenshot: true, screenshotText: 'Hovered on Menu'}"
201
+ */
202
+ export async function mouseoverOnText(
203
+ page: Page,
204
+ text: string,
205
+ options?: string | Record<string, any>
206
+ ) {
207
+ const resolvedText = vars.replaceVariables(text);
208
+ const options_json =
209
+ typeof options === "string" ? parseLooseJson(options) : options || {};
210
+ const {
211
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
212
+ pattern,
213
+ screenshot = false,
214
+ screenshotText = "",
215
+ screenshotFullPage = true,
216
+ } = options_json;
217
+
218
+ if (isPlaywrightRunner()) {
219
+ await __allureAny_mouse.step(
220
+ `Web: Mouseover on text -text: ${resolvedText} -options: ${JSON.stringify(options_json)}`,
221
+ async () => {
222
+ await doMouseoverOnText();
223
+ }
224
+ );
225
+ } else {
226
+ await doMouseoverOnText();
227
+ }
228
+
229
+ async function doMouseoverOnText() {
230
+ if (!page) throw new Error("Page not initialized");
231
+ // Use webLocResolver to find the element by text
232
+ const target = await webLocResolver(
233
+ "text",
234
+ resolvedText,
235
+ page,
236
+ pattern,
237
+ actionTimeout
238
+ );
239
+ await target.hover({ timeout: actionTimeout });
240
+ await processScreenshot(
241
+ page,
242
+ screenshot,
243
+ screenshotText || `Hovered on text: ${resolvedText}`,
244
+ screenshotFullPage
245
+ );
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Web: Click Button -field: {param} -options: {param}
251
+ *
252
+ * Clicks a button element on the page, identified by text, label, id, name, pattern, or locator.
253
+ *
254
+ * @param field - The label, text, id, name, or selector of the button to click (e.g., "Submit", "Save", "Cancel").
255
+ * @param options - Optional JSON string or object:
256
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured testExecution > actionTimeout or 10000 milliseconds.
257
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
258
+ * - screenshot: [boolean] Capture a screenshot after clicking the button. Default: false.
259
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
260
+ * - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
261
+ * - screenshotBefore: [boolean] Capture a screenshot before clicking. Default: false.
262
+ *
263
+ * @example
264
+ * Web: Click Button -field: "Register" -options: "{screenshot: true, screenshotText: 'After clicking Register'}"
265
+ */
266
+ export async function clickButton(
267
+ page: Page,
268
+ field: string | Locator,
269
+ options?: string | Record<string, any>
270
+ ) {
271
+ const options_json =
272
+ typeof options === "string" ? parseLooseJson(options) : options || {};
273
+ const {
274
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
275
+ pattern,
276
+ isDoubleClick = false,
277
+ screenshot = false,
278
+ screenshotText = "",
279
+ screenshotFullPage = true,
280
+ screenshotBefore = false,
281
+ } = options_json || {};
282
+
283
+ if (isPlaywrightRunner()) {
284
+ await __allureAny_mouse.step(
285
+ `Web: Click Button -field: ${field} -options: ${JSON.stringify(
286
+ options_json
287
+ )}`,
288
+ async () => {
289
+ await doClickButton();
290
+ }
291
+ );
292
+ } else {
293
+ await doClickButton();
294
+ }
295
+ async function doClickButton() {
296
+ if (!page) throw new Error("Page not initialized");
297
+ const target =
298
+ typeof field === "string"
299
+ ? await webLocResolver(
300
+ "button",
301
+ field,
302
+ page,
303
+ pattern,
304
+ actionTimeout,
305
+ "after"
306
+ )
307
+ : field;
308
+ await processScreenshot(
309
+ page,
310
+ screenshotBefore,
311
+ screenshotText,
312
+ screenshotFullPage
313
+ );
314
+ await target.click();
315
+ await page.waitForLoadState("load");
316
+
317
+ await processScreenshot(
318
+ page,
319
+ screenshot,
320
+ screenshotText,
321
+ screenshotFullPage
322
+ );
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Web: Click Link -field: {param} -options: {param}
328
+ *
329
+ * Clicks a link element on the page, identified by link text, label, id, name, or pattern.
330
+ *
331
+ * @param field - The text, label, id, name, or selector of the link to click (e.g., "Home", "Login", "Forgot Password").
332
+ * @param options - Optional JSON string or object:
333
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
334
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
335
+ * - screenshot: [boolean] Capture a screenshot after clicking the link. Default: false.
336
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
337
+ * - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
338
+ * - screenshotBefore: [boolean] Capture a screenshot before clicking. Default: false.
339
+ *
340
+ * @example
341
+ * Web: Click Link -field: "Register" -options: "{screenshot: true, screenshotText: 'After clicking Register'}"
342
+ */
343
+ export async function clickLink(
344
+ page: Page,
345
+ field: string | Locator,
346
+ options?: string | Record<string, any>
347
+ ) {
348
+ const options_json =
349
+ typeof options === "string" ? parseLooseJson(options) : options || {};
350
+ const {
351
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
352
+ pattern,
353
+ screenshot = false,
354
+ screenshotText = "",
355
+ screenshotFullPage = true,
356
+ screenshotBefore = false,
357
+ } = options_json || {};
358
+
359
+ if (isPlaywrightRunner()) {
360
+ await __allureAny_mouse.step(
361
+ `Web: Click Link -field: ${field} -options: ${JSON.stringify(
362
+ options_json
363
+ )}`,
364
+ async () => {
365
+ await doClickLink();
366
+ }
367
+ );
368
+ } else {
369
+ await doClickLink();
370
+ }
371
+
372
+ async function doClickLink() {
373
+ if (!page) throw new Error("Page not initialized");
374
+ await waitForPageToLoad(page, actionTimeout);
375
+ const target =
376
+ typeof field === "string"
377
+ ? await webLocResolver("link", field, page, pattern, actionTimeout)
378
+ : field;
379
+ await processScreenshot(
380
+ page,
381
+ screenshotBefore,
382
+ screenshotText,
383
+ screenshotFullPage
384
+ );
385
+ await target.click({ timeout: actionTimeout });
386
+
387
+ await processScreenshot(
388
+ page,
389
+ screenshot,
390
+ screenshotText,
391
+ screenshotFullPage
392
+ );
393
+ }
394
+ }
395
+
396
+ /**
397
+ * Web: Click tab -field: {param} -options: {param}
398
+ *
399
+ * Clicks a tab element on the page, identified by link text, label, id, name, or pattern.
400
+ *
401
+ * @param field - The text, label, id, name, or selector of the link to click (e.g., "Home", "Login", "Forgot Password").
402
+ * @param options - Optional JSON string or object:
403
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
404
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
405
+ * - screenshot: [boolean] Capture a screenshot after clicking the link. Default: false.
406
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
407
+ * - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
408
+ * - screenshotBefore: [boolean] Capture a screenshot before clicking. Default: false.
409
+ *
410
+ * @example
411
+ * Web: Click tab -field: "Register" -options: "{screenshot: true, screenshotText: 'After clicking Register'}"
412
+ */
413
+ export async function clickTab(
414
+ page: Page,
415
+ field: string | Locator,
416
+ options?: string | Record<string, any>
417
+ ) {
418
+ const options_json =
419
+ typeof options === "string" ? parseLooseJson(options) : options || {};
420
+ const {
421
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
422
+ pattern,
423
+ screenshot = false,
424
+ screenshotText = "",
425
+ screenshotFullPage = true,
426
+ screenshotBefore = false,
427
+ } = options_json || {};
428
+
429
+ if (isPlaywrightRunner()) {
430
+ await __allureAny_mouse.step(
431
+ `Web: Click Link -field: ${field} -options: ${JSON.stringify(
432
+ options_json
433
+ )}`,
434
+ async () => {
435
+ await doClickTab();
436
+ }
437
+ );
438
+ } else {
439
+ await doClickTab();
440
+ }
441
+
442
+ async function doClickTab() {
443
+ if (!page) throw new Error("Page not initialized");
444
+ await waitForPageToLoad(page, actionTimeout);
445
+ const target =
446
+ typeof field === "string"
447
+ ? await webLocResolver("tab", field, page, pattern, actionTimeout)
448
+ : field;
449
+ await processScreenshot(
450
+ page,
451
+ screenshotBefore,
452
+ screenshotText,
453
+ screenshotFullPage
454
+ );
455
+ await target.click({ timeout: actionTimeout });
456
+
457
+ await processScreenshot(
458
+ page,
459
+ screenshot,
460
+ screenshotText,
461
+ screenshotFullPage
462
+ );
463
+ }
464
+ }
465
+
466
+ /**
467
+ * Web: Click radio button -field: {param} -options: {param}
468
+ *
469
+ * Selects a radio button element on the page, identified by label, text, id, name, or pattern.
470
+ *
471
+ * @param field - The label, text, id, name, or selector of the radio button to select (e.g., "Yes", "No", "Subscribe").
472
+ * @param options - Optional JSON string or object:
473
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
474
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
475
+ * - force: [boolean] Force the action (e.g., ignore actionability checks). Default: true.
476
+ * - screenshot: [boolean] Capture a screenshot after selecting the radio button. Default: false.
477
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
478
+ * - screenshotFullPage: [boolean] Capture a full page screenshot. Default: true.
479
+ * - screenshotBefore: [boolean] Capture a screenshot before selecting the radio button. Default: false.
480
+ *
481
+ * @example
482
+ * Web: Click radio button -field: "{radio_group:: Newsletter} Yes" -options: "{screenshot: true, screenshotText: 'After selecting Yes for Newsletter'}"
483
+ */
484
+ export async function clickRadioButton(
485
+ page: Page,
486
+ field: string | Locator,
487
+ options?: string | Record<string, any>
488
+ ) {
489
+ const options_json =
490
+ typeof options === "string" ? parseLooseJson(options) : options || {};
491
+ const {
492
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
493
+ pattern,
494
+ force = true, // Playwright's force option
495
+ screenshot = false,
496
+ screenshotText = "",
497
+ screenshotFullPage = true,
498
+ screenshotBefore = false,
499
+ smartIQ_refreshLoc = "",
500
+ } = options_json || {};
501
+ if (isPlaywrightRunner()) {
502
+ await __allureAny_mouse.step(
503
+ `Web: Click radio button -field: ${field} -options: ${JSON.stringify(
504
+ options_json
505
+ )}`,
506
+ async () => {
507
+ await doClickRadioButton();
508
+ }
509
+ );
510
+ } else {
511
+ await doClickRadioButton();
512
+ }
513
+ async function doClickRadioButton() {
514
+ if (!page) throw new Error("Page not initialized");
515
+
516
+ const target =
517
+ typeof field === "string"
518
+ ? await webLocResolver(
519
+ "radio",
520
+ field,
521
+ page,
522
+ pattern,
523
+ smartIQ_refreshLoc
524
+ )
525
+ : field;
526
+
527
+ await processScreenshot(
528
+ page,
529
+ screenshotBefore,
530
+ screenshotText,
531
+ screenshotFullPage
532
+ );
533
+ await target.check({ force, timeout: actionTimeout }); // Playwright's API for selecting radio buttons
534
+ await processScreenshot(
535
+ page,
536
+ screenshot,
537
+ screenshotText,
538
+ screenshotFullPage
539
+ );
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Web: Click checkbox -field: {param} -options: {param}
545
+ *
546
+ * Selects a checkbox element on the page, identified by label, text, id, name, or pattern.
547
+ *
548
+ * @param field - The label, text, id, name, or selector of the checkbox to select (e.g., "Agree", "Subscribe").
549
+ * @param options - Optional JSON string or object:
550
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
551
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
552
+ * - force: [boolean] Force the action (e.g., ignore actionability checks). Default: true.
553
+ * - screenshot: [boolean] Capture a screenshot after selecting the checkbox. Default: false.
554
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
555
+ * - screenshotFullPage: [boolean] Capture a full page screenshot. Default: true.
556
+ * - screenshotBefore: [boolean] Capture a screenshot before selecting the checkbox. Default: false.
557
+ *
558
+ * @example
559
+ * Web: Click checkbox -field: "{checkbox_group:: Accept Terms} Agree" -options: "{screenshot: true, screenshotText: 'After selecting Agree for Accept Terms'}"
560
+ */
561
+ export async function clickCheckbox(
562
+ page: Page,
563
+ field: string | Locator,
564
+ options?: string | Record<string, any>
565
+ ) {
566
+ const options_json =
567
+ typeof options === "string" ? parseLooseJson(options) : options || {};
568
+ const {
569
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")),
570
+ pattern,
571
+ force = true, // Playwright's force option
572
+ screenshot = false,
573
+ screenshotText = "",
574
+ screenshotFullPage = true,
575
+ screenshotBefore = false,
576
+ smartIQ_refreshLoc = "",
577
+ } = options_json || {};
578
+
579
+ if (isPlaywrightRunner()) {
580
+ await __allureAny_mouse.step(
581
+ `Web: Click radio button -field: ${field} -options: ${JSON.stringify(
582
+ options_json
583
+ )}`,
584
+ async () => {
585
+ await doClickCheckbox();
586
+ }
587
+ );
588
+ } else {
589
+ await doClickCheckbox();
590
+ }
591
+
592
+ async function doClickCheckbox() {
593
+ if (!page) throw new Error("Page not initialized");
594
+
595
+ const target =
596
+ typeof field === "string"
597
+ ? await webLocResolver(
598
+ "checkbox",
599
+ field,
600
+ page,
601
+ pattern,
602
+ smartIQ_refreshLoc
603
+ )
604
+ : field;
605
+
606
+ await processScreenshot(
607
+ page,
608
+ screenshotBefore,
609
+ screenshotText,
610
+ screenshotFullPage
611
+ );
612
+ await target.check({ force, timeout: actionTimeout }); // Playwright's API for selecting radio buttons
613
+ await processScreenshot(
614
+ page,
615
+ screenshot,
616
+ screenshotText,
617
+ screenshotFullPage
618
+ );
619
+ }
620
+ }
621
+
622
+ /**
623
+ * Web: Click at Coordinates -x: {param} -y: {param} -options: {param}
624
+ *
625
+ * Clicks at the specified page coordinates (default: 0,0).
626
+ *
627
+ * @param page - Playwright Page instance
628
+ * @param x - X coordinate (default: 0)
629
+ * @param y - Y coordinate (default: 0)
630
+ * @param options - Optional string or object:
631
+ * - screenshot: [boolean] Capture screenshot after clicking (default: false)
632
+ * - screenshotText: [string] Description for screenshot
633
+ * - screenshotFullPage: [boolean] Full page screenshot (default: true)
634
+ *
635
+ * @example
636
+ * await clickAtCoordinates(page); // Clicks at (0,0)
637
+ * await clickAtCoordinates(page, 100, 200, { screenshot: true });
638
+ */
639
+ export async function clickAtCoordinates(
640
+ page: Page,
641
+ x: number = 0,
642
+ y: number = 0,
643
+ options?: string | Record<string, any>
644
+ ) {
645
+ const options_json =
646
+ typeof options === "string" ? parseLooseJson(options) : options || {};
647
+ const {
648
+ screenshot = false,
649
+ screenshotText = "",
650
+ screenshotFullPage = true,
651
+ } = options_json;
652
+
653
+ if (!page) throw new Error("Page not initialized");
654
+
655
+ if (isPlaywrightRunner()) {
656
+ await __allureAny_mouse.step(
657
+ `Web: Click at Coordinates -x: ${x} -y: ${y} -options: ${JSON.stringify(options_json)}`,
658
+ async () => {
659
+ await doClickAtCoordinates();
660
+ }
661
+ );
662
+ } else {
663
+ await doClickAtCoordinates();
664
+ }
665
+
666
+ async function doClickAtCoordinates() {
667
+ await page.mouse.click(x, y);
668
+ await attachLog(
669
+ `✅ Clicked at coordinates (${x}, ${y})`,
670
+ "text/plain"
671
+ );
672
+ await processScreenshot(
673
+ page,
674
+ screenshot,
675
+ screenshotText || `Clicked at coordinates (${x}, ${y})`,
676
+ screenshotFullPage
677
+ );
678
+ }
679
+ }
680
+
681
+
682
+ /**
683
+ * Web: Drag and Drop -source: {param} -target: {param} -options: {param}
684
+ *
685
+ * Drags an element from source to target location.
686
+ *
687
+ * @param page Playwright Page instance
688
+ * @param source The source element to drag (label, text, id, name, or selector).
689
+ * @param target The target element to drop onto (label, text, id, name, or selector).
690
+ * @param options Optional JSON string or object:
691
+ * - fieldType: [string] Type of the elements (e.g., "item", "icon"). Default: "".
692
+ * - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
693
+ * - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
694
+ * - screenshot: [boolean] Capture a screenshot after drag and drop. Default: false.
695
+ * - screenshotText: [string] Text description for the screenshot. Default: "".
696
+ * - screenshotFullPage: [boolean] Capture a full page screenshot. Default: true.
697
+ * - screenshotBefore: [boolean] Capture a screenshot before drag and drop. Default: false.
698
+ *
699
+ * @example
700
+ * Web: Drag and Drop -source: "Item A" -target: "Item B" -options: "{screenshot: true, screenshotText: 'After drag and drop'}"
701
+ */
702
+ export async function dragAndDrop(page: Page, source: string | Locator, target: string | Locator, options?: string | Record<string, any>) {
703
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
704
+ const src = typeof source === 'string'
705
+ ? await webLocResolver(options_json?.fieldType || '', source, page, options_json?.pattern, typeof options_json?.actionTimeout === 'number' ? options_json.actionTimeout : undefined, options_json?.smartAiRefresh || '')
706
+ : source;
707
+ const dst = typeof target === 'string'
708
+ ? await webLocResolver(options_json?.fieldType || '', target, page, options_json?.pattern, typeof options_json?.actionTimeout === 'number' ? options_json.actionTimeout : undefined, options_json?.smartAiRefresh || '')
709
+ : target;
710
+ const stepName = `Web: Drag And Drop -source: ${typeof source === 'string' ? source : '<locator>'} -target: ${typeof target === 'string' ? target : '<locator>'}`;
711
+ if (isPlaywrightRunner()) {
712
+ await __allureAny_mouse.step(stepName, async () => { await src.dragTo(dst); });
713
+ } else {
714
+ await src.dragTo(dst);
715
+ }
716
+ }
717
+
718
+ /**
719
+ * Web: Scroll To -x: {param} -y: {param} -options: {param}
720
+ *
721
+ * Scrolls the page to the specified x and y coordinates.
722
+ *
723
+ * @param page Playwright Page instance
724
+ * @param x The x-coordinate to scroll to.
725
+ * @param y The y-coordinate to scroll to.
726
+ * @param options Optional JSON string or object (reserved for future use).
727
+ *
728
+ * @example
729
+ * Web: Scroll To -x: 0 -y: 500 -options: "{}"
730
+ */
731
+ export async function scrollTo(page: Page, x: number, y: number, options?: string | Record<string, any>) {
732
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
733
+ const stepName = `Web: Scroll To -x: ${x} -y: ${y}`;
734
+ if (isPlaywrightRunner()) {
735
+ await __allureAny_mouse.step(stepName, async () => {
736
+ await page.evaluate(([px, py]) => window.scrollTo(px, py), [x, y]);
737
+ });
738
+ } else {
739
+ await page.evaluate(([px, py]) => window.scrollTo(px, py), [x, y]);
740
+ }
741
+ }
742
+
743
+ /**
744
+ * Web: Scroll Up -amount: {param} -options: {param}
745
+ *
746
+ * Scrolls the page up by the specified amount.
747
+ *
748
+ * @param page Playwright Page instance
749
+ * @param amount The amount in pixels to scroll up (default: 200).
750
+ * @param options Optional JSON string or object (reserved for future use).
751
+ *
752
+ * @example
753
+ * Web: Scroll Up -amount: 300 -options: "{}"
754
+ */
755
+ export async function scrollUp(page: Page, amount: number = 200, options?: string | Record<string, any>) {
756
+ return scrollBy(page, -Math.abs(amount), options);
757
+ }
758
+
759
+ /**
760
+ * Web: Scroll Down -amount: {param} -options: {param}
761
+ *
762
+ * Scrolls the page down by the specified amount.
763
+ *
764
+ * @param page Playwright Page instance
765
+ * @param amount The amount in pixels to scroll down (default: 200).
766
+ * @param options Optional JSON string or object (reserved for future use).
767
+ *
768
+ * @example
769
+ * Web: Scroll Down -amount: 300 -options: "{}"
770
+ */
771
+ export async function scrollDown(page: Page, amount: number = 200, options?: string | Record<string, any>) {
772
+ return scrollBy(page, Math.abs(amount), options);
773
+ }
774
+
775
+ /**
776
+ * Web: Scroll By -dy: {param} -options: {param}
777
+ *
778
+ * Scrolls the page vertically by the specified amount.
779
+ *
780
+ * @param page Playwright Page instance
781
+ * @param dy The amount in pixels to scroll by (positive for down, negative for up).
782
+ * @param options Optional JSON string or object (reserved for future use).
783
+ *
784
+ * @example
785
+ * Web: Scroll By -dy: 250 -options: "{}"
786
+ */
787
+ async function scrollBy(page: Page, dy: number, options?: string | Record<string, any>) {
788
+ /**
789
+ * Web: Scroll By -dy: {param} -options: {param}
790
+ *
791
+ * Scrolls the page vertically by the specified amount.
792
+ * Wraps the action in an Allure step when running under Playwright.
793
+ *
794
+ * @param page - Playwright Page instance
795
+ * @param dy - Pixels to scroll by (positive = down, negative = up)
796
+ * @param options - Optional JSON string or object (reserved)
797
+ */
798
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
799
+ const stepName = `Web: Scroll By -dy: ${dy}`;
800
+ if (isPlaywrightRunner()) {
801
+ await __allureAny_mouse.step(stepName, async () => {
802
+ await page.evaluate((d) => window.scrollBy(0, d), dy);
803
+ });
804
+ } else {
805
+ await page.evaluate((d) => window.scrollBy(0, d), dy);
806
+ }
807
+ }
808
+
809
+ /**
810
+ * Web: Click and Wait for New Page -field: {param} -options: {param}
811
+ *
812
+ * Clicks a button or link and waits for a new page (tab) to open.
813
+ *
814
+ * @param context - Playwright BrowserContext
815
+ * @param page - Current Playwright Page
816
+ * @param field - The button/link text or locator to click
817
+ * @param options - Options for clickButton/clickLink
818
+ * @returns The new Page object
819
+ *
820
+ * @example
821
+ * const newPage = await clickAndWaitForNewPage(context, page, "Open Tab", { screenshot: true });
822
+ */
823
+ export async function clickAndWaitForNewPage(
824
+ context: BrowserContext,
825
+ page: Page,
826
+ field: string | Locator,
827
+ options?: string | Record<string, any>
828
+ ) {
829
+ const options_json =
830
+ typeof options === "string" ? parseLooseJson(options) : options || {};
831
+
832
+ if (isPlaywrightRunner()) {
833
+ return await __allureAny_web.step(
834
+ `Web: Click and Wait for New Page -field: ${field} -options: ${JSON.stringify(options_json)}`,
835
+ async () => {
836
+ return await doClickAndWaitForNewPage();
837
+ }
838
+ );
839
+ } else {
840
+ return await doClickAndWaitForNewPage();
841
+ }
842
+
843
+ async function doClickAndWaitForNewPage() {
844
+ if (!context) throw new Error("BrowserContext not initialized");
845
+ if (!page) throw new Error("Page not initialized");
846
+
847
+ // Try button first, fallback to link if not found
848
+ let clickFn = clickButton;
849
+ try {
850
+ if (typeof field === "string") {
851
+ await page.waitForSelector(`button:has-text("${field}")`, { timeout: 2000 });
852
+ }
853
+ } catch {
854
+ clickFn = clickLink;
855
+ }
856
+
857
+ const [newPage] = await Promise.all([
858
+ context.waitForEvent('page'),
859
+ clickFn(page, field, options_json)
860
+ ]);
861
+ await newPage.waitForLoadState('domcontentloaded');
862
+ return newPage;
863
+ }
864
+ }