@sun-asterisk/sungen 1.0.23 → 2.0.0

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 (364) hide show
  1. package/README.md +198 -74
  2. package/dist/cli/commands/add.d.ts.map +1 -1
  3. package/dist/cli/commands/add.js +5 -3
  4. package/dist/cli/commands/add.js.map +1 -1
  5. package/dist/cli/commands/generate.d.ts.map +1 -1
  6. package/dist/cli/commands/generate.js +110 -35
  7. package/dist/cli/commands/generate.js.map +1 -1
  8. package/dist/cli/index.d.ts +2 -2
  9. package/dist/cli/index.js +5 -16
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/frame-enter-action.hbs +1 -0
  12. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/frame-exit-action.hbs +1 -0
  13. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/keyboard-global-action.hbs +1 -0
  14. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/scroll-action.hbs +1 -0
  15. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -0
  16. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/label-value-assertion.hbs +2 -0
  17. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +3 -0
  18. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +3 -0
  19. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +2 -0
  20. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +2 -0
  21. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +2 -0
  22. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +2 -0
  23. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +2 -0
  24. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  25. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +11 -2
  26. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +11 -2
  27. package/dist/generators/test-generator/code-generator.d.ts +0 -1
  28. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  29. package/dist/generators/test-generator/code-generator.js +0 -47
  30. package/dist/generators/test-generator/code-generator.js.map +1 -1
  31. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  32. package/dist/generators/test-generator/patterns/assertion-patterns.js +33 -8
  33. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  34. package/dist/generators/test-generator/patterns/index.d.ts +4 -1
  35. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  36. package/dist/generators/test-generator/patterns/index.js +17 -5
  37. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  38. package/dist/generators/test-generator/patterns/interaction-patterns.js +1 -1
  39. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  40. package/dist/generators/test-generator/patterns/keyboard-patterns.d.ts +7 -0
  41. package/dist/generators/test-generator/patterns/keyboard-patterns.d.ts.map +1 -0
  42. package/dist/generators/test-generator/patterns/keyboard-patterns.js +47 -0
  43. package/dist/generators/test-generator/patterns/keyboard-patterns.js.map +1 -0
  44. package/dist/generators/test-generator/patterns/scope-patterns.d.ts +7 -0
  45. package/dist/generators/test-generator/patterns/scope-patterns.d.ts.map +1 -0
  46. package/dist/generators/test-generator/patterns/scope-patterns.js +36 -0
  47. package/dist/generators/test-generator/patterns/scope-patterns.js.map +1 -0
  48. package/dist/generators/test-generator/patterns/scroll-patterns.d.ts +7 -0
  49. package/dist/generators/test-generator/patterns/scroll-patterns.d.ts.map +1 -0
  50. package/dist/generators/test-generator/patterns/scroll-patterns.js +25 -0
  51. package/dist/generators/test-generator/patterns/scroll-patterns.js.map +1 -0
  52. package/dist/generators/test-generator/patterns/table-patterns.d.ts +7 -0
  53. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -0
  54. package/dist/generators/test-generator/patterns/table-patterns.js +192 -0
  55. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -0
  56. package/dist/generators/test-generator/step-mapper.d.ts +1 -3
  57. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  58. package/dist/generators/test-generator/step-mapper.js +36 -34
  59. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  60. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  61. package/dist/generators/test-generator/template-engine.js +4 -1
  62. package/dist/generators/test-generator/template-engine.js.map +1 -1
  63. package/dist/generators/test-generator/types.d.ts +7 -24
  64. package/dist/generators/test-generator/types.d.ts.map +1 -1
  65. package/dist/generators/test-generator/types.js +2 -101
  66. package/dist/generators/test-generator/types.js.map +1 -1
  67. package/dist/generators/test-generator/utils/selector-resolver.d.ts +14 -0
  68. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  69. package/dist/generators/test-generator/utils/selector-resolver.js +37 -11
  70. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  71. package/dist/orchestrator/project-initializer.d.ts +8 -0
  72. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  73. package/dist/orchestrator/project-initializer.js +343 -32
  74. package/dist/orchestrator/project-initializer.js.map +1 -1
  75. package/dist/orchestrator/screen-manager.d.ts +1 -32
  76. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  77. package/dist/orchestrator/screen-manager.js +55 -216
  78. package/dist/orchestrator/screen-manager.js.map +1 -1
  79. package/dist/utils/selector-types.d.ts +1 -1
  80. package/dist/utils/selector-types.d.ts.map +1 -1
  81. package/dist/utils/selector-types.js +3 -0
  82. package/dist/utils/selector-types.js.map +1 -1
  83. package/package.json +2 -2
  84. package/src/cli/commands/add.ts +5 -3
  85. package/src/cli/commands/generate.ts +90 -38
  86. package/src/cli/index.ts +5 -16
  87. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/frame-enter-action.hbs +1 -0
  88. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/frame-exit-action.hbs +1 -0
  89. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/keyboard-global-action.hbs +1 -0
  90. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/scroll-action.hbs +1 -0
  91. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -0
  92. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/label-value-assertion.hbs +2 -0
  93. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +3 -0
  94. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +3 -0
  95. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +2 -0
  96. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +2 -0
  97. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +2 -0
  98. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +2 -0
  99. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +2 -0
  100. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  101. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +11 -2
  102. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +11 -2
  103. package/src/generators/test-generator/code-generator.ts +0 -59
  104. package/src/generators/test-generator/patterns/assertion-patterns.ts +39 -8
  105. package/src/generators/test-generator/patterns/index.ts +12 -3
  106. package/src/generators/test-generator/patterns/interaction-patterns.ts +1 -1
  107. package/src/generators/test-generator/patterns/keyboard-patterns.ts +51 -0
  108. package/src/generators/test-generator/patterns/scope-patterns.ts +40 -0
  109. package/src/generators/test-generator/patterns/scroll-patterns.ts +27 -0
  110. package/src/generators/test-generator/patterns/table-patterns.ts +232 -0
  111. package/src/generators/test-generator/step-mapper.ts +39 -34
  112. package/src/generators/test-generator/template-engine.ts +3 -1
  113. package/src/generators/test-generator/types.ts +7 -112
  114. package/src/generators/test-generator/utils/selector-resolver.ts +70 -25
  115. package/src/orchestrator/project-initializer.ts +345 -32
  116. package/src/orchestrator/screen-manager.ts +61 -233
  117. package/src/utils/selector-types.ts +3 -0
  118. package/dist/cli/commands/cache-clear.d.ts +0 -3
  119. package/dist/cli/commands/cache-clear.d.ts.map +0 -1
  120. package/dist/cli/commands/cache-clear.js +0 -24
  121. package/dist/cli/commands/cache-clear.js.map +0 -1
  122. package/dist/cli/commands/full.d.ts +0 -3
  123. package/dist/cli/commands/full.d.ts.map +0 -1
  124. package/dist/cli/commands/full.js +0 -37
  125. package/dist/cli/commands/full.js.map +0 -1
  126. package/dist/cli/commands/live-scan.d.ts +0 -3
  127. package/dist/cli/commands/live-scan.d.ts.map +0 -1
  128. package/dist/cli/commands/live-scan.js +0 -78
  129. package/dist/cli/commands/live-scan.js.map +0 -1
  130. package/dist/cli/commands/map.d.ts +0 -3
  131. package/dist/cli/commands/map.d.ts.map +0 -1
  132. package/dist/cli/commands/map.js +0 -93
  133. package/dist/cli/commands/map.js.map +0 -1
  134. package/dist/cli/commands/validate.d.ts +0 -3
  135. package/dist/cli/commands/validate.d.ts.map +0 -1
  136. package/dist/cli/commands/validate.js +0 -43
  137. package/dist/cli/commands/validate.js.map +0 -1
  138. package/dist/cli/utils.d.ts +0 -6
  139. package/dist/cli/utils.d.ts.map +0 -1
  140. package/dist/cli/utils.js +0 -101
  141. package/dist/cli/utils.js.map +0 -1
  142. package/dist/config/config-loader.d.ts +0 -51
  143. package/dist/config/config-loader.d.ts.map +0 -1
  144. package/dist/config/config-loader.js +0 -216
  145. package/dist/config/config-loader.js.map +0 -1
  146. package/dist/config/config-schema.d.ts +0 -121
  147. package/dist/config/config-schema.d.ts.map +0 -1
  148. package/dist/config/config-schema.js +0 -7
  149. package/dist/config/config-schema.js.map +0 -1
  150. package/dist/core/live-scanner/config-reader.d.ts +0 -10
  151. package/dist/core/live-scanner/config-reader.d.ts.map +0 -1
  152. package/dist/core/live-scanner/config-reader.js +0 -87
  153. package/dist/core/live-scanner/config-reader.js.map +0 -1
  154. package/dist/core/live-scanner/element-finder.d.ts +0 -20
  155. package/dist/core/live-scanner/element-finder.d.ts.map +0 -1
  156. package/dist/core/live-scanner/element-finder.js +0 -486
  157. package/dist/core/live-scanner/element-finder.js.map +0 -1
  158. package/dist/core/live-scanner/index.d.ts +0 -8
  159. package/dist/core/live-scanner/index.d.ts.map +0 -1
  160. package/dist/core/live-scanner/index.js +0 -33
  161. package/dist/core/live-scanner/index.js.map +0 -1
  162. package/dist/core/live-scanner/matrix-reader.d.ts +0 -17
  163. package/dist/core/live-scanner/matrix-reader.d.ts.map +0 -1
  164. package/dist/core/live-scanner/matrix-reader.js +0 -60
  165. package/dist/core/live-scanner/matrix-reader.js.map +0 -1
  166. package/dist/core/live-scanner/matrix-writer.d.ts +0 -7
  167. package/dist/core/live-scanner/matrix-writer.d.ts.map +0 -1
  168. package/dist/core/live-scanner/matrix-writer.js +0 -103
  169. package/dist/core/live-scanner/matrix-writer.js.map +0 -1
  170. package/dist/core/live-scanner/role-fallback.d.ts +0 -15
  171. package/dist/core/live-scanner/role-fallback.d.ts.map +0 -1
  172. package/dist/core/live-scanner/role-fallback.js +0 -45
  173. package/dist/core/live-scanner/role-fallback.js.map +0 -1
  174. package/dist/core/live-scanner/scanner.d.ts +0 -13
  175. package/dist/core/live-scanner/scanner.d.ts.map +0 -1
  176. package/dist/core/live-scanner/scanner.js +0 -243
  177. package/dist/core/live-scanner/scanner.js.map +0 -1
  178. package/dist/core/live-scanner/step-replayer.d.ts +0 -26
  179. package/dist/core/live-scanner/step-replayer.d.ts.map +0 -1
  180. package/dist/core/live-scanner/step-replayer.js +0 -286
  181. package/dist/core/live-scanner/step-replayer.js.map +0 -1
  182. package/dist/core/live-scanner/types.d.ts +0 -52
  183. package/dist/core/live-scanner/types.d.ts.map +0 -1
  184. package/dist/core/live-scanner/types.js +0 -14
  185. package/dist/core/live-scanner/types.js.map +0 -1
  186. package/dist/core/selector-base/annotation-handler.d.ts +0 -45
  187. package/dist/core/selector-base/annotation-handler.d.ts.map +0 -1
  188. package/dist/core/selector-base/annotation-handler.js +0 -102
  189. package/dist/core/selector-base/annotation-handler.js.map +0 -1
  190. package/dist/core/selector-base/base-generator.d.ts +0 -49
  191. package/dist/core/selector-base/base-generator.d.ts.map +0 -1
  192. package/dist/core/selector-base/base-generator.js +0 -214
  193. package/dist/core/selector-base/base-generator.js.map +0 -1
  194. package/dist/core/selector-base/gherkin-parser.d.ts +0 -24
  195. package/dist/core/selector-base/gherkin-parser.d.ts.map +0 -1
  196. package/dist/core/selector-base/gherkin-parser.js +0 -42
  197. package/dist/core/selector-base/gherkin-parser.js.map +0 -1
  198. package/dist/core/selector-mapper/priority-mapper.d.ts +0 -74
  199. package/dist/core/selector-mapper/priority-mapper.d.ts.map +0 -1
  200. package/dist/core/selector-mapper/priority-mapper.js +0 -477
  201. package/dist/core/selector-mapper/priority-mapper.js.map +0 -1
  202. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts +0 -91
  203. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts.map +0 -1
  204. package/dist/core/ui-scanner/heuristics/base-heuristic.js +0 -175
  205. package/dist/core/ui-scanner/heuristics/base-heuristic.js.map +0 -1
  206. package/dist/core/ui-scanner/react-scanner.d.ts +0 -32
  207. package/dist/core/ui-scanner/react-scanner.d.ts.map +0 -1
  208. package/dist/core/ui-scanner/react-scanner.js +0 -163
  209. package/dist/core/ui-scanner/react-scanner.js.map +0 -1
  210. package/dist/core/ui-scanner/scanner-interface.d.ts +0 -94
  211. package/dist/core/ui-scanner/scanner-interface.d.ts.map +0 -1
  212. package/dist/core/ui-scanner/scanner-interface.js +0 -33
  213. package/dist/core/ui-scanner/scanner-interface.js.map +0 -1
  214. package/dist/core/ui-scanner/strict-scanner.d.ts +0 -81
  215. package/dist/core/ui-scanner/strict-scanner.d.ts.map +0 -1
  216. package/dist/core/ui-scanner/strict-scanner.js +0 -511
  217. package/dist/core/ui-scanner/strict-scanner.js.map +0 -1
  218. package/dist/core/validator/data-validator.d.ts +0 -38
  219. package/dist/core/validator/data-validator.d.ts.map +0 -1
  220. package/dist/core/validator/data-validator.js +0 -212
  221. package/dist/core/validator/data-validator.js.map +0 -1
  222. package/dist/core/validator/feature-validator.d.ts +0 -27
  223. package/dist/core/validator/feature-validator.d.ts.map +0 -1
  224. package/dist/core/validator/feature-validator.js +0 -182
  225. package/dist/core/validator/feature-validator.js.map +0 -1
  226. package/dist/core/validator/index.d.ts +0 -46
  227. package/dist/core/validator/index.d.ts.map +0 -1
  228. package/dist/core/validator/index.js +0 -17
  229. package/dist/core/validator/index.js.map +0 -1
  230. package/dist/core/validator/screen-validator.d.ts +0 -35
  231. package/dist/core/validator/screen-validator.d.ts.map +0 -1
  232. package/dist/core/validator/screen-validator.js +0 -195
  233. package/dist/core/validator/screen-validator.js.map +0 -1
  234. package/dist/core/validator/selector-validator.d.ts +0 -36
  235. package/dist/core/validator/selector-validator.d.ts.map +0 -1
  236. package/dist/core/validator/selector-validator.js +0 -210
  237. package/dist/core/validator/selector-validator.js.map +0 -1
  238. package/dist/external/ai-provider.d.ts +0 -60
  239. package/dist/external/ai-provider.d.ts.map +0 -1
  240. package/dist/external/ai-provider.js +0 -30
  241. package/dist/external/ai-provider.js.map +0 -1
  242. package/dist/external/anthropic-provider.d.ts +0 -29
  243. package/dist/external/anthropic-provider.d.ts.map +0 -1
  244. package/dist/external/anthropic-provider.js +0 -85
  245. package/dist/external/anthropic-provider.js.map +0 -1
  246. package/dist/generators/cache/cache-manager.d.ts +0 -66
  247. package/dist/generators/cache/cache-manager.d.ts.map +0 -1
  248. package/dist/generators/cache/cache-manager.js +0 -286
  249. package/dist/generators/cache/cache-manager.js.map +0 -1
  250. package/dist/generators/dsl-writer/index.d.ts +0 -33
  251. package/dist/generators/dsl-writer/index.d.ts.map +0 -1
  252. package/dist/generators/dsl-writer/index.js +0 -226
  253. package/dist/generators/dsl-writer/index.js.map +0 -1
  254. package/dist/generators/scaffold-generator/index.d.ts +0 -162
  255. package/dist/generators/scaffold-generator/index.d.ts.map +0 -1
  256. package/dist/generators/scaffold-generator/index.js +0 -868
  257. package/dist/generators/scaffold-generator/index.js.map +0 -1
  258. package/dist/generators/selector-mapper/ai-mapper.d.ts +0 -56
  259. package/dist/generators/selector-mapper/ai-mapper.d.ts.map +0 -1
  260. package/dist/generators/selector-mapper/ai-mapper.js +0 -457
  261. package/dist/generators/selector-mapper/ai-mapper.js.map +0 -1
  262. package/dist/generators/selector-mapper/hybrid-mapper.d.ts +0 -67
  263. package/dist/generators/selector-mapper/hybrid-mapper.d.ts.map +0 -1
  264. package/dist/generators/selector-mapper/hybrid-mapper.js +0 -349
  265. package/dist/generators/selector-mapper/hybrid-mapper.js.map +0 -1
  266. package/dist/generators/selector-mapper/index.d.ts +0 -8
  267. package/dist/generators/selector-mapper/index.d.ts.map +0 -1
  268. package/dist/generators/selector-mapper/index.js +0 -12
  269. package/dist/generators/selector-mapper/index.js.map +0 -1
  270. package/dist/generators/selector-mapper/intelligent-mapper.d.ts +0 -125
  271. package/dist/generators/selector-mapper/intelligent-mapper.d.ts.map +0 -1
  272. package/dist/generators/selector-mapper/intelligent-mapper.js +0 -391
  273. package/dist/generators/selector-mapper/intelligent-mapper.js.map +0 -1
  274. package/dist/generators/test-generator/ai-step-mapper.d.ts +0 -27
  275. package/dist/generators/test-generator/ai-step-mapper.d.ts.map +0 -1
  276. package/dist/generators/test-generator/ai-step-mapper.js +0 -204
  277. package/dist/generators/test-generator/ai-step-mapper.js.map +0 -1
  278. package/dist/generators/test-generator/auth-setup-generator.d.ts +0 -18
  279. package/dist/generators/test-generator/auth-setup-generator.d.ts.map +0 -1
  280. package/dist/generators/test-generator/auth-setup-generator.js +0 -82
  281. package/dist/generators/test-generator/auth-setup-generator.js.map +0 -1
  282. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts +0 -7
  283. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts.map +0 -1
  284. package/dist/generators/test-generator/patterns/legacy-patterns.js +0 -98
  285. package/dist/generators/test-generator/patterns/legacy-patterns.js.map +0 -1
  286. package/dist/generators/test-generator/templates/auth-setup.ts.hbs +0 -36
  287. package/dist/generators/ui-model-builder/deep-scanner.d.ts +0 -121
  288. package/dist/generators/ui-model-builder/deep-scanner.d.ts.map +0 -1
  289. package/dist/generators/ui-model-builder/deep-scanner.js +0 -1113
  290. package/dist/generators/ui-model-builder/deep-scanner.js.map +0 -1
  291. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts +0 -110
  292. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts.map +0 -1
  293. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js +0 -608
  294. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js.map +0 -1
  295. package/dist/generators/ui-model-builder/react-scanner.d.ts +0 -107
  296. package/dist/generators/ui-model-builder/react-scanner.d.ts.map +0 -1
  297. package/dist/generators/ui-model-builder/react-scanner.js +0 -797
  298. package/dist/generators/ui-model-builder/react-scanner.js.map +0 -1
  299. package/dist/orchestrator/cache-manager.d.ts +0 -15
  300. package/dist/orchestrator/cache-manager.d.ts.map +0 -1
  301. package/dist/orchestrator/cache-manager.js +0 -62
  302. package/dist/orchestrator/cache-manager.js.map +0 -1
  303. package/dist/orchestrator/pipeline.d.ts +0 -56
  304. package/dist/orchestrator/pipeline.d.ts.map +0 -1
  305. package/dist/orchestrator/pipeline.js +0 -298
  306. package/dist/orchestrator/pipeline.js.map +0 -1
  307. package/dist/orchestrator/reporter.d.ts +0 -15
  308. package/dist/orchestrator/reporter.d.ts.map +0 -1
  309. package/dist/orchestrator/reporter.js +0 -30
  310. package/dist/orchestrator/reporter.js.map +0 -1
  311. package/src/cli/commands/cache-clear.ts +0 -22
  312. package/src/cli/commands/full.ts +0 -35
  313. package/src/cli/commands/live-scan.ts +0 -82
  314. package/src/cli/commands/map.ts +0 -97
  315. package/src/cli/commands/validate.ts +0 -43
  316. package/src/cli/utils.ts +0 -106
  317. package/src/config/ai-providers.yaml +0 -56
  318. package/src/config/config-loader.ts +0 -248
  319. package/src/config/config-schema.ts +0 -148
  320. package/src/config/default.config.yaml +0 -107
  321. package/src/config/framework.config.yaml +0 -52
  322. package/src/config/routes.yaml +0 -31
  323. package/src/core/live-scanner/config-reader.ts +0 -57
  324. package/src/core/live-scanner/element-finder.ts +0 -541
  325. package/src/core/live-scanner/index.ts +0 -7
  326. package/src/core/live-scanner/matrix-reader.ts +0 -65
  327. package/src/core/live-scanner/matrix-writer.ts +0 -77
  328. package/src/core/live-scanner/role-fallback.ts +0 -43
  329. package/src/core/live-scanner/scanner.ts +0 -254
  330. package/src/core/live-scanner/step-replayer.ts +0 -306
  331. package/src/core/live-scanner/types.ts +0 -58
  332. package/src/core/selector-base/annotation-handler.ts +0 -127
  333. package/src/core/selector-base/base-generator.ts +0 -234
  334. package/src/core/selector-base/gherkin-parser.ts +0 -57
  335. package/src/core/selector-mapper/priority-mapper.ts +0 -607
  336. package/src/core/ui-scanner/heuristics/base-heuristic.ts +0 -216
  337. package/src/core/ui-scanner/react-scanner.ts +0 -156
  338. package/src/core/ui-scanner/scanner-interface.ts +0 -133
  339. package/src/core/ui-scanner/strict-scanner.ts +0 -629
  340. package/src/core/validator/data-validator.ts +0 -202
  341. package/src/core/validator/feature-validator.ts +0 -176
  342. package/src/core/validator/index.ts +0 -57
  343. package/src/core/validator/screen-validator.ts +0 -209
  344. package/src/core/validator/selector-validator.ts +0 -209
  345. package/src/external/ai-provider.ts +0 -90
  346. package/src/external/anthropic-provider.ts +0 -114
  347. package/src/generators/README.md +0 -410
  348. package/src/generators/cache/cache-manager.ts +0 -322
  349. package/src/generators/dsl-writer/index.ts +0 -253
  350. package/src/generators/scaffold-generator/index.ts +0 -1019
  351. package/src/generators/selector-mapper/ai-mapper.ts +0 -528
  352. package/src/generators/selector-mapper/hybrid-mapper.ts +0 -427
  353. package/src/generators/selector-mapper/index.ts +0 -10
  354. package/src/generators/selector-mapper/intelligent-mapper.ts +0 -530
  355. package/src/generators/test-generator/ai-step-mapper.ts +0 -224
  356. package/src/generators/test-generator/auth-setup-generator.ts +0 -59
  357. package/src/generators/test-generator/patterns/legacy-patterns.ts +0 -104
  358. package/src/generators/test-generator/templates/auth-setup.ts.hbs +0 -36
  359. package/src/generators/ui-model-builder/deep-scanner.ts +0 -1244
  360. package/src/generators/ui-model-builder/enhanced-deep-scanner.ts +0 -731
  361. package/src/generators/ui-model-builder/react-scanner.ts +0 -959
  362. package/src/orchestrator/cache-manager.ts +0 -32
  363. package/src/orchestrator/pipeline.ts +0 -354
  364. package/src/orchestrator/reporter.ts +0 -36
