@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,2 @@
1
+ export declare function attachResolvedStep(thisArg: any, template: string): Promise<void>;
2
+ export declare function defineLoggedStep(pattern: string, implementation: Function): (this: any, ...args: any[]) => any;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachResolvedStep = attachResolvedStep;
4
+ exports.defineLoggedStep = defineLoggedStep;
5
+ const global_1 = require("../../global");
6
+ async function attachResolvedStep(thisArg, template) {
7
+ const resolved = global_1.vars.replaceVariables(template);
8
+ await thisArg.attach(`🧾 Resolved Step: ${resolved}`, 'text/plain');
9
+ }
10
+ function defineLoggedStep(pattern, implementation) {
11
+ return function (...args) {
12
+ const stepText = pattern.replace(/\{param\}/g, (_match, i) => `"${args[i]}"`);
13
+ attachResolvedStep.call(this, stepText);
14
+ return implementation.apply(this, args);
15
+ };
16
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Reads test data from .json, .xlsx, or .csv
3
+ *
4
+ * @param file - Filename WITH extension, e.g., "login.json", "login.xlsx", "login.csv"
5
+ * @param sheetName - (optional) Sheet name for Excel files
6
+ */
7
+ export declare function getTestData(file: string, sheetName?: string): any[];
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.getTestData = getTestData;
40
+ const fs_1 = __importDefault(require("fs"));
41
+ const path_1 = __importDefault(require("path"));
42
+ const XLSX = __importStar(require("@e965/xlsx"));
43
+ /**
44
+ * Reads test data from .json, .xlsx, or .csv
45
+ *
46
+ * @param file - Filename WITH extension, e.g., "login.json", "login.xlsx", "login.csv"
47
+ * @param sheetName - (optional) Sheet name for Excel files
48
+ */
49
+ function getTestData(file, sheetName) {
50
+ // Attempt to locate the project's test-data directory robustly.
51
+ // Strategy:
52
+ // 1. Starting at process.cwd(), walk upward looking for a folder that
53
+ // contains a package.json (project root) and a test-data subfolder.
54
+ // 2. If found, use <foundRoot>/test-data/<file>.
55
+ // 3. Otherwise, fallback to process.cwd()/test-data/<file> and report a clear ENOENT.
56
+ function findProjectRootWithTestData(startDir) {
57
+ let current = path_1.default.resolve(startDir);
58
+ const root = path_1.default.parse(current).root;
59
+ while (true) {
60
+ const pkg = path_1.default.join(current, 'package.json');
61
+ const td = path_1.default.join(current, 'test-data');
62
+ if (fs_1.default.existsSync(pkg) && fs_1.default.existsSync(td) && fs_1.default.statSync(td).isDirectory()) {
63
+ return td;
64
+ }
65
+ if (current === root)
66
+ break;
67
+ current = path_1.default.dirname(current);
68
+ }
69
+ return null;
70
+ }
71
+ const start = process.cwd();
72
+ const projectTestData = findProjectRootWithTestData(start);
73
+ // If not found by walking upward, also check immediate subdirectories of the
74
+ // current directory. This handles the common developer workspace layout where
75
+ // the workspace root contains multiple project folders (e.g. PlayQ_PROJECT).
76
+ let basePath;
77
+ if (projectTestData) {
78
+ basePath = projectTestData;
79
+ }
80
+ else {
81
+ // scan one-level children for a project that contains package.json and test-data
82
+ const children = fs_1.default.readdirSync(start, { withFileTypes: true });
83
+ let found = null;
84
+ for (const child of children) {
85
+ if (!child.isDirectory())
86
+ continue;
87
+ const candidate = path_1.default.join(start, child.name);
88
+ const pkg = path_1.default.join(candidate, 'package.json');
89
+ const td = path_1.default.join(candidate, 'test-data');
90
+ try {
91
+ if (fs_1.default.existsSync(pkg) && fs_1.default.existsSync(td) && fs_1.default.statSync(td).isDirectory()) {
92
+ found = td;
93
+ break;
94
+ }
95
+ }
96
+ catch (e) {
97
+ // ignore permission or stat errors on non-readable dirs
98
+ }
99
+ }
100
+ basePath = found || path_1.default.resolve(process.cwd(), 'test-data');
101
+ }
102
+ const filePath = path_1.default.join(basePath, file);
103
+ if (!fs_1.default.existsSync(filePath)) {
104
+ throw new Error(`ENOENT: test data file not found: ${filePath}. Searched from ${start}`);
105
+ }
106
+ const ext = path_1.default.extname(file).toLowerCase();
107
+ switch (ext) {
108
+ case '.json': {
109
+ const raw = fs_1.default.readFileSync(filePath, 'utf-8');
110
+ return JSON.parse(raw);
111
+ }
112
+ case '.xlsx': {
113
+ const workbook = XLSX.readFile(filePath);
114
+ const sheet = workbook.Sheets[sheetName || workbook.SheetNames[0]];
115
+ const rows = XLSX.utils.sheet_to_json(sheet, { raw: false });
116
+ // Try to parse booleans/numbers
117
+ return rows.map(row => {
118
+ const parsedRow = {};
119
+ for (const key in row) {
120
+ const value = row[key];
121
+ if (value === 'true' || value === 'false') {
122
+ parsedRow[key] = value === 'true';
123
+ }
124
+ else if (!isNaN(value) && value.trim() !== '') {
125
+ parsedRow[key] = Number(value);
126
+ }
127
+ else {
128
+ parsedRow[key] = value;
129
+ }
130
+ }
131
+ return parsedRow;
132
+ });
133
+ // const workbook = XLSX.readFile(filePath);
134
+ // const sheet = workbook.Sheets[sheetName || workbook.SheetNames[0]];
135
+ // return XLSX.utils.sheet_to_json(sheet);
136
+ }
137
+ case '.csv': {
138
+ const fileData = fs_1.default.readFileSync(filePath, 'utf-8');
139
+ const worksheet = XLSX.read(fileData, { type: 'string' }).Sheets['Sheet1'];
140
+ return XLSX.utils.sheet_to_json(worksheet);
141
+ }
142
+ default:
143
+ throw new Error(`Unsupported file extension: ${ext}`);
144
+ }
145
+ }
@@ -0,0 +1,10 @@
1
+ export declare function dataTest<T extends Record<string, any>>(label: string, dataSource: T[] | {
2
+ file: string;
3
+ filter?: string;
4
+ sheet?: string;
5
+ testType?: string;
6
+ suffix?: string;
7
+ }, callback: (args: {
8
+ row: T;
9
+ page?: any;
10
+ }) => Promise<void>): void;
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.dataTest = dataTest;
37
+ // dataTest.ts
38
+ const test_1 = require("@playwright/test");
39
+ const dataLoader_1 = require("./dataLoader");
40
+ const vars = __importStar(require("../../bundle/vars"));
41
+ const customFaker_1 = require("../../faker/customFaker");
42
+ function dataTest(label, dataSource, callback) {
43
+ let dataset = [];
44
+ const { testType = "UI", suffix = "" } = typeof dataSource === "object" && !Array.isArray(dataSource) ? dataSource : {};
45
+ if (Array.isArray(dataSource)) {
46
+ dataset = applyRowReplacements(dataSource);
47
+ }
48
+ else {
49
+ let { file, filter, sheet } = dataSource;
50
+ file = vars.replaceVariables(file);
51
+ sheet = (sheet) ? vars.replaceVariables(sheet) : undefined;
52
+ filter = vars.replaceVariables(filter);
53
+ const raw = (0, dataLoader_1.getTestData)(file, sheet);
54
+ // Expand faker/variable placeholders within each row before filtering/scheduling tests
55
+ const preprocessed = applyRowReplacements(raw);
56
+ dataset = filter
57
+ ? preprocessed.filter(row => {
58
+ try {
59
+ // Create a scoped function where row keys are destructured
60
+ const fn = new Function("row", `
61
+ const { ${Object.keys(row).join(", ")} } = row;
62
+ return ${filter};
63
+ `);
64
+ return fn(row);
65
+ }
66
+ catch (err) {
67
+ console.warn(`⚠️ Filter failed: ${filter}`, err);
68
+ return false;
69
+ }
70
+ })
71
+ : preprocessed;
72
+ }
73
+ test_1.test.describe(label, () => {
74
+ dataset.forEach((row, index) => {
75
+ vars.setValue('playq.iteration.count', `${index + 1}`);
76
+ const name = `${label} ${vars.replaceVariables(replaceIterationDataVars(suffix, row))} [-${index + 1}-]`;
77
+ if (testType.toUpperCase() === "API") {
78
+ (0, test_1.test)(name, async () => {
79
+ test_1.test.info().annotations.push({ type: "tag", description: label });
80
+ await callback({ row });
81
+ });
82
+ }
83
+ else {
84
+ (0, test_1.test)(name, async ({ page }) => {
85
+ test_1.test.info().annotations.push({ type: "tag", description: label });
86
+ await callback({ row, page });
87
+ });
88
+ }
89
+ });
90
+ });
91
+ }
92
+ // ----------------- helpers -----------------
93
+ function applyRowReplacements(rows) {
94
+ return rows.map((row) => {
95
+ const out = { ...row };
96
+ for (const k of Object.keys(out)) {
97
+ const v = out[k];
98
+ if (typeof v === 'string') {
99
+ // First, evaluate any faker placeholders
100
+ const withFaker = replaceFakerPlaceholders(v);
101
+ // Then, apply generic variable replacements
102
+ out[k] = typeof withFaker === 'string' ? vars.replaceVariables(withFaker) : withFaker;
103
+ }
104
+ }
105
+ return out;
106
+ });
107
+ }
108
+ function replaceFakerPlaceholders(input) {
109
+ const trimmed = input.trim();
110
+ // Entire value is wrapped: #{faker....}
111
+ const wrapped = trimmed.match(/^#\{(faker(?:\.[a-zA-Z0-9_]+)+\((.*)\))\}$/);
112
+ if (wrapped) {
113
+ return evalFakerCall(wrapped[1]);
114
+ }
115
+ // Entire value is a faker call: faker....
116
+ const full = trimmed.match(/^faker((?:\.[a-zA-Z0-9_]+)+)\((.*)\)$/);
117
+ if (full) {
118
+ return evalFakerFromParts(full[1], full[2]);
119
+ }
120
+ // Embedded placeholders inside a larger string
121
+ return input.replace(/#\{faker((?:\.[a-zA-Z0-9_]+)+)\((.*?)\)\}/g, (_m, pathPart, argsRaw) => {
122
+ try {
123
+ const val = evalFakerFromParts(pathPart, argsRaw);
124
+ return String(val);
125
+ }
126
+ catch (e) {
127
+ console.warn(`⚠️ Failed to evaluate faker placeholder: #{faker${pathPart}(${argsRaw})}`, e);
128
+ return _m;
129
+ }
130
+ });
131
+ }
132
+ function evalFakerCall(expr) {
133
+ // expr like: faker.xxx.yyy(args)
134
+ const m = expr.match(/^faker((?:\.[a-zA-Z0-9_]+)+)\((.*)\)$/);
135
+ if (!m)
136
+ throw new Error(`Invalid faker expression: ${expr}`);
137
+ return evalFakerFromParts(m[1], m[2]);
138
+ }
139
+ function evalFakerFromParts(pathPart, argsRaw) {
140
+ const path = pathPart.replace(/^\./, '');
141
+ const parts = path.split('.');
142
+ // Prefer global faker set up by core; fall back to imported one
143
+ let ctx = globalThis.faker || customFaker_1.faker;
144
+ let fn = ctx;
145
+ for (const p of parts) {
146
+ fn = fn === null || fn === void 0 ? void 0 : fn[p];
147
+ }
148
+ if (typeof fn !== 'function')
149
+ throw new Error(`Resolved faker path is not a function: faker.${path}`);
150
+ const args = parseFakerArgs(argsRaw);
151
+ return fn(...args);
152
+ }
153
+ function parseFakerArgs(argsRaw) {
154
+ const trimmed = (argsRaw || '').trim();
155
+ if (!trimmed)
156
+ return [];
157
+ if (trimmed.startsWith('{')) {
158
+ // Object literal; normalize to JSON
159
+ const normalized = trimmed
160
+ .replace(/([{,]\s*)([a-zA-Z0-9_]+)\s*:/g, '$1"$2":')
161
+ .replace(/'/g, '"');
162
+ try {
163
+ return [JSON.parse(normalized)];
164
+ }
165
+ catch (e) {
166
+ throw new Error(`Failed to parse faker argument object: ${argsRaw}`);
167
+ }
168
+ }
169
+ // Simple comma-separated values (strip surrounding quotes)
170
+ return splitArgs(trimmed).map(a => a.trim().replace(/^(["'])(.*)\1$/, '$2'));
171
+ }
172
+ function splitArgs(s) {
173
+ const out = [];
174
+ let buf = '';
175
+ let depth = 0;
176
+ let quote = null;
177
+ for (let i = 0; i < s.length; i++) {
178
+ const ch = s[i];
179
+ if (quote) {
180
+ if (ch === quote && s[i - 1] !== '\\') {
181
+ quote = null;
182
+ }
183
+ buf += ch;
184
+ continue;
185
+ }
186
+ if (ch === '"' || ch === "'") {
187
+ quote = ch;
188
+ buf += ch;
189
+ continue;
190
+ }
191
+ if (ch === '{' || ch === '[' || ch === '(')
192
+ depth++;
193
+ if (ch === '}' || ch === ']' || ch === ')')
194
+ depth--;
195
+ if (ch === ',' && depth === 0) {
196
+ out.push(buf);
197
+ buf = '';
198
+ continue;
199
+ }
200
+ buf += ch;
201
+ }
202
+ if (buf)
203
+ out.push(buf);
204
+ return out;
205
+ }
206
+ /**
207
+ * Replaces all #{playq.iteration.data.KEY} in the input string with the value from the row object.
208
+ * @param input The string containing placeholders.
209
+ * @param row The row object with data.
210
+ * @returns The string with placeholders replaced.
211
+ */
212
+ function replaceIterationDataVars(input, row) {
213
+ return input.replace(/#\{playq\.iteration\.data\.([a-zA-Z0-9_]+)\}/g, (_, key) => {
214
+ return row[key] !== undefined ? String(row[key]) : '';
215
+ });
216
+ }
@@ -0,0 +1,38 @@
1
+ export declare class TOTPHelper {
2
+ private secret;
3
+ private serviceName;
4
+ private accountName;
5
+ constructor(secret?: string, serviceName?: string, accountName?: string);
6
+ /**
7
+ * Generate a new TOTP secret
8
+ */
9
+ generateSecret(): string;
10
+ /**
11
+ * Generate current TOTP token
12
+ */
13
+ generateToken(): string;
14
+ /**
15
+ * Verify TOTP token
16
+ */
17
+ verifyToken(token: string): boolean;
18
+ /**
19
+ * Get OTP Auth URL for QR code generation
20
+ */
21
+ getOtpAuthUrl(): string;
22
+ /**
23
+ * Generate QR code for authenticator app setup
24
+ */
25
+ generateQRCode(): Promise<string>;
26
+ /**
27
+ * Get the secret (for environment variable storage)
28
+ */
29
+ getSecret(): string;
30
+ /**
31
+ * Check if current time is near token expiry
32
+ */
33
+ getTimeRemaining(): number;
34
+ /**
35
+ * Generate token with retry logic for time window
36
+ */
37
+ generateTokenWithRetry(maxRetries?: number): Promise<string>;
38
+ }
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TOTPHelper = void 0;
37
+ const otplib_1 = require("otplib");
38
+ const QRCode = __importStar(require("qrcode"));
39
+ class TOTPHelper {
40
+ constructor(secret, serviceName = 'PlayQ', accountName = 'automation') {
41
+ this.secret = secret || this.generateSecret();
42
+ this.serviceName = serviceName;
43
+ this.accountName = accountName;
44
+ // Configure otplib options
45
+ otplib_1.authenticator.options = {
46
+ window: 2, // Allow 2 time steps tolerance
47
+ step: 30 // 30-second time step
48
+ };
49
+ }
50
+ /**
51
+ * Generate a new TOTP secret
52
+ */
53
+ generateSecret() {
54
+ return otplib_1.authenticator.generateSecret();
55
+ }
56
+ /**
57
+ * Generate current TOTP token
58
+ */
59
+ generateToken() {
60
+ return otplib_1.authenticator.generate(this.secret);
61
+ }
62
+ /**
63
+ * Verify TOTP token
64
+ */
65
+ verifyToken(token) {
66
+ return otplib_1.authenticator.verify({
67
+ token,
68
+ secret: this.secret
69
+ });
70
+ }
71
+ /**
72
+ * Get OTP Auth URL for QR code generation
73
+ */
74
+ getOtpAuthUrl() {
75
+ return otplib_1.authenticator.keyuri(this.accountName, this.serviceName, this.secret);
76
+ }
77
+ /**
78
+ * Generate QR code for authenticator app setup
79
+ */
80
+ async generateQRCode() {
81
+ const otpAuthUrl = this.getOtpAuthUrl();
82
+ return await QRCode.toDataURL(otpAuthUrl);
83
+ }
84
+ /**
85
+ * Get the secret (for environment variable storage)
86
+ */
87
+ getSecret() {
88
+ return this.secret;
89
+ }
90
+ /**
91
+ * Check if current time is near token expiry
92
+ */
93
+ getTimeRemaining() {
94
+ const epoch = Math.round(Date.now() / 1000.0);
95
+ const timeStep = 30;
96
+ return timeStep - (epoch % timeStep);
97
+ }
98
+ /**
99
+ * Generate token with retry logic for time window
100
+ */
101
+ async generateTokenWithRetry(maxRetries = 3) {
102
+ let attempts = 0;
103
+ while (attempts < maxRetries) {
104
+ const timeRemaining = this.getTimeRemaining();
105
+ // If token expires soon, wait for new window
106
+ if (timeRemaining < 5) {
107
+ console.log(`Token expires in ${timeRemaining}s, waiting for new window...`);
108
+ await new Promise(resolve => setTimeout(resolve, (timeRemaining + 1) * 1000));
109
+ }
110
+ const token = this.generateToken();
111
+ console.log(`Generated TOTP token: ${token.substring(0, 3)}*** (${this.getTimeRemaining()}s remaining)`);
112
+ return token;
113
+ }
114
+ throw new Error('Failed to generate TOTP token after retries');
115
+ }
116
+ }
117
+ exports.TOTPHelper = TOTPHelper;
@@ -0,0 +1,2 @@
1
+ export declare function encrypt(plaintext: string): string;
2
+ export declare function decrypt(data: string): string;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.encrypt = encrypt;
7
+ exports.decrypt = decrypt;
8
+ // src/utils/cryptoUtil.ts
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ const dotenv_1 = __importDefault(require("dotenv"));
11
+ dotenv_1.default.config();
12
+ const algorithm = 'aes-256-gcm';
13
+ const secretKey = crypto_1.default.scryptSync(process.env.PLAYQ_SECRET_KEY || '_DEFAULT_SECRET_32_CHARACTERS_!_', 'salt', 32);
14
+ const ivLength = 12; // Recommended IV size for GCM
15
+ function encrypt(plaintext) {
16
+ const iv = crypto_1.default.randomBytes(ivLength);
17
+ const cipher = crypto_1.default.createCipheriv(algorithm, secretKey, iv);
18
+ const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
19
+ const authTag = cipher.getAuthTag();
20
+ const combined = Buffer.concat([iv, authTag, encrypted]);
21
+ return combined.toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
22
+ }
23
+ function decrypt(data) {
24
+ const combined = Buffer.from(data.replace(/-/g, '+').replace(/_/g, '/'), 'base64');
25
+ const iv = combined.subarray(0, ivLength);
26
+ const authTag = combined.subarray(ivLength, ivLength + 16);
27
+ const encrypted = combined.subarray(ivLength + 16);
28
+ const decipher = crypto_1.default.createDecipheriv(algorithm, secretKey, iv);
29
+ decipher.setAuthTag(authTag);
30
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
31
+ return decrypted.toString('utf8');
32
+ }
33
+ // const algorithm = 'aes-256-cbc';
34
+ // const secretKey = process.env.CRYPTO_SECRET_KEY || '_DEFAULT_SECRET_32_CHARACTERS_!_';
35
+ // const ivLength = 16; // AES block size
36
+ // // --- Encrypt ---
37
+ // export function encrypt(text: string): string {
38
+ // const iv = crypto.randomBytes(ivLength);
39
+ // const cipher = crypto.createCipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv);
40
+ // let encrypted = cipher.update(text, 'utf8', 'hex');
41
+ // encrypted += cipher.final('hex');
42
+ // return iv.toString('hex') + ':' + encrypted;
43
+ // }
44
+ // // --- Decrypt ---
45
+ // export function decrypt(encryptedText: string): string {
46
+ // const [ivHex, encrypted] = encryptedText.split(':');
47
+ // if (!ivHex || !encrypted) throw new Error('Invalid encrypted text format.');
48
+ // const iv = Buffer.from(ivHex, 'hex');
49
+ // const decipher = crypto.createDecipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv);
50
+ // let decrypted = decipher.update(encrypted, 'hex', 'utf8');
51
+ // decrypted += decipher.final('utf8');
52
+ // return decrypted;
53
+ // }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};