@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,83 @@
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
+ var _a;
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const fs_1 = __importDefault(require("fs"));
41
+ const path_1 = __importDefault(require("path"));
42
+ const glob_1 = require("glob");
43
+ const vars = __importStar(require("../helper/bundle/vars"));
44
+ const config = {};
45
+ const sgGenerator_1 = require("./sgGenerator");
46
+ const featureFileCache_1 = require("./featureFileCache");
47
+ const featureFilePreProcess_1 = require("./featureFilePreProcess");
48
+ const featureFileCache = ((_a = config === null || config === void 0 ? void 0 : config.cucumber) === null || _a === void 0 ? void 0 : _a.featureFileCache) || (vars.getConfigValue('cucumber.featureFileCache') || false);
49
+ const isForce = process.argv.includes('--force');
50
+ console.log('🚀 Running preProcessEntry.ts...');
51
+ console.log(`⚙️ featureFileCache enabled: ${featureFileCache}`);
52
+ console.log(`⚙️ Force flag: ${isForce}`);
53
+ (0, sgGenerator_1.generateStepGroupsIfNeeded)(isForce);
54
+ const featureFiles = (0, glob_1.sync)('test/features/**/*.feature');
55
+ if (!featureFiles.length) {
56
+ console.warn('⚠️ No feature files found under features/**/*.feature');
57
+ }
58
+ // Clean up execution folder before generating new feature files
59
+ const executionDir = path_1.default.join('_Temp', 'execution');
60
+ if (fs_1.default.existsSync(executionDir)) {
61
+ fs_1.default.rmSync(executionDir, { recursive: true, force: true });
62
+ console.log(`🧹 Cleaned up execution folder: ${executionDir}`);
63
+ }
64
+ for (const originalPath of featureFiles) {
65
+ console.log(`🔧 Processing: ${originalPath}`);
66
+ const cachedPath = (0, featureFileCache_1.getCachedFeatureFilePath)(originalPath);
67
+ console.log(`📄 Cached path: ${cachedPath}`);
68
+ if (featureFileCache && !isForce && (0, featureFileCache_1.shouldUseCachedFeature)(originalPath, cachedPath)) {
69
+ console.log(`✅ Using cached feature file: ${cachedPath}`);
70
+ continue;
71
+ }
72
+ const updatedContent = (0, featureFilePreProcess_1.preprocessFeatureFile)(originalPath);
73
+ if (!updatedContent || !updatedContent.trim().startsWith('Feature')) {
74
+ console.warn(`❌ Skipping cache write for ${originalPath}: Invalid content. Preview:\n${(updatedContent || '').substring(0, 100)}`);
75
+ continue;
76
+ }
77
+ fs_1.default.mkdirSync(path_1.default.dirname(cachedPath), { recursive: true });
78
+ fs_1.default.writeFileSync(cachedPath, updatedContent, 'utf-8');
79
+ console.log(`📥 Updated cached feature file: ${cachedPath}`);
80
+ if (featureFileCache) {
81
+ (0, featureFileCache_1.updateFeatureCacheMeta)(originalPath, cachedPath);
82
+ }
83
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,258 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const csv_parser_1 = __importDefault(require("csv-parser"));
9
+ // import xlsx from 'xlsx';
10
+ const xlsx_1 = __importDefault(require("@e965/xlsx"));
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ const sgGenerator_1 = require("./sgGenerator");
13
+ const config = {};
14
+ function loadStepGroupCache() {
15
+ const cachePath = path_1.default.resolve('_Temp/.cache/stepGroup_cache.json');
16
+ if (!fs_1.default.existsSync(cachePath)) {
17
+ console.error(`❌ Step group JSON cache not found. Please run sgGenerator.ts first.`);
18
+ return {};
19
+ }
20
+ return JSON.parse(fs_1.default.readFileSync(cachePath, 'utf-8'));
21
+ }
22
+ const args = process.argv.slice(2);
23
+ const isForced = args.includes('--force');
24
+ function sha256(content) {
25
+ return crypto_1.default.createHash('sha256').update(content).digest('hex');
26
+ }
27
+ const featureCachePath = path_1.default.resolve('_Temp/.cache/featureMeta.json');
28
+ const featureCache = fs_1.default.existsSync(featureCachePath)
29
+ ? JSON.parse(fs_1.default.readFileSync(featureCachePath, 'utf8'))
30
+ : {};
31
+ const sourceDir = path_1.default.resolve('test/features');
32
+ const outputDir = path_1.default.resolve('_Temp/execution');
33
+ const dataDir = path_1.default.resolve('test-data');
34
+ function findFeatureFiles(dir) {
35
+ let results = [];
36
+ fs_1.default.readdirSync(dir).forEach(file => {
37
+ const fullPath = path_1.default.join(dir, file);
38
+ const stat = fs_1.default.statSync(fullPath);
39
+ if (stat.isDirectory()) {
40
+ results = results.concat(findFeatureFiles(fullPath));
41
+ }
42
+ else if (file.endsWith('.feature')) {
43
+ results.push(fullPath);
44
+ }
45
+ });
46
+ return results;
47
+ }
48
+ function ensureOutputPath(featurePath) {
49
+ const relativePath = path_1.default.relative(sourceDir, featurePath);
50
+ const targetPath = path_1.default.join(outputDir, relativePath);
51
+ const dir = path_1.default.dirname(targetPath);
52
+ fs_1.default.mkdirSync(dir, { recursive: true });
53
+ return targetPath;
54
+ }
55
+ function isNumeric(val) {
56
+ return typeof val === 'string' && val.trim() !== '' && !isNaN(Number(val));
57
+ }
58
+ function validateIdentifiers(filter, inputPath) {
59
+ const invalidIdentifiers = Array.from(filter.matchAll(/_([A-Z0-9_\-\.]+)/gi))
60
+ .map(match => match[1])
61
+ .filter(id => !/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(`_${id}`));
62
+ if (invalidIdentifiers.length > 0) {
63
+ console.error(`❌ Invalid identifiers in filter: ${invalidIdentifiers.map(i => `"_${i}"`).join(', ')}`);
64
+ console.error(` 👉 Use only letters, numbers, and underscores (e.g., _SUB_STATUS)`);
65
+ console.error(` ✋ Please fix this in feature file: ${inputPath}`);
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+ function substituteFilter(filter, row) {
71
+ const allKeys = Object.keys(row);
72
+ const pattern = /\b[_a-zA-Z][_a-zA-Z0-9]*\b/g;
73
+ return filter.replace(pattern, (key) => {
74
+ var _a;
75
+ const raw = (_a = row[key]) !== null && _a !== void 0 ? _a : row[`_${key}`];
76
+ if (raw === undefined)
77
+ return key; // leave as-is if not found
78
+ return isNumeric(raw) ? raw.trim() : JSON.stringify(raw);
79
+ });
80
+ }
81
+ function preprocessFeatureFile(inputPath, outputPath, stepGroupCache, stepGroupCacheHash) {
82
+ const relativePath = path_1.default.relative(sourceDir, inputPath);
83
+ let featureHashInput = fs_1.default.readFileSync(inputPath, 'utf-8') + stepGroupCacheHash;
84
+ const featureText = fs_1.default.readFileSync(inputPath, 'utf-8');
85
+ const lines = featureText.split('\n');
86
+ let dataFile = '';
87
+ let filter = '';
88
+ let sheetName = '';
89
+ let exampleLineIndex = -1;
90
+ lines.forEach((line, index) => {
91
+ const exampleMatch = line.trim().startsWith('Examples:') && line.includes('{');
92
+ if (exampleMatch) {
93
+ exampleLineIndex = index;
94
+ const jsonStr = line.replace(/^Examples:\s*/, '').trim();
95
+ try {
96
+ const parsed = JSON.parse(jsonStr.replace(/'/g, '"'));
97
+ dataFile = parsed.dataFile;
98
+ filter = parsed.filter;
99
+ sheetName = parsed.sheetName;
100
+ if (!validateIdentifiers(filter, inputPath)) {
101
+ return;
102
+ }
103
+ // Add to hash input: options for Examples
104
+ featureHashInput += JSON.stringify({ filter, sheetName, dataFile });
105
+ }
106
+ catch (err) {
107
+ console.error(`❌ Failed to parse Examples JSON in ${inputPath}:\n`, err);
108
+ return;
109
+ }
110
+ }
111
+ });
112
+ // If there is a data file, append its content to the hash input (if it exists)
113
+ let fullPath = '';
114
+ if (dataFile) {
115
+ const ext = path_1.default.extname(dataFile).toLowerCase();
116
+ fullPath = path_1.default.join(dataDir, path_1.default.basename(dataFile));
117
+ if (fs_1.default.existsSync(fullPath)) {
118
+ // For CSV, read as utf-8; for XLSX, hash the file buffer.
119
+ if (ext === '.csv') {
120
+ featureHashInput += fs_1.default.readFileSync(fullPath, 'utf-8');
121
+ }
122
+ else if (ext === '.xlsx') {
123
+ featureHashInput += fs_1.default.readFileSync(fullPath).toString('base64');
124
+ }
125
+ }
126
+ }
127
+ // Compute current hash
128
+ const currentHash = sha256(featureHashInput);
129
+ if (!isForced && featureCache[relativePath] && featureCache[relativePath] === currentHash) {
130
+ console.log(`⏩ Skipped (unchanged): ${relativePath}`);
131
+ return;
132
+ }
133
+ if (!dataFile || !filter || exampleLineIndex === -1) {
134
+ // No Examples, just expand step groups and write output
135
+ console.log("📣 No Examples detected. Proceeding with step group expansion only...");
136
+ const expandedLines = expandStepGroups(lines, inputPath, stepGroupCache);
137
+ const outputContent = expandedLines.join('\n');
138
+ fs_1.default.writeFileSync(outputPath, outputContent, 'utf-8');
139
+ featureCache[relativePath] = currentHash;
140
+ console.log(`📄 Preprocessed (no Examples): ${outputPath}`);
141
+ return;
142
+ }
143
+ // Has Examples with data
144
+ console.log("✔ Should generate examples (this line will NOT show if the block above returns)");
145
+ const ext = path_1.default.extname(dataFile).toLowerCase();
146
+ const rows = [];
147
+ const buildExamplesFile = () => {
148
+ if (rows.length === 0) {
149
+ console.log(`❌ No matching rows found in ${dataFile}`);
150
+ fs_1.default.writeFileSync(outputPath, featureText, 'utf-8');
151
+ featureCache[relativePath] = currentHash;
152
+ return;
153
+ }
154
+ const headers = Object.keys(rows[0]); // Include all headers including _ENV, _STATUS etc.
155
+ const examples = ['Examples:', ` | ${headers.join(' | ')} |`]
156
+ .concat(rows.map(r => {
157
+ const rowData = headers.map(h => r[h] || '');
158
+ return ` | ${rowData.join(' | ')} |`;
159
+ }));
160
+ const outputLines = [
161
+ ...lines.slice(0, exampleLineIndex),
162
+ ...examples,
163
+ ...lines.slice(exampleLineIndex + 1),
164
+ ];
165
+ // Expand Step Groups before processing Examples
166
+ const expandedLines = expandStepGroups(outputLines, inputPath, stepGroupCache);
167
+ // Rebuild Examples only after step groups are expanded
168
+ const finalLines = expandedLines.join('\n');
169
+ fs_1.default.writeFileSync(outputPath, finalLines, 'utf-8');
170
+ featureCache[relativePath] = currentHash;
171
+ console.log(`✅ Processed: ${outputPath}`);
172
+ };
173
+ if (ext === '.csv') {
174
+ fs_1.default.createReadStream(fullPath)
175
+ .pipe((0, csv_parser_1.default)())
176
+ .on('data', (row) => {
177
+ try {
178
+ if (eval(substituteFilter(filter, row))) {
179
+ rows.push(row);
180
+ }
181
+ }
182
+ catch (e) {
183
+ console.warn(`⚠️ Skipping row due to filter error: ${e.message}`);
184
+ }
185
+ })
186
+ .on('end', buildExamplesFile);
187
+ }
188
+ else if (ext === '.xlsx') {
189
+ const workbook = xlsx_1.default.readFile(fullPath);
190
+ const sheet = sheetName || workbook.SheetNames[0];
191
+ const sheetData = xlsx_1.default.utils.sheet_to_json(workbook.Sheets[sheet]);
192
+ sheetData.forEach((row) => {
193
+ try {
194
+ if (eval(substituteFilter(filter, row))) {
195
+ rows.push(row);
196
+ }
197
+ }
198
+ catch (e) {
199
+ console.warn(`⚠️ Skipping row due to filter error: ${e.message}`);
200
+ }
201
+ });
202
+ buildExamplesFile();
203
+ }
204
+ else {
205
+ console.error(`❌ Unsupported file type: ${ext}`);
206
+ fs_1.default.writeFileSync(outputPath, featureText, 'utf-8');
207
+ featureCache[relativePath] = currentHash;
208
+ }
209
+ }
210
+ function run() {
211
+ console.log("🔄 Generating step group definitions from sgGenerator...");
212
+ (0, sgGenerator_1.generateStepGroups)({ force: isForced }); // Regenerate stepGroup_steps.ts before preprocessing
213
+ // if (fs.existsSync(outputDir)) {
214
+ // fs.rmSync(outputDir, { recursive: true, force: true });
215
+ // }
216
+ fs_1.default.mkdirSync(outputDir, { recursive: true });
217
+ // Load step group cache once
218
+ const stepGroupCache = loadStepGroupCache();
219
+ const stepGroupCacheHash = sha256(JSON.stringify(stepGroupCache));
220
+ const features = findFeatureFiles(sourceDir);
221
+ if (!features.length) {
222
+ console.log('No feature files found.');
223
+ return;
224
+ }
225
+ features.forEach(featurePath => {
226
+ // Skip the step group directory
227
+ if (featurePath.includes('_step_group') || featurePath.includes('step_group')) {
228
+ console.log(`🛑 Skipping step group directory: ${featurePath}`);
229
+ return;
230
+ }
231
+ const outPath = ensureOutputPath(featurePath);
232
+ preprocessFeatureFile(featurePath, outPath, stepGroupCache, stepGroupCacheHash);
233
+ });
234
+ // Save the feature cache at the end
235
+ fs_1.default.mkdirSync(path_1.default.dirname(featureCachePath), { recursive: true });
236
+ fs_1.default.writeFileSync(featureCachePath, JSON.stringify(featureCache, null, 2), 'utf8');
237
+ }
238
+ function expandStepGroups(lines, inputPath, stepGroupCache) {
239
+ return lines.flatMap(line => {
240
+ // const match = line.trim().match(/^\* Step Group: -([a-zA-Z0-9_.]+)-/);
241
+ const match = line.trim().match(/^(?:\*|Given|When|Then|And|But) Step Group: -([a-zA-Z0-9_.]+)-/);
242
+ if (match) {
243
+ const groupName = match[1];
244
+ const group = stepGroupCache[groupName];
245
+ if (!group) {
246
+ console.error(`❌ Step Group not found: ${groupName} (in ${inputPath})`);
247
+ process.exit(1);
248
+ }
249
+ return [
250
+ `* - Step Group - START: "${groupName}" Desc: "${group.description}"`,
251
+ ...group.steps.map(step => ` ${step}`),
252
+ `* - Step Group - END: "${groupName}"`
253
+ ];
254
+ }
255
+ return [line];
256
+ });
257
+ }
258
+ run();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,221 @@
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
+ const child_process_1 = require("child_process");
7
+ const env_1 = require("../helper/bundle/env");
8
+ const path_1 = __importDefault(require("path"));
9
+ // Note: remove stray invalid import; runner does not need faker
10
+ // loadEnv();
11
+ // console.log(' - Runner (PLAYQ_ENV):', process.env.PLAYQ_ENV );
12
+ // console.log(' - Runner (PLAYQ_RUNNER):', process.env.PLAYQ_RUNNER );
13
+ // console.log(' - Runner (PLAYQ_GREP):', process.env.PLAYQ_GREP );
14
+ // console.log(' - Runner (PLAYQ_TAGS):', process.env.PLAYQ_TAGS );
15
+ // console.log(' - Runner (PLAYQ_PROJECT):', process.env.PLAYQ_PROJECT );
16
+ // console.log(' - Env (RUNNER - cc_card_type):', process.env['cc_card_type']);
17
+ // console.log(' - Env (RUNNER - config.testExecution.timeout):', process.env['config.testExecution.timeout'] );
18
+ if (process.env.PLAYQ_RUNNER && process.env.PLAYQ_RUNNER === 'cucumber') {
19
+ // Allow vars to initialize in the cucumber child process (do NOT set PLAYQ_NO_INIT_VARS here)
20
+ // Ensure legacy TEST_RUNNER flag used by helper code is set
21
+ process.env.TEST_RUNNER = 'cucumber';
22
+ // Provide a default browser type if none supplied via config/env
23
+ if (!process.env['PLAYQ__browser__browserType'] && !process.env['browser.browserType']) {
24
+ process.env.PLAYQ__browser__browserType = 'chromium';
25
+ }
26
+ (0, env_1.loadEnv)();
27
+ const cucumberArgs = [
28
+ 'cucumber-js',
29
+ '--config',
30
+ 'cucumber.js',
31
+ '--profile',
32
+ 'default',
33
+ ];
34
+ if (process.env.PLAYQ_TAGS)
35
+ cucumberArgs.push('--tags', process.env.PLAYQ_TAGS);
36
+ const run = (0, child_process_1.spawn)('npx', cucumberArgs, {
37
+ stdio: 'inherit',
38
+ env: { ...process.env },
39
+ shell: true,
40
+ });
41
+ run.on('close', (code) => {
42
+ try {
43
+ const pkgPath = path_1.default.resolve(process.cwd(), 'package.json');
44
+ const pkg = require(pkgPath);
45
+ if (pkg.scripts && pkg.scripts['posttest:cucumber']) {
46
+ (0, child_process_1.execSync)('npm run posttest:cucumber', { stdio: 'inherit' });
47
+ }
48
+ else {
49
+ console.log('ℹ️ Skipping posttest:cucumber (script not defined)');
50
+ }
51
+ }
52
+ catch (err) {
53
+ console.log('ℹ️ Posttest check failed, continuing:', (err === null || err === void 0 ? void 0 : err.message) || err);
54
+ }
55
+ process.exit(code);
56
+ });
57
+ }
58
+ else {
59
+ if (process.env.PLAYQ_RUN_CONFIG) {
60
+ // Dynamically import the run_config object from the specified run config file
61
+ // Look for run config in the user's project root
62
+ const runConfigPath = path_1.default.resolve(process.cwd(), `resources/run-configs/${process.env.PLAYQ_RUN_CONFIG}.run`);
63
+ const runConfig = require(runConfigPath).default;
64
+ console.log('🌐 Running with runConfig:', JSON.stringify(runConfig));
65
+ for (const cfg of runConfig.runs) {
66
+ console.log(` - Running test with grep: ${cfg.PLAYQ_GREP}, env: ${cfg.PLAYQ_ENV}`);
67
+ Object.keys(cfg).forEach(key => {
68
+ if (key.trim() == 'PLAYQ_RUNNER')
69
+ throw new Error('PLAYQ_RUNNER is not allowed in run configs');
70
+ process.env[key] = cfg[key];
71
+ console.log(`Setting ${key} = ${cfg[key]}`);
72
+ });
73
+ process.env.PLAYQ_NO_INIT_VARS = '1';
74
+ (0, env_1.loadEnv)();
75
+ const command = `npx playwright test --config=playq/config/playwright/playwright.config.js${process.env.PLAYQ_GREP ? ` --grep="${process.env.PLAYQ_GREP}"` : ''}${process.env.PLAYQ_PROJECT ? ` --project="${process.env.PLAYQ_PROJECT}"` : ''}`;
76
+ const childEnv = { ...process.env };
77
+ // Ensure child initializes vars by removing the parent-side guard
78
+ delete childEnv.PLAYQ_NO_INIT_VARS;
79
+ const preload = '-r ts-node/register';
80
+ childEnv.NODE_OPTIONS = childEnv.NODE_OPTIONS
81
+ ? `${childEnv.NODE_OPTIONS} ${preload}`
82
+ : preload;
83
+ // Ensure core and project roots propagate to child
84
+ if (!childEnv.PLAYQ_CORE_ROOT)
85
+ childEnv.PLAYQ_CORE_ROOT = path_1.default.resolve(__dirname, '..');
86
+ if (!childEnv.PLAYQ_PROJECT_ROOT)
87
+ childEnv.PLAYQ_PROJECT_ROOT = process.cwd();
88
+ // Point ts-node to the project's tsconfig for path aliases
89
+ const projectTsConfig = path_1.default.resolve(process.cwd(), 'tsconfig.json');
90
+ childEnv.TS_NODE_PROJECT = projectTsConfig;
91
+ childEnv.TS_NODE_TRANSPILE_ONLY = childEnv.TS_NODE_TRANSPILE_ONLY || 'true';
92
+ const result = (0, child_process_1.spawnSync)(command, {
93
+ stdio: 'inherit',
94
+ shell: true,
95
+ env: childEnv,
96
+ });
97
+ }
98
+ }
99
+ else {
100
+ process.env.PLAYQ_NO_INIT_VARS = '1';
101
+ (0, env_1.loadEnv)();
102
+ const command = `npx playwright test --config=playq/config/playwright/playwright.config.js${process.env.PLAYQ_GREP ? ` --grep="${process.env.PLAYQ_GREP}"` : ''}${process.env.PLAYQ_PROJECT ? ` --project="${process.env.PLAYQ_PROJECT}"` : ''}`;
103
+ const childEnv = { ...process.env };
104
+ // Ensure child initializes vars by removing the parent-side guard
105
+ delete childEnv.PLAYQ_NO_INIT_VARS;
106
+ const preload = '-r ts-node/register';
107
+ childEnv.NODE_OPTIONS = childEnv.NODE_OPTIONS
108
+ ? `${childEnv.NODE_OPTIONS} ${preload}`
109
+ : preload;
110
+ // Ensure core and project roots propagate to child
111
+ if (!childEnv.PLAYQ_CORE_ROOT)
112
+ childEnv.PLAYQ_CORE_ROOT = path_1.default.resolve(__dirname, '..');
113
+ if (!childEnv.PLAYQ_PROJECT_ROOT)
114
+ childEnv.PLAYQ_PROJECT_ROOT = process.cwd();
115
+ // Point ts-node to the project's tsconfig for path aliases
116
+ const projectTsConfig = path_1.default.resolve(process.cwd(), 'tsconfig.json');
117
+ childEnv.TS_NODE_PROJECT = projectTsConfig;
118
+ childEnv.TS_NODE_TRANSPILE_ONLY = childEnv.TS_NODE_TRANSPILE_ONLY || 'true';
119
+ const result = (0, child_process_1.spawnSync)(command, {
120
+ stdio: 'inherit',
121
+ shell: true,
122
+ env: childEnv,
123
+ });
124
+ }
125
+ }
126
+ // console.log(' - Runner (PLAYQ_ENV):', process.env.PLAYQ_ENV );
127
+ // console.log(' - Runner (PLAYQ_RUNNER):', process.env.PLAYQ_RUNNER );
128
+ // console.log(' - Runner (PLAYQ_GREP):', process.env.PLAYQ_GREP );
129
+ // console.log(' - Runner (PLAYQ_TAGS):', process.env.PLAYQ_TAGS );
130
+ // console.log(' - Runner (PLAYQ_PROJECT):', process.env.PLAYQ_PROJECT );
131
+ // console.log(' - Env (RUNNER - cc_card_type):', process.env.cc_card_type );
132
+ // let runner = 'playwright';
133
+ // let env = '';
134
+ // let grep = '';
135
+ // let tags = '';
136
+ // let prj = '';
137
+ // console.log('🌐 os.platform():', os.platform());
138
+ // // Use minimist for all platforms for consistency
139
+ // const args = minimist(process.argv.slice(2));
140
+ // // Try npm_config_* first (for npm script context), then fall back to minimist
141
+ // grep = process.env.npm_config_grep || args.grep || '';
142
+ // env = process.env.npm_config_env || args.env || '';
143
+ // tags = process.env.npm_config_tags || args.tags || '';
144
+ // prj = process.env.npm_config_project || args.project || '';
145
+ // runner = ['cucumber', 'bdd', 'cuke'].includes(
146
+ // (process.env.npm_config_runner || args.runner || '').toLowerCase()
147
+ // )
148
+ // ? 'cucumber'
149
+ // : 'playwright';
150
+ // console.log('🌐 grep:', grep);
151
+ // console.log('🌐 env:', env);
152
+ // console.log('🌐 tags:', tags);
153
+ // console.log('🌐 prj:', prj);
154
+ // console.log('🌐 runner:', runner);
155
+ // // Debug information
156
+ // console.log('🔍 Debug - process.argv:', process.argv);
157
+ // console.log('🔍 Debug - minimist args:', args);
158
+ // console.log('🔍 Debug - npm_config_env:', process.env.npm_config_env);
159
+ // console.log('🔍 Debug - npm_config_grep:', process.env.npm_config_grep);
160
+ // process.env.TS_NODE_PROJECT = './tsconfig.json';
161
+ // require('tsconfig-paths').register();
162
+ // console.log('🌐 Running tests with args:', process.argv);
163
+ // console.log(process.platform);
164
+ // console.log(process.env.npm_config_env);
165
+ // process.env.TEST_RUNNER = runner;
166
+ // if (tags) process.env.TAGS = tags;
167
+ // if (grep) process.env.GREP = grep;
168
+ // if (prj) process.env.PROJECT = prj;
169
+ // if (env) {
170
+ // process.env.RUN_ENV = env;
171
+ // loadEnv(env);
172
+ // }
173
+ // if (runner === 'cucumber') {
174
+ // execSync('npm run pretest:cucumber', { stdio: 'inherit' });
175
+ // const cucumberArgs = [
176
+ // 'cucumber-js',
177
+ // '--config',
178
+ // 'cucumber.js',
179
+ // '--profile',
180
+ // 'default',
181
+ // ];
182
+ // if (tags) cucumberArgs.push('--tags', tags);
183
+ // console.log(`🚀 Running Cucumber with args: ${cucumberArgs.join(' ')}`);
184
+ // console.log('📦 Final Cucumber command:', `npx ${cucumberArgs.join(' ')}`);
185
+ // const run = spawn('npx', cucumberArgs, {
186
+ // stdio: 'inherit',
187
+ // env: { ...process.env, RUN_ENV: env, PROJECT: prj },
188
+ // shell: true,
189
+ // });
190
+ // run.on('close', (code) => {
191
+ // execSync('npm run posttest:cucumber', { stdio: 'inherit' });
192
+ // process.exit(code);
193
+ // });
194
+ // } else if (runner === 'playwright') {
195
+ // try {
196
+ // execSync('npm run pretest:playwright', { stdio: 'inherit' });
197
+ // } catch (error) {
198
+ // console.log(
199
+ // '⚠️ Pre-test cleanup had some issues, but continuing with tests...'
200
+ // );
201
+ // }
202
+ // const command = `npx playwright test --config=config/playwright/playwright.config.ts${
203
+ // grep ? ` --grep='${grep}'` : ''
204
+ // }${prj ? ` --project=${prj}` : ''}`;
205
+ // const result = spawnSync(command, {
206
+ // stdio: 'inherit',
207
+ // shell: true,
208
+ // env: { ...process.env, RUN_ENV: env, PROJECT: prj },
209
+ // });
210
+ // try {
211
+ // execSync('npm run posttest:playwright', { stdio: 'inherit' });
212
+ // } catch (error) {
213
+ // console.log(
214
+ // '⚠️ Post-test reporting had some issues, but test execution completed.'
215
+ // );
216
+ // }
217
+ // process.exit(result.status || 0);
218
+ // } else {
219
+ // console.error(`❌ Unknown runner: ${runner}`);
220
+ // process.exit(1);
221
+ // }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const child_process_1 = require("child_process");
9
+ const child_process_2 = require("child_process");
10
+ const yargs_1 = __importDefault(require("yargs"));
11
+ const args = (0, yargs_1.default)(process.argv).argv;
12
+ const runnerName = args.runner;
13
+ if (!runnerName) {
14
+ console.error('❌ Missing --runner=<name>');
15
+ process.exit(1);
16
+ }
17
+ const runnerPath = path_1.default.resolve(`./resources/runners/${runnerName}.run.json`);
18
+ if (!fs_1.default.existsSync(runnerPath)) {
19
+ console.error(`❌ Runner file not found: ${runnerPath}`);
20
+ process.exit(1);
21
+ }
22
+ const runnerConfig = JSON.parse(fs_1.default.readFileSync(runnerPath, 'utf-8'));
23
+ const { runType, runs } = runnerConfig;
24
+ (0, child_process_2.execSync)('npm run pretest:playwright', { stdio: 'inherit' });
25
+ async function runOneTest(config) {
26
+ const env = config.env ? config.env : '';
27
+ const grep = config.grep ? `--grep="${config.grep}"` : '';
28
+ // const env = config.env ? `--env="${config.env}"` : '';
29
+ const prj = config.project ? `--project=${config.project}"` : '';
30
+ const command = `npx playwright test --config=config/playwright/playwright.config.js ${grep} ${prj}`;
31
+ console.log(`🔹 Running: ${command}`);
32
+ const result = (0, child_process_1.spawnSync)(command, {
33
+ stdio: 'inherit',
34
+ shell: true,
35
+ env: { ...process.env, TEST_RUNNER: "playwright", RUN_ENV: env }
36
+ // env: { ...process.env }
37
+ });
38
+ if (result.status !== 0) {
39
+ console.error(`❌ Test failed: ${grep}`);
40
+ process.exit(result.status);
41
+ }
42
+ }
43
+ async function runTests() {
44
+ if (runType === 'sequential') {
45
+ for (const run of runs) {
46
+ await runOneTest(run);
47
+ }
48
+ }
49
+ else if (runType === 'parallel') {
50
+ const promises = runs.map(run => new Promise((resolve, reject) => {
51
+ const env = run.env ? run.env : '';
52
+ const grep = run.grep ? `--grep="${run.grep}"` : '';
53
+ // const env = run.env ? `--env="${run.env}"` : '';
54
+ const prj = run.project ? `--project=${run.project}"` : '';
55
+ const command = `npx playwright test --config=config/playwright/playwright.config.js ${grep} ${prj}`;
56
+ const proc = (0, child_process_1.spawnSync)(command, {
57
+ stdio: 'inherit',
58
+ shell: true,
59
+ env: { ...process.env, TEST_RUNNER: "playwright", RUN_ENV: env }
60
+ });
61
+ if (proc.status !== 0) {
62
+ reject(new Error(`Failed: ${command}`));
63
+ }
64
+ else {
65
+ resolve(true);
66
+ }
67
+ }));
68
+ try {
69
+ await Promise.all(promises);
70
+ }
71
+ catch (err) {
72
+ console.error('❌ One or more test batches failed.');
73
+ process.exit(1);
74
+ }
75
+ }
76
+ else {
77
+ console.error(`❌ Unknown runType: ${runType}`);
78
+ process.exit(1);
79
+ }
80
+ }
81
+ runTests().then(() => {
82
+ (0, child_process_2.execSync)('npm run posttest:playwright', { stdio: 'inherit' });
83
+ console.log('✅ All test runs completed.');
84
+ process.exit(0);
85
+ });
@@ -0,0 +1,11 @@
1
+ type StepGroup = {
2
+ name: string;
3
+ description: string;
4
+ steps: string[];
5
+ };
6
+ export declare function extractStepGroups(fileContent: string, filename: string): StepGroup[];
7
+ declare function generateStepGroups(options?: {
8
+ force?: boolean;
9
+ }): void;
10
+ export { generateStepGroups };
11
+ export declare function generateStepGroupsIfNeeded(force?: boolean): void;