@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,17 @@
1
+ import { Given, When, Then } from "@cucumber/cucumber";
2
+
3
+ Given("Step Group: {param} {param}", async function (stepGroupName, stepGroupDesc) {
4
+ console.error(`❌ Step Group not available: ${stepGroupName} | ${stepGroupDesc}`);
5
+ });
6
+
7
+ Given("- Step Group - START: {param} Desc: {param}", async function (stepGroupName, stepGroupDesc) {
8
+ console.log(`-> Step Group [START]: ${stepGroupName} | ${stepGroupDesc}`);
9
+ });
10
+
11
+ Given("- Step Group - END: {string}", async function (stepGroupName) {
12
+ console.log(`-> Step Group [END]: ${stepGroupName}`);
13
+ });
14
+
15
+ Given("Step Group: tests", async function (stepGroupName, stepGroupDesc) {
16
+ console.error(`❌ Step Group not available: ${stepGroupName} | ${stepGroupDesc}`);
17
+ });
@@ -0,0 +1,179 @@
1
+ /**
2
+ * @file alertActions.ts
3
+ *
4
+ * Browser alert handling actions for PlayQ across Playwright and Cucumber.
5
+ * Provides accept, dismiss, fill, and verification of alert messages with
6
+ * runner-aware logging and Allure-compatible step wrappers.
7
+ *
8
+ * Key Features:
9
+ * - Hybrid runner support (Playwright/Cucumber) via lightweight shims
10
+ * - Consistent step naming for reporting and traceability
11
+ * - Attaches alert text to reports where available
12
+ *
13
+ * Authors: PlayQ Team
14
+ * Version: v1.0.0
15
+ */
16
+ import * as allure from "allure-js-commons";
17
+ import { Page } from "@playwright/test";
18
+ import { vars, comm } from "../../../global";
19
+ import { processScreenshot } from "./screenshotActions";
20
+
21
+ function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
22
+ const __allureAny_alert: any = allure as any;
23
+ if (typeof __allureAny_alert.step !== 'function') { __allureAny_alert.step = async (_n: string, f: any) => await f(); }
24
+
25
+ /**
26
+ * Web: Accept Alert -options: {param}
27
+ *
28
+ * Waits for a browser alert and accepts it. Attaches the alert text and optionally captures a screenshot.
29
+ *
30
+ * @param page - Playwright Page instance
31
+ * @param options - Optional JSON string or object:
32
+ * - actionTimeout: [number] Timeout to wait for alert (default: config or 10000)
33
+ * - screenshot: [boolean] Capture screenshot after handling the alert (default: false)
34
+ * - screenshotText: [string] Description for screenshot (default: "")
35
+ * - screenshotFullPage: [boolean] Full page screenshot (default: true)
36
+ * @throws Error if page is not initialized or alert does not appear within timeout
37
+ */
38
+ export async function acceptAlert(page: Page, options?: string | Record<string, any>) {
39
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
40
+ const {
41
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")) || 10000,
42
+ screenshot = false,
43
+ screenshotText = "",
44
+ screenshotFullPage = true,
45
+ } = options_json;
46
+ const stepName = `Web: Accept Alert -options: ${JSON.stringify(options_json)}`;
47
+ if (!page) throw new Error("Page not initialized");
48
+ async function run() {
49
+ const dialog = await page.waitForEvent('dialog', { timeout: actionTimeout }).catch(() => null);
50
+ if (!dialog) throw new Error(`❌ No alert appeared within ${actionTimeout}ms`);
51
+ await comm.attachLog(`Alert Text: ${dialog.message()}`, 'text/plain', 'Alert');
52
+ await dialog.accept();
53
+ await processScreenshot(page, screenshot, screenshotText || 'After alert accept', screenshotFullPage);
54
+ }
55
+ if (isPlaywrightRunner()) { await __allureAny_alert.step(stepName, run); } else { await run(); }
56
+ }
57
+
58
+ /**
59
+ * Web: Dismiss Alert -options: {param}
60
+ *
61
+ * Waits for a browser alert and dismisses it. Attaches the alert text and optionally captures a screenshot.
62
+ *
63
+ * @param page - Playwright Page instance
64
+ * @param options - Optional JSON string or object:
65
+ * - actionTimeout: [number] Timeout to wait for alert (default: config or 10000)
66
+ * - screenshot: [boolean] Capture screenshot after handling the alert (default: false)
67
+ * - screenshotText: [string] Description for screenshot (default: "")
68
+ * - screenshotFullPage: [boolean] Full page screenshot (default: true)
69
+ * @throws Error if page is not initialized or alert does not appear within timeout
70
+ */
71
+ export async function dismissAlert(page: Page, options?: string | Record<string, any>) {
72
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
73
+ const {
74
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")) || 10000,
75
+ screenshot = false,
76
+ screenshotText = "",
77
+ screenshotFullPage = true,
78
+ } = options_json;
79
+ const stepName = `Web: Dismiss Alert -options: ${JSON.stringify(options_json)}`;
80
+ if (!page) throw new Error("Page not initialized");
81
+ async function run() {
82
+ const dialog = await page.waitForEvent('dialog', { timeout: actionTimeout }).catch(() => null);
83
+ if (!dialog) throw new Error(`❌ No alert appeared within ${actionTimeout}ms`);
84
+ await comm.attachLog(`Alert Text: ${dialog.message()}`, 'text/plain', 'Alert');
85
+ await dialog.dismiss();
86
+ await processScreenshot(page, screenshot, screenshotText || 'After alert dismiss', screenshotFullPage);
87
+ }
88
+ if (isPlaywrightRunner()) { await __allureAny_alert.step(stepName, run); } else { await run(); }
89
+ }
90
+
91
+ /**
92
+ * Web: Fill Alert -text: {param} -options: {param}
93
+ *
94
+ * Waits for a prompt alert and fills it with the provided text. Attaches the alert text and optionally captures a screenshot.
95
+ *
96
+ * @param page - Playwright Page instance
97
+ * @param text - Text to send to alert prompt
98
+ * @param options - Optional JSON string or object:
99
+ * - actionTimeout: [number] Timeout to wait for alert (default: config or 10000)
100
+ * - screenshot: [boolean] Capture screenshot after handling the alert (default: false)
101
+ * - screenshotText: [string] Description for screenshot (default: "")
102
+ * - screenshotFullPage: [boolean] Full page screenshot (default: true)
103
+ * @throws Error if page is not initialized or alert does not appear within timeout
104
+ */
105
+ export async function fillAlert(page: Page, text: string, options?: string | Record<string, any>) {
106
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
107
+ const {
108
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")) || 10000,
109
+ screenshot = false,
110
+ screenshotText = "",
111
+ screenshotFullPage = true,
112
+ } = options_json;
113
+ const stepName = `Web: Fill Alert -text: ${text} -options: ${JSON.stringify(options_json)}`;
114
+ if (!page) throw new Error("Page not initialized");
115
+ async function run() {
116
+ const dialog = await page.waitForEvent('dialog', { timeout: actionTimeout }).catch(() => null);
117
+ if (!dialog) throw new Error(`❌ No alert appeared within ${actionTimeout}ms`);
118
+ await comm.attachLog(`Alert Text: ${dialog.message()}`, 'text/plain', 'Alert');
119
+ await dialog.accept(text);
120
+ await processScreenshot(page, screenshot, screenshotText || 'After alert fill', screenshotFullPage);
121
+ }
122
+ if (isPlaywrightRunner()) { await __allureAny_alert.step(stepName, run); } else { await run(); }
123
+ }
124
+
125
+ /**
126
+ * Web: See Alert Text -expected: {param} -options: {param}
127
+ *
128
+ * Verifies the next alert message matches the expected text. Supports partial match and case-insensitive comparison.
129
+ *
130
+ * @param page - Playwright Page instance
131
+ * @param expected - Expected alert text
132
+ * @param options - Optional JSON string or object:
133
+ * - actionTimeout: [number] Timeout to wait for alert (default: config or 10000)
134
+ * - partialMatch: [boolean] If true, checks substring instead of exact match (default: false)
135
+ * - ignoreCase: [boolean] Case-insensitive comparison (default: false)
136
+ * - assert: [boolean] If false, logs failure but does not throw (default: true)
137
+ * - screenshot: [boolean] Capture screenshot after verification (default: false)
138
+ * - screenshotText: [string] Description for screenshot (default: "")
139
+ * - screenshotFullPage: [boolean] Full page screenshot (default: true)
140
+ */
141
+ export async function seeAlertText(page: Page, expected: string, options?: string | Record<string, any>) {
142
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
143
+ const {
144
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")) || 10000,
145
+ partialMatch = false,
146
+ ignoreCase = false,
147
+ assert = true,
148
+ screenshot = false,
149
+ screenshotText = "",
150
+ screenshotFullPage = true,
151
+ } = options_json;
152
+ const stepName = `Web: See Alert Text -expected: ${expected} -options: ${JSON.stringify(options_json)}`;
153
+ if (!page) throw new Error("Page not initialized");
154
+ async function run() {
155
+ const dialog = await page.waitForEvent('dialog', { timeout: actionTimeout }).catch(() => null);
156
+ if (!dialog) {
157
+ const msg = `❌ No alert appeared within ${actionTimeout}ms`;
158
+ await comm.attachLog(msg, 'text/plain', 'Alert');
159
+ if (assert) throw new Error(msg);
160
+ return;
161
+ }
162
+ let msg = dialog.message();
163
+ await comm.attachLog(`Alert Text: ${msg}`, 'text/plain', 'Alert');
164
+ let exp = vars.replaceVariables(expected);
165
+ let actual = msg;
166
+ if (ignoreCase) { exp = exp.toLowerCase(); actual = actual.toLowerCase(); }
167
+ const matched = partialMatch ? actual.includes(exp) : actual === exp;
168
+ if (!matched) {
169
+ const err = `Alert text mismatch: expected '${expected}'${partialMatch ? " (partial)" : ""}, got '${msg}'`;
170
+ await comm.attachLog(`❌ ${err}`, 'text/plain', 'Validation');
171
+ if (assert) throw new Error(err);
172
+ } else {
173
+ await comm.attachLog(`✅ Alert text matched: '${msg}'`, 'text/plain', 'Validation');
174
+ }
175
+ await dialog.dismiss();
176
+ await processScreenshot(page, screenshot, screenshotText || 'After alert verification', screenshotFullPage);
177
+ }
178
+ if (isPlaywrightRunner()) { await __allureAny_alert.step(stepName, run); } else { await run(); }
179
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @file cookieActions.ts
3
+ *
4
+ * Cookie management utilities for PlayQ web tests.
5
+ * Supports setting, reading, and clearing cookies with reporting-friendly
6
+ * step wrappers compatible with Playwright and Cucumber runners.
7
+ *
8
+ * Authors: PlayQ Team
9
+ * Version: v1.0.0
10
+ */
11
+ import * as allure from "allure-js-commons";
12
+ import type { Page } from "playwright";
13
+ import { vars } from "../../../global";
14
+
15
+ function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
16
+ const __allureAny_cookie: any = allure as any;
17
+ if (typeof __allureAny_cookie.step !== 'function') { __allureAny_cookie.step = async (_n: string, f: any) => await f(); }
18
+
19
+ /**
20
+ * Web: Set Cookie -name: {param} -value: {param} -options: {param}
21
+ *
22
+ * Adds a cookie for the current page URL.
23
+ *
24
+ * @param page - Playwright Page instance
25
+ * @param name - Cookie name
26
+ * @param value - Cookie value
27
+ * @param options - Optional JSON string or object with cookie attributes:
28
+ * - domain, path, sameSite, secure, httpOnly, expires
29
+ * @throws Error if page is not initialized or required params are missing
30
+ */
31
+ export async function setCookie(page: Page, name: string, value: string, options?: string | Record<string, any>) {
32
+ if (!page) throw new Error("Page not initialized");
33
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
34
+ const stepName = `Web: Set Cookie -name: ${name}`;
35
+ if (!name) throw new Error("Cookie.setCookie: 'name' is required");
36
+ if (value === undefined || value === null) throw new Error("Cookie.setCookie: 'value' is required");
37
+ const ctx = page.context();
38
+ const cookie: any = { name, value };
39
+
40
+ // Precedence: explicit url > domain/path > current page url
41
+ const explicitUrl = options_json?.url;
42
+ const explicitDomain = options_json?.domain;
43
+ const explicitPath = options_json?.path;
44
+
45
+ if (explicitUrl) {
46
+ // When url is specified, do not include domain/path
47
+ cookie.url = explicitUrl;
48
+ } else if (explicitDomain || explicitPath) {
49
+ // When domain/path are specified, do not include url
50
+ if (explicitDomain) cookie.domain = explicitDomain;
51
+ cookie.path = explicitPath || '/';
52
+ } else {
53
+ // Default to current page url if no domain/path/url provided
54
+ cookie.url = page.url();
55
+ }
56
+
57
+ if (options_json?.sameSite) cookie.sameSite = options_json.sameSite;
58
+ if (options_json?.secure !== undefined) cookie.secure = !!options_json.secure;
59
+ if (options_json?.httpOnly !== undefined) cookie.httpOnly = !!options_json.httpOnly;
60
+ if (typeof options_json?.expires === 'number') cookie.expires = options_json.expires;
61
+ if (isPlaywrightRunner()) { await __allureAny_cookie.step(stepName, async () => { await ctx.addCookies([cookie]); }); }
62
+ else { await ctx.addCookies([cookie]); }
63
+ }
64
+
65
+ /**
66
+ * Web: Get Cookie -name: {param}
67
+ *
68
+ * Retrieves the value of a cookie by name.
69
+ *
70
+ * @param page - Playwright Page instance
71
+ * @param name - Cookie name
72
+ * @param options - Optional JSON string or object: { assert?: boolean }
73
+ * @returns Cookie value or undefined
74
+ * @throws Error if page is not initialized or when assert=true and cookie missing
75
+ */
76
+ export async function getCookie(page: Page, name: string, options?: string | Record<string, any>) {
77
+ if (!page) throw new Error("Page not initialized");
78
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
79
+ const stepName = `Web: Get Cookie -name: ${name}`;
80
+ const run = async () => {
81
+ const cookies = await page.context().cookies(page.url());
82
+ const val = cookies.find(c => c.name === name)?.value;
83
+ if (options_json?.assert === true && (val === undefined || val === null)) {
84
+ throw new Error(`Cookie.getCookie: No cookie found with name '${name}'`);
85
+ }
86
+ return val;
87
+ };
88
+ if (isPlaywrightRunner()) { return __allureAny_cookie.step(stepName, run); }
89
+ return run();
90
+ }
91
+
92
+ /**
93
+ * Web: Delete Cookie -name: {param}
94
+ *
95
+ * Clears cookies. Note: Playwright API does not support deleting a single cookie directly; this clears all cookies in context.
96
+ *
97
+ * @param page - Playwright Page instance
98
+ * @param name - Cookie name (for reporting only)
99
+ * @throws Error if page is not initialized
100
+ */
101
+ export async function deleteCookie(page: Page, name: string) {
102
+ if (!page) throw new Error("Page not initialized");
103
+ const stepName = `Web: Delete Cookie -name: ${name}`;
104
+ const run = async () => {
105
+ const ctx = page.context();
106
+ await ctx.clearCookies();
107
+ };
108
+ if (isPlaywrightRunner()) { await __allureAny_cookie.step(stepName, run); } else { await run(); }
109
+ }
110
+
111
+ /**
112
+ * Web: Clear Cookies
113
+ *
114
+ * Clears all cookies in the current browser context.
115
+ *
116
+ * @param page - Playwright Page instance
117
+ * @throws Error if page is not initialized
118
+ */
119
+ export async function clearCookies(page: Page) {
120
+ if (!page) throw new Error("Page not initialized");
121
+ const stepName = `Web: Clear Cookies`;
122
+ const run = async () => { await page.context().clearCookies(); };
123
+ if (isPlaywrightRunner()) { await __allureAny_cookie.step(stepName, run); } else { await run(); }
124
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @file downloadActions.ts
3
+ *
4
+ * Simple filesystem helpers used in web download scenarios.
5
+ * Provides directory listing and file existence checks with
6
+ * Allure-compatible step wrappers.
7
+ *
8
+ * Authors: PlayQ Team
9
+ * Version: v1.0.0
10
+ */
11
+ import * as allure from "allure-js-commons";
12
+ import * as fs from "fs";
13
+ import * as path from "path";
14
+ import type { Page, Locator } from "playwright";
15
+ import { vars, webLocResolver } from "../../../global";
16
+ import { waitForPageToLoad } from "./waitActions";
17
+ import { processScreenshot } from "./screenshotActions";
18
+
19
+ function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
20
+ const __allureAny_dl: any = allure as any;
21
+ if (typeof __allureAny_dl.step !== 'function') { __allureAny_dl.step = async (_n: string, f: any) => await f(); }
22
+
23
+ /**
24
+ * Web: List Files -dir: {param}
25
+ *
26
+ * Lists files in the given directory.
27
+ *
28
+ * @param dirPath - Directory path
29
+ * @returns Array of filenames or empty list if directory does not exist
30
+ * @throws Error if `dirPath` is empty
31
+ */
32
+ export async function listFiles(dirPath: string) {
33
+ if (!dirPath) throw new Error("download.listFiles: 'dirPath' is required");
34
+ const abs = path.resolve(dirPath);
35
+ const stepName = `Web: List Files -dir: ${abs}`;
36
+ const run = async () => fs.existsSync(abs) ? fs.readdirSync(abs) : [];
37
+ if (isPlaywrightRunner()) { return __allureAny_dl.step(stepName, run); }
38
+ return run();
39
+ }
40
+
41
+ /**
42
+ * Web: Has File -dir: {param} -fileName: {param}
43
+ *
44
+ * Checks if a file exists in the directory listing.
45
+ *
46
+ * @param dirPath - Directory path
47
+ * @param fileName - File name to check
48
+ * @returns True if present; false otherwise
49
+ * @throws Error if `dirPath` or `fileName` is empty
50
+ */
51
+ export async function hasFile(dirPath: string, fileName: string) {
52
+ if (!dirPath) throw new Error("download.hasFile: 'dirPath' is required");
53
+ if (!fileName) throw new Error("download.hasFile: 'fileName' is required");
54
+ const stepName = `Web: Has File -dir: ${path.resolve(dirPath)} -fileName: ${fileName}`;
55
+ const run = async () => {
56
+ const files = await listFiles(dirPath);
57
+ return files.includes(fileName);
58
+ };
59
+ if (isPlaywrightRunner()) { return __allureAny_dl.step(stepName, run); }
60
+ return run();
61
+ }
62
+
63
+ /**
64
+ * Web: Download File -field: {param} -options: {param}
65
+ *
66
+ * Triggers a download by clicking the target element and saves it to a directory.
67
+ *
68
+ * @param page - Playwright Page instance
69
+ * @param field - Button/link text, selector, or Locator to click (e.g., 'Download Text')
70
+ * @param options - Optional JSON string or object:
71
+ * - pattern: [string] Locator pattern namespace (e.g., 'letcodesamples')
72
+ * - locatorCategory: [string] 'button' | 'link' (default 'button') used by webLocResolver
73
+ * - targetDir: [string] Directory to save file (default: PLAYQ_PROJECT_ROOT/_Temp/downloads)
74
+ * - fileName: [string] Override file name; default is suggested filename
75
+ * - actionTimeout: [number] Timeout for waits/clicks (default from config/testExecution)
76
+ * - screenshot, screenshotText, screenshotFullPage, screenshotBefore: screenshot options
77
+ *
78
+ * @returns Saved file absolute path
79
+ */
80
+ export async function downloadFile(
81
+ page: Page,
82
+ field: string | Locator,
83
+ options?: string | Record<string, any>
84
+ ) {
85
+ if (!page) throw new Error("Page not initialized");
86
+ const options_json = typeof options === 'string' ? vars.parseLooseJson(options) : options || {};
87
+ const {
88
+ pattern,
89
+ locatorCategory = 'button',
90
+ targetDir,
91
+ fileName,
92
+ actionTimeout = Number(vars.getConfigValue("testExecution.actionTimeout")) || 60000,
93
+ screenshot = false,
94
+ screenshotText = "",
95
+ screenshotFullPage = true,
96
+ screenshotBefore = false,
97
+ } = options_json || {};
98
+
99
+ const resolvedField = typeof field === 'string' ? vars.replaceVariables(field) : field;
100
+ const stepName = `Web: Download File -field: ${typeof resolvedField === 'string' ? resolvedField : '<locator>'}`;
101
+
102
+ const run = async () => {
103
+ await waitForPageToLoad(page, actionTimeout);
104
+ const target =
105
+ typeof resolvedField === 'string'
106
+ ? await webLocResolver(locatorCategory, resolvedField, page, pattern, actionTimeout)
107
+ : resolvedField;
108
+
109
+ await processScreenshot(page, screenshotBefore, screenshotText, screenshotFullPage);
110
+
111
+ const [download] = await Promise.all([
112
+ page.waitForEvent('download', { timeout: actionTimeout }),
113
+ (target as any).click({ timeout: actionTimeout })
114
+ ]);
115
+
116
+ const suggested = download.suggestedFilename();
117
+ const root = (targetDir ? path.resolve(targetDir) : path.join(process.env.PLAYQ_PROJECT_ROOT || process.cwd(), '_Temp', 'downloads'));
118
+ if (!fs.existsSync(root)) fs.mkdirSync(root, { recursive: true });
119
+ const finalName = fileName || suggested;
120
+ const savePath = path.join(root, finalName);
121
+ await download.saveAs(savePath);
122
+
123
+ await processScreenshot(page, screenshot, screenshotText, screenshotFullPage);
124
+ return savePath;
125
+ };
126
+
127
+ if (isPlaywrightRunner()) { return __allureAny_dl.step(stepName, run); }
128
+ return run();
129
+ }