@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,43 +0,0 @@
1
- /**
2
- * Role Fallback Groups
3
- * Maps Gherkin element type hints to ordered lists of ARIA roles to try.
4
- */
5
-
6
- const ROLE_FALLBACK_GROUPS: Record<string, string[]> = {
7
- button: ['button', 'link', 'menuitem', 'tab'],
8
- link: ['link', 'button', 'menuitem'],
9
- field: ['textbox', 'combobox', 'searchbox', 'spinbutton'],
10
- dropdown: ['combobox', 'listbox', 'select', 'button'],
11
- checkbox: ['checkbox', 'switch'],
12
- text: ['heading', 'paragraph'],
13
- menuitem: ['menuitem', 'option', 'link'],
14
- dialog: ['dialog', 'alertdialog'],
15
- modal: ['dialog', 'alertdialog'],
16
- tab: ['tab', 'button', 'link'],
17
- row: ['row', 'listitem', 'option'],
18
- tag: ['button', 'link', 'option'],
19
- uploader: ['textbox', 'button'],
20
- textarea: ['textbox'],
21
- radio: ['radio'],
22
- select: ['combobox', 'listbox', 'select'],
23
- page: [],
24
- };
25
-
26
- /**
27
- * Get the ordered list of ARIA roles to try for a given Gherkin element type.
28
- * Returns empty array if the type is unknown (will fall through to text matching).
29
- */
30
- export function getRoleFallbacks(gherkinType: string): string[] {
31
- const normalized = gherkinType.toLowerCase().trim();
32
- return ROLE_FALLBACK_GROUPS[normalized] || [];
33
- }
34
-
35
- /**
36
- * Check if a Gherkin type should use getByText as its primary strategy
37
- * (types that don't map well to ARIA roles).
38
- */
39
- export function isTextOnlyType(gherkinType: string): boolean {
40
- const normalized = gherkinType.toLowerCase().trim();
41
- return normalized === 'text' || normalized === 'message' || normalized === 'error'
42
- || normalized === 'warning' || normalized === 'success' || normalized === 'alert';
43
- }
@@ -1,254 +0,0 @@
1
- /**
2
- * Live Scanner
3
- * Main orchestrator: parses features, sets up auth, replays steps, collects elements.
4
- */
5
-
6
- import * as fs from 'fs';
7
- import * as path from 'path';
8
- import { glob } from 'glob';
9
- import { LiveScanResult, LiveScanScenario, LiveScanOptions } from './types';
10
- import { replaySteps } from './step-replayer';
11
- import { writeMatrix } from './matrix-writer';
12
- import { readMatrix, mergeMatrixElements } from './matrix-reader';
13
- import { readBaseUrlFromPlaywrightConfig } from './config-reader';
14
-
15
- export class LiveScanner {
16
- private options: LiveScanOptions;
17
-
18
- constructor(options: LiveScanOptions) {
19
- this.options = options;
20
- }
21
-
22
- async scan(): Promise<LiveScanResult[]> {
23
- const { screenName, screensDir } = this.options;
24
- const screenDir = path.join(screensDir, screenName);
25
- const featuresDir = path.join(screenDir, 'features');
26
- const selectorsDir = path.join(screenDir, 'selectors');
27
-
28
- if (!fs.existsSync(featuresDir)) {
29
- throw new Error(`Features directory not found: ${featuresDir}`);
30
- }
31
-
32
- // Resolve baseUrl: explicit option > playwright.config.ts
33
- const baseUrl = this.resolveBaseUrl();
34
- console.log(`🌐 Base URL: ${baseUrl}`);
35
-
36
- fs.mkdirSync(selectorsDir, { recursive: true });
37
-
38
- const featureFiles = glob.sync('**/*.feature', {
39
- cwd: featuresDir,
40
- absolute: true,
41
- });
42
-
43
- if (featureFiles.length === 0) {
44
- throw new Error(`No .feature files found in ${featuresDir}`);
45
- }
46
-
47
- // Lazy-load playwright to avoid errors when not installed
48
- let playwright: any;
49
- try {
50
- playwright = require('playwright');
51
- } catch {
52
- throw new Error(
53
- 'Playwright is required for live-scan. Install it with: npm install playwright'
54
- );
55
- }
56
-
57
- const browser = await playwright.chromium.launch({
58
- headless: !this.options.headed,
59
- });
60
-
61
- const results: LiveScanResult[] = [];
62
-
63
- try {
64
- // Parse all features first
65
- const { GherkinParser } = require('../../generators/gherkin-parser');
66
- const parser = new GherkinParser();
67
-
68
- for (const featureFile of featureFiles) {
69
- const featureName = path.basename(featureFile, '.feature');
70
- console.log(`\n📄 Scanning feature: ${featureName}`);
71
-
72
- // Load existing matrix for incremental scan (non-force mode)
73
- let existingResult: LiveScanResult | null = null;
74
- if (!this.options.force) {
75
- const matrixPath = path.join(selectorsDir, `${featureName}.live-scan.yaml`);
76
- existingResult = readMatrix(matrixPath);
77
- if (existingResult) {
78
- console.log(` 📦 Found existing scan — resolved elements will be skipped`);
79
- }
80
- }
81
-
82
- try {
83
- const parsed = parser.parseFeatureFile(featureFile);
84
- const result = await this.scanFeature(browser, playwright, parsed, baseUrl, existingResult);
85
- results.push(result);
86
-
87
- // Write matrix file
88
- const matrixPath = path.join(selectorsDir, `${featureName}.live-scan.yaml`);
89
- writeMatrix(result, matrixPath);
90
- console.log(` ✅ Matrix written: ${matrixPath}`);
91
- } catch (error: any) {
92
- console.error(` ❌ Failed to scan ${featureName}: ${error.message}`);
93
- }
94
- }
95
- } finally {
96
- await browser.close();
97
- }
98
-
99
- return results;
100
- }
101
-
102
- private resolveBaseUrl(): string {
103
- // 1. Explicit option (from --url flag)
104
- if (this.options.baseUrl) {
105
- return this.options.baseUrl;
106
- }
107
-
108
- // 2. Auto-detect from playwright.config.ts
109
- const detected = readBaseUrlFromPlaywrightConfig(process.cwd());
110
- if (detected) {
111
- console.log(`📋 Auto-detected baseURL from playwright.config.ts`);
112
- return detected;
113
- }
114
-
115
- throw new Error(
116
- 'Base URL not found. Either:\n' +
117
- ' • Add baseURL to your playwright.config.ts\n' +
118
- ' • Use --url <baseUrl> flag'
119
- );
120
- }
121
-
122
- private async scanFeature(
123
- browser: any,
124
- playwright: any,
125
- feature: any,
126
- baseUrl: string,
127
- existingResult?: LiveScanResult | null
128
- ): Promise<LiveScanResult> {
129
- const featurePath = feature.path || '/';
130
- const scenarios: Record<string, LiveScanScenario> = {};
131
-
132
- // Build merged existing elements map for skip logic
133
- const existingElements = existingResult ? mergeMatrixElements(existingResult) : undefined;
134
-
135
- // Build a map of @steps scenarios for resolution
136
- const stepsMap = new Map<string, any>();
137
- for (const scenario of feature.scenarios) {
138
- if (scenario.stepsName) {
139
- stepsMap.set(scenario.stepsName, scenario);
140
- }
141
- }
142
-
143
- for (const scenario of feature.scenarios) {
144
- // Skip @steps-only scenarios (they're reusable blocks, not standalone)
145
- if (scenario.stepsName && !scenario.extendsName) {
146
- console.log(` ⏭️ Skipping @steps block: ${scenario.name}`);
147
- continue;
148
- }
149
-
150
- const scenarioKey = slugify(scenario.name);
151
- console.log(` 🎬 Scenario: ${scenario.name}`);
152
-
153
- // Extract auth tag
154
- const authTag = scenario.tags.find((t: string) => t.startsWith('@auth:'));
155
- const authRole = authTag ? authTag.replace('@auth:', '') : null;
156
-
157
- // Resolve @extend: inline base steps
158
- let steps = [...scenario.steps];
159
- if (scenario.extendsName) {
160
- const baseScenario = stepsMap.get(scenario.extendsName);
161
- if (baseScenario) {
162
- steps = [...baseScenario.steps, ...steps];
163
- console.log(` 🔗 Extended with @steps:${scenario.extendsName} (${baseScenario.steps.length} steps)`);
164
- } else {
165
- console.warn(` ⚠️ @extend:${scenario.extendsName} not found`);
166
- }
167
- }
168
-
169
- // Set up browser context with auth
170
- const contextOptions: any = {};
171
- if (authRole) {
172
- const authPath = path.join(this.options.authDir || 'specs/.auth', `${authRole}.json`);
173
- if (fs.existsSync(authPath)) {
174
- contextOptions.storageState = authPath;
175
- console.log(` 🔐 Auth: ${authRole}`);
176
- } else {
177
- console.warn(` ⚠️ Auth file not found for role '${authRole}', scanning without authentication`);
178
- }
179
- }
180
-
181
- const context = await browser.newContext(contextOptions);
182
- const page = await context.newPage();
183
-
184
- try {
185
- const result = await replaySteps(page, steps, featurePath, baseUrl, existingElements);
186
-
187
- scenarios[scenarioKey] = {
188
- auth: authRole,
189
- extends: scenario.extendsName || null,
190
- path: featurePath,
191
- elements: result.elements,
192
- };
193
-
194
- // Print element summary
195
- const elementCount = Object.keys(result.elements).length;
196
- const skipped = Object.values(result.elements).filter(
197
- (e: any) => e.skipped
198
- ).length;
199
- const resolved = Object.values(result.elements).filter(
200
- (e: any) => e.matchMethod !== 'unresolved'
201
- ).length;
202
- const warnings = Object.values(result.elements).filter(
203
- (e: any) => e.warning
204
- ).length;
205
-
206
- const skippedInfo = skipped > 0 ? `, ${skipped} cached` : '';
207
- console.log(` 📊 Elements: ${resolved}/${elementCount} resolved${skippedInfo}${warnings > 0 ? `, ${warnings} warnings` : ''}`);
208
-
209
- for (const error of result.errors) {
210
- console.log(` ⚠️ ${error}`);
211
- }
212
-
213
- // Print per-element status
214
- for (const [key, el] of Object.entries(result.elements) as any) {
215
- if (el.skipped) {
216
- // Already printed in replaySteps
217
- continue;
218
- }
219
- if (el.matchMethod === 'unresolved') {
220
- console.log(` ✗ [${el.gherkinRef}] ${el.gherkinType} → NOT FOUND`);
221
- } else if (el.warning) {
222
- console.log(` ⚠ [${el.gherkinRef}] ${el.gherkinType} → ${el.selectorType}(${el.selectorValue || el.name}) (${el.warning})`);
223
- } else {
224
- const locatorDesc = el.selectorType
225
- ? `${el.selectorType}${el.role ? `('${el.role}', {name: '${el.name}'})` : `('${el.selectorValue || el.name}')`}`
226
- : el.gherkinType;
227
- console.log(` ✓ [${el.gherkinRef}] → getBy${capitalize(el.selectorType || 'text')}${el.role ? `('${el.role}', {name: '${el.name}'})` : `('${el.selectorValue || el.name}')`}`);
228
- }
229
- }
230
- } finally {
231
- await context.close();
232
- }
233
- }
234
-
235
- return {
236
- screen: this.options.screenName,
237
- baseUrl,
238
- scannedAt: new Date().toISOString(),
239
- scenarios,
240
- };
241
- }
242
- }
243
-
244
- function slugify(text: string): string {
245
- return text
246
- .toLowerCase()
247
- .replace(/[^\w\s-]/g, '')
248
- .trim()
249
- .replace(/\s+/g, '-');
250
- }
251
-
252
- function capitalize(str: string): string {
253
- return str.charAt(0).toUpperCase() + str.slice(1);
254
- }
@@ -1,306 +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
- * Replay a sequence of Gherkin steps on a Playwright page,
28
- * finding and interacting with elements along the way.
29
- */
30
- export async function replaySteps(
31
- page: Page,
32
- steps: ParsedStepInfo[],
33
- featurePath: string,
34
- baseUrl: string,
35
- existingElements?: Record<string, LiveElement>
36
- ): Promise<ReplayResult> {
37
- const elements: Record<string, LiveElement> = {};
38
- const errors: string[] = [];
39
- let currentContext: ElementContext = 'page';
40
-
41
- // Pre-scan: detect which base keys have multiple normalized element types
42
- // so we can append --type suffix (matching scaffold generator behavior)
43
- // Uses normalizeElementType to match scaffold generator's extractTargetType mapping
44
- // e.g. modal/dialog both normalize to 'dialog', so they won't create a false conflict
45
- const typesPerKey = new Map<string, Set<string>>();
46
- for (const step of steps) {
47
- if (!step.selectorRef) continue;
48
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
49
- const action = detectAction(step.text);
50
- const normalizedType = normalizeElementType(step.elementType || 'button', action);
51
- if (!typesPerKey.has(baseKey)) {
52
- typesPerKey.set(baseKey, new Set());
53
- }
54
- typesPerKey.get(baseKey)!.add(normalizedType);
55
- }
56
- const conflictKeys = new Set<string>();
57
- for (const [key, types] of typesPerKey) {
58
- if (types.size > 1) conflictKeys.add(key);
59
- }
60
-
61
- for (const step of steps) {
62
- try {
63
- const action = detectAction(step.text);
64
-
65
- // Handle navigation (Given User is on [x] page)
66
- if (action === 'navigate') {
67
- await page.goto(baseUrl + featurePath, { waitUntil: 'networkidle', timeout: 15000 });
68
- await settle(page);
69
- if (step.selectorRef) {
70
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
71
- const normalizedType = normalizeElementType(step.elementType || 'page', action);
72
- const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
73
- // Record the page element but don't search for it on the DOM
74
- elements[key] = {
75
- gherkinRef: step.selectorRef,
76
- gherkinType: step.elementType || 'page',
77
- selectorType: '',
78
- selectorValue: featurePath,
79
- role: '',
80
- name: step.selectorRef,
81
- testid: null,
82
- tag: '',
83
- contenteditable: false,
84
- placeholder: null,
85
- label: null,
86
- context: 'page',
87
- matchMethod: 'exact_role',
88
- exact: false,
89
- warning: null,
90
- };
91
- }
92
- continue;
93
- }
94
-
95
- // Skip steps without element references
96
- if (!step.selectorRef) continue;
97
-
98
- const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
99
- const elementType = step.elementType || 'button';
100
- const normalizedType = normalizeElementType(elementType, action);
101
- const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
102
- const nth = step.nth || 0;
103
-
104
- // Skip column-type elements — they use header text matching, no DOM lookup needed
105
- if (normalizedType === 'column') {
106
- console.log(` ⏭️ [${step.selectorRef}] column → skipped (table header match)`);
107
- continue;
108
- }
109
-
110
- // Skip if element already resolved in existing scan (non-force mode)
111
- if (existingElements && existingElements[key] && existingElements[key].matchMethod !== 'unresolved') {
112
- elements[key] = existingElements[key];
113
- (elements[key] as any).skipped = true;
114
- console.log(` ⏩ [${step.selectorRef}] ${elementType} → cached (${existingElements[key].selectorType})`);
115
-
116
- // Still execute clicks for cached elements to maintain page state
117
- if (action === 'click') {
118
- try {
119
- await executeClick(page, step.selectorRef, elementType, nth);
120
- await settle(page);
121
- currentContext = await detectCurrentContext(page, currentContext, step.text);
122
- } catch {
123
- // Click failed for cached element, continue anyway
124
- }
125
- }
126
- continue;
127
- }
128
-
129
- // Find the element on the page, scoped to current context (dialog/page)
130
- const element = await findElement(page, step.selectorRef, elementType, nth, currentContext);
131
- element.context = currentContext;
132
-
133
- // Record in matrix (first match wins for duplicate keys)
134
- if (!elements[key]) {
135
- elements[key] = element;
136
- }
137
-
138
- // Execute the action if element was found
139
- if (element.matchMethod !== 'unresolved') {
140
- if (action === 'click') {
141
- await executeClick(page, step.selectorRef, elementType, nth);
142
- await settle(page);
143
- currentContext = await detectCurrentContext(page, currentContext, step.text);
144
- } else if (action === 'fill') {
145
- // For fill actions during scanning, use a placeholder value
146
- // We just need to verify the element exists
147
- }
148
- // 'see' and 'wait' actions: just record, don't interact
149
- } else {
150
- errors.push(`Step "${step.text}": element [${step.selectorRef}] not found`);
151
- // Continue scanning remaining steps — record what we can even if some elements are missing
152
- }
153
- } catch (error: any) {
154
- errors.push(`Step "${step.text}": ${error.message}`);
155
- // On navigation or critical errors, stop replaying this scenario
156
- if (error.message.includes('Navigation') || error.message.includes('net::')) {
157
- break;
158
- }
159
- }
160
- }
161
-
162
- return { elements, errors };
163
- }
164
-
165
- async function executeClick(
166
- page: Page,
167
- ref: string,
168
- elementType: string,
169
- nth: number
170
- ): Promise<void> {
171
- const namePattern = new RegExp(escapeRegex(ref), 'i');
172
-
173
- // Try role-based click first
174
- const { getRoleFallbacks } = require('./role-fallback');
175
- const roles = getRoleFallbacks(elementType);
176
-
177
- for (const role of roles) {
178
- try {
179
- const locator = page.getByRole(role as any, { name: namePattern });
180
- const target = nth > 0 ? locator.nth(nth) : locator.first();
181
- if (await target.isVisible({ timeout: 3000 })) {
182
- await target.click({ timeout: 5000 });
183
- return;
184
- }
185
- } catch {
186
- continue;
187
- }
188
- }
189
-
190
- // Fallback to text click
191
- try {
192
- const locator = page.getByText(namePattern);
193
- const target = nth > 0 ? locator.nth(nth) : locator.first();
194
- await target.click({ timeout: 5000 });
195
- } catch {
196
- // Try testid as last resort
197
- const normalized = ref.toLowerCase().replace(/[\s_-]+/g, '-');
198
- await page.locator(`[data-testid*="${normalized}" i]`).first().click({ timeout: 5000 });
199
- }
200
- }
201
-
202
- function detectAction(text: string): string {
203
- const lower = text.toLowerCase();
204
- if (/\b(is on|navigate|go to|visit|open)\b/.test(lower) && /\bpage\b/.test(lower)) return 'navigate';
205
- if (/\b(click|press|tap|submit)\b/.test(lower)) return 'click';
206
- if (/\b(fill|enter|type|input)\b/.test(lower)) return 'fill';
207
- if (/\b(see|verify|check|expect|visible|displayed)\b/.test(lower)) return 'see';
208
- if (/\b(select|choose|pick)\b/.test(lower)) return 'select';
209
- if (/\b(wait)\b/.test(lower)) return 'wait';
210
- return 'see';
211
- }
212
-
213
- async function detectCurrentContext(
214
- page: Page,
215
- previous: ElementContext,
216
- stepText: string
217
- ): Promise<ElementContext> {
218
- const lower = stepText.toLowerCase();
219
-
220
- // Check if we opened a dialog/modal
221
- if (/\b(dialog|modal|panel)\b/.test(lower)) {
222
- return 'dialog';
223
- }
224
-
225
- // Check if a dialog is now visible on the page
226
- try {
227
- const dialogLocator = page.getByRole('dialog');
228
- if (await dialogLocator.count() > 0) {
229
- return 'dialog';
230
- }
231
- } catch {
232
- // ignore
233
- }
234
-
235
- // Check for menu
236
- if (/\b(menu|dropdown)\b/.test(lower)) {
237
- return 'menu';
238
- }
239
-
240
- try {
241
- const menuLocator = page.getByRole('menu');
242
- if (await menuLocator.count() > 0) {
243
- return 'menu';
244
- }
245
- } catch {
246
- // ignore
247
- }
248
-
249
- return previous;
250
- }
251
-
252
- async function settle(page: Page): Promise<void> {
253
- try {
254
- await page.waitForLoadState('networkidle', { timeout: 5000 });
255
- } catch {
256
- // Timeout is acceptable — page may have long-polling connections
257
- }
258
- // Small extra wait for animations/transitions
259
- await page.waitForTimeout(300);
260
- }
261
-
262
- function generateElementKey(ref: string, elementType?: string, nth?: number): string {
263
- // Use the same key generation as the scaffold generator
264
- // so live-scan keys match scaffold keys in the map command.
265
- // Append --N suffix for nth > 0, consistent with scaffold generator format.
266
- const baseKey = SelectorResolver.generateKey(ref);
267
- return nth && nth > 0 ? `${baseKey}--${nth}` : baseKey;
268
- }
269
-
270
- /**
271
- * Normalize element type to match scaffold generator's extractTargetType() mapping.
272
- * e.g. modal→dialog, img/icon/logo→img, input→field, select→dropdown, etc.
273
- */
274
- function normalizeElementType(elementType: string, action: string): string {
275
- const t = elementType.toLowerCase();
276
- if (t === 'page') return 'page';
277
- if (t === 'link') return 'link';
278
- if (t === 'button') return 'button';
279
- if (t === 'radio') return 'radio';
280
- if (t === 'dropdown' || t === 'select') return 'dropdown';
281
- if (t === 'checkbox') return 'checkbox';
282
- if (t === 'field' || t === 'input') return 'field';
283
- if (t === 'textbox') return 'textbox';
284
- if (t === 'textarea') return 'textarea';
285
- if (t === 'text') return 'text';
286
- if (t === 'label') return 'label';
287
- if (t === 'uploader') return 'uploader';
288
- if (t === 'element') return 'element';
289
- if (t === 'column' || t === 'columnheader') return 'column';
290
- if (t === 'logo' || t === 'image' || t === 'img' || t === 'icon') return 'img';
291
- if (t === 'dialog' || t === 'modal') return 'dialog';
292
- if (t === 'heading' || t === 'header') return 'heading';
293
- if (t === 'title' || t === 'caption' || t === 'message') return 'text';
294
- // Default based on action (matches scaffold generator)
295
- switch (action) {
296
- case 'click': return 'text';
297
- case 'fill': return 'field';
298
- case 'see': return 'text';
299
- case 'select': return 'dropdown';
300
- default: return 'element';
301
- }
302
- }
303
-
304
- function escapeRegex(str: string): string {
305
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
306
- }
@@ -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' | '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
- }