@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,607 @@
1
+ /**
2
+ * Priority-based Selector Mapper - v3.1
3
+ *
4
+ * Maps Gherkin element references to actual selectors using priority waterfall:
5
+ *
6
+ * Priority 1: Direct ID Match (data-testid) - INSTANT, FREE, DETERMINISTIC
7
+ * Priority 2: Accessibility Match (role + aria-label) - SEMANTIC, STABLE, FREE
8
+ * Priority 3: Heuristic/AI Fallback - LAST RESORT
9
+ *
10
+ * Philosophy: AI is a safety net, not the primary solution
11
+ */
12
+
13
+ import { StrictUIElement, StrictScanResult } from '../ui-scanner/strict-scanner';
14
+
15
+ // ============================================================================
16
+ // TYPES
17
+ // ============================================================================
18
+
19
+ export interface SelectorMappingConfig {
20
+ strategy: 'priority-waterfall';
21
+ priorities: ('direct-id' | 'accessibility' | 'heuristic-ai')[];
22
+ aiProvider?: string;
23
+ model?: string;
24
+ confidenceThreshold?: number; // Minimum confidence to accept (0.0 - 1.0)
25
+ }
26
+
27
+ export interface MappingRequest {
28
+ elementId: string; // From Gherkin: [login.email-input]
29
+ screenName: string; // e.g., "login"
30
+ uiModel: StrictScanResult; // Scanned UI elements
31
+ }
32
+
33
+ export interface MappingResult {
34
+ elementId: string; // Original Gherkin reference
35
+ selector: string; // Final selector (Playwright-compatible)
36
+ fallbackSelector?: string; // Fallback if primary fails
37
+
38
+ // Discovery metadata
39
+ discoveryMethod: 'direct-id' | 'accessibility' | 'heuristic' | 'ai';
40
+ confidence: number; // 0.0 - 1.0
41
+ matchedElement?: StrictUIElement;
42
+
43
+ // Stats
44
+ attemptedPriorities: string[];
45
+ mappingTime: number; // ms
46
+
47
+ // Warnings
48
+ warnings?: string[];
49
+ }
50
+
51
+ export interface MappingStats {
52
+ totalMappings: number;
53
+ successfulMappings: number;
54
+ failedMappings: number;
55
+
56
+ // By priority
57
+ directIdMatches: number;
58
+ accessibilityMatches: number;
59
+ heuristicMatches: number;
60
+ aiMatches: number;
61
+
62
+ // Performance
63
+ averageMappingTime: number;
64
+ totalMappingTime: number;
65
+
66
+ // Cost (AI calls)
67
+ aiCallsCount: number;
68
+ estimatedCost: number; // USD
69
+ }
70
+
71
+ // ============================================================================
72
+ // PRIORITY LEVEL 1: DIRECT ID MATCHER
73
+ // ============================================================================
74
+
75
+ class DirectIDMatcher {
76
+ /**
77
+ * Priority 1: Exact or fuzzy data-testid matching
78
+ *
79
+ * Confidence levels:
80
+ * - 1.0: Exact match
81
+ * - 0.95: Partial match (testid contains element name)
82
+ * - 0.0: No match
83
+ */
84
+ match(elementName: string, uiElements: StrictUIElement[]): MappingResult | null {
85
+ const startTime = Date.now();
86
+
87
+ // Normalize element name
88
+ const normalized = this.normalize(elementName);
89
+
90
+ // Try exact match first
91
+ for (const element of uiElements) {
92
+ if (element.discoveryMethod !== 'direct-id') continue;
93
+
94
+ const testId = this.extractTestId(element.primaryLocator);
95
+ if (!testId) continue;
96
+
97
+ const testIdNorm = this.normalize(testId);
98
+
99
+ // Exact match
100
+ if (testIdNorm === normalized) {
101
+ return {
102
+ elementId: elementName,
103
+ selector: element.primaryLocator,
104
+ fallbackSelector: element.fallbackStrategy,
105
+ discoveryMethod: 'direct-id',
106
+ confidence: 1.0,
107
+ matchedElement: element,
108
+ attemptedPriorities: ['direct-id'],
109
+ mappingTime: Date.now() - startTime,
110
+ };
111
+ }
112
+ }
113
+
114
+ // Try partial match (fuzzy)
115
+ for (const element of uiElements) {
116
+ if (element.discoveryMethod !== 'direct-id') continue;
117
+
118
+ const testId = this.extractTestId(element.primaryLocator);
119
+ if (!testId) continue;
120
+
121
+ const testIdNorm = this.normalize(testId);
122
+
123
+ // Partial match (contains)
124
+ if (testIdNorm.includes(normalized) || normalized.includes(testIdNorm)) {
125
+ return {
126
+ elementId: elementName,
127
+ selector: element.primaryLocator,
128
+ fallbackSelector: element.fallbackStrategy,
129
+ discoveryMethod: 'direct-id',
130
+ confidence: 0.95,
131
+ matchedElement: element,
132
+ attemptedPriorities: ['direct-id'],
133
+ mappingTime: Date.now() - startTime,
134
+ warnings: [`Partial match: ${elementName} ≈ ${testId}`],
135
+ };
136
+ }
137
+ }
138
+
139
+ return null;
140
+ }
141
+
142
+ private normalize(str: string): string {
143
+ let normalized = str.toLowerCase().replace(/[\[\]]/g, ''); // Remove brackets
144
+
145
+ // Remove screen prefix: "auth-login.email-input" → "email-input" OR "auth-login-email-input" → "email-input"
146
+ normalized = normalized.replace(/^[^.]*\./, ''); // Remove prefix before dot
147
+
148
+ // Also try to remove prefix before third hyphen (screen-name-element pattern)
149
+ // e.g., "auth-login-email-input" → "email-input"
150
+ const parts = normalized.split('-');
151
+ if (parts.length >= 3) {
152
+ // Assume screen name is first two parts: "auth-login"
153
+ normalized = parts.slice(2).join('-');
154
+ }
155
+
156
+ // Finally remove all separators for comparison
157
+ return normalized.replace(/[-_\s]/g, '');
158
+ }
159
+
160
+ private extractTestId(locator: string): string | null {
161
+ // Extract from [data-testid="..."]
162
+ const match = locator.match(/data-testid="([^"]+)"/);
163
+ return match ? match[1] : null;
164
+ }
165
+ }
166
+
167
+ // ============================================================================
168
+ // PRIORITY LEVEL 2: ACCESSIBILITY MATCHER
169
+ // ============================================================================
170
+
171
+ class AccessibilityMatcher {
172
+ /**
173
+ * Priority 2: Semantic matching via role + aria-label
174
+ *
175
+ * Confidence levels:
176
+ * - 0.9: role + aria-label match
177
+ * - 0.8: role match with similar text
178
+ * - 0.0: No match
179
+ */
180
+ match(elementName: string, uiElements: StrictUIElement[]): MappingResult | null {
181
+ const startTime = Date.now();
182
+
183
+ // Infer expected role and label from element name
184
+ const expected = this.inferExpectedAttributes(elementName);
185
+
186
+ // Try matching by role + aria-label
187
+ for (const element of uiElements) {
188
+ if (element.discoveryMethod !== 'accessibility') continue;
189
+
190
+ const role = element.role;
191
+ const ariaLabel = element.ariaLabel;
192
+
193
+ if (!role) continue;
194
+
195
+ // Match role + aria-label
196
+ if (expected.role === role && ariaLabel) {
197
+ const labelNorm = this.normalize(ariaLabel);
198
+ const expectedLabelNorm = this.normalize(expected.label || elementName);
199
+
200
+ if (labelNorm.includes(expectedLabelNorm) || expectedLabelNorm.includes(labelNorm)) {
201
+ return {
202
+ elementId: elementName,
203
+ selector: element.primaryLocator,
204
+ fallbackSelector: element.fallbackStrategy,
205
+ discoveryMethod: 'accessibility',
206
+ confidence: 0.9,
207
+ matchedElement: element,
208
+ attemptedPriorities: ['direct-id', 'accessibility'],
209
+ mappingTime: Date.now() - startTime,
210
+ };
211
+ }
212
+ }
213
+
214
+ // Match role with text/placeholder
215
+ if (expected.role === role) {
216
+ const text = element.text || element.placeholder || element.label;
217
+ if (text) {
218
+ const textNorm = this.normalize(text);
219
+ const expectedNorm = this.normalize(elementName);
220
+
221
+ if (textNorm.includes(expectedNorm) || expectedNorm.includes(textNorm)) {
222
+ return {
223
+ elementId: elementName,
224
+ selector: element.primaryLocator,
225
+ fallbackSelector: element.fallbackStrategy,
226
+ discoveryMethod: 'accessibility',
227
+ confidence: 0.8,
228
+ matchedElement: element,
229
+ attemptedPriorities: ['direct-id', 'accessibility'],
230
+ mappingTime: Date.now() - startTime,
231
+ warnings: [`Matched by role + text: ${role}`],
232
+ };
233
+ }
234
+ }
235
+ }
236
+ }
237
+
238
+ return null;
239
+ }
240
+
241
+ private inferExpectedAttributes(elementName: string): { role?: string; label?: string } {
242
+ const normalized = elementName.toLowerCase();
243
+
244
+ // Infer role from common patterns
245
+ if (normalized.includes('button') || normalized.includes('btn')) {
246
+ return { role: 'button', label: elementName };
247
+ }
248
+
249
+ if (normalized.includes('link')) {
250
+ return { role: 'link', label: elementName };
251
+ }
252
+
253
+ if (normalized.includes('input') || normalized.includes('field')) {
254
+ return { role: 'textbox', label: elementName };
255
+ }
256
+
257
+ if (normalized.includes('select') || normalized.includes('dropdown')) {
258
+ return { role: 'combobox', label: elementName };
259
+ }
260
+
261
+ return { label: elementName };
262
+ }
263
+
264
+ private normalize(str: string): string {
265
+ return str
266
+ .toLowerCase()
267
+ .replace(/[\[\]]/g, '')
268
+ .replace(/[-_\s]/g, '');
269
+ }
270
+ }
271
+
272
+ // ============================================================================
273
+ // PRIORITY LEVEL 3: HEURISTIC MATCHER
274
+ // ============================================================================
275
+
276
+ class HeuristicMatcher {
277
+ /**
278
+ * Priority 3: Heuristic matching using various strategies
279
+ *
280
+ * Strategies:
281
+ * - Pattern matching (email, password, submit...)
282
+ * - Tag + type matching
283
+ * - Text content matching
284
+ * - Position-based matching
285
+ *
286
+ * Confidence: 0.5 - 0.75
287
+ */
288
+ match(elementName: string, uiElements: StrictUIElement[]): MappingResult | null {
289
+ const startTime = Date.now();
290
+
291
+ // Strategy 1: Pattern matching
292
+ const patternMatch = this.matchByPattern(elementName, uiElements);
293
+ if (patternMatch) {
294
+ return {
295
+ ...patternMatch,
296
+ attemptedPriorities: ['direct-id', 'accessibility', 'heuristic'],
297
+ mappingTime: Date.now() - startTime,
298
+ } as MappingResult;
299
+ }
300
+
301
+ // Strategy 2: Tag + attribute matching
302
+ const tagMatch = this.matchByTagAndAttributes(elementName, uiElements);
303
+ if (tagMatch) {
304
+ return {
305
+ ...tagMatch,
306
+ attemptedPriorities: ['direct-id', 'accessibility', 'heuristic'],
307
+ mappingTime: Date.now() - startTime,
308
+ } as MappingResult;
309
+ }
310
+
311
+ // Strategy 3: Text content matching
312
+ const textMatch = this.matchByTextContent(elementName, uiElements);
313
+ if (textMatch) {
314
+ return {
315
+ ...textMatch,
316
+ attemptedPriorities: ['direct-id', 'accessibility', 'heuristic'],
317
+ mappingTime: Date.now() - startTime,
318
+ } as MappingResult;
319
+ }
320
+
321
+ return null;
322
+ }
323
+
324
+ private matchByPattern(elementName: string, elements: StrictUIElement[]): Partial<MappingResult> | null {
325
+ const normalized = elementName.toLowerCase();
326
+
327
+ // Email pattern
328
+ if (normalized.includes('email') || normalized.includes('mail')) {
329
+ const match = elements.find(el =>
330
+ el.tag === 'input' &&
331
+ (el.elementType === 'email' ||
332
+ el.props.type === 'email' ||
333
+ el.props.name?.includes('email'))
334
+ );
335
+
336
+ if (match) {
337
+ return {
338
+ elementId: elementName,
339
+ selector: match.primaryLocator,
340
+ fallbackSelector: match.fallbackStrategy,
341
+ discoveryMethod: 'heuristic',
342
+ confidence: 0.75,
343
+ matchedElement: match,
344
+ warnings: ['Pattern match: email input'],
345
+ };
346
+ }
347
+ }
348
+
349
+ // Password pattern
350
+ if (normalized.includes('password') || normalized.includes('pass')) {
351
+ const match = elements.find(el =>
352
+ el.tag === 'input' &&
353
+ (el.elementType === 'password' || el.props.type === 'password')
354
+ );
355
+
356
+ if (match) {
357
+ return {
358
+ elementId: elementName,
359
+ selector: match.primaryLocator,
360
+ fallbackSelector: match.fallbackStrategy,
361
+ discoveryMethod: 'heuristic',
362
+ confidence: 0.75,
363
+ matchedElement: match,
364
+ warnings: ['Pattern match: password input'],
365
+ };
366
+ }
367
+ }
368
+
369
+ // Submit button pattern
370
+ if (normalized.includes('submit') || normalized.includes('login') || normalized.includes('signin')) {
371
+ const match = elements.find(el =>
372
+ el.tag === 'button' &&
373
+ (el.elementType === 'submit' || el.props.type === 'submit')
374
+ );
375
+
376
+ if (match) {
377
+ return {
378
+ elementId: elementName,
379
+ selector: match.primaryLocator,
380
+ fallbackSelector: match.fallbackStrategy,
381
+ discoveryMethod: 'heuristic',
382
+ confidence: 0.7,
383
+ matchedElement: match,
384
+ warnings: ['Pattern match: submit button'],
385
+ };
386
+ }
387
+ }
388
+
389
+ return null;
390
+ }
391
+
392
+ private matchByTagAndAttributes(elementName: string, elements: StrictUIElement[]): Partial<MappingResult> | null {
393
+ const normalized = elementName.toLowerCase();
394
+
395
+ // Infer tag type
396
+ let expectedTag: string | null = null;
397
+ if (normalized.includes('input')) expectedTag = 'input';
398
+ if (normalized.includes('button') || normalized.includes('btn')) expectedTag = 'button';
399
+ if (normalized.includes('link')) expectedTag = 'a';
400
+ if (normalized.includes('select')) expectedTag = 'select';
401
+
402
+ if (!expectedTag) return null;
403
+
404
+ // Find elements matching tag
405
+ const candidates = elements.filter(el => el.tag === expectedTag);
406
+
407
+ if (candidates.length === 1) {
408
+ // Only one candidate - likely match
409
+ return {
410
+ elementId: elementName,
411
+ selector: candidates[0].primaryLocator,
412
+ fallbackSelector: candidates[0].fallbackStrategy,
413
+ discoveryMethod: 'heuristic',
414
+ confidence: 0.65,
415
+ matchedElement: candidates[0],
416
+ warnings: [`Only ${expectedTag} element found`],
417
+ };
418
+ }
419
+
420
+ return null;
421
+ }
422
+
423
+ private matchByTextContent(elementName: string, elements: StrictUIElement[]): Partial<MappingResult> | null {
424
+ const normalized = this.normalize(elementName);
425
+
426
+ for (const element of elements) {
427
+ const text = element.text || element.label || element.placeholder;
428
+ if (!text) continue;
429
+
430
+ const textNorm = this.normalize(text);
431
+
432
+ if (textNorm.includes(normalized) || normalized.includes(textNorm)) {
433
+ return {
434
+ elementId: elementName,
435
+ selector: element.primaryLocator,
436
+ fallbackSelector: element.fallbackStrategy,
437
+ discoveryMethod: 'heuristic',
438
+ confidence: 0.6,
439
+ matchedElement: element,
440
+ warnings: [`Text match: "${text}"`],
441
+ };
442
+ }
443
+ }
444
+
445
+ return null;
446
+ }
447
+
448
+ private normalize(str: string): string {
449
+ return str
450
+ .toLowerCase()
451
+ .replace(/[\[\]]/g, '')
452
+ .replace(/[-_\s]/g, '');
453
+ }
454
+ }
455
+
456
+ // ============================================================================
457
+ // PRIORITY MAPPER (Main Class)
458
+ // ============================================================================
459
+
460
+ export class PriorityMapper {
461
+ private config: SelectorMappingConfig;
462
+ private directIdMatcher = new DirectIDMatcher();
463
+ private accessibilityMatcher = new AccessibilityMatcher();
464
+ private heuristicMatcher = new HeuristicMatcher();
465
+
466
+ private stats: MappingStats = {
467
+ totalMappings: 0,
468
+ successfulMappings: 0,
469
+ failedMappings: 0,
470
+ directIdMatches: 0,
471
+ accessibilityMatches: 0,
472
+ heuristicMatches: 0,
473
+ aiMatches: 0,
474
+ averageMappingTime: 0,
475
+ totalMappingTime: 0,
476
+ aiCallsCount: 0,
477
+ estimatedCost: 0,
478
+ };
479
+
480
+ constructor(config: SelectorMappingConfig) {
481
+ this.config = config;
482
+ }
483
+
484
+ /**
485
+ * Map a single element using priority waterfall
486
+ */
487
+ async mapElement(request: MappingRequest): Promise<MappingResult> {
488
+ this.stats.totalMappings++;
489
+
490
+ const elementName = this.extractElementName(request.elementId);
491
+ const uiElements = request.uiModel.elements;
492
+
493
+ const confidenceThreshold = this.config.confidenceThreshold || 0.5;
494
+
495
+ // Priority 1: Direct ID Match
496
+ if (this.config.priorities.includes('direct-id')) {
497
+ const result = this.directIdMatcher.match(elementName, uiElements);
498
+ if (result && result.confidence >= confidenceThreshold) {
499
+ this.stats.successfulMappings++;
500
+ this.stats.directIdMatches++;
501
+ this.stats.totalMappingTime += result.mappingTime;
502
+ return result;
503
+ }
504
+ }
505
+
506
+ // Priority 2: Accessibility Match
507
+ if (this.config.priorities.includes('accessibility')) {
508
+ const result = this.accessibilityMatcher.match(elementName, uiElements);
509
+ if (result && result.confidence >= confidenceThreshold) {
510
+ this.stats.successfulMappings++;
511
+ this.stats.accessibilityMatches++;
512
+ this.stats.totalMappingTime += result.mappingTime;
513
+ return result;
514
+ }
515
+ }
516
+
517
+ // Priority 3: Heuristic Match
518
+ if (this.config.priorities.includes('heuristic-ai')) {
519
+ const result = this.heuristicMatcher.match(elementName, uiElements);
520
+ if (result && result.confidence >= confidenceThreshold) {
521
+ this.stats.successfulMappings++;
522
+ this.stats.heuristicMatches++;
523
+ this.stats.totalMappingTime += result.mappingTime;
524
+ return result;
525
+ }
526
+ }
527
+
528
+ // Priority 4: AI Fallback (TODO: implement)
529
+ // if (this.config.priorities.includes('heuristic-ai')) {
530
+ // const aiResult = await this.aiMapper.map(request);
531
+ // if (aiResult) {
532
+ // this.stats.successfulMappings++;
533
+ // this.stats.aiMatches++;
534
+ // this.stats.aiCallsCount++;
535
+ // this.stats.estimatedCost += 0.002; // Estimate
536
+ // return aiResult;
537
+ // }
538
+ // }
539
+
540
+ // No match found
541
+ this.stats.failedMappings++;
542
+
543
+ return {
544
+ elementId: request.elementId,
545
+ selector: `/* TODO: Map ${request.elementId} */`,
546
+ discoveryMethod: 'heuristic',
547
+ confidence: 0,
548
+ attemptedPriorities: this.config.priorities,
549
+ mappingTime: 0,
550
+ warnings: ['No match found - manual mapping required'],
551
+ };
552
+ }
553
+
554
+ /**
555
+ * Map multiple elements in batch
556
+ */
557
+ async mapElements(requests: MappingRequest[]): Promise<MappingResult[]> {
558
+ const results: MappingResult[] = [];
559
+
560
+ for (const request of requests) {
561
+ const result = await this.mapElement(request);
562
+ results.push(result);
563
+ }
564
+
565
+ // Calculate average mapping time
566
+ if (this.stats.totalMappings > 0) {
567
+ this.stats.averageMappingTime = this.stats.totalMappingTime / this.stats.totalMappings;
568
+ }
569
+
570
+ return results;
571
+ }
572
+
573
+ /**
574
+ * Get mapping statistics
575
+ */
576
+ getStats(): MappingStats {
577
+ return { ...this.stats };
578
+ }
579
+
580
+ /**
581
+ * Reset statistics
582
+ */
583
+ resetStats(): void {
584
+ this.stats = {
585
+ totalMappings: 0,
586
+ successfulMappings: 0,
587
+ failedMappings: 0,
588
+ directIdMatches: 0,
589
+ accessibilityMatches: 0,
590
+ heuristicMatches: 0,
591
+ aiMatches: 0,
592
+ averageMappingTime: 0,
593
+ totalMappingTime: 0,
594
+ aiCallsCount: 0,
595
+ estimatedCost: 0,
596
+ };
597
+ }
598
+
599
+ private extractElementName(elementId: string): string {
600
+ // Remove brackets: [login.email] → login.email
601
+ let cleaned = elementId.replace(/[\[\]]/g, '');
602
+
603
+ // Extract element name: login.email → email (keep last part)
604
+ const parts = cleaned.split('.');
605
+ return parts[parts.length - 1];
606
+ }
607
+ }