@sun-asterisk/sungen 1.0.24 → 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 (362) 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/table-cell-by-filter.hbs +3 -0
  17. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +3 -0
  18. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +2 -0
  19. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +2 -0
  20. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +2 -0
  21. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +2 -0
  22. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +2 -0
  23. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  24. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +11 -2
  25. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +11 -2
  26. package/dist/generators/test-generator/code-generator.d.ts +0 -1
  27. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  28. package/dist/generators/test-generator/code-generator.js +0 -47
  29. package/dist/generators/test-generator/code-generator.js.map +1 -1
  30. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  31. package/dist/generators/test-generator/patterns/assertion-patterns.js +2 -0
  32. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  33. package/dist/generators/test-generator/patterns/index.d.ts +4 -1
  34. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  35. package/dist/generators/test-generator/patterns/index.js +17 -5
  36. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  37. package/dist/generators/test-generator/patterns/interaction-patterns.js +1 -1
  38. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  39. package/dist/generators/test-generator/patterns/keyboard-patterns.d.ts +7 -0
  40. package/dist/generators/test-generator/patterns/keyboard-patterns.d.ts.map +1 -0
  41. package/dist/generators/test-generator/patterns/keyboard-patterns.js +47 -0
  42. package/dist/generators/test-generator/patterns/keyboard-patterns.js.map +1 -0
  43. package/dist/generators/test-generator/patterns/scope-patterns.d.ts +7 -0
  44. package/dist/generators/test-generator/patterns/scope-patterns.d.ts.map +1 -0
  45. package/dist/generators/test-generator/patterns/scope-patterns.js +36 -0
  46. package/dist/generators/test-generator/patterns/scope-patterns.js.map +1 -0
  47. package/dist/generators/test-generator/patterns/scroll-patterns.d.ts +7 -0
  48. package/dist/generators/test-generator/patterns/scroll-patterns.d.ts.map +1 -0
  49. package/dist/generators/test-generator/patterns/scroll-patterns.js +25 -0
  50. package/dist/generators/test-generator/patterns/scroll-patterns.js.map +1 -0
  51. package/dist/generators/test-generator/patterns/table-patterns.d.ts +7 -0
  52. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -0
  53. package/dist/generators/test-generator/patterns/table-patterns.js +192 -0
  54. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -0
  55. package/dist/generators/test-generator/step-mapper.d.ts +1 -3
  56. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  57. package/dist/generators/test-generator/step-mapper.js +30 -27
  58. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  59. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  60. package/dist/generators/test-generator/template-engine.js +4 -1
  61. package/dist/generators/test-generator/template-engine.js.map +1 -1
  62. package/dist/generators/test-generator/types.d.ts +7 -24
  63. package/dist/generators/test-generator/types.d.ts.map +1 -1
  64. package/dist/generators/test-generator/types.js +2 -101
  65. package/dist/generators/test-generator/types.js.map +1 -1
  66. package/dist/generators/test-generator/utils/selector-resolver.d.ts +14 -0
  67. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  68. package/dist/generators/test-generator/utils/selector-resolver.js +37 -11
  69. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  70. package/dist/orchestrator/project-initializer.d.ts +8 -0
  71. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  72. package/dist/orchestrator/project-initializer.js +343 -32
  73. package/dist/orchestrator/project-initializer.js.map +1 -1
  74. package/dist/orchestrator/screen-manager.d.ts +1 -32
  75. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  76. package/dist/orchestrator/screen-manager.js +55 -216
  77. package/dist/orchestrator/screen-manager.js.map +1 -1
  78. package/dist/utils/selector-types.d.ts +1 -1
  79. package/dist/utils/selector-types.d.ts.map +1 -1
  80. package/dist/utils/selector-types.js +3 -0
  81. package/dist/utils/selector-types.js.map +1 -1
  82. package/package.json +2 -2
  83. package/src/cli/commands/add.ts +5 -3
  84. package/src/cli/commands/generate.ts +90 -38
  85. package/src/cli/index.ts +5 -16
  86. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/frame-enter-action.hbs +1 -0
  87. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/frame-exit-action.hbs +1 -0
  88. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/keyboard-global-action.hbs +1 -0
  89. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/scroll-action.hbs +1 -0
  90. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -0
  91. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +3 -0
  92. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +3 -0
  93. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +2 -0
  94. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +2 -0
  95. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +2 -0
  96. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +2 -0
  97. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +2 -0
  98. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  99. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +11 -2
  100. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +11 -2
  101. package/src/generators/test-generator/code-generator.ts +0 -59
  102. package/src/generators/test-generator/patterns/assertion-patterns.ts +2 -0
  103. package/src/generators/test-generator/patterns/index.ts +12 -3
  104. package/src/generators/test-generator/patterns/interaction-patterns.ts +1 -1
  105. package/src/generators/test-generator/patterns/keyboard-patterns.ts +51 -0
  106. package/src/generators/test-generator/patterns/scope-patterns.ts +40 -0
  107. package/src/generators/test-generator/patterns/scroll-patterns.ts +27 -0
  108. package/src/generators/test-generator/patterns/table-patterns.ts +232 -0
  109. package/src/generators/test-generator/step-mapper.ts +33 -27
  110. package/src/generators/test-generator/template-engine.ts +3 -1
  111. package/src/generators/test-generator/types.ts +7 -112
  112. package/src/generators/test-generator/utils/selector-resolver.ts +70 -25
  113. package/src/orchestrator/project-initializer.ts +345 -32
  114. package/src/orchestrator/screen-manager.ts +61 -233
  115. package/src/utils/selector-types.ts +3 -0
  116. package/dist/cli/commands/cache-clear.d.ts +0 -3
  117. package/dist/cli/commands/cache-clear.d.ts.map +0 -1
  118. package/dist/cli/commands/cache-clear.js +0 -24
  119. package/dist/cli/commands/cache-clear.js.map +0 -1
  120. package/dist/cli/commands/full.d.ts +0 -3
  121. package/dist/cli/commands/full.d.ts.map +0 -1
  122. package/dist/cli/commands/full.js +0 -37
  123. package/dist/cli/commands/full.js.map +0 -1
  124. package/dist/cli/commands/live-scan.d.ts +0 -3
  125. package/dist/cli/commands/live-scan.d.ts.map +0 -1
  126. package/dist/cli/commands/live-scan.js +0 -78
  127. package/dist/cli/commands/live-scan.js.map +0 -1
  128. package/dist/cli/commands/map.d.ts +0 -3
  129. package/dist/cli/commands/map.d.ts.map +0 -1
  130. package/dist/cli/commands/map.js +0 -93
  131. package/dist/cli/commands/map.js.map +0 -1
  132. package/dist/cli/commands/validate.d.ts +0 -3
  133. package/dist/cli/commands/validate.d.ts.map +0 -1
  134. package/dist/cli/commands/validate.js +0 -43
  135. package/dist/cli/commands/validate.js.map +0 -1
  136. package/dist/cli/utils.d.ts +0 -6
  137. package/dist/cli/utils.d.ts.map +0 -1
  138. package/dist/cli/utils.js +0 -101
  139. package/dist/cli/utils.js.map +0 -1
  140. package/dist/config/config-loader.d.ts +0 -51
  141. package/dist/config/config-loader.d.ts.map +0 -1
  142. package/dist/config/config-loader.js +0 -216
  143. package/dist/config/config-loader.js.map +0 -1
  144. package/dist/config/config-schema.d.ts +0 -121
  145. package/dist/config/config-schema.d.ts.map +0 -1
  146. package/dist/config/config-schema.js +0 -7
  147. package/dist/config/config-schema.js.map +0 -1
  148. package/dist/core/live-scanner/config-reader.d.ts +0 -10
  149. package/dist/core/live-scanner/config-reader.d.ts.map +0 -1
  150. package/dist/core/live-scanner/config-reader.js +0 -87
  151. package/dist/core/live-scanner/config-reader.js.map +0 -1
  152. package/dist/core/live-scanner/element-finder.d.ts +0 -20
  153. package/dist/core/live-scanner/element-finder.d.ts.map +0 -1
  154. package/dist/core/live-scanner/element-finder.js +0 -481
  155. package/dist/core/live-scanner/element-finder.js.map +0 -1
  156. package/dist/core/live-scanner/index.d.ts +0 -8
  157. package/dist/core/live-scanner/index.d.ts.map +0 -1
  158. package/dist/core/live-scanner/index.js +0 -33
  159. package/dist/core/live-scanner/index.js.map +0 -1
  160. package/dist/core/live-scanner/matrix-reader.d.ts +0 -17
  161. package/dist/core/live-scanner/matrix-reader.d.ts.map +0 -1
  162. package/dist/core/live-scanner/matrix-reader.js +0 -60
  163. package/dist/core/live-scanner/matrix-reader.js.map +0 -1
  164. package/dist/core/live-scanner/matrix-writer.d.ts +0 -7
  165. package/dist/core/live-scanner/matrix-writer.d.ts.map +0 -1
  166. package/dist/core/live-scanner/matrix-writer.js +0 -103
  167. package/dist/core/live-scanner/matrix-writer.js.map +0 -1
  168. package/dist/core/live-scanner/role-fallback.d.ts +0 -15
  169. package/dist/core/live-scanner/role-fallback.d.ts.map +0 -1
  170. package/dist/core/live-scanner/role-fallback.js +0 -46
  171. package/dist/core/live-scanner/role-fallback.js.map +0 -1
  172. package/dist/core/live-scanner/scanner.d.ts +0 -22
  173. package/dist/core/live-scanner/scanner.d.ts.map +0 -1
  174. package/dist/core/live-scanner/scanner.js +0 -303
  175. package/dist/core/live-scanner/scanner.js.map +0 -1
  176. package/dist/core/live-scanner/step-replayer.d.ts +0 -26
  177. package/dist/core/live-scanner/step-replayer.d.ts.map +0 -1
  178. package/dist/core/live-scanner/step-replayer.js +0 -473
  179. package/dist/core/live-scanner/step-replayer.js.map +0 -1
  180. package/dist/core/live-scanner/types.d.ts +0 -52
  181. package/dist/core/live-scanner/types.d.ts.map +0 -1
  182. package/dist/core/live-scanner/types.js +0 -14
  183. package/dist/core/live-scanner/types.js.map +0 -1
  184. package/dist/core/selector-base/annotation-handler.d.ts +0 -45
  185. package/dist/core/selector-base/annotation-handler.d.ts.map +0 -1
  186. package/dist/core/selector-base/annotation-handler.js +0 -102
  187. package/dist/core/selector-base/annotation-handler.js.map +0 -1
  188. package/dist/core/selector-base/base-generator.d.ts +0 -49
  189. package/dist/core/selector-base/base-generator.d.ts.map +0 -1
  190. package/dist/core/selector-base/base-generator.js +0 -214
  191. package/dist/core/selector-base/base-generator.js.map +0 -1
  192. package/dist/core/selector-base/gherkin-parser.d.ts +0 -24
  193. package/dist/core/selector-base/gherkin-parser.d.ts.map +0 -1
  194. package/dist/core/selector-base/gherkin-parser.js +0 -42
  195. package/dist/core/selector-base/gherkin-parser.js.map +0 -1
  196. package/dist/core/selector-mapper/priority-mapper.d.ts +0 -74
  197. package/dist/core/selector-mapper/priority-mapper.d.ts.map +0 -1
  198. package/dist/core/selector-mapper/priority-mapper.js +0 -477
  199. package/dist/core/selector-mapper/priority-mapper.js.map +0 -1
  200. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts +0 -91
  201. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts.map +0 -1
  202. package/dist/core/ui-scanner/heuristics/base-heuristic.js +0 -175
  203. package/dist/core/ui-scanner/heuristics/base-heuristic.js.map +0 -1
  204. package/dist/core/ui-scanner/react-scanner.d.ts +0 -32
  205. package/dist/core/ui-scanner/react-scanner.d.ts.map +0 -1
  206. package/dist/core/ui-scanner/react-scanner.js +0 -163
  207. package/dist/core/ui-scanner/react-scanner.js.map +0 -1
  208. package/dist/core/ui-scanner/scanner-interface.d.ts +0 -94
  209. package/dist/core/ui-scanner/scanner-interface.d.ts.map +0 -1
  210. package/dist/core/ui-scanner/scanner-interface.js +0 -33
  211. package/dist/core/ui-scanner/scanner-interface.js.map +0 -1
  212. package/dist/core/ui-scanner/strict-scanner.d.ts +0 -81
  213. package/dist/core/ui-scanner/strict-scanner.d.ts.map +0 -1
  214. package/dist/core/ui-scanner/strict-scanner.js +0 -511
  215. package/dist/core/ui-scanner/strict-scanner.js.map +0 -1
  216. package/dist/core/validator/data-validator.d.ts +0 -38
  217. package/dist/core/validator/data-validator.d.ts.map +0 -1
  218. package/dist/core/validator/data-validator.js +0 -212
  219. package/dist/core/validator/data-validator.js.map +0 -1
  220. package/dist/core/validator/feature-validator.d.ts +0 -27
  221. package/dist/core/validator/feature-validator.d.ts.map +0 -1
  222. package/dist/core/validator/feature-validator.js +0 -182
  223. package/dist/core/validator/feature-validator.js.map +0 -1
  224. package/dist/core/validator/index.d.ts +0 -46
  225. package/dist/core/validator/index.d.ts.map +0 -1
  226. package/dist/core/validator/index.js +0 -17
  227. package/dist/core/validator/index.js.map +0 -1
  228. package/dist/core/validator/screen-validator.d.ts +0 -35
  229. package/dist/core/validator/screen-validator.d.ts.map +0 -1
  230. package/dist/core/validator/screen-validator.js +0 -195
  231. package/dist/core/validator/screen-validator.js.map +0 -1
  232. package/dist/core/validator/selector-validator.d.ts +0 -36
  233. package/dist/core/validator/selector-validator.d.ts.map +0 -1
  234. package/dist/core/validator/selector-validator.js +0 -210
  235. package/dist/core/validator/selector-validator.js.map +0 -1
  236. package/dist/external/ai-provider.d.ts +0 -60
  237. package/dist/external/ai-provider.d.ts.map +0 -1
  238. package/dist/external/ai-provider.js +0 -30
  239. package/dist/external/ai-provider.js.map +0 -1
  240. package/dist/external/anthropic-provider.d.ts +0 -29
  241. package/dist/external/anthropic-provider.d.ts.map +0 -1
  242. package/dist/external/anthropic-provider.js +0 -85
  243. package/dist/external/anthropic-provider.js.map +0 -1
  244. package/dist/generators/cache/cache-manager.d.ts +0 -66
  245. package/dist/generators/cache/cache-manager.d.ts.map +0 -1
  246. package/dist/generators/cache/cache-manager.js +0 -286
  247. package/dist/generators/cache/cache-manager.js.map +0 -1
  248. package/dist/generators/dsl-writer/index.d.ts +0 -33
  249. package/dist/generators/dsl-writer/index.d.ts.map +0 -1
  250. package/dist/generators/dsl-writer/index.js +0 -226
  251. package/dist/generators/dsl-writer/index.js.map +0 -1
  252. package/dist/generators/scaffold-generator/index.d.ts +0 -162
  253. package/dist/generators/scaffold-generator/index.d.ts.map +0 -1
  254. package/dist/generators/scaffold-generator/index.js +0 -877
  255. package/dist/generators/scaffold-generator/index.js.map +0 -1
  256. package/dist/generators/selector-mapper/ai-mapper.d.ts +0 -56
  257. package/dist/generators/selector-mapper/ai-mapper.d.ts.map +0 -1
  258. package/dist/generators/selector-mapper/ai-mapper.js +0 -457
  259. package/dist/generators/selector-mapper/ai-mapper.js.map +0 -1
  260. package/dist/generators/selector-mapper/hybrid-mapper.d.ts +0 -67
  261. package/dist/generators/selector-mapper/hybrid-mapper.d.ts.map +0 -1
  262. package/dist/generators/selector-mapper/hybrid-mapper.js +0 -349
  263. package/dist/generators/selector-mapper/hybrid-mapper.js.map +0 -1
  264. package/dist/generators/selector-mapper/index.d.ts +0 -8
  265. package/dist/generators/selector-mapper/index.d.ts.map +0 -1
  266. package/dist/generators/selector-mapper/index.js +0 -12
  267. package/dist/generators/selector-mapper/index.js.map +0 -1
  268. package/dist/generators/selector-mapper/intelligent-mapper.d.ts +0 -125
  269. package/dist/generators/selector-mapper/intelligent-mapper.d.ts.map +0 -1
  270. package/dist/generators/selector-mapper/intelligent-mapper.js +0 -391
  271. package/dist/generators/selector-mapper/intelligent-mapper.js.map +0 -1
  272. package/dist/generators/test-generator/ai-step-mapper.d.ts +0 -27
  273. package/dist/generators/test-generator/ai-step-mapper.d.ts.map +0 -1
  274. package/dist/generators/test-generator/ai-step-mapper.js +0 -204
  275. package/dist/generators/test-generator/ai-step-mapper.js.map +0 -1
  276. package/dist/generators/test-generator/auth-setup-generator.d.ts +0 -18
  277. package/dist/generators/test-generator/auth-setup-generator.d.ts.map +0 -1
  278. package/dist/generators/test-generator/auth-setup-generator.js +0 -82
  279. package/dist/generators/test-generator/auth-setup-generator.js.map +0 -1
  280. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts +0 -7
  281. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts.map +0 -1
  282. package/dist/generators/test-generator/patterns/legacy-patterns.js +0 -98
  283. package/dist/generators/test-generator/patterns/legacy-patterns.js.map +0 -1
  284. package/dist/generators/test-generator/templates/auth-setup.ts.hbs +0 -36
  285. package/dist/generators/ui-model-builder/deep-scanner.d.ts +0 -121
  286. package/dist/generators/ui-model-builder/deep-scanner.d.ts.map +0 -1
  287. package/dist/generators/ui-model-builder/deep-scanner.js +0 -1113
  288. package/dist/generators/ui-model-builder/deep-scanner.js.map +0 -1
  289. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts +0 -110
  290. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts.map +0 -1
  291. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js +0 -608
  292. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js.map +0 -1
  293. package/dist/generators/ui-model-builder/react-scanner.d.ts +0 -107
  294. package/dist/generators/ui-model-builder/react-scanner.d.ts.map +0 -1
  295. package/dist/generators/ui-model-builder/react-scanner.js +0 -797
  296. package/dist/generators/ui-model-builder/react-scanner.js.map +0 -1
  297. package/dist/orchestrator/cache-manager.d.ts +0 -15
  298. package/dist/orchestrator/cache-manager.d.ts.map +0 -1
  299. package/dist/orchestrator/cache-manager.js +0 -62
  300. package/dist/orchestrator/cache-manager.js.map +0 -1
  301. package/dist/orchestrator/pipeline.d.ts +0 -56
  302. package/dist/orchestrator/pipeline.d.ts.map +0 -1
  303. package/dist/orchestrator/pipeline.js +0 -298
  304. package/dist/orchestrator/pipeline.js.map +0 -1
  305. package/dist/orchestrator/reporter.d.ts +0 -15
  306. package/dist/orchestrator/reporter.d.ts.map +0 -1
  307. package/dist/orchestrator/reporter.js +0 -30
  308. package/dist/orchestrator/reporter.js.map +0 -1
  309. package/src/cli/commands/cache-clear.ts +0 -22
  310. package/src/cli/commands/full.ts +0 -35
  311. package/src/cli/commands/live-scan.ts +0 -82
  312. package/src/cli/commands/map.ts +0 -97
  313. package/src/cli/commands/validate.ts +0 -43
  314. package/src/cli/utils.ts +0 -106
  315. package/src/config/ai-providers.yaml +0 -56
  316. package/src/config/config-loader.ts +0 -248
  317. package/src/config/config-schema.ts +0 -148
  318. package/src/config/default.config.yaml +0 -107
  319. package/src/config/framework.config.yaml +0 -52
  320. package/src/config/routes.yaml +0 -31
  321. package/src/core/live-scanner/config-reader.ts +0 -57
  322. package/src/core/live-scanner/element-finder.ts +0 -534
  323. package/src/core/live-scanner/index.ts +0 -7
  324. package/src/core/live-scanner/matrix-reader.ts +0 -65
  325. package/src/core/live-scanner/matrix-writer.ts +0 -77
  326. package/src/core/live-scanner/role-fallback.ts +0 -44
  327. package/src/core/live-scanner/scanner.ts +0 -321
  328. package/src/core/live-scanner/step-replayer.ts +0 -503
  329. package/src/core/live-scanner/types.ts +0 -58
  330. package/src/core/selector-base/annotation-handler.ts +0 -127
  331. package/src/core/selector-base/base-generator.ts +0 -234
  332. package/src/core/selector-base/gherkin-parser.ts +0 -57
  333. package/src/core/selector-mapper/priority-mapper.ts +0 -607
  334. package/src/core/ui-scanner/heuristics/base-heuristic.ts +0 -216
  335. package/src/core/ui-scanner/react-scanner.ts +0 -156
  336. package/src/core/ui-scanner/scanner-interface.ts +0 -133
  337. package/src/core/ui-scanner/strict-scanner.ts +0 -629
  338. package/src/core/validator/data-validator.ts +0 -202
  339. package/src/core/validator/feature-validator.ts +0 -176
  340. package/src/core/validator/index.ts +0 -57
  341. package/src/core/validator/screen-validator.ts +0 -209
  342. package/src/core/validator/selector-validator.ts +0 -209
  343. package/src/external/ai-provider.ts +0 -90
  344. package/src/external/anthropic-provider.ts +0 -114
  345. package/src/generators/README.md +0 -410
  346. package/src/generators/cache/cache-manager.ts +0 -322
  347. package/src/generators/dsl-writer/index.ts +0 -253
  348. package/src/generators/scaffold-generator/index.ts +0 -1029
  349. package/src/generators/selector-mapper/ai-mapper.ts +0 -528
  350. package/src/generators/selector-mapper/hybrid-mapper.ts +0 -427
  351. package/src/generators/selector-mapper/index.ts +0 -10
  352. package/src/generators/selector-mapper/intelligent-mapper.ts +0 -530
  353. package/src/generators/test-generator/ai-step-mapper.ts +0 -224
  354. package/src/generators/test-generator/auth-setup-generator.ts +0 -59
  355. package/src/generators/test-generator/patterns/legacy-patterns.ts +0 -104
  356. package/src/generators/test-generator/templates/auth-setup.ts.hbs +0 -36
  357. package/src/generators/ui-model-builder/deep-scanner.ts +0 -1244
  358. package/src/generators/ui-model-builder/enhanced-deep-scanner.ts +0 -731
  359. package/src/generators/ui-model-builder/react-scanner.ts +0 -959
  360. package/src/orchestrator/cache-manager.ts +0 -32
  361. package/src/orchestrator/pipeline.ts +0 -354
  362. package/src/orchestrator/reporter.ts +0 -36
