@sun-asterisk/sungen 1.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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +490 -0
  3. package/bin/sungen.js +12 -0
  4. package/dist/cli/commands/auto-tag-command.d.ts +8 -0
  5. package/dist/cli/commands/auto-tag-command.d.ts.map +1 -0
  6. package/dist/cli/commands/auto-tag-command.js +104 -0
  7. package/dist/cli/commands/auto-tag-command.js.map +1 -0
  8. package/dist/cli/index.d.ts +7 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +196 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/config/ai-providers.yaml +56 -0
  13. package/dist/config/config-loader.d.ts +51 -0
  14. package/dist/config/config-loader.d.ts.map +1 -0
  15. package/dist/config/config-loader.js +216 -0
  16. package/dist/config/config-loader.js.map +1 -0
  17. package/dist/config/config-schema.d.ts +121 -0
  18. package/dist/config/config-schema.d.ts.map +1 -0
  19. package/dist/config/config-schema.js +7 -0
  20. package/dist/config/config-schema.js.map +1 -0
  21. package/dist/config/default.config.yaml +101 -0
  22. package/dist/config/framework.config.yaml +52 -0
  23. package/dist/config/routes.yaml +31 -0
  24. package/dist/core/selector-base/annotation-handler.d.ts +45 -0
  25. package/dist/core/selector-base/annotation-handler.d.ts.map +1 -0
  26. package/dist/core/selector-base/annotation-handler.js +102 -0
  27. package/dist/core/selector-base/annotation-handler.js.map +1 -0
  28. package/dist/core/selector-base/base-generator.d.ts +49 -0
  29. package/dist/core/selector-base/base-generator.d.ts.map +1 -0
  30. package/dist/core/selector-base/base-generator.js +214 -0
  31. package/dist/core/selector-base/base-generator.js.map +1 -0
  32. package/dist/core/selector-base/gherkin-parser.d.ts +24 -0
  33. package/dist/core/selector-base/gherkin-parser.d.ts.map +1 -0
  34. package/dist/core/selector-base/gherkin-parser.js +42 -0
  35. package/dist/core/selector-base/gherkin-parser.js.map +1 -0
  36. package/dist/core/selector-mapper/priority-mapper.d.ts +74 -0
  37. package/dist/core/selector-mapper/priority-mapper.d.ts.map +1 -0
  38. package/dist/core/selector-mapper/priority-mapper.js +477 -0
  39. package/dist/core/selector-mapper/priority-mapper.js.map +1 -0
  40. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts +91 -0
  41. package/dist/core/ui-scanner/heuristics/base-heuristic.d.ts.map +1 -0
  42. package/dist/core/ui-scanner/heuristics/base-heuristic.js +175 -0
  43. package/dist/core/ui-scanner/heuristics/base-heuristic.js.map +1 -0
  44. package/dist/core/ui-scanner/react-scanner.d.ts +32 -0
  45. package/dist/core/ui-scanner/react-scanner.d.ts.map +1 -0
  46. package/dist/core/ui-scanner/react-scanner.js +163 -0
  47. package/dist/core/ui-scanner/react-scanner.js.map +1 -0
  48. package/dist/core/ui-scanner/scanner-interface.d.ts +94 -0
  49. package/dist/core/ui-scanner/scanner-interface.d.ts.map +1 -0
  50. package/dist/core/ui-scanner/scanner-interface.js +33 -0
  51. package/dist/core/ui-scanner/scanner-interface.js.map +1 -0
  52. package/dist/core/ui-scanner/strict-scanner.d.ts +81 -0
  53. package/dist/core/ui-scanner/strict-scanner.d.ts.map +1 -0
  54. package/dist/core/ui-scanner/strict-scanner.js +511 -0
  55. package/dist/core/ui-scanner/strict-scanner.js.map +1 -0
  56. package/dist/executor/playwright/playwright-generator.d.ts +33 -0
  57. package/dist/executor/playwright/playwright-generator.d.ts.map +1 -0
  58. package/dist/executor/playwright/playwright-generator.js +136 -0
  59. package/dist/executor/playwright/playwright-generator.js.map +1 -0
  60. package/dist/executor/test-generator.d.ts +63 -0
  61. package/dist/executor/test-generator.d.ts.map +1 -0
  62. package/dist/executor/test-generator.js +30 -0
  63. package/dist/executor/test-generator.js.map +1 -0
  64. package/dist/external/ai-provider.d.ts +60 -0
  65. package/dist/external/ai-provider.d.ts.map +1 -0
  66. package/dist/external/ai-provider.js +30 -0
  67. package/dist/external/ai-provider.js.map +1 -0
  68. package/dist/external/anthropic-provider.d.ts +29 -0
  69. package/dist/external/anthropic-provider.d.ts.map +1 -0
  70. package/dist/external/anthropic-provider.js +85 -0
  71. package/dist/external/anthropic-provider.js.map +1 -0
  72. package/dist/generators/cache/cache-manager.d.ts +66 -0
  73. package/dist/generators/cache/cache-manager.d.ts.map +1 -0
  74. package/dist/generators/cache/cache-manager.js +286 -0
  75. package/dist/generators/cache/cache-manager.js.map +1 -0
  76. package/dist/generators/cli.d.ts +7 -0
  77. package/dist/generators/cli.d.ts.map +1 -0
  78. package/dist/generators/cli.js +570 -0
  79. package/dist/generators/cli.js.map +1 -0
  80. package/dist/generators/dsl-writer/index.d.ts +33 -0
  81. package/dist/generators/dsl-writer/index.d.ts.map +1 -0
  82. package/dist/generators/dsl-writer/index.js +226 -0
  83. package/dist/generators/dsl-writer/index.js.map +1 -0
  84. package/dist/generators/gherkin-parser/index.d.ts +47 -0
  85. package/dist/generators/gherkin-parser/index.d.ts.map +1 -0
  86. package/dist/generators/gherkin-parser/index.js +149 -0
  87. package/dist/generators/gherkin-parser/index.js.map +1 -0
  88. package/dist/generators/gherkin-parser/selector-extractor.d.ts +37 -0
  89. package/dist/generators/gherkin-parser/selector-extractor.d.ts.map +1 -0
  90. package/dist/generators/gherkin-parser/selector-extractor.js +108 -0
  91. package/dist/generators/gherkin-parser/selector-extractor.js.map +1 -0
  92. package/dist/generators/scaffold-generator/index.d.ts +111 -0
  93. package/dist/generators/scaffold-generator/index.d.ts.map +1 -0
  94. package/dist/generators/scaffold-generator/index.js +408 -0
  95. package/dist/generators/scaffold-generator/index.js.map +1 -0
  96. package/dist/generators/selector-mapper/ai-mapper.d.ts +56 -0
  97. package/dist/generators/selector-mapper/ai-mapper.d.ts.map +1 -0
  98. package/dist/generators/selector-mapper/ai-mapper.js +457 -0
  99. package/dist/generators/selector-mapper/ai-mapper.js.map +1 -0
  100. package/dist/generators/selector-mapper/hybrid-mapper.d.ts +67 -0
  101. package/dist/generators/selector-mapper/hybrid-mapper.d.ts.map +1 -0
  102. package/dist/generators/selector-mapper/hybrid-mapper.js +349 -0
  103. package/dist/generators/selector-mapper/hybrid-mapper.js.map +1 -0
  104. package/dist/generators/selector-mapper/index.d.ts +8 -0
  105. package/dist/generators/selector-mapper/index.d.ts.map +1 -0
  106. package/dist/generators/selector-mapper/index.js +12 -0
  107. package/dist/generators/selector-mapper/index.js.map +1 -0
  108. package/dist/generators/selector-mapper/intelligent-mapper.d.ts +125 -0
  109. package/dist/generators/selector-mapper/intelligent-mapper.d.ts.map +1 -0
  110. package/dist/generators/selector-mapper/intelligent-mapper.js +391 -0
  111. package/dist/generators/selector-mapper/intelligent-mapper.js.map +1 -0
  112. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +49 -0
  113. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -0
  114. package/dist/generators/test-generator/adapters/adapter-interface.js +7 -0
  115. package/dist/generators/test-generator/adapters/adapter-interface.js.map +1 -0
  116. package/dist/generators/test-generator/adapters/adapter-registry.d.ts +29 -0
  117. package/dist/generators/test-generator/adapters/adapter-registry.d.ts.map +1 -0
  118. package/dist/generators/test-generator/adapters/adapter-registry.js +50 -0
  119. package/dist/generators/test-generator/adapters/adapter-registry.js.map +1 -0
  120. package/dist/generators/test-generator/adapters/index.d.ts +4 -0
  121. package/dist/generators/test-generator/adapters/index.d.ts.map +1 -0
  122. package/dist/generators/test-generator/adapters/index.js +13 -0
  123. package/dist/generators/test-generator/adapters/index.js.map +1 -0
  124. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +23 -0
  125. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -0
  126. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js +38 -0
  127. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -0
  128. package/dist/generators/test-generator/adapters/playwright/templates/before-each.hbs +8 -0
  129. package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +5 -0
  130. package/dist/generators/test-generator/adapters/playwright/templates/scenario.hbs +8 -0
  131. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/check-action.hbs +1 -0
  132. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/clear-action.hbs +1 -0
  133. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-action.hbs +1 -0
  134. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/double-click-action.hbs +1 -0
  135. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -0
  136. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/hover-action.hbs +1 -0
  137. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/press-action.hbs +1 -0
  138. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -0
  139. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/uncheck-action.hbs +1 -0
  140. package/dist/generators/test-generator/adapters/playwright/templates/steps/active-state-assertion.hbs +2 -0
  141. package/dist/generators/test-generator/adapters/playwright/templates/steps/ai-response-assertion-selector.hbs +5 -0
  142. package/dist/generators/test-generator/adapters/playwright/templates/steps/ai-response-assertion-simple.hbs +1 -0
  143. package/dist/generators/test-generator/adapters/playwright/templates/steps/application-running.hbs +1 -0
  144. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +1 -0
  145. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -0
  146. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +1 -0
  147. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -0
  148. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -0
  149. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -0
  150. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +1 -0
  151. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +1 -0
  152. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +1 -0
  153. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-visible-assertion.hbs +1 -0
  154. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +1 -0
  155. package/dist/generators/test-generator/adapters/playwright/templates/steps/check-action.hbs +1 -0
  156. package/dist/generators/test-generator/adapters/playwright/templates/steps/checkbox.hbs +2 -0
  157. package/dist/generators/test-generator/adapters/playwright/templates/steps/checked-assertion.hbs +1 -0
  158. package/dist/generators/test-generator/adapters/playwright/templates/steps/clear-action.hbs +1 -0
  159. package/dist/generators/test-generator/adapters/playwright/templates/steps/clear-auth.hbs +6 -0
  160. package/dist/generators/test-generator/adapters/playwright/templates/steps/clear-browser-state.hbs +6 -0
  161. package/dist/generators/test-generator/adapters/playwright/templates/steps/clear-database.hbs +4 -0
  162. package/dist/generators/test-generator/adapters/playwright/templates/steps/clear.hbs +2 -0
  163. package/dist/generators/test-generator/adapters/playwright/templates/steps/click-action.hbs +1 -0
  164. package/dist/generators/test-generator/adapters/playwright/templates/steps/click.hbs +2 -0
  165. package/dist/generators/test-generator/adapters/playwright/templates/steps/contain-text-assertion.hbs +1 -0
  166. package/dist/generators/test-generator/adapters/playwright/templates/steps/contains-text-assertion.hbs +2 -0
  167. package/dist/generators/test-generator/adapters/playwright/templates/steps/count-assertion.hbs +1 -0
  168. package/dist/generators/test-generator/adapters/playwright/templates/steps/count-greater-than.hbs +3 -0
  169. package/dist/generators/test-generator/adapters/playwright/templates/steps/count-less-than.hbs +3 -0
  170. package/dist/generators/test-generator/adapters/playwright/templates/steps/disabled-assertion.hbs +2 -0
  171. package/dist/generators/test-generator/adapters/playwright/templates/steps/displayed-containing-text.hbs +3 -0
  172. package/dist/generators/test-generator/adapters/playwright/templates/steps/displayed-with-text.hbs +3 -0
  173. package/dist/generators/test-generator/adapters/playwright/templates/steps/double-click-action.hbs +1 -0
  174. package/dist/generators/test-generator/adapters/playwright/templates/steps/empty-assertion-advanced.hbs +3 -0
  175. package/dist/generators/test-generator/adapters/playwright/templates/steps/empty-assertion.hbs +2 -0
  176. package/dist/generators/test-generator/adapters/playwright/templates/steps/enabled-assertion.hbs +2 -0
  177. package/dist/generators/test-generator/adapters/playwright/templates/steps/error-message-assertion.hbs +3 -0
  178. package/dist/generators/test-generator/adapters/playwright/templates/steps/fill-action.hbs +1 -0
  179. package/dist/generators/test-generator/adapters/playwright/templates/steps/fill.hbs +2 -0
  180. package/dist/generators/test-generator/adapters/playwright/templates/steps/focused-assertion.hbs +1 -0
  181. package/dist/generators/test-generator/adapters/playwright/templates/steps/generic-message-assertion.hbs +3 -0
  182. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-attribute.hbs +2 -0
  183. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-class.hbs +2 -0
  184. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-count.hbs +2 -0
  185. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-image-src.hbs +3 -0
  186. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-link.hbs +3 -0
  187. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-placeholder.hbs +3 -0
  188. package/dist/generators/test-generator/adapters/playwright/templates/steps/has-value.hbs +2 -0
  189. package/dist/generators/test-generator/adapters/playwright/templates/steps/have-text-assertion.hbs +1 -0
  190. package/dist/generators/test-generator/adapters/playwright/templates/steps/hover-action.hbs +1 -0
  191. package/dist/generators/test-generator/adapters/playwright/templates/steps/html5-validation-check.hbs +4 -0
  192. package/dist/generators/test-generator/adapters/playwright/templates/steps/is-checked.hbs +2 -0
  193. package/dist/generators/test-generator/adapters/playwright/templates/steps/is-editable.hbs +2 -0
  194. package/dist/generators/test-generator/adapters/playwright/templates/steps/is-focused.hbs +2 -0
  195. package/dist/generators/test-generator/adapters/playwright/templates/steps/is-hidden.hbs +2 -0
  196. package/dist/generators/test-generator/adapters/playwright/templates/steps/is-unchecked.hbs +2 -0
  197. package/dist/generators/test-generator/adapters/playwright/templates/steps/locator.hbs +1 -0
  198. package/dist/generators/test-generator/adapters/playwright/templates/steps/login.hbs +8 -0
  199. package/dist/generators/test-generator/adapters/playwright/templates/steps/message-assertion-body.hbs +1 -0
  200. package/dist/generators/test-generator/adapters/playwright/templates/steps/message-assertion-selector.hbs +2 -0
  201. package/dist/generators/test-generator/adapters/playwright/templates/steps/message-count-assertion.hbs +3 -0
  202. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -0
  203. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/route-assertion.hbs +2 -0
  204. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element.hbs +1 -0
  205. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-timeout.hbs +1 -0
  206. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation.hbs +1 -0
  207. package/dist/generators/test-generator/adapters/playwright/templates/steps/not-checked-assertion.hbs +1 -0
  208. package/dist/generators/test-generator/adapters/playwright/templates/steps/not-visible-assertion.hbs +1 -0
  209. package/dist/generators/test-generator/adapters/playwright/templates/steps/not-visible.hbs +2 -0
  210. package/dist/generators/test-generator/adapters/playwright/templates/steps/notification-assertion.hbs +4 -0
  211. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +1 -0
  212. package/dist/generators/test-generator/adapters/playwright/templates/steps/press-action.hbs +1 -0
  213. package/dist/generators/test-generator/adapters/playwright/templates/steps/press-enter.hbs +2 -0
  214. package/dist/generators/test-generator/adapters/playwright/templates/steps/redirect-assertion.hbs +3 -0
  215. package/dist/generators/test-generator/adapters/playwright/templates/steps/route-assertion.hbs +2 -0
  216. package/dist/generators/test-generator/adapters/playwright/templates/steps/screen-navigation.hbs +3 -0
  217. package/dist/generators/test-generator/adapters/playwright/templates/steps/scroll-bottom-assertion.hbs +5 -0
  218. package/dist/generators/test-generator/adapters/playwright/templates/steps/select-action.hbs +1 -0
  219. package/dist/generators/test-generator/adapters/playwright/templates/steps/select.hbs +2 -0
  220. package/dist/generators/test-generator/adapters/playwright/templates/steps/setup/application-running.hbs +1 -0
  221. package/dist/generators/test-generator/adapters/playwright/templates/steps/setup/clear-auth.hbs +6 -0
  222. package/dist/generators/test-generator/adapters/playwright/templates/steps/setup/clear-browser-state.hbs +6 -0
  223. package/dist/generators/test-generator/adapters/playwright/templates/steps/setup/clear-database.hbs +4 -0
  224. package/dist/generators/test-generator/adapters/playwright/templates/steps/setup/user-login-todo.hbs +6 -0
  225. package/dist/generators/test-generator/adapters/playwright/templates/steps/text-matches-pattern.hbs +3 -0
  226. package/dist/generators/test-generator/adapters/playwright/templates/steps/uncheck-action.hbs +1 -0
  227. package/dist/generators/test-generator/adapters/playwright/templates/steps/user-login-todo.hbs +6 -0
  228. package/dist/generators/test-generator/adapters/playwright/templates/steps/visibility-assertion.hbs +2 -0
  229. package/dist/generators/test-generator/adapters/playwright/templates/steps/visible-assertion.hbs +1 -0
  230. package/dist/generators/test-generator/adapters/playwright/templates/steps/wait-for-element.hbs +1 -0
  231. package/dist/generators/test-generator/adapters/playwright/templates/steps/wait-timeout.hbs +1 -0
  232. package/dist/generators/test-generator/adapters/playwright/templates/steps/wait.hbs +1 -0
  233. package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +19 -0
  234. package/dist/generators/test-generator/ai-step-mapper.d.ts +27 -0
  235. package/dist/generators/test-generator/ai-step-mapper.d.ts.map +1 -0
  236. package/dist/generators/test-generator/ai-step-mapper.js +204 -0
  237. package/dist/generators/test-generator/ai-step-mapper.js.map +1 -0
  238. package/dist/generators/test-generator/code-generator.d.ts +52 -0
  239. package/dist/generators/test-generator/code-generator.d.ts.map +1 -0
  240. package/dist/generators/test-generator/code-generator.js +191 -0
  241. package/dist/generators/test-generator/code-generator.js.map +1 -0
  242. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts +7 -0
  243. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -0
  244. package/dist/generators/test-generator/patterns/assertion-patterns.js +173 -0
  245. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -0
  246. package/dist/generators/test-generator/patterns/form-patterns.d.ts +8 -0
  247. package/dist/generators/test-generator/patterns/form-patterns.d.ts.map +1 -0
  248. package/dist/generators/test-generator/patterns/form-patterns.js +110 -0
  249. package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -0
  250. package/dist/generators/test-generator/patterns/index.d.ts +45 -0
  251. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -0
  252. package/dist/generators/test-generator/patterns/index.js +106 -0
  253. package/dist/generators/test-generator/patterns/index.js.map +1 -0
  254. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +7 -0
  255. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -0
  256. package/dist/generators/test-generator/patterns/interaction-patterns.js +100 -0
  257. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -0
  258. package/dist/generators/test-generator/patterns/navigation-patterns.d.ts +8 -0
  259. package/dist/generators/test-generator/patterns/navigation-patterns.d.ts.map +1 -0
  260. package/dist/generators/test-generator/patterns/navigation-patterns.js +92 -0
  261. package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -0
  262. package/dist/generators/test-generator/patterns/setup-patterns.d.ts +7 -0
  263. package/dist/generators/test-generator/patterns/setup-patterns.d.ts.map +1 -0
  264. package/dist/generators/test-generator/patterns/setup-patterns.js +84 -0
  265. package/dist/generators/test-generator/patterns/setup-patterns.js.map +1 -0
  266. package/dist/generators/test-generator/patterns/types.d.ts +38 -0
  267. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -0
  268. package/dist/generators/test-generator/patterns/types.js +3 -0
  269. package/dist/generators/test-generator/patterns/types.js.map +1 -0
  270. package/dist/generators/test-generator/step-mapper-old.d.ts +180 -0
  271. package/dist/generators/test-generator/step-mapper-old.d.ts.map +1 -0
  272. package/dist/generators/test-generator/step-mapper-old.js +752 -0
  273. package/dist/generators/test-generator/step-mapper-old.js.map +1 -0
  274. package/dist/generators/test-generator/step-mapper-refactored.d.ts +47 -0
  275. package/dist/generators/test-generator/step-mapper-refactored.d.ts.map +1 -0
  276. package/dist/generators/test-generator/step-mapper-refactored.js +182 -0
  277. package/dist/generators/test-generator/step-mapper-refactored.js.map +1 -0
  278. package/dist/generators/test-generator/step-mapper.d.ts +66 -0
  279. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -0
  280. package/dist/generators/test-generator/step-mapper.js +248 -0
  281. package/dist/generators/test-generator/step-mapper.js.map +1 -0
  282. package/dist/generators/test-generator/template-engine.d.ts +33 -0
  283. package/dist/generators/test-generator/template-engine.d.ts.map +1 -0
  284. package/dist/generators/test-generator/template-engine.js +129 -0
  285. package/dist/generators/test-generator/template-engine.js.map +1 -0
  286. package/dist/generators/test-generator/utils/data-resolver.d.ts +39 -0
  287. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -0
  288. package/dist/generators/test-generator/utils/data-resolver.js +162 -0
  289. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -0
  290. package/dist/generators/test-generator/utils/path-inference.d.ts +49 -0
  291. package/dist/generators/test-generator/utils/path-inference.d.ts.map +1 -0
  292. package/dist/generators/test-generator/utils/path-inference.js +286 -0
  293. package/dist/generators/test-generator/utils/path-inference.js.map +1 -0
  294. package/dist/generators/test-generator/utils/selector-resolver.d.ts +93 -0
  295. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -0
  296. package/dist/generators/test-generator/utils/selector-resolver.js +408 -0
  297. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -0
  298. package/dist/generators/types.d.ts +118 -0
  299. package/dist/generators/types.d.ts.map +1 -0
  300. package/dist/generators/types.js +48 -0
  301. package/dist/generators/types.js.map +1 -0
  302. package/dist/generators/ui-model-builder/deep-scanner.d.ts +121 -0
  303. package/dist/generators/ui-model-builder/deep-scanner.d.ts.map +1 -0
  304. package/dist/generators/ui-model-builder/deep-scanner.js +1113 -0
  305. package/dist/generators/ui-model-builder/deep-scanner.js.map +1 -0
  306. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts +110 -0
  307. package/dist/generators/ui-model-builder/enhanced-deep-scanner.d.ts.map +1 -0
  308. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js +608 -0
  309. package/dist/generators/ui-model-builder/enhanced-deep-scanner.js.map +1 -0
  310. package/dist/generators/ui-model-builder/react-scanner.d.ts +107 -0
  311. package/dist/generators/ui-model-builder/react-scanner.d.ts.map +1 -0
  312. package/dist/generators/ui-model-builder/react-scanner.js +797 -0
  313. package/dist/generators/ui-model-builder/react-scanner.js.map +1 -0
  314. package/dist/input/cli-adapter.d.ts +63 -0
  315. package/dist/input/cli-adapter.d.ts.map +1 -0
  316. package/dist/input/cli-adapter.js +173 -0
  317. package/dist/input/cli-adapter.js.map +1 -0
  318. package/dist/input/config-adapter.d.ts +25 -0
  319. package/dist/input/config-adapter.d.ts.map +1 -0
  320. package/dist/input/config-adapter.js +70 -0
  321. package/dist/input/config-adapter.js.map +1 -0
  322. package/dist/input/input-adapter.d.ts +28 -0
  323. package/dist/input/input-adapter.d.ts.map +1 -0
  324. package/dist/input/input-adapter.js +17 -0
  325. package/dist/input/input-adapter.js.map +1 -0
  326. package/dist/input/vscode-adapter.d.ts +62 -0
  327. package/dist/input/vscode-adapter.d.ts.map +1 -0
  328. package/dist/input/vscode-adapter.js +64 -0
  329. package/dist/input/vscode-adapter.js.map +1 -0
  330. package/dist/orchestrator/cache-manager.d.ts +37 -0
  331. package/dist/orchestrator/cache-manager.d.ts.map +1 -0
  332. package/dist/orchestrator/cache-manager.js +148 -0
  333. package/dist/orchestrator/cache-manager.js.map +1 -0
  334. package/dist/orchestrator/pipeline.d.ts +73 -0
  335. package/dist/orchestrator/pipeline.d.ts.map +1 -0
  336. package/dist/orchestrator/pipeline.js +607 -0
  337. package/dist/orchestrator/pipeline.js.map +1 -0
  338. package/dist/orchestrator/project-initializer.d.ts +51 -0
  339. package/dist/orchestrator/project-initializer.d.ts.map +1 -0
  340. package/dist/orchestrator/project-initializer.js +326 -0
  341. package/dist/orchestrator/project-initializer.js.map +1 -0
  342. package/dist/orchestrator/reporter.d.ts +15 -0
  343. package/dist/orchestrator/reporter.d.ts.map +1 -0
  344. package/dist/orchestrator/reporter.js +30 -0
  345. package/dist/orchestrator/reporter.js.map +1 -0
  346. package/dist/orchestrator/screen-manager.d.ts +47 -0
  347. package/dist/orchestrator/screen-manager.d.ts.map +1 -0
  348. package/dist/orchestrator/screen-manager.js +271 -0
  349. package/dist/orchestrator/screen-manager.js.map +1 -0
  350. package/dist/tools/auto-tagger.d.ts +107 -0
  351. package/dist/tools/auto-tagger.d.ts.map +1 -0
  352. package/dist/tools/auto-tagger.js +502 -0
  353. package/dist/tools/auto-tagger.js.map +1 -0
  354. package/package.json +73 -0
  355. package/src/cli/commands/auto-tag-command.ts +80 -0
  356. package/src/cli/index.ts +205 -0
  357. package/src/config/ai-providers.yaml +56 -0
  358. package/src/config/config-loader.ts +248 -0
  359. package/src/config/config-schema.ts +148 -0
  360. package/src/config/default.config.yaml +101 -0
  361. package/src/config/framework.config.yaml +52 -0
  362. package/src/config/routes.yaml +31 -0
  363. package/src/core/selector-base/annotation-handler.ts +127 -0
  364. package/src/core/selector-base/base-generator.ts +234 -0
  365. package/src/core/selector-base/gherkin-parser.ts +57 -0
  366. package/src/core/selector-mapper/priority-mapper.ts +607 -0
  367. package/src/core/ui-scanner/heuristics/base-heuristic.ts +216 -0
  368. package/src/core/ui-scanner/react-scanner.ts +156 -0
  369. package/src/core/ui-scanner/scanner-interface.ts +133 -0
  370. package/src/core/ui-scanner/strict-scanner.ts +629 -0
  371. package/src/executor/playwright/playwright-generator.ts +125 -0
  372. package/src/executor/test-generator.ts +90 -0
  373. package/src/external/ai-provider.ts +90 -0
  374. package/src/external/anthropic-provider.ts +114 -0
  375. package/src/generators/README.md +410 -0
  376. package/src/generators/cache/cache-manager.ts +322 -0
  377. package/src/generators/cli.ts +640 -0
  378. package/src/generators/dsl-writer/index.ts +253 -0
  379. package/src/generators/gherkin-parser/index.ts +155 -0
  380. package/src/generators/gherkin-parser/selector-extractor.ts +142 -0
  381. package/src/generators/scaffold-generator/index.ts +524 -0
  382. package/src/generators/selector-mapper/ai-mapper.ts +528 -0
  383. package/src/generators/selector-mapper/hybrid-mapper.ts +427 -0
  384. package/src/generators/selector-mapper/index.ts +10 -0
  385. package/src/generators/selector-mapper/intelligent-mapper.ts +530 -0
  386. package/src/generators/test-generator/adapters/adapter-interface.ts +49 -0
  387. package/src/generators/test-generator/adapters/adapter-registry.ts +56 -0
  388. package/src/generators/test-generator/adapters/index.ts +9 -0
  389. package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +40 -0
  390. package/src/generators/test-generator/adapters/playwright/templates/before-each.hbs +8 -0
  391. package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +5 -0
  392. package/src/generators/test-generator/adapters/playwright/templates/scenario.hbs +8 -0
  393. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/check-action.hbs +1 -0
  394. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/clear-action.hbs +1 -0
  395. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-action.hbs +1 -0
  396. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/double-click-action.hbs +1 -0
  397. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -0
  398. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/hover-action.hbs +1 -0
  399. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/press-action.hbs +1 -0
  400. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -0
  401. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/uncheck-action.hbs +1 -0
  402. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +1 -0
  403. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -0
  404. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +1 -0
  405. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -0
  406. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -0
  407. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -0
  408. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +1 -0
  409. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +1 -0
  410. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +1 -0
  411. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-visible-assertion.hbs +1 -0
  412. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +1 -0
  413. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -0
  414. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/route-assertion.hbs +2 -0
  415. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element.hbs +1 -0
  416. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-timeout.hbs +1 -0
  417. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +1 -0
  418. package/src/generators/test-generator/adapters/playwright/templates/steps/setup/application-running.hbs +1 -0
  419. package/src/generators/test-generator/adapters/playwright/templates/steps/setup/clear-auth.hbs +6 -0
  420. package/src/generators/test-generator/adapters/playwright/templates/steps/setup/clear-browser-state.hbs +6 -0
  421. package/src/generators/test-generator/adapters/playwright/templates/steps/setup/clear-database.hbs +4 -0
  422. package/src/generators/test-generator/adapters/playwright/templates/steps/setup/user-login-todo.hbs +6 -0
  423. package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +19 -0
  424. package/src/generators/test-generator/ai-step-mapper.ts +224 -0
  425. package/src/generators/test-generator/code-generator.ts +235 -0
  426. package/src/generators/test-generator/patterns/assertion-patterns.ts +183 -0
  427. package/src/generators/test-generator/patterns/form-patterns.ts +124 -0
  428. package/src/generators/test-generator/patterns/index.ts +97 -0
  429. package/src/generators/test-generator/patterns/interaction-patterns.ts +119 -0
  430. package/src/generators/test-generator/patterns/navigation-patterns.ts +110 -0
  431. package/src/generators/test-generator/patterns/setup-patterns.ts +94 -0
  432. package/src/generators/test-generator/patterns/types.ts +41 -0
  433. package/src/generators/test-generator/step-mapper.ts +254 -0
  434. package/src/generators/test-generator/template-engine.ts +160 -0
  435. package/src/generators/test-generator/utils/data-resolver.ts +147 -0
  436. package/src/generators/test-generator/utils/path-inference.ts +344 -0
  437. package/src/generators/test-generator/utils/selector-resolver.ts +480 -0
  438. package/src/generators/types.ts +226 -0
  439. package/src/generators/ui-model-builder/deep-scanner.ts +1244 -0
  440. package/src/generators/ui-model-builder/enhanced-deep-scanner.ts +731 -0
  441. package/src/generators/ui-model-builder/react-scanner.ts +959 -0
  442. package/src/input/cli-adapter.ts +185 -0
  443. package/src/input/config-adapter.ts +71 -0
  444. package/src/input/input-adapter.ts +32 -0
  445. package/src/input/vscode-adapter.ts +90 -0
  446. package/src/orchestrator/cache-manager.ts +138 -0
  447. package/src/orchestrator/pipeline.ts +713 -0
  448. package/src/orchestrator/project-initializer.ts +315 -0
  449. package/src/orchestrator/reporter.ts +36 -0
  450. package/src/orchestrator/screen-manager.ts +268 -0
  451. package/src/tools/auto-tagger.ts +572 -0