@@ -1,82 +0,0 @@
1
- import { Command } from 'commander';
2
-
3
- export function registerLiveScanCommand(program: Command): void {
4
- program
5
- .command('live-scan')
6
- .description('Scan a live site to discover real selectors for Gherkin element references')
7
- .requiredOption('-s, --screen <name>', 'Screen name to scan')
8
- .option('--url <baseUrl>', 'Override base URL (default: read from playwright.config.ts)')
9
- .option('--headed', 'Launch browser in headed (visible) mode', false)
10
- .option('--auth-dir <path>', 'Directory containing auth storage state files', 'specs/.auth')
11
- .option('-f, --force', 'Force rescan all elements, ignoring existing results', false)
12
- .action(async (options) => {
13
- try {
14
- const { LiveScanner } = require('../../core/live-scanner');
15
-
16
- console.log('\n🔍 Sungen Live Scanner\n');
17
- console.log(`📍 Screen: ${options.screen}`);
18
- console.log(`🖥️ Mode: ${options.headed ? 'headed' : 'headless'}`);
19
- if (options.force) {
20
- console.log(`🔄 Force mode: rescanning all elements`);
21
- }
22
-
23
- const scanner = new LiveScanner({
24
- baseUrl: options.url,
25
- screenName: options.screen,
26
- screensDir: 'qa/screens',
27
- headed: options.headed,
28
- authDir: options.authDir,
29
- force: options.force,
30
- });
31
-
32
- const results = await scanner.scan();
33
-
34
- // Print final summary
35
- console.log('\n📊 SCAN SUMMARY\n');
36
-
37
- let totalElements = 0;
38
- let totalResolved = 0;
39
- let totalWarnings = 0;
40
- let totalUnresolved = 0;
41
- let totalSkipped = 0;
42
-
43
- for (const result of results) {
44
- for (const scenario of Object.values(result.scenarios) as any[]) {
45
- for (const element of Object.values(scenario.elements) as any[]) {
46
- totalElements++;
47
- if ((element as any).skipped) {
48
- totalSkipped++;
49
- totalResolved++;
50
- } else if (element.matchMethod === 'unresolved') {
51
- totalUnresolved++;
52
- } else {
53
- totalResolved++;
54
- if (element.warning) totalWarnings++;
55
- }
56
- }
57
- }
58
- }
59
-
60
- console.log(`Total Elements: ${totalElements}`);
61
- console.log(`Resolved: ${totalResolved}`);
62
- if (totalSkipped > 0) {
63
- console.log(`Skipped (cached): ${totalSkipped}`);
64
- }
65
- console.log(`Warnings: ${totalWarnings}`);
66
- console.log(`Unresolved: ${totalUnresolved}`);
67
-
68
- if (totalUnresolved > 0) {
69
- console.log(`\n⚠️ ${totalUnresolved} element(s) could not be found on the live site`);
70
- }
71
-
72
- if (totalResolved > 0) {
73
- console.log(`\n✅ Live scan complete. Run 'sungen map --screen ${options.screen}' to generate selectors.`);
74
- }
75
-
76
- console.log('');
77
- } catch (error: any) {
78
- console.error('\n❌ Live scan failed:', error.message);
79
- process.exit(1);
80
- }
81
- });
82
- }
@@ -1,97 +0,0 @@
1
- import { Command } from 'commander';
2
- import { ConfigLoader } from '../../config/config-loader';
3
-
4
- export function registerMapCommand(program: Command): void {
5
- program
6
- .command('map')
7
- .description('Generate selector and test-data YAML from Gherkin feature files')
8
- .option('-s, --screen <name>', 'Screen name (reads from qa/screens/<name>/features/)')
9
- .option('--file <path>', 'Single feature file path (generates selectors next to features folder)')
10
- .option('-o, --output <dir>', 'Output directory for generated files')
11
- .option('-f, --force', 'Force overwrite existing YAML files and rescan all elements')
12
- .option('--skip-live-scan', 'Skip live-scan before mapping (live-scan runs by default)')
13
- .option('--headed', 'Launch browser in headed mode during live-scan', false)
14
- .option('--auth-dir <path>', 'Auth storage state directory for live-scan', 'specs/.auth')
15
- .option('-v, --verbose', 'Detailed output')
16
- .action(async (options) => {
17
- try {
18
- const path = require('path');
19
- const cliOptions = {
20
- ...program.opts(),
21
- ...options,
22
- };
23
- const config = new ConfigLoader().load(cliOptions);
24
- const { ScaffoldGenerator } = require('../../generators/scaffold-generator');
25
-
26
- const generator = new ScaffoldGenerator();
27
-
28
- if (options.screen) {
29
- const screensDir = options.output || 'qa/screens';
30
- const forceOverwrite = cliOptions.force || false;
31
-
32
- // Run live-scan by default before mapping (skip with --skip-live-scan)
33
- if (!options.skipLiveScan) {
34
- const { LiveScanner } = require('../../core/live-scanner');
35
- console.log('🔍 Running live-scan before mapping...\n');
36
-
37
- const scanner = new LiveScanner({
38
- screenName: options.screen,
39
- screensDir,
40
- headed: options.headed,
41
- authDir: options.authDir,
42
- });
43
-
44
- await scanner.scan();
45
- console.log('');
46
- }
47
-
48
- if (forceOverwrite) {
49
- console.log(`Mapping screen: ${options.screen} (force: selectors will be overwritten)\n`);
50
- } else {
51
- console.log(`Mapping screen: ${options.screen}\n`);
52
- }
53
-
54
- const results = generator.processScreen(options.screen, screensDir, forceOverwrite);
55
-
56
- for (const result of results) {
57
- console.log(`✓ Mapped ${result.featureFile}.feature`);
58
-
59
- if (result.selectorsSkipped) {
60
- console.log(` ⊘ ${path.basename(result.selectorsPath)} (skipped - already exists)`);
61
- } else {
62
- console.log(` → ${path.basename(result.selectorsPath)} (${result.elementCount} elements)`);
63
- }
64
-
65
- if (result.testDataMerged) {
66
- console.log(` ↻ ${path.basename(result.testDataPath)} (smart-merged — ${result.dataRefCount} variables)\n`);
67
- } else {
68
- console.log(` → ${path.basename(result.testDataPath)} (${result.dataRefCount} variables)\n`);
69
- }
70
- }
71
-
72
- console.log(`Next step: sungen generate --screen ${options.screen}`);
73
- console.log(' This will create the test specs based on the mapped selectors and test data.');
74
- } else if (options.file) {
75
- const deriveOutputDir = (featureFilePath: string): string => {
76
- const featureDir = path.dirname(featureFilePath);
77
- if (featureDir.includes('features')) {
78
- return featureDir.replace(/features\/?$/, 'selectors/screens');
79
- }
80
- return path.join(featureDir, '..', 'selectors', 'screens');
81
- };
82
-
83
- const outputDir = options.output || deriveOutputDir(options.file);
84
- const forceOverwrite = cliOptions.force || false;
85
- console.log(`Mapping from file: ${options.file}\n`);
86
- const result = generator.processFeatureFile(options.file, outputDir, forceOverwrite);
87
- console.log(`✓ Generated: ${result.outputPath} (${result.elementCount} elements)`);
88
- } else {
89
- console.error('❌ Error: Please specify --screen <name> or --file <path>');
90
- process.exit(1);
91
- }
92
- } catch (error) {
93
- console.error('❌ Mapping failed:', error);
94
- process.exit(1);
95
- }
96
- });
97
- }
@@ -1,43 +0,0 @@
1
- import { Command } from 'commander';
2
- import { ValidationResult } from '../../core/validator';
3
- import { printValidationResult } from '../utils';
4
-
5
- export function registerValidateCommand(program: Command): void {
6
- program
7
- .command('validate')
8
- .description('Validate Gherkin features and selector/test-data mappings')
9
- .option('-s, --screen <name>', 'Validate specific screen (optional, defaults to all)')
10
- .option('--json', 'Output results as JSON')
11
- .option('-v, --verbose', 'Show all checks, not just failures')
12
- .action(async (options) => {
13
- try {
14
- const { ScreenValidator } = require('../../core/validator');
15
-
16
- const validator = new ScreenValidator({
17
- verbose: options.verbose,
18
- });
19
-
20
- let result: ValidationResult;
21
- if (options.screen) {
22
- console.log(`Validating screen: ${options.screen}\n`);
23
- result = validator.validateScreen(options.screen);
24
- } else {
25
- console.log('Validating all screens...\n');
26
- result = validator.validateAll();
27
- }
28
-
29
- if (options.json) {
30
- console.log(JSON.stringify(result, null, 2));
31
- } else {
32
- printValidationResult(result, options.verbose);
33
- }
34
-
35
- if (!result.valid) {
36
- process.exit(1);
37
- }
38
- } catch (error) {
39
- console.error('❌ Validation failed:', error);
40
- process.exit(1);
41
- }
42
- });
43
- }
package/src/cli/utils.ts DELETED
@@ -1,106 +0,0 @@
1
- import { ValidationResult } from '../core/validator';
2
-
3
- /**
4
- * Get human-readable description for error code
5
- */
6
- function getErrorDescription(code: string): string {
7
- switch (code) {
8
- case 'GHERKIN_SYNTAX_ERROR': return 'Gherkin syntax errors';
9
- case 'MISSING_PATH_METADATA': return 'missing Path: metadata';
10
- case 'MISSING_SELECTOR_FILE': return 'missing selector files';
11
- case 'MISSING_SELECTOR': return 'missing selector definitions';
12
- case 'MISSING_DATA_FILE': return 'missing test-data files';
13
- case 'MISSING_DATA_REF': return 'missing data references';
14
- case 'INVALID_YAML_SYNTAX': return 'invalid YAML syntax';
15
- case 'INVALID_SELECTOR_TYPE': return 'invalid selector types';
16
- case 'INVALID_DATA_VALUE': return 'invalid data values';
17
- case 'EMPTY_FEATURE': return 'empty feature files';
18
- default: return 'errors';
19
- }
20
- }
21
-
22
- /**
23
- * Print validation result to console
24
- */
25
- export function printValidationResult(result: ValidationResult, verbose: boolean = false): void {
26
- for (const fileResult of result.results) {
27
- if (fileResult.valid) {
28
- if (verbose) {
29
- console.log(`✓ ${fileResult.file}`);
30
- console.log(` ✓ Gherkin syntax valid`);
31
- if (fileResult.warnings.length === 0) {
32
- console.log(` ✓ All checks passed`);
33
- }
34
- } else {
35
- console.log(`✓ ${fileResult.file}`);
36
- }
37
- } else {
38
- console.log(`✗ ${fileResult.file}`);
39
- }
40
-
41
- for (const warning of fileResult.warnings) {
42
- const lineInfo = warning.line ? `:${warning.line}` : '';
43
- console.log(` ⊘ ${warning.message}${lineInfo}`);
44
- }
45
-
46
- for (const error of fileResult.errors) {
47
- const lineInfo = error.line ? `:${error.line}` : '';
48
- console.log(` ✗ ${error.message}${lineInfo}`);
49
- }
50
-
51
- if (!fileResult.valid || (verbose && fileResult.warnings.length > 0)) {
52
- console.log('');
53
- }
54
- }
55
-
56
- console.log('\nSummary:');
57
- console.log(` Files: ${result.summary.totalFiles} total, ${result.summary.passedFiles} passed, ${result.summary.failedFiles} failed`);
58
- console.log(` Errors: ${result.summary.totalErrors}`);
59
- console.log(` Warnings: ${result.summary.totalWarnings}`);
60
-
61
- if (result.summary.totalErrors > 0) {
62
- const errorsByType = new Map<string, number>();
63
- const errorsByFile = new Map<string, string[]>();
64
-
65
- for (const fileResult of result.results) {
66
- for (const error of fileResult.errors) {
67
- errorsByType.set(error.code, (errorsByType.get(error.code) || 0) + 1);
68
-
69
- if (error.code === 'MISSING_SELECTOR' || error.code === 'MISSING_DATA_REF') {
70
- if (!errorsByFile.has(fileResult.file)) {
71
- errorsByFile.set(fileResult.file, []);
72
- }
73
- if (error.element) {
74
- errorsByFile.get(fileResult.file)!.push(error.element);
75
- }
76
- }
77
- }
78
- }
79
-
80
- console.log('\nError Breakdown:');
81
- for (const [code, count] of errorsByType.entries()) {
82
- const description = getErrorDescription(code);
83
- console.log(` ${code}: ${count} ${description}`);
84
- }
85
-
86
- if (errorsByType.has('MISSING_SELECTOR_FILE') || errorsByType.has('MISSING_DATA_FILE')) {
87
- console.log('\n💡 Suggested Fix:');
88
- console.log(' Run: sungen map --screen <name>');
89
- console.log(' This will generate missing selector and test-data files');
90
- } else if (errorsByType.has('MISSING_SELECTOR') || errorsByType.has('MISSING_DATA_REF')) {
91
- console.log('\n💡 Suggested Fix:');
92
- if (errorsByType.has('MISSING_SELECTOR')) {
93
- console.log(' Missing selectors - Add them to the selector YAML files');
94
- }
95
- if (errorsByType.has('MISSING_DATA_REF')) {
96
- console.log(' Missing data refs - Add them to the test-data YAML files');
97
- }
98
- }
99
- }
100
-
101
- if (result.valid) {
102
- console.log('\n✅ Validation passed');
103
- } else {
104
- console.log('\n❌ Validation failed');
105
- }
106
- }
@@ -1,56 +0,0 @@
1
- # AI Provider Configuration
2
-
3
- providers:
4
- # Claude - Best for DSL generation (cheap + fast)
5
- claude:
6
- generation:
7
- model: "claude-3-haiku-20240307"
8
- temperature: 0.2
9
- maxTokens: 2048
10
- vision:
11
- model: "claude-3-sonnet-20240229"
12
- temperature: 0.3
13
- maxTokens: 4096
14
-
15
- # OpenAI - Best for vision tasks
16
- openai:
17
- generation:
18
- model: "gpt-4o-mini"
19
- temperature: 0.2
20
- maxTokens: 2048
21
- vision:
22
- model: "gpt-4o"
23
- temperature: 0.3
24
- maxTokens: 4096
25
-
26
- # Gemini - Alternative provider
27
- gemini:
28
- generation:
29
- model: "gemini-1.5-flash"
30
- temperature: 0.2
31
- maxTokens: 2048
32
- vision:
33
- model: "gemini-1.5-pro"
34
- temperature: 0.3
35
- maxTokens: 4096
36
-
37
- # Default provider for each task type
38
- defaults:
39
- generation: "claude"
40
- vision: "openai"
41
- analysis: "claude"
42
-
43
- # Cost optimization (estimated cost per 1M tokens)
44
- costs:
45
- claude-haiku:
46
- input: 0.25
47
- output: 1.25
48
- gpt-4o-mini:
49
- input: 0.15
50
- output: 0.60
51
- gpt-4o:
52
- input: 2.50
53
- output: 10.00
54
- gemini-flash:
55
- input: 0.075
56
- output: 0.30
@@ -1,248 +0,0 @@
1
- /**
2
- * Configuration Loader
3
- * Loads and merges configuration from multiple sources with priority:
4
- * CLI Options > Custom Config File > Default Config File
5
- */
6
-
7
- import fs from 'fs';
8
- import path from 'path';
9
- import yaml from 'yaml';
10
- import { FrameworkConfig, CLIOptions, RuntimeConfig } from './config-schema';
11
-
12
- export class ConfigLoader {
13
- private defaultConfigPath: string;
14
-
15
- constructor() {
16
- this.defaultConfigPath = path.join(__dirname, 'default.config.yaml');
17
- }
18
-
19
- /**
20
- * Load runtime configuration with priority merging
21
- * Priority: CLI > Custom File > Default File
22
- */
23
- load(cliOptions: CLIOptions = {}): RuntimeConfig {
24
- // 1. Load default config
25
- const defaultConfig = this.loadDefaultConfig();
26
-
27
- // 2. Load custom config file if specified, or look for sungen.config.yaml in CWD
28
- let fileConfig: Partial<FrameworkConfig> = {};
29
- let configSource: 'default' | 'file' | 'cli' = 'default';
30
-
31
- if (cliOptions.config) {
32
- fileConfig = this.loadCustomConfig(cliOptions.config);
33
- configSource = 'file';
34
- } else {
35
- // Try to load sungen.config.yaml from current working directory
36
- const defaultConfigPath = path.join(process.cwd(), 'sungen.config.yaml');
37
- if (fs.existsSync(defaultConfigPath)) {
38
- fileConfig = this.loadCustomConfig(defaultConfigPath);
39
- configSource = 'file';
40
- }
41
- }
42
-
43
- // 3. Merge configs: default < file < CLI
44
- const mergedConfig = this.mergeConfigs(defaultConfig, fileConfig, cliOptions);
45
-
46
- // Override source if CLI has significant options
47
- if (Object.keys(cliOptions).length > 0) {
48
- configSource = 'cli';
49
- }
50
-
51
- return {
52
- ...mergedConfig,
53
- cliOptions,
54
- configSource
55
- };
56
- }
57
-
58
- /**
59
- * Load default configuration from default.config.yaml
60
- */
61
- private loadDefaultConfig(): FrameworkConfig {
62
- try {
63
- const content = fs.readFileSync(this.defaultConfigPath, 'utf-8');
64
- return yaml.parse(content) as FrameworkConfig;
65
- } catch (error) {
66
- throw new Error(`Failed to load default config: ${error}`);
67
- }
68
- }
69
-
70
- /**
71
- * Load custom configuration file
72
- */
73
- private loadCustomConfig(configPath: string): Partial<FrameworkConfig> {
74
- try {
75
- const fullPath = path.resolve(configPath);
76
-
77
- if (!fs.existsSync(fullPath)) {
78
- throw new Error(`Config file not found: ${fullPath}`);
79
- }
80
-
81
- const content = fs.readFileSync(fullPath, 'utf-8');
82
- return yaml.parse(content) as Partial<FrameworkConfig>;
83
- } catch (error) {
84
- throw new Error(`Failed to load custom config: ${error}`);
85
- }
86
- }
87
-
88
- /**
89
- * Merge configurations with priority: CLI > File > Default
90
- */
91
- private mergeConfigs(
92
- defaultConfig: FrameworkConfig,
93
- fileConfig: Partial<FrameworkConfig>,
94
- cliOptions: CLIOptions
95
- ): FrameworkConfig {
96
- // Deep merge default + file config
97
- const merged = this.deepMerge(defaultConfig, fileConfig);
98
-
99
- // Apply CLI overrides (highest priority)
100
- if (cliOptions.verbose !== undefined) {
101
- merged.verbose = cliOptions.verbose;
102
- }
103
-
104
- if (cliOptions.force !== undefined) {
105
- merged.force = cliOptions.force;
106
- }
107
-
108
- if (cliOptions.depth !== undefined) {
109
- merged.scanner.maxDepth = cliOptions.depth;
110
- }
111
-
112
- if (cliOptions.aiMapper !== undefined) {
113
- merged.testGenerator.enableAIFallback = cliOptions.aiMapper;
114
- }
115
-
116
- if (cliOptions.framework !== undefined) {
117
- merged.testGenerator.framework = cliOptions.framework;
118
- }
119
-
120
- // Selector mapping mode overrides
121
- if (cliOptions.mode !== undefined) {
122
- merged.selectorMapping.mode = cliOptions.mode;
123
- }
124
-
125
- return merged;
126
- }
127
-
128
- /**
129
- * Deep merge two objects
130
- */
131
- private deepMerge<T>(target: T, source: Partial<T>): T {
132
- const result = { ...target };
133
-
134
- for (const key in source) {
135
- const sourceValue = source[key];
136
- const targetValue = result[key];
137
-
138
- if (sourceValue === undefined) {
139
- continue;
140
- }
141
-
142
- if (this.isObject(sourceValue) && this.isObject(targetValue)) {
143
- result[key] = this.deepMerge(targetValue, sourceValue as any);
144
- } else {
145
- result[key] = sourceValue as any;
146
- }
147
- }
148
-
149
- return result;
150
- }
151
-
152
- /**
153
- * Check if value is a plain object
154
- */
155
- private isObject(value: any): value is Record<string, any> {
156
- return value !== null && typeof value === 'object' && !Array.isArray(value);
157
- }
158
-
159
- /**
160
- * Validate configuration
161
- */
162
- validate(config: RuntimeConfig): void {
163
- const errors: string[] = [];
164
-
165
- // Validate required paths
166
- if (!config.paths.sourceRoot) {
167
- errors.push('paths.sourceRoot is required');
168
- }
169
-
170
- // Validate scanner
171
- if (!['react', 'vue', 'angular'].includes(config.scanner.framework)) {
172
- errors.push(`Invalid scanner.framework: ${config.scanner.framework}`);
173
- }
174
-
175
- if (config.scanner.maxDepth < 1) {
176
- errors.push('scanner.maxDepth must be >= 1');
177
- }
178
-
179
- // Validate AI provider
180
- if (!['anthropic', 'copilot', 'openai'].includes(config.selectorMapping.aiProvider)) {
181
- errors.push(`Invalid selectorMapping.aiProvider: ${config.selectorMapping.aiProvider}`);
182
- }
183
-
184
- // Validate test framework
185
- if (!['playwright', 'appium', 'integration'].includes(config.testGenerator.framework)) {
186
- errors.push(`Invalid testGenerator.framework: ${config.testGenerator.framework}`);
187
- }
188
-
189
- if (errors.length > 0) {
190
- throw new Error(`Configuration validation failed:\n${errors.join('\n')}`);
191
- }
192
- }
193
-
194
- /**
195
- * Get configuration value by path (dot notation)
196
- * Example: get('scanner.maxDepth')
197
- */
198
- get(config: RuntimeConfig, path: string): any {
199
- return path.split('.').reduce((obj, key) => obj?.[key], config as any);
200
- }
201
-
202
- /**
203
- * Display current configuration (for debugging)
204
- */
205
- display(config: RuntimeConfig): string {
206
- const displayed = {
207
- version: config.version,
208
- source: config.configSource,
209
- verbose: config.verbose,
210
- force: config.force,
211
- scanner: {
212
- framework: config.scanner.framework,
213
- maxDepth: config.scanner.maxDepth
214
- },
215
- selectorMapping: {
216
- aiProvider: config.selectorMapping.aiProvider,
217
- model: config.selectorMapping.model
218
- },
219
- testGenerator: {
220
- framework: config.testGenerator.framework,
221
- aiProvider: config.testGenerator.aiProvider,
222
- enableAIFallback: config.testGenerator.enableAIFallback
223
- },
224
- cache: {
225
- enabled: config.cache.enabled
226
- }
227
- };
228
-
229
- return yaml.stringify(displayed);
230
- }
231
- }
232
-
233
- // Singleton instance
234
- let configLoader: ConfigLoader;
235
-
236
- export function getConfigLoader(): ConfigLoader {
237
- if (!configLoader) {
238
- configLoader = new ConfigLoader();
239
- }
240
- return configLoader;
241
- }
242
-
243
- export function loadConfig(cliOptions: CLIOptions = {}): RuntimeConfig {
244
- const loader = getConfigLoader();
245
- const config = loader.load(cliOptions);
246
- loader.validate(config);
247
- return config;
248
- }