@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,53 @@
1
+ /**
2
+ * @file reportingActions.ts
3
+ *
4
+ * Lightweight reporting helpers for PlayQ web actions.
5
+ * Attaches info/pass/fail messages to the test report via comm fixture.
6
+ *
7
+ * Authors: PlayQ Team
8
+ * Version: v1.0.0
9
+ */
10
+ import { comm } from "../../../global";
11
+
12
+ /**
13
+ * Web: Log Info -message: {param}
14
+ *
15
+ * Attaches an informational log message to the test report.
16
+ *
17
+ * @param message - Message to attach
18
+ */
19
+ export async function logInfo(message: string) { await comm.attachLog(message, 'text/plain', 'INFO'); }
20
+
21
+ /**
22
+ * Web: Log Pass -message: {param}
23
+ *
24
+ * Attaches a success log message to the test report.
25
+ *
26
+ * @param message - Message to attach
27
+ */
28
+ export async function logPass(message: string) { await comm.attachLog(`✅ ${message}`, 'text/plain', 'PASS'); }
29
+
30
+ /**
31
+ * Web: Log Fail -message: {param}
32
+ *
33
+ * Attaches a failure log message to the test report.
34
+ *
35
+ * @param message - Message to attach
36
+ */
37
+ export async function logFail(message: string) { await comm.attachLog(`❌ ${message}`, 'text/plain', 'FAIL'); }
38
+
39
+ /**
40
+ * Web: Assert -condition: {param} -message: {param}
41
+ *
42
+ * Asserts a condition and logs pass/fail. Throws on failure.
43
+ *
44
+ * @param condition - Condition to assert
45
+ * @param message - Optional message to include in logs and error
46
+ */
47
+ export async function assert(condition: boolean, message?: string) {
48
+ if (!condition) { await logFail(message || 'Assertion failed'); throw new Error(message || 'Assertion failed'); }
49
+ await logPass(message || 'Assertion passed');
50
+ }
51
+
52
+ // Friendly aliases
53
+ export const assertLog = assert;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @file screenshotActions.ts
3
+ *
4
+ * Screenshot helpers for PlayQ web actions.
5
+ * Provides takeScreenshot and internal processScreenshot with hybrid
6
+ * runner support (Playwright/Cucumber) and robust attachment fallbacks.
7
+ *
8
+ * Authors: PlayQ Team
9
+ * Version: v1.0.0
10
+ */
11
+ import * as fs from "fs";
12
+ import * as path from "path";
13
+ import * as allure from "allure-js-commons";
14
+ import { Page, Locator } from "@playwright/test";
15
+ import { webFixture } from "../../../global";
16
+ import { waitForPageToLoad } from "./waitActions";
17
+ import { parseLooseJson } from '../../bundle/vars';
18
+
19
+ function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
20
+ function isCucumberRunner() { return process.env.TEST_RUNNER === 'cucumber'; }
21
+
22
+ const __allureAny_shot: any = allure as any;
23
+ if (typeof __allureAny_shot.step !== 'function') {
24
+ __allureAny_shot.step = async (_name: string, fn: any) => await fn();
25
+ }
26
+
27
+ /**
28
+ * Takes a screenshot of the provided Playwright page.
29
+ *
30
+ * @param page - The Playwright Page object to capture.
31
+ * @param options - Optional screenshot configuration. Can be a JSON string or an object.
32
+ * - `screenshot_text` (string): Optional text to annotate the screenshot.
33
+ * - `screenshot_fullPage` (boolean): Whether to capture the full page (default: true).
34
+ * @throws Will throw an error if the page is not initialized.
35
+ * @remarks
36
+ * Waits for the page to load before taking the screenshot.
37
+ */
38
+ export async function takeScreenshot(
39
+ page: Page,
40
+ options?: string | Record<string, any>
41
+ ) {
42
+ const options_json =
43
+ typeof options === "string" ? parseLooseJson(options) : options || {};
44
+ const { screenshot_text = "", screenshot_fullPage = true } = options_json;
45
+
46
+ if (!page) throw new Error("Page not initialized");
47
+ await waitForPageToLoad(page);
48
+ await processScreenshot(page, true, screenshot_text, screenshot_fullPage);
49
+ }
50
+
51
+ function persistScreenshotToDisk(buffer: Buffer, text: string) {
52
+ try {
53
+ const baseDir = path.resolve(process.cwd(), "test-results", "screenshots");
54
+ fs.mkdirSync(baseDir, { recursive: true });
55
+ const safe = (text || "screenshot").toString().toLowerCase().replace(/[^a-z0-9-_]+/gi, "_").slice(0, 80);
56
+ const file = path.join(baseDir, `${Date.now()}_${safe || "shot"}.png`);
57
+ fs.writeFileSync(file, buffer);
58
+ console.log(`📸 Screenshot saved to: ${file}`);
59
+ } catch (e) {
60
+ console.warn(`⚠️ Failed to save screenshot to disk: ${e?.message || e}`);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Web: Process Screenshot -options: {param}
66
+ *
67
+ * Internal helper to capture and attach a screenshot.
68
+ *
69
+ * @param page - Playwright Page instance
70
+ * @param shouldTake - Whether to capture
71
+ * @param text - Attachment text
72
+ * @param fullPage - Full page flag
73
+ * @param selector - Optional Locator to screenshot
74
+ */
75
+ export async function processScreenshot(
76
+ page: Page,
77
+ shouldTake: boolean,
78
+ text: string = "Screenshot",
79
+ fullPage: boolean = true,
80
+ selector?: Locator
81
+ ) {
82
+ if (!shouldTake) return;
83
+ if (!page) throw new Error("Page not initialized for screenshot");
84
+ const screenshotBuffer = selector
85
+ ? await selector.screenshot()
86
+ : await page.screenshot({ fullPage });
87
+
88
+ try {
89
+ if (isCucumberRunner()) {
90
+ const world = webFixture.getWorld();
91
+ if (world && typeof world.attach === "function") {
92
+ await world.attach(screenshotBuffer, "image/png");
93
+ await world.attach(`Screenshot Text: ${text}`, "text/plain");
94
+ console.log(`✅ Screenshot attached via Cucumber World: ${text}`);
95
+ } else {
96
+ console.warn(`⚠️ No Cucumber World context. Screenshot not attached.`);
97
+ }
98
+ } else if (isPlaywrightRunner()) {
99
+ const { test } = await import("@playwright/test");
100
+ await test
101
+ .info()
102
+ .attach(text, { body: screenshotBuffer, contentType: "image/png" });
103
+ console.log(`✅ Screenshot attached via Playwright: ${text}`);
104
+ } else {
105
+ console.warn(`⚠️ Unknown runner context. Screenshot not attached.`);
106
+ }
107
+ } catch (error) {
108
+ console.warn(`⚠️ Error attaching screenshot: ${error.message}`);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Web: Take Full Screenshot -options: {param}
114
+ *
115
+ * Captures a full-page screenshot by delegating to `takeScreenshot` with defaults.
116
+ *
117
+ * @param page - Playwright Page instance
118
+ * @param options - Optional JSON string or object (merged with defaults)
119
+ */
120
+ export async function takeFullScreenshot(page: Page, options?: string | Record<string, any>) {
121
+ const defaults = { screenshot: true, screenshotFullPage: true };
122
+ let opts = typeof options === 'string' ? defaults : { ...defaults, ...(options || {}) };
123
+ return takeScreenshot(page, opts as any);
124
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @file testDataActions.ts
3
+ *
4
+ * Test data helpers for PlayQ web actions.
5
+ * Supports JSON and CSV loading plus sample data generation via faker.
6
+ *
7
+ * Authors: PlayQ Team
8
+ * Version: v1.0.0
9
+ */
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { faker } from "../../../global";
13
+
14
+ /**
15
+ * Web: Load Test Data JSON -file: {param}
16
+ *
17
+ * Loads and parses JSON test data from a file.
18
+ *
19
+ * @param filePath - Path to JSON file
20
+ * @returns Parsed JSON content
21
+ * @throws Error if file does not exist or JSON parsing fails
22
+ */
23
+ export async function loadFromJson(filePath: string) {
24
+ if (!filePath) throw new Error("testData.loadFromJson: 'filePath' is required");
25
+ const abs = path.resolve(filePath);
26
+ if (!fs.existsSync(abs)) throw new Error(`testData.loadFromJson: File not found at '${abs}'`);
27
+ const content = fs.readFileSync(abs, 'utf-8');
28
+ try {
29
+ return JSON.parse(content);
30
+ } catch (err: any) {
31
+ throw new Error(`testData.loadFromJson: Failed to parse JSON - ${err?.message || err}`);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Web: Load Test Data CSV -file: {param}
37
+ *
38
+ * Loads CSV test data from a file and returns an array of objects.
39
+ *
40
+ * @param filePath - Path to CSV file
41
+ * @returns Array of row objects keyed by header names
42
+ * @throws Error if file does not exist or CSV is empty/invalid
43
+ */
44
+ export async function loadFromCsv(filePath: string) {
45
+ if (!filePath) throw new Error("testData.loadFromCsv: 'filePath' is required");
46
+ const abs = path.resolve(filePath);
47
+ if (!fs.existsSync(abs)) throw new Error(`testData.loadFromCsv: File not found at '${abs}'`);
48
+ const content = (fs.readFileSync(abs, 'utf-8') || '').trim();
49
+ if (!content) throw new Error("testData.loadFromCsv: CSV file is empty");
50
+ const [headerLine, ...rows] = content.split(/\r?\n/);
51
+ if (!headerLine) throw new Error("testData.loadFromCsv: Missing header line");
52
+ const headers = headerLine.split(',').map(h => h.trim());
53
+ return rows.filter(r => r && r.trim().length > 0).map(r => {
54
+ const cols = r.split(',');
55
+ const obj: any = {};
56
+ headers.forEach((h, i) => obj[h] = (cols[i] ?? '').trim());
57
+ return obj;
58
+ });
59
+ }
60
+
61
+ /**
62
+ * Web: Generate Sample Data -schema: {param}
63
+ *
64
+ * Generates sample test data, optionally merged with a provided schema.
65
+ *
66
+ * @param schema - Optional object to override default generated fields
67
+ * @returns Object containing generated sample fields
68
+ */
69
+ function generateValueByDescriptor(descriptor: string): any {
70
+ const d = (descriptor || '').toString().toLowerCase().trim();
71
+ switch (d) {
72
+ case 'string':
73
+ return faker?.lorem?.word?.() || 'sample';
74
+ case 'number':
75
+ case 'int':
76
+ case 'integer':
77
+ return (faker as any)?.number?.int?.({ min: 0, max: 9999 }) ?? 0;
78
+ case 'float':
79
+ case 'decimal':
80
+ return (faker as any)?.number?.float?.({ min: 0, max: 9999, precision: 0.01 }) ?? 0.0;
81
+ case 'boolean':
82
+ return Math.random() < 0.5;
83
+ case 'email':
84
+ return faker?.internet?.email?.() || 'user@example.com';
85
+ case 'phone':
86
+ case 'phonenumber':
87
+ return faker?.phone?.number?.() || '1234567890';
88
+ case 'firstname':
89
+ return faker?.person?.firstName?.() || 'John';
90
+ case 'lastname':
91
+ return faker?.person?.lastName?.() || 'Doe';
92
+ case 'fullname':
93
+ case 'name':
94
+ return `${faker?.person?.firstName?.() || 'John'} ${faker?.person?.lastName?.() || 'Doe'}`;
95
+ case 'uuid':
96
+ return (faker as any)?.string?.uuid?.() || '00000000-0000-0000-0000-000000000000';
97
+ case 'date':
98
+ return new Date().toISOString().slice(0, 10);
99
+ case 'datetime':
100
+ case 'isodatetime':
101
+ return new Date().toISOString();
102
+ case 'timestamp':
103
+ return Date.now();
104
+ case 'url':
105
+ return faker?.internet?.url?.() || 'https://example.com';
106
+ case 'ip':
107
+ case 'ipv4':
108
+ return (faker as any)?.internet?.ip?.() || '127.0.0.1';
109
+ case 'city':
110
+ return (faker as any)?.location?.city?.() || 'Metropolis';
111
+ case 'country':
112
+ return (faker as any)?.location?.country?.() || 'Wonderland';
113
+ case 'company':
114
+ return (faker as any)?.company?.name?.() || 'ACME Inc.';
115
+ default:
116
+ // Unknown descriptor → return as-is to avoid surprises
117
+ return descriptor;
118
+ }
119
+ }
120
+
121
+ function generateFromSchema(schema: any): any {
122
+ if (schema == null) return schema;
123
+ if (Array.isArray(schema)) {
124
+ // If array has a single descriptor like ['string'], generate a small array of values
125
+ if (schema.length === 1 && typeof schema[0] === 'string') {
126
+ return [generateValueByDescriptor(schema[0] as string), generateValueByDescriptor(schema[0] as string)];
127
+ }
128
+ // Otherwise, map values
129
+ return schema.map((v) => (typeof v === 'string' ? generateValueByDescriptor(v) : generateFromSchema(v)));
130
+ }
131
+ if (typeof schema === 'object') {
132
+ const out: any = {};
133
+ for (const [k, v] of Object.entries(schema)) {
134
+ if (typeof v === 'string') {
135
+ out[k] = generateValueByDescriptor(v);
136
+ } else if (typeof v === 'number' || typeof v === 'boolean') {
137
+ out[k] = v;
138
+ } else if (Array.isArray(v)) {
139
+ out[k] = generateFromSchema(v);
140
+ } else if (typeof v === 'object' && v !== null) {
141
+ out[k] = generateFromSchema(v);
142
+ } else {
143
+ out[k] = v;
144
+ }
145
+ }
146
+ return out;
147
+ }
148
+ if (typeof schema === 'string') return generateValueByDescriptor(schema);
149
+ return schema;
150
+ }
151
+
152
+ export async function generateSampleData(schema?: Record<string, any>) {
153
+ const sample = {
154
+ firstName: faker?.person?.firstName?.() || 'John',
155
+ lastName: faker?.person?.lastName?.() || 'Doe',
156
+ email: faker?.internet?.email?.() || 'john.doe@example.com',
157
+ phone: faker?.phone?.number?.() || '1234567890'
158
+ } as any;
159
+ if (!schema) return sample;
160
+ const interpreted = generateFromSchema(schema);
161
+ return { ...sample, ...interpreted };
162
+ }