@@ -0,0 +1,528 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * AI-Assisted Selector Mapper
4
+ * Uses AI (Claude/Gemini) to map Gherkin element IDs to CSS selectors
5
+ */
6
+
7
+ import Anthropic from '@anthropic-ai/sdk';
8
+ import { GoogleGenerativeAI } from '@google/generative-ai';
9
+ import { UIModel, UIElement, SelectorDSL, SelectorEntry } from '../types';
10
+
11
+ // ============================================================================
12
+ // Configuration
13
+ // ============================================================================
14
+
15
+ export interface AIMapperConfig {
16
+ provider: 'anthropic' | 'google';
17
+ model?: string;
18
+ apiKey?: string;
19
+ verbose?: boolean;
20
+ }
21
+
22
+ interface MappingRequest {
23
+ uiModel: UIModel;
24
+ elementIds: string[]; // e.g., ["[login.email]", "[login.password]", "[login.submit]"]
25
+ }
26
+
27
+ interface MappingResult {
28
+ selectors: SelectorDSL;
29
+ metadata: {
30
+ aiModel: string;
31
+ tokenCost?: number;
32
+ provider: string;
33
+ };
34
+ }
35
+
36
+ // ============================================================================
37
+ // AI Mapper Class
38
+ // ============================================================================
39
+
40
+ export class AIMapper {
41
+ private config: AIMapperConfig;
42
+ private anthropic?: Anthropic;
43
+ private googleAI?: GoogleGenerativeAI;
44
+
45
+ constructor(config: AIMapperConfig) {
46
+ this.config = config;
47
+
48
+ // Initialize AI clients
49
+ if (config.provider === 'anthropic') {
50
+ const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
51
+ if (!apiKey) {
52
+ throw new Error('ANTHROPIC_API_KEY not found');
53
+ }
54
+ this.anthropic = new Anthropic({ apiKey });
55
+ } else if (config.provider === 'google') {
56
+ const apiKey = config.apiKey || process.env.GEMINI_API_KEY;
57
+ if (!apiKey) {
58
+ throw new Error('GEMINI_API_KEY not found');
59
+ }
60
+ this.googleAI = new GoogleGenerativeAI(apiKey);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Map element IDs to selectors using AI
66
+ */
67
+ async mapSelectors(request: MappingRequest): Promise<MappingResult> {
68
+ const prompt = this.buildPrompt(request);
69
+
70
+ if (this.config.verbose) {
71
+ console.log('\n📤 Sending request to AI...');
72
+ }
73
+
74
+ let response: string;
75
+ let aiModel: string;
76
+ let tokenCost: number | undefined;
77
+
78
+ if (this.config.provider === 'anthropic') {
79
+ const result = await this.callAnthropic(prompt);
80
+ response = result.response;
81
+ aiModel = result.model;
82
+ tokenCost = result.tokenCost;
83
+ } else {
84
+ const result = await this.callGoogle(prompt);
85
+ response = result.response;
86
+ aiModel = result.model;
87
+ }
88
+
89
+ // Parse AI response
90
+ const selectors = this.parseResponse(response, request.elementIds);
91
+
92
+ // UPDATED: Phase 1 - Task 3 - Don't create fake fallback placeholders
93
+ // Return null selectors with confidence "none" for missing elements
94
+ for (const elementId of request.elementIds) {
95
+ // CRITICAL FIX: Use clean ID to match heuristic format
96
+ const cleanId = elementId.replace(/[\[\]]/g, '').split('.').pop() || elementId;
97
+
98
+ if (!selectors[cleanId]) {
99
+ selectors[cleanId] = {
100
+ selector: null,
101
+ type: 'unknown',
102
+ description: 'Element not found in UI Model - re-scan or add manually',
103
+ discoveryMethod: 'ai-static-analysis',
104
+ locatorType: 'css',
105
+ confidence: 'none',
106
+ reason: 'not-in-ui-model',
107
+ suggestedAction: 'Run discovery again or add data-testid to source code'
108
+ };
109
+ }
110
+ }
111
+
112
+ return {
113
+ selectors,
114
+ metadata: {
115
+ aiModel,
116
+ tokenCost,
117
+ provider: this.config.provider
118
+ }
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Build prompt for AI
124
+ */
125
+ private buildPrompt(request: MappingRequest): string {
126
+ const { uiModel, elementIds } = request;
127
+
128
+ // Extract ALL relevant attributes from UI model (DON'T simplify!)
129
+ const enrichedElements = uiModel.elements.map(el => {
130
+ // Extract critical props from the props object
131
+ const props = el.props || {};
132
+
133
+ return {
134
+ key: el.key,
135
+ tag: el.tag,
136
+ // Top-level attributes
137
+ id: el.id,
138
+ name: el.name,
139
+ placeholder: el.placeholder,
140
+ ariaLabel: el.ariaLabel,
141
+ testId: el.testId,
142
+ text: el.text,
143
+ role: el.role,
144
+ // CRITICAL: Extract props that AI needs for selector generation
145
+ type: props.type, // button type="submit", input type="password"
146
+ href: props.href, // link href="/auth/register"
147
+ value: props.value, // input value
148
+ disabled: props.disabled, // button disabled
149
+ required: props.required, // input required
150
+ autoComplete: props.autoComplete, // input autocomplete
151
+ // Keep full props for AI to reference if needed
152
+ allProps: props
153
+ };
154
+ });
155
+
156
+ const prompt = `You are a test automation expert. Given a UI Model and a list of element IDs from Gherkin test scenarios, generate CSS selectors for each element.
157
+
158
+ **CRITICAL: Use Semantic Understanding**
159
+ The element IDs come from QA-written Gherkin scenarios and use human-readable names. You MUST understand the semantic meaning of each ID and match it to the appropriate UI element.
160
+
161
+ **PHASE 2 ENHANCEMENT: Semantic Aliases & Context Awareness**
162
+
163
+ Gherkin names often use INTENT-based naming while UI uses IMPLEMENTATION-based text. You must bridge this semantic gap:
164
+
165
+ **Common Semantic Aliases:**
166
+
167
+ **Action Buttons:**
168
+ - "clear" / "clear-button" ≈ "New Chat" button (clears chat history)
169
+ - "send" / "send-button" ≈ "Send", "Submit", "→", "➤" button
170
+ - "submit" / "submit-button" ≈ "Submit", "Continue", "Sign In", "Register" button
171
+ - "cancel" / "cancel-button" ≈ "Cancel", "Back", "Close" button
172
+ - "delete" / "delete-button" ≈ "Delete", "Remove", "×" button
173
+ - "edit" / "edit-button" ≈ "Edit", "Modify", "✎" button
174
+ - "save" / "save-button" ≈ "Save", "Update", "Confirm" button
175
+
176
+ **Brand/Identity Elements:**
177
+ - "logo" ≈ heading with brand name OR image with alt="logo"
178
+ - "title" ≈ main heading (h1) with brand/app name
179
+ - "tagline" ≈ subtitle or description text
180
+
181
+ **Navigation:**
182
+ - "login-link" / "signin-link" ≈ link with text "Login", "Sign In", "Log In"
183
+ - "register-link" / "signup-link" ≈ link with text "Register", "Sign Up", "Create Account"
184
+ - "logout-link" / "signout-link" ≈ link/button with text "Logout", "Sign Out", "Log Out"
185
+ - "back-link" ≈ link with text "Back", "←", "Return"
186
+
187
+ **Input Fields (aliases for same field):**
188
+ - "email" / "email-input" / "email-field" → input[type='email'] OR input[name='email']
189
+ - "password" / "pass" / "password-input" / "pw" → input[type='password']
190
+ - "message" / "message-input" / "input" / "textarea" → textarea for messages
191
+ - "search" / "search-input" → input[type='search'] OR placeholder containing "search"
192
+
193
+ **Container Elements:**
194
+ - "messages" / "messages-container" / "messages-list" → div with overflow-y-auto OR flex-1 (scrollable area)
195
+ - "empty-state" → text/paragraph shown when no content (e.g., "No messages yet", "Start a conversation")
196
+ - "error" / "error-message" → text with red color (text-red-*) OR bg-red-*
197
+
198
+ **Conditional Elements (may have isConditional marker):**
199
+ - "timestamp" / "message-timestamp" → small text with time format (text-xs, text-gray-500)
200
+ - "error" / "field-error" → conditionally rendered error message
201
+ - "copy-button" → button that appears on hover (opacity-0 group-hover:opacity-100)
202
+ - "tooltip" → conditionally shown helper text
203
+
204
+ **Context Clues:**
205
+ - If Gherkin says "clear-button" but UI has "New Chat" button → Match if button clears/resets state
206
+ - If Gherkin says "logo" but UI has h1 text → Match heading with brand name
207
+ - If Gherkin says "send" but UI has "Submit" → Match if button submits form
208
+ - If multiple buttons exist, use context: submit buttons usually have type='submit', cancel buttons may have type='button'
209
+
210
+ **Examples of semantic matching:**
211
+ - \`[auth-login.email]\` OR \`[auth-login.email-input]\` → input with name="email" or id="email-address"
212
+ - \`[auth-login.password]\` OR \`[auth-login.pass]\` → input with type="password" or name="password"
213
+ - \`[auth-login.submit]\` OR \`[auth-login.login-button]\` → button with type="submit" OR button:has-text("Sign In")
214
+ - \`[auth-login.signup-link]\` OR \`[auth-login.register-link]\` → link (a tag) pointing to signup/register
215
+ - \`[chat.input]\` OR \`[chat.message-input]\` → textarea or input for chat messages
216
+ - \`[chat.send-button]\` OR \`[chat.send]\` → button to send messages OR button:has-text("Send")
217
+ - \`[chat.clear-button]\` → button:has-text("New Chat") (semantic alias: clear ≈ new chat)
218
+ - \`[home.logo]\` → h1:has-text("PEU AI-Native Workflow") (logo as text heading)
219
+
220
+ **Screen:** ${uiModel.screenId}
221
+ **Framework:** ${uiModel.framework}
222
+
223
+ **UI Elements Available:**
224
+ ${JSON.stringify(enrichedElements, null, 2)}
225
+
226
+ **Element IDs to Resolve (from Gherkin):**
227
+ ${elementIds.map(id => `- ${id}`).join('\n')}
228
+
229
+ **CRITICAL INSTRUCTIONS - MUST FOLLOW:**
230
+
231
+ 1. **Use EXACT attributes from UI Model** - Each element has \`type\`, \`href\`, \`id\`, \`name\`, etc. Use these EXACT values!
232
+
233
+ 2. **MANDATORY Selector Priority:**
234
+
235
+ **FOR BUTTONS (tag="button"):**
236
+ - If element has \`type\` attribute → **MUST use** \`button[type="..."]\`
237
+ - Example: \`type: "submit"\` → \`button[type='submit']\` (NOT \`button[role='button']\`!)
238
+ - Only use text if no type: \`button:has-text("...")\`
239
+
240
+ **FOR LINKS (tag="a", tag="link"):**
241
+ - If element has \`href\` → **MUST use** \`a[href="..."]\`
242
+ - Use EXACT href from UI Model
243
+ - Example: \`href: "/auth/register"\` → \`a[href='/auth/register']\`
244
+
245
+ **FOR INPUTS (tag="input"):**
246
+ - Priority: \`id\` > \`name\` > \`type\` + \`placeholder\`
247
+ - Example: \`id: "email-address"\` → \`#email-address\`
248
+ - Example: \`name: "password"\` → \`input[name='password']\`
249
+
250
+ **FOR TEXTAREA:**
251
+ - Priority: \`id\` > \`name\` > \`placeholder\`
252
+ - Example: \`placeholder: "Type your message"\` → \`textarea[placeholder*='Type your message']\`
253
+
254
+ 3. **NEVER use these (BANNED):**
255
+ - Generic \`role\` attribute for buttons/inputs
256
+ - Class names NOT in UI Model
257
+ - Invented/guessed selectors
258
+ - Just tag name without attributes (e.g., \`button\`, \`textarea\`)
259
+
260
+ 4. **Semantic matching:** "email", "email-input", "email-field" all = same element
261
+
262
+ 5. **Confidence levels:**
263
+ - \`high\`: Used id/name/type/href from UI Model - exact match
264
+ - \`medium\`: Used placeholder/text from UI Model OR semantic alias match (e.g., "clear" → "New Chat")
265
+ - \`low\`: Ambiguous match - multiple elements could match
266
+ - \`none\`: Element not found in UI Model (needs manual review)
267
+
268
+ 6. **PHASE 2: Ambiguity Detection & Helpful Messages**
269
+
270
+ If you find MULTIPLE elements that could match a Gherkin ID:
271
+ - Set confidence to \`low\`
272
+ - In description, list ALL potential matches
273
+ - Example:
274
+ \`\`\`json
275
+ {
276
+ "[chat.messages]": {
277
+ "selector": "div.flex-1.overflow-y-auto",
278
+ "type": "container",
279
+ "description": "AMBIGUOUS: Could be (1) messages container (div.flex-1), (2) messages list (div.max-w-4xl), or (3) message items. Recommend using [chat.messages-container] for container, [chat.messages-list] for list, or [chat.messages-item] for items.",
280
+ "confidence": "low"
281
+ }
282
+ }
283
+ \`\`\`
284
+
285
+ If element uses semantic alias:
286
+ - Set confidence to \`medium\`
287
+ - Explain the alias in description
288
+ - Example:
289
+ \`\`\`json
290
+ {
291
+ "[chat.clear-button]": {
292
+ "selector": "button:has-text('New Chat')",
293
+ "type": "button",
294
+ "description": "Semantic match: 'clear-button' maps to 'New Chat' button (clears chat history)",
295
+ "confidence": "medium"
296
+ }
297
+ }
298
+ \`\`\`
299
+
300
+ 7. **IF ELEMENT NOT FOUND IN UI MODEL:**
301
+ - DO NOT guess selectors or invent className patterns like \`div[className*='...']\`
302
+ - DO NOT create fake data-testid attributes like \`[data-testid="messages"]\`
303
+ - RETURN exactly:
304
+ \`\`\`json
305
+ {
306
+ "[element-id]": {
307
+ "selector": null,
308
+ "type": "unknown",
309
+ "description": "Element not found in UI Model",
310
+ "confidence": "none"
311
+ }
312
+ }
313
+ \`\`\`
314
+
315
+ **Return ONLY valid JSON with this structure:**
316
+ \`\`\`json
317
+ {
318
+ "[element-id]": {
319
+ "selector": "css-selector-string",
320
+ "type": "input|button|link|textarea|text|container",
321
+ "description": "Human readable description",
322
+ "confidence": "high|medium|low"
323
+ }
324
+ }
325
+ \`\`\`
326
+
327
+ **Example Response (showing CORRECT usage):**
328
+ \`\`\`json
329
+ {
330
+ "[auth-login.email]": {
331
+ "selector": "#email-address",
332
+ "type": "input",
333
+ "description": "Email input field",
334
+ "confidence": "high"
335
+ },
336
+ "[auth-login.submit]": {
337
+ "selector": "button[type='submit']",
338
+ "type": "button",
339
+ "description": "Login submit button",
340
+ "confidence": "high"
341
+ },
342
+ "[auth-login.signup-link]": {
343
+ "selector": "a[href='/auth/register']",
344
+ "type": "link",
345
+ "description": "Sign up link",
346
+ "confidence": "high"
347
+ }
348
+ }
349
+ \`\`\`
350
+
351
+ **WRONG Examples (NEVER do this):**
352
+ ❌ \`"selector": "button[role='button']"\` - DON'T use role when type exists!
353
+ ❌ \`"selector": "button"\` - DON'T use tag only!
354
+ ❌ \`"selector": ".submit-btn"\` - DON'T invent class names!
355
+ ❌ \`"selector": "div[className*='chat-messages']"\` - DON'T guess className patterns!
356
+ ❌ \`"selector": "[data-testid='messages']"\` - DON'T create fake testids!
357
+ ✅ \`"selector": "button[type='submit']"\` - CORRECT! Uses type from UI Model!
358
+ ✅ \`"selector": null, "confidence": "none"\` - CORRECT! If not found in UI Model!
359
+
360
+ **IMPORTANT:** Return ONLY the JSON object, no markdown, no additional text.`;
361
+
362
+ return prompt;
363
+ }
364
+
365
+ /**
366
+ * Call Anthropic API
367
+ */
368
+ private async callAnthropic(prompt: string): Promise<{
369
+ response: string;
370
+ model: string;
371
+ tokenCost: number;
372
+ }> {
373
+ if (!this.anthropic) {
374
+ throw new Error('Anthropic client not initialized');
375
+ }
376
+
377
+ const model = this.config.model || 'claude-3-5-haiku-20241022';
378
+
379
+ const message = await this.anthropic.messages.create({
380
+ model,
381
+ max_tokens: 4096,
382
+ messages: [{
383
+ role: 'user',
384
+ content: prompt
385
+ }]
386
+ });
387
+
388
+ const response = message.content[0].type === 'text' ? message.content[0].text : '';
389
+ const tokenCost = message.usage.input_tokens + message.usage.output_tokens;
390
+
391
+ if (this.config.verbose) {
392
+ console.log(`✅ Response received (${tokenCost} tokens)`);
393
+ }
394
+
395
+ return { response, model, tokenCost };
396
+ }
397
+
398
+ /**
399
+ * Call Google Gemini API
400
+ */
401
+ private async callGoogle(prompt: string): Promise<{
402
+ response: string;
403
+ model: string;
404
+ }> {
405
+ if (!this.googleAI) {
406
+ throw new Error('Google AI client not initialized');
407
+ }
408
+
409
+ const model = this.config.model || 'gemini-2.0-flash-exp';
410
+ const genModel = this.googleAI.getGenerativeModel({ model });
411
+
412
+ const result = await genModel.generateContent(prompt);
413
+ const response = result.response.text();
414
+
415
+ if (this.config.verbose) {
416
+ console.log(`✅ Response received from ${model}`);
417
+ }
418
+
419
+ return { response, model };
420
+ }
421
+
422
+ /**
423
+ * Parse AI response into SelectorDSL
424
+ */
425
+ private parseResponse(response: string, elementIds: string[]): SelectorDSL {
426
+ // Extract JSON from response (handle markdown code blocks)
427
+ let jsonStr = response.trim();
428
+
429
+ // Remove markdown code blocks if present
430
+ const codeBlockMatch = jsonStr.match(/```(?:json)?\s*(\{[\s\S]*\})\s*```/);
431
+ if (codeBlockMatch) {
432
+ jsonStr = codeBlockMatch[1];
433
+ }
434
+
435
+ try {
436
+ const parsed = JSON.parse(jsonStr);
437
+ const selectors: SelectorDSL = {};
438
+
439
+ // Convert to SelectorDSL format
440
+ for (const elementId of elementIds) {
441
+ if (parsed[elementId]) {
442
+ const entry = parsed[elementId];
443
+
444
+ // CRITICAL FIX: Clean element ID to match heuristic format
445
+ // [auth-login.email] → email
446
+ // [chat.message-input] → message-input
447
+ const cleanId = elementId.replace(/[\[\]]/g, '').split('.').pop() || elementId;
448
+
449
+ selectors[cleanId] = {
450
+ selector: entry.selector,
451
+ type: entry.type,
452
+ description: entry.description,
453
+ discoveryMethod: 'ai-static-analysis',
454
+ locatorType: 'css',
455
+ confidence: entry.confidence || 'medium'
456
+ };
457
+ }
458
+ }
459
+
460
+ return selectors;
461
+ } catch (error) {
462
+ console.error('Failed to parse AI response:', error);
463
+ console.error('Response:', response);
464
+ throw new Error('AI response is not valid JSON');
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Create fallback selector using heuristic rules
470
+ */
471
+ private createFallbackSelector(elementId: string, uiModel: UIModel): SelectorEntry {
472
+ // Extract element name from ID
473
+ // e.g., "[login.email]" -> "email"
474
+ const match = elementId.match(/\[([^.]+)\.([^\]]+)\]/);
475
+ const elementName = match ? match[2] : 'unknown';
476
+
477
+ // Try to find matching element by name
478
+ const matchingElement = uiModel.elements.find(el =>
479
+ el.name === elementName ||
480
+ el.id === elementName ||
481
+ el.testId?.includes(elementName)
482
+ );
483
+
484
+ if (matchingElement) {
485
+ // Build selector
486
+ let selector = matchingElement.tag;
487
+ if (matchingElement.testId) {
488
+ selector = `[data-testid="${matchingElement.testId}"]`;
489
+ } else if (matchingElement.id) {
490
+ selector = `#${matchingElement.id}`;
491
+ } else if (matchingElement.name) {
492
+ selector = `${matchingElement.tag}[name="${matchingElement.name}"]`;
493
+ }
494
+
495
+ return {
496
+ selector,
497
+ type: matchingElement.tag,
498
+ description: `Fallback selector for ${elementName}`,
499
+ discoveryMethod: 'ai-static-analysis',
500
+ locatorType: 'css',
501
+ confidence: 'low'
502
+ };
503
+ }
504
+
505
+ // Ultimate fallback
506
+ return {
507
+ selector: `[data-testid="${elementName}"]`,
508
+ type: 'unknown',
509
+ description: `Placeholder selector for ${elementName} - needs manual review`,
510
+ discoveryMethod: 'ai-static-analysis',
511
+ locatorType: 'css',
512
+ confidence: 'low'
513
+ };
514
+ }
515
+ }
516
+
517
+ // ============================================================================
518
+ // Factory Function
519
+ // ============================================================================
520
+
521
+ export async function mapSelectors(
522
+ uiModel: UIModel,
523
+ elementIds: string[],
524
+ config: AIMapperConfig
525
+ ): Promise<MappingResult> {
526
+ const mapper = new AIMapper(config);
527
+ return mapper.mapSelectors({ uiModel, elementIds });
528
+ }