@@ -1,503 +0,0 @@
1
- /**
2
- * Step Replayer
3
- * Replays Gherkin steps on a live Playwright page to reveal dynamic elements.
4
- * Takes a snapshot and finds elements after each action.
5
- */
6
-
7
- import type { Page } from 'playwright';
8
- import { findElement } from './element-finder';
9
- import { LiveElement, ElementContext } from './types';
10
- import { SelectorResolver } from '../../generators/test-generator/utils/selector-resolver';
11
-
12
- interface ParsedStepInfo {
13
- keyword: string;
14
- text: string;
15
- selectorRef?: string;
16
- dataRef?: string;
17
- elementType?: string;
18
- nth?: number;
19
- }
20
-
21
- interface ReplayResult {
22
- elements: Record<string, LiveElement>;
23
- errors: string[];
24
- }
25
-
26
- /**
27
- * Resolve a {{dataRef}} path against test-data object.
28
- * Supports dot-notation: "email.valid" → testData.email.valid
29
- */
30
- function resolveDataRef(testData: Record<string, any>, dataRef: string): string {
31
- const parts = dataRef.replace(/[{}]/g, '').split('.');
32
- let value: any = testData;
33
- for (const part of parts) {
34
- value = value?.[part];
35
- }
36
- return typeof value === 'string' ? value : String(value ?? '');
37
- }
38
-
39
- /**
40
- * Replay a sequence of Gherkin steps on a Playwright page,
41
- * finding and interacting with elements along the way.
42
- */
43
- export async function replaySteps(
44
- page: Page,
45
- steps: ParsedStepInfo[],
46
- featurePath: string,
47
- baseUrl: string,
48
- existingElements?: Record<string, LiveElement>,
49
- testData?: Record<string, any> | null
50
- ): Promise<ReplayResult> {
51
- const elements: Record<string, LiveElement> = {};
52
- const errors: string[] = [];
53
- let currentContext: ElementContext = 'page';
54
-
55
- // Pre-scan: detect which base keys have multiple normalized element types
56
- // so we can append --type suffix (matching scaffold generator behavior)
57
- // Uses normalizeElementType to match scaffold generator's extractTargetType mapping
58
- // e.g. modal/dialog both normalize to 'dialog', so they won't create a false conflict
59
- const typesPerKey = new Map<string, Set<string>>();
60
- for (const step of steps) {
61
- if (!step.selectorRef) continue;
62
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
63
- const action = detectAction(step.text);
64
- const normalizedType = normalizeElementType(step.elementType || 'button', action);
65
- if (!typesPerKey.has(baseKey)) {
66
- typesPerKey.set(baseKey, new Set());
67
- }
68
- typesPerKey.get(baseKey)!.add(normalizedType);
69
- }
70
- const conflictKeys = new Set<string>();
71
- for (const [key, types] of typesPerKey) {
72
- if (types.size > 1) conflictKeys.add(key);
73
- }
74
-
75
- for (const step of steps) {
76
- try {
77
- const action = detectAction(step.text);
78
-
79
- // Handle navigation (Given User is on [x] page)
80
- if (action === 'navigate') {
81
- await page.goto(baseUrl + featurePath, { waitUntil: 'networkidle', timeout: 15000 });
82
- await settle(page);
83
- if (step.selectorRef) {
84
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
85
- const normalizedType = normalizeElementType(step.elementType || 'page', action);
86
- const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
87
- // Record the page element but don't search for it on the DOM
88
- elements[key] = {
89
- gherkinRef: step.selectorRef,
90
- gherkinType: step.elementType || 'page',
91
- selectorType: '',
92
- selectorValue: featurePath,
93
- role: '',
94
- name: step.selectorRef,
95
- testid: null,
96
- tag: '',
97
- contenteditable: false,
98
- placeholder: null,
99
- label: null,
100
- context: 'page',
101
- matchMethod: 'exact_role',
102
- exact: false,
103
- warning: null,
104
- };
105
- }
106
- continue;
107
- }
108
-
109
- // Skip steps without element references
110
- if (!step.selectorRef) continue;
111
-
112
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
113
- const elementType = step.elementType || 'button';
114
- const normalizedType = normalizeElementType(elementType, action);
115
- const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
116
- const nth = step.nth || 0;
117
-
118
- // Skip column-type elements — they use header text matching, no DOM lookup needed
119
- if (normalizedType === 'column') {
120
- console.log(` ⏭️ [${step.selectorRef}] column → skipped (table header match)`);
121
- continue;
122
- }
123
-
124
- // Skip if element already resolved in existing scan (non-force mode)
125
- if (existingElements && existingElements[key] && existingElements[key].matchMethod !== 'unresolved') {
126
- elements[key] = existingElements[key];
127
- (elements[key] as any).skipped = true;
128
- console.log(` ⏩ [${step.selectorRef}] ${elementType} → cached (${existingElements[key].selectorType})`);
129
-
130
- // Still execute actions for cached elements to maintain page state
131
- if (action === 'click') {
132
- try {
133
- await executeClick(page, step.selectorRef, elementType, nth);
134
- await settle(page);
135
- currentContext = await detectCurrentContext(page, currentContext, step.text);
136
- } catch {
137
- // Click failed for cached element, continue anyway
138
- }
139
- } else if (action === 'fill' && testData && step.dataRef) {
140
- try {
141
- const value = resolveDataRef(testData, step.dataRef);
142
- if (value) {
143
- await executeFill(page, step.selectorRef, elementType, nth, value);
144
- await settle(page);
145
- }
146
- } catch {
147
- // Fill failed for cached element, continue anyway
148
- }
149
- } else if (action === 'select' && testData && step.dataRef) {
150
- try {
151
- const value = resolveDataRef(testData, step.dataRef);
152
- if (value) {
153
- await executeSelect(page, step.selectorRef, elementType, nth, value);
154
- await settle(page);
155
- }
156
- } catch {
157
- // Select failed for cached element, continue anyway
158
- }
159
- }
160
- continue;
161
- }
162
-
163
- // Find the element on the page, scoped to current context (dialog/page)
164
- const element = await findElement(page, step.selectorRef, elementType, nth, currentContext);
165
- element.context = currentContext;
166
-
167
- // Record in matrix (first match wins for duplicate keys)
168
- if (!elements[key]) {
169
- elements[key] = element;
170
- }
171
-
172
- // Execute the action if element was found
173
- if (element.matchMethod !== 'unresolved') {
174
- if (action === 'click') {
175
- await executeClick(page, step.selectorRef, elementType, nth);
176
- await settle(page);
177
- currentContext = await detectCurrentContext(page, currentContext, step.text);
178
- } else if (action === 'fill') {
179
- if (testData && step.dataRef) {
180
- const value = resolveDataRef(testData, step.dataRef);
181
- if (value) {
182
- try {
183
- await executeFill(page, step.selectorRef, elementType, nth, value);
184
- await settle(page);
185
- } catch (e: any) {
186
- errors.push(`Step "${step.text}": fill failed — ${e.message}`);
187
- }
188
- }
189
- }
190
- } else if (action === 'select') {
191
- if (testData && step.dataRef) {
192
- const value = resolveDataRef(testData, step.dataRef);
193
- if (value) {
194
- try {
195
- await executeSelect(page, step.selectorRef, elementType, nth, value);
196
- await settle(page);
197
- } catch (e: any) {
198
- errors.push(`Step "${step.text}": select failed — ${e.message}`);
199
- }
200
- }
201
- }
202
- }
203
- // Label-value detection: check if the data value appears in a sibling element
204
- if (action === 'see' && normalizedType === 'text' && (elementType === 'label' || elementType === 'title' || elementType === 'caption') && testData && step.dataRef) {
205
- const dataValue = resolveDataRef(testData, step.dataRef);
206
- if (dataValue) {
207
- try {
208
- // Check if the parent container has both the label text and the data value
209
- const hasLabelValue = await page.getByText(new RegExp(escapeRegex(element.gherkinRef) + '.*' + escapeRegex(dataValue))).first().isVisible({ timeout: 2000 });
210
- if (hasLabelValue) {
211
- element.matchMethod = 'label-value';
212
- elements[key] = element;
213
- }
214
- } catch {
215
- // Regex match failed, keep original matchMethod
216
- }
217
- }
218
- }
219
- // 'see' and 'wait' actions: just record, don't interact
220
- } else {
221
- // Try data-value fallback for click actions: use the resolved data value as element name
222
- if (action === 'click' && testData && step.dataRef) {
223
- const dataValue = resolveDataRef(testData, step.dataRef);
224
- if (dataValue) {
225
- // Brief wait for dynamic content (e.g. autocomplete dropdown after fill)
226
- await page.waitForTimeout(1000);
227
- const fallback = await findElement(page, dataValue, elementType, nth, currentContext);
228
- if (fallback.matchMethod !== 'unresolved') {
229
- // Preserve original gherkinRef; clear locator values since they come
230
- // from test-data ({{dataRef}}) at runtime, not hardcoded from DOM.
231
- // Store dataValue for logging in scanner.ts
232
- fallback.gherkinRef = step.selectorRef;
233
- (fallback as any).dataValue = dataValue;
234
- fallback.name = '';
235
- fallback.exact = false;
236
- elements[key] = fallback;
237
- try {
238
- await executeClick(page, dataValue, elementType, nth);
239
- await settle(page);
240
- currentContext = await detectCurrentContext(page, currentContext, step.text);
241
- } catch {
242
- // Click failed, element still recorded
243
- }
244
- continue;
245
- }
246
- }
247
- }
248
- errors.push(`Step "${step.text}": element [${step.selectorRef}] not found`);
249
- // Continue scanning remaining steps — record what we can even if some elements are missing
250
- }
251
- } catch (error: any) {
252
- errors.push(`Step "${step.text}": ${error.message}`);
253
- // On navigation or critical errors, stop replaying this scenario
254
- if (error.message.includes('Navigation') || error.message.includes('net::')) {
255
- break;
256
- }
257
- }
258
- }
259
-
260
- return { elements, errors };
261
- }
262
-
263
- async function executeClick(
264
- page: Page,
265
- ref: string,
266
- elementType: string,
267
- nth: number
268
- ): Promise<void> {
269
- const namePattern = new RegExp(escapeRegex(ref), 'i');
270
-
271
- // Try role-based click first
272
- const { getRoleFallbacks } = require('./role-fallback');
273
- const roles = getRoleFallbacks(elementType);
274
-
275
- for (const role of roles) {
276
- try {
277
- const locator = page.getByRole(role as any, { name: namePattern });
278
- const target = nth > 0 ? locator.nth(nth) : locator.first();
279
- if (await target.isVisible({ timeout: 3000 })) {
280
- await target.click({ timeout: 5000 });
281
- return;
282
- }
283
- } catch {
284
- continue;
285
- }
286
- }
287
-
288
- // Fallback to text click
289
- try {
290
- const locator = page.getByText(namePattern);
291
- const target = nth > 0 ? locator.nth(nth) : locator.first();
292
- await target.click({ timeout: 5000 });
293
- } catch {
294
- // Try testid as last resort
295
- const normalized = ref.toLowerCase().replace(/[\s_-]+/g, '-');
296
- await page.locator(`[data-testid*="${normalized}" i]`).first().click({ timeout: 5000 });
297
- }
298
- }
299
-
300
- async function executeFill(
301
- page: Page,
302
- ref: string,
303
- elementType: string,
304
- nth: number,
305
- value: string
306
- ): Promise<void> {
307
- const namePattern = new RegExp(escapeRegex(ref), 'i');
308
-
309
- // Try placeholder first — most direct for input fields, avoids slow role attempts
310
- try {
311
- const locator = page.getByPlaceholder(namePattern);
312
- const target = nth > 0 ? locator.nth(nth) : locator.first();
313
- if (await target.isVisible({ timeout: 3000 })) {
314
- await target.fill(value, { timeout: 5000 });
315
- return;
316
- }
317
- } catch {
318
- // continue
319
- }
320
-
321
- // Try label
322
- try {
323
- const locator = page.getByLabel(namePattern);
324
- const target = nth > 0 ? locator.nth(nth) : locator.first();
325
- if (await target.isVisible({ timeout: 3000 })) {
326
- await target.fill(value, { timeout: 5000 });
327
- return;
328
- }
329
- } catch {
330
- // continue
331
- }
332
-
333
- // Try role-based fill (textbox, combobox, spinbutton)
334
- const { getRoleFallbacks } = require('./role-fallback');
335
- const roles = getRoleFallbacks(elementType);
336
-
337
- for (const role of roles) {
338
- try {
339
- const locator = page.getByRole(role as any, { name: namePattern });
340
- const target = nth > 0 ? locator.nth(nth) : locator.first();
341
- if (await target.isVisible({ timeout: 3000 })) {
342
- await target.fill(value, { timeout: 5000 });
343
- return;
344
- }
345
- } catch {
346
- continue;
347
- }
348
- }
349
-
350
- // Try testid as last resort
351
- const normalized = ref.toLowerCase().replace(/[\s_-]+/g, '-');
352
- await page.locator(`[data-testid*="${normalized}" i]`).first().fill(value, { timeout: 5000 });
353
- }
354
-
355
- async function executeSelect(
356
- page: Page,
357
- ref: string,
358
- elementType: string,
359
- nth: number,
360
- value: string
361
- ): Promise<void> {
362
- const namePattern = new RegExp(escapeRegex(ref), 'i');
363
-
364
- // Try label first — most direct for select elements
365
- try {
366
- const locator = page.getByLabel(namePattern);
367
- const target = nth > 0 ? locator.nth(nth) : locator.first();
368
- if (await target.isVisible({ timeout: 3000 })) {
369
- await target.selectOption(value, { timeout: 5000 });
370
- return;
371
- }
372
- } catch {
373
- // continue
374
- }
375
-
376
- // Try role-based select (combobox, listbox)
377
- const { getRoleFallbacks } = require('./role-fallback');
378
- const roles = getRoleFallbacks(elementType);
379
-
380
- for (const role of roles) {
381
- try {
382
- const locator = page.getByRole(role as any, { name: namePattern });
383
- const target = nth > 0 ? locator.nth(nth) : locator.first();
384
- if (await target.isVisible({ timeout: 3000 })) {
385
- await target.selectOption(value, { timeout: 5000 });
386
- return;
387
- }
388
- } catch {
389
- continue;
390
- }
391
- }
392
-
393
- // Try testid as last resort
394
- const normalized = ref.toLowerCase().replace(/[\s_-]+/g, '-');
395
- await page.locator(`[data-testid*="${normalized}" i]`).first().selectOption(value, { timeout: 5000 });
396
- }
397
-
398
- function detectAction(text: string): string {
399
- const lower = text.toLowerCase();
400
- if (/\b(is on|navigate|go to|visit|open)\b/.test(lower) && /\bpage\b/.test(lower)) return 'navigate';
401
- if (/\b(click|press|tap|submit)\b/.test(lower)) return 'click';
402
- if (/\b(fill|enter|type|input)\b/.test(lower)) return 'fill';
403
- if (/\b(see|verify|check|expect|visible|displayed)\b/.test(lower)) return 'see';
404
- if (/\b(select|choose|pick)\b/.test(lower)) return 'select';
405
- if (/\b(wait)\b/.test(lower)) return 'wait';
406
- return 'see';
407
- }
408
-
409
- async function detectCurrentContext(
410
- page: Page,
411
- previous: ElementContext,
412
- stepText: string
413
- ): Promise<ElementContext> {
414
- const lower = stepText.toLowerCase();
415
-
416
- // Check if we opened a dialog/modal
417
- if (/\b(dialog|modal|panel)\b/.test(lower)) {
418
- return 'dialog';
419
- }
420
-
421
- // Check if a dialog is now visible on the page
422
- try {
423
- const dialogLocator = page.getByRole('dialog');
424
- if (await dialogLocator.count() > 0) {
425
- return 'dialog';
426
- }
427
- } catch {
428
- // ignore
429
- }
430
-
431
- // Check for menu
432
- if (/\b(menu|dropdown)\b/.test(lower)) {
433
- return 'menu';
434
- }
435
-
436
- try {
437
- const menuLocator = page.getByRole('menu');
438
- if (await menuLocator.count() > 0) {
439
- return 'menu';
440
- }
441
- } catch {
442
- // ignore
443
- }
444
-
445
- return previous;
446
- }
447
-
448
- async function settle(page: Page): Promise<void> {
449
- try {
450
- await page.waitForLoadState('networkidle', { timeout: 5000 });
451
- } catch {
452
- // Timeout is acceptable — page may have long-polling connections
453
- }
454
- // Small extra wait for animations/transitions
455
- await page.waitForTimeout(300);
456
- }
457
-
458
- function generateElementKey(ref: string, elementType?: string, nth?: number): string {
459
- // Use the same key generation as the scaffold generator
460
- // so live-scan keys match scaffold keys in the map command.
461
- // Append --N suffix for nth > 0, consistent with scaffold generator format.
462
- const baseKey = SelectorResolver.generateKey(ref);
463
- return nth && nth > 0 ? `${baseKey}--${nth}` : baseKey;
464
- }
465
-
466
- /**
467
- * Normalize element type to match scaffold generator's extractTargetType() mapping.
468
- * e.g. modal→dialog, img/icon/logo→img, input→field, select→dropdown, etc.
469
- */
470
- function normalizeElementType(elementType: string, action: string): string {
471
- const t = elementType.toLowerCase();
472
- if (t === 'page') return 'page';
473
- if (t === 'link') return 'link';
474
- if (t === 'button') return 'button';
475
- if (t === 'radio') return 'radio';
476
- if (t === 'dropdown' || t === 'select') return 'dropdown';
477
- if (t === 'checkbox') return 'checkbox';
478
- if (t === 'field' || t === 'input') return 'field';
479
- if (t === 'textbox') return 'textbox';
480
- if (t === 'textarea') return 'textarea';
481
- if (t === 'text') return 'text';
482
- if (t === 'label') return 'label';
483
- if (t === 'uploader') return 'uploader';
484
- if (t === 'element') return 'element';
485
- if (t === 'column' || t === 'columnheader') return 'column';
486
- if (t === 'logo' || t === 'image' || t === 'img' || t === 'icon') return 'img';
487
- if (t === 'option' || t === 'item' || t === 'listitem') return 'option';
488
- if (t === 'dialog' || t === 'modal') return 'dialog';
489
- if (t === 'heading' || t === 'header') return 'heading';
490
- if (t === 'title' || t === 'caption' || t === 'message') return 'text';
491
- // Default based on action (matches scaffold generator)
492
- switch (action) {
493
- case 'click': return 'text';
494
- case 'fill': return 'field';
495
- case 'see': return 'text';
496
- case 'select': return 'dropdown';
497
- default: return 'element';
498
- }
499
- }
500
-
501
- function escapeRegex(str: string): string {
502
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
503
- }
@@ -1,58 +0,0 @@
1
- /**
2
- * Live Scanner Types
3
- * Defines the data structures for live DOM scanning and matrix file output.
4
- *
5
- * Selector types map directly to Playwright locator strategies:
6
- * testid → page.getByTestId(value)
7
- * role → page.getByRole(value, { name })
8
- * label → page.getByLabel(value)
9
- * placeholder → page.getByPlaceholder(value)
10
- * text → page.getByText(value)
11
- */
12
-
13
- export type MatchMethod = 'testid' | 'exact_role' | 'role_fallback' | 'label' | 'placeholder' | 'text_only' | 'contenteditable' | 'label-value' | 'unresolved';
14
-
15
- export type SelectorType = 'testid' | 'role' | 'label' | 'placeholder' | 'text' | 'locator';
16
-
17
- export type ElementContext = 'page' | 'dialog' | 'menu' | 'modal' | 'popup';
18
-
19
- export interface LiveElement {
20
- gherkinRef: string;
21
- gherkinType: string;
22
- selectorType: SelectorType | '';
23
- selectorValue: string;
24
- role: string;
25
- name: string;
26
- testid: string | null;
27
- tag: string;
28
- contenteditable: boolean;
29
- placeholder: string | null;
30
- label: string | null;
31
- context: ElementContext;
32
- matchMethod: MatchMethod;
33
- exact: boolean;
34
- warning: string | null;
35
- }
36
-
37
- export interface LiveScanScenario {
38
- auth: string | null;
39
- extends: string | null;
40
- path: string;
41
- elements: Record<string, LiveElement>;
42
- }
43
-
44
- export interface LiveScanResult {
45
- screen: string;
46
- baseUrl: string;
47
- scannedAt: string;
48
- scenarios: Record<string, LiveScanScenario>;
49
- }
50
-
51
- export interface LiveScanOptions {
52
- baseUrl?: string;
53
- screenName: string;
54
- screensDir: string;
55
- headed?: boolean;
56
- authDir?: string;
57
- force?: boolean;
58
- }
@@ -1,127 +0,0 @@
1
- /**
2
- * Annotation Handler
3
- * Handles Gherkin annotations: selector IDs, data refs, ignore, etc.
4
- */
5
-
6
- import { RuntimeConfig } from '../../config/config-schema';
7
- import { ParsedScenario, ParsedStep } from './gherkin-parser';
8
-
9
- export interface ExtractedAnnotation {
10
- id: string;
11
- type: 'selector' | 'data' | 'ignore';
12
- value?: string;
13
- }
14
-
15
- export class AnnotationHandler {
16
- private config: RuntimeConfig;
17
-
18
- constructor(config: RuntimeConfig) {
19
- this.config = config;
20
- }
21
-
22
- /**
23
- * Extract element ID from step text
24
- * Supports: [screen.element] ONLY (not data refs)
25
- * Data refs <data.field> are handled separately in test-data system
26
- */
27
- extractElementId(stepText: string, screenName: string): ExtractedAnnotation | null {
28
- // Extract selector ID: [screen.element-name]
29
- const selectorPattern = new RegExp(this.config.annotations.selectorId.pattern);
30
- const selectorMatch = stepText.match(selectorPattern);
31
-
32
- if (selectorMatch) {
33
- const fullId = selectorMatch[1]; // e.g., "chat.input"
34
- const [screen, element] = fullId.split('.');
35
-
36
- // Only return if it matches the target screen
37
- if (screen === screenName) {
38
- return {
39
- id: element,
40
- type: 'selector'
41
- };
42
- }
43
- }
44
-
45
- // NOTE: Data references <data.field> are NOT included in selector files
46
- // They belong in qa/test-data/ directory, not qa/selectors/
47
- // This is per GHERKIN_STANDARDS.md specification
48
-
49
- return null;
50
- }
51
-
52
- /**
53
- * Check if step should be ignored
54
- * Supports: # @ignore
55
- */
56
- shouldIgnoreStep(step: ParsedStep): boolean {
57
- const ignorePattern = new RegExp(this.config.annotations.ignore.pattern);
58
- return ignorePattern.test(step.text);
59
- }
60
-
61
- /**
62
- * Check if entire scenario should be ignored
63
- * Supports: # @ignore-testcase
64
- */
65
- shouldIgnoreScenario(scenario: ParsedScenario): boolean {
66
- // Check scenario description
67
- // @ts-ignore - Legacy parser may have description field
68
- if (scenario.description) {
69
- const ignorePattern = new RegExp(this.config.annotations.ignoreTestCase.pattern);
70
- // @ts-ignore
71
- if (ignorePattern.test(scenario.description)) {
72
- return true;
73
- }
74
- }
75
-
76
- // Check scenario tags (if any)
77
- // @ts-ignore - Legacy parser may have tags field
78
- if (scenario.tags && scenario.tags.includes('@ignore')) {
79
- return true;
80
- }
81
-
82
- return false;
83
- }
84
-
85
- /**
86
- * Check if step should be skipped in production
87
- * Supports: # @skip-production
88
- */
89
- shouldSkipInProduction(step: ParsedStep): boolean {
90
- const skipPattern = new RegExp(this.config.annotations.skipProduction.pattern);
91
- return skipPattern.test(step.text);
92
- }
93
-
94
- /**
95
- * Extract all element IDs from step (can have multiple)
96
- */
97
- extractAllElementIds(stepText: string): string[] {
98
- const ids: string[] = [];
99
-
100
- // Extract all [screen.element] patterns
101
- const selectorPattern = new RegExp(this.config.annotations.selectorId.pattern, 'g');
102
- let match;
103
-
104
- while ((match = selectorPattern.exec(stepText)) !== null) {
105
- ids.push(match[1]);
106
- }
107
-
108
- return ids;
109
- }
110
-
111
- /**
112
- * Extract data references from step
113
- */
114
- extractDataRefs(stepText: string): string[] {
115
- const refs: string[] = [];
116
-
117
- // Extract all <data.ref> patterns
118
- const dataPattern = new RegExp(this.config.annotations.dataRef.pattern, 'g');
119
- let match;
120
-
121
- while ((match = dataPattern.exec(stepText)) !== null) {
122
- refs.push(match[1]);
123
- }
124
-
125
- return refs;
126
- }
127
- }