@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,530 @@
1
+ /**
2
+ * Intelligent Selector Mapper with Context-Aware Scoring
3
+ *
4
+ * Maps logical element names (from Gherkin) to actual UI elements using:
5
+ * 1. Semantic context understanding
6
+ * 2. Multi-criteria scoring algorithm
7
+ * 3. Ambiguity detection and resolution
8
+ * 4. Reasoning generation for transparency
9
+ */
10
+
11
+ interface EnhancedUIElement {
12
+ key: string;
13
+ tag: string;
14
+ text: string | null;
15
+ testId?: string;
16
+ role?: string;
17
+ id?: string;
18
+ name?: string;
19
+ placeholder?: string;
20
+ semanticContext: {
21
+ purpose: string;
22
+ section: string;
23
+ interactionType: string;
24
+ formContext?: {
25
+ formName: string;
26
+ fieldName: string;
27
+ formPurpose: string;
28
+ };
29
+ spatialContext: {
30
+ precedingText?: string;
31
+ followingText?: string;
32
+ nearbyLabels?: string[];
33
+ };
34
+ accessibility: {
35
+ ariaRole?: string;
36
+ ariaLabel?: string;
37
+ implicitRole?: string;
38
+ };
39
+ };
40
+ selectorStrategies: Array<{
41
+ type: string;
42
+ selector: string;
43
+ confidence: string;
44
+ stability: string;
45
+ playwrightCode?: string;
46
+ }>;
47
+ }
48
+
49
+ interface SelectorMapping {
50
+ logicalName: string;
51
+ element: EnhancedUIElement;
52
+ primary: {
53
+ type: string;
54
+ selector: string;
55
+ playwright: string;
56
+ confidence: string;
57
+ };
58
+ fallbacks: Array<{
59
+ type: string;
60
+ selector: string;
61
+ playwright: string;
62
+ }>;
63
+ score: number;
64
+ reasoning: string[];
65
+ contextClues: string[];
66
+ ambiguityWarning?: string;
67
+ }
68
+
69
+ export class IntelligentSelectorMapper {
70
+ /**
71
+ * Map a logical name to best matching element using context
72
+ */
73
+ mapElement(
74
+ logicalName: string,
75
+ elements: EnhancedUIElement[],
76
+ gherkinContext?: string
77
+ ): SelectorMapping | null {
78
+ // 1. Find candidates
79
+ const candidates = this.findCandidates(logicalName, elements);
80
+
81
+ if (candidates.length === 0) {
82
+ console.warn(`⚠️ No candidates found for: ${logicalName}`);
83
+ return null;
84
+ }
85
+
86
+ // 2. Score each candidate
87
+ const scored = candidates.map(element => ({
88
+ element,
89
+ score: this.scoreElement(element, logicalName, gherkinContext),
90
+ reasoning: this.generateReasoning(element, logicalName, gherkinContext),
91
+ contextClues: this.extractContextClues(element, gherkinContext),
92
+ }));
93
+
94
+ // 3. Sort by score
95
+ scored.sort((a, b) => b.score - a.score);
96
+
97
+ // 4. Detect ambiguity
98
+ const best = scored[0];
99
+ const secondBest = scored[1];
100
+ const ambiguityWarning = this.detectAmbiguity(best, secondBest);
101
+
102
+ // 5. Build mapping
103
+ const primary = this.selectPrimaryStrategy(best.element);
104
+ const fallbacks = best.element.selectorStrategies
105
+ .filter(s => s !== primary)
106
+ .sort((a, b) => this.strategyPriority(b) - this.strategyPriority(a));
107
+
108
+ return {
109
+ logicalName,
110
+ element: best.element,
111
+ primary: {
112
+ type: primary.type,
113
+ selector: primary.selector,
114
+ playwright: primary.playwrightCode || primary.selector,
115
+ confidence: primary.confidence,
116
+ },
117
+ fallbacks: fallbacks.map(s => ({
118
+ type: s.type,
119
+ selector: s.selector,
120
+ playwright: s.playwrightCode || s.selector,
121
+ })),
122
+ score: best.score,
123
+ reasoning: best.reasoning,
124
+ contextClues: best.contextClues,
125
+ ambiguityWarning,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Find candidate elements that might match logical name
131
+ */
132
+ private findCandidates(logicalName: string, elements: EnhancedUIElement[]): EnhancedUIElement[] {
133
+ const normalized = this.normalizeLogicalName(logicalName);
134
+ const keywords = normalized.split(/[-_\s]+/);
135
+
136
+ return elements.filter(element => {
137
+ // Match by text content
138
+ if (element.text && this.textMatches(element.text, keywords)) {
139
+ return true;
140
+ }
141
+
142
+ // Match by ARIA label
143
+ if (element.semanticContext.accessibility.ariaLabel) {
144
+ if (this.textMatches(element.semanticContext.accessibility.ariaLabel, keywords)) {
145
+ return true;
146
+ }
147
+ }
148
+
149
+ // Match by form field name
150
+ if (element.semanticContext.formContext?.fieldName) {
151
+ if (this.textMatches(element.semanticContext.formContext.fieldName, keywords)) {
152
+ return true;
153
+ }
154
+ }
155
+
156
+ // Match by element name
157
+ if (element.name && this.textMatches(element.name, keywords)) {
158
+ return true;
159
+ }
160
+
161
+ // Match by placeholder
162
+ if (element.placeholder && this.textMatches(element.placeholder, keywords)) {
163
+ return true;
164
+ }
165
+
166
+ // Match by purpose + tag
167
+ const purposeMatch = keywords.some(k =>
168
+ element.semanticContext.purpose.toLowerCase().includes(k)
169
+ );
170
+ const tagMatch = keywords.some(k => element.tag.toLowerCase().includes(k));
171
+
172
+ if (purposeMatch || tagMatch) {
173
+ return true;
174
+ }
175
+
176
+ return false;
177
+ });
178
+ }
179
+
180
+ /**
181
+ * Score an element based on how well it matches logical name
182
+ */
183
+ private scoreElement(
184
+ element: EnhancedUIElement,
185
+ logicalName: string,
186
+ gherkinContext?: string
187
+ ): number {
188
+ let score = 0;
189
+ const normalized = this.normalizeLogicalName(logicalName);
190
+ const keywords = normalized.split(/[-_\s]+/);
191
+
192
+ // === TEXT CONTENT MATCHING (0-50 points) ===
193
+ if (element.text) {
194
+ const textNorm = element.text.toLowerCase();
195
+ if (textNorm === normalized) {
196
+ score += 50; // Exact match
197
+ } else if (keywords.every(k => textNorm.includes(k))) {
198
+ score += 35; // Contains all keywords
199
+ } else if (keywords.some(k => textNorm.includes(k))) {
200
+ score += 20; // Contains some keywords
201
+ }
202
+ }
203
+
204
+ // === ARIA LABEL MATCHING (0-45 points) ===
205
+ const ariaLabel = element.semanticContext.accessibility.ariaLabel;
206
+ if (ariaLabel) {
207
+ const ariaNorm = ariaLabel.toLowerCase();
208
+ if (ariaNorm === normalized) {
209
+ score += 45;
210
+ } else if (keywords.every(k => ariaNorm.includes(k))) {
211
+ score += 30;
212
+ } else if (keywords.some(k => ariaNorm.includes(k))) {
213
+ score += 15;
214
+ }
215
+ }
216
+
217
+ // === FORM FIELD NAME MATCHING (0-40 points) ===
218
+ if (element.semanticContext.formContext) {
219
+ const fieldName = element.semanticContext.formContext.fieldName.toLowerCase();
220
+ if (fieldName === normalized) {
221
+ score += 40;
222
+ } else if (keywords.every(k => fieldName.includes(k))) {
223
+ score += 25;
224
+ } else if (keywords.some(k => fieldName.includes(k))) {
225
+ score += 12;
226
+ }
227
+ }
228
+
229
+ // === NAME ATTRIBUTE MATCHING (0-35 points) ===
230
+ if (element.name) {
231
+ const nameNorm = element.name.toLowerCase();
232
+ if (nameNorm === normalized) {
233
+ score += 35;
234
+ } else if (keywords.every(k => nameNorm.includes(k))) {
235
+ score += 20;
236
+ } else if (keywords.some(k => nameNorm.includes(k))) {
237
+ score += 10;
238
+ }
239
+ }
240
+
241
+ // === PLACEHOLDER MATCHING (0-30 points) ===
242
+ if (element.placeholder) {
243
+ const placeholderNorm = element.placeholder.toLowerCase();
244
+ if (keywords.every(k => placeholderNorm.includes(k))) {
245
+ score += 30;
246
+ } else if (keywords.some(k => placeholderNorm.includes(k))) {
247
+ score += 15;
248
+ }
249
+ }
250
+
251
+ // === PURPOSE MATCHING (0-20 points) ===
252
+ const purposeKeywords = {
253
+ button: 'action',
254
+ input: 'input',
255
+ link: 'navigation',
256
+ select: 'input',
257
+ checkbox: 'input',
258
+ };
259
+
260
+ keywords.forEach(keyword => {
261
+ if (purposeKeywords[keyword] === element.semanticContext.purpose) {
262
+ score += 20;
263
+ }
264
+ });
265
+
266
+ // === TAG MATCHING (0-15 points) ===
267
+ keywords.forEach(keyword => {
268
+ if (element.tag.toLowerCase() === keyword) {
269
+ score += 15;
270
+ }
271
+ });
272
+
273
+ // === GHERKIN CONTEXT MATCHING (0-25 points) ===
274
+ if (gherkinContext) {
275
+ const contextNorm = gherkinContext.toLowerCase();
276
+
277
+ // Preceding text mentioned
278
+ if (element.semanticContext.spatialContext.precedingText) {
279
+ const preceding = element.semanticContext.spatialContext.precedingText.toLowerCase();
280
+ if (contextNorm.includes(preceding)) {
281
+ score += 15;
282
+ }
283
+ }
284
+
285
+ // Section mentioned
286
+ if (contextNorm.includes(element.semanticContext.section)) {
287
+ score += 10;
288
+ }
289
+
290
+ // Form context mentioned
291
+ if (element.semanticContext.formContext) {
292
+ const formPurpose = element.semanticContext.formContext.formPurpose;
293
+ if (contextNorm.includes(formPurpose)) {
294
+ score += 10;
295
+ }
296
+ }
297
+ }
298
+
299
+ // === SELECTOR QUALITY BONUS (0-20 points) ===
300
+ const hasHighConfARIA = element.selectorStrategies.some(
301
+ s => s.type === 'aria' && s.confidence === 'high'
302
+ );
303
+ if (hasHighConfARIA) {
304
+ score += 20;
305
+ }
306
+
307
+ // === UNIQUENESS PENALTY (0 to -30 points) ===
308
+ // This would require passing all elements to check for duplicates
309
+ // For now, skip this in basic implementation
310
+
311
+ return Math.max(0, score);
312
+ }
313
+
314
+ /**
315
+ * Generate human-readable reasoning for the mapping
316
+ */
317
+ private generateReasoning(
318
+ element: EnhancedUIElement,
319
+ logicalName: string,
320
+ gherkinContext?: string
321
+ ): string[] {
322
+ const reasons: string[] = [];
323
+
324
+ // Text match
325
+ if (element.text) {
326
+ reasons.push(`Text: "${element.text}"`);
327
+ }
328
+
329
+ // ARIA label
330
+ if (element.semanticContext.accessibility.ariaLabel) {
331
+ reasons.push(`ARIA label: "${element.semanticContext.accessibility.ariaLabel}"`);
332
+ }
333
+
334
+ // Form context
335
+ if (element.semanticContext.formContext) {
336
+ reasons.push(
337
+ `Form field: ${element.semanticContext.formContext.formName}/${element.semanticContext.formContext.fieldName}`
338
+ );
339
+ }
340
+
341
+ // Element type
342
+ reasons.push(`Element: <${element.tag}>`);
343
+
344
+ // Purpose
345
+ reasons.push(`Purpose: ${element.semanticContext.purpose}`);
346
+
347
+ // Section
348
+ if (element.semanticContext.section !== 'main') {
349
+ reasons.push(`Section: ${element.semanticContext.section}`);
350
+ }
351
+
352
+ // Preceding text
353
+ if (element.semanticContext.spatialContext.precedingText) {
354
+ reasons.push(`After: "${element.semanticContext.spatialContext.precedingText}"`);
355
+ }
356
+
357
+ return reasons;
358
+ }
359
+
360
+ /**
361
+ * Extract context clues that helped with matching
362
+ */
363
+ private extractContextClues(
364
+ element: EnhancedUIElement,
365
+ gherkinContext?: string
366
+ ): string[] {
367
+ const clues: string[] = [];
368
+
369
+ if (element.semanticContext.section !== 'main') {
370
+ clues.push(`section:${element.semanticContext.section}`);
371
+ }
372
+
373
+ if (element.semanticContext.formContext) {
374
+ clues.push(`form:${element.semanticContext.formContext.formName}`);
375
+ }
376
+
377
+ if (element.semanticContext.accessibility.ariaLabel) {
378
+ clues.push(`aria-label`);
379
+ }
380
+
381
+ if (element.semanticContext.spatialContext.precedingText) {
382
+ clues.push(`has-preceding-text`);
383
+ }
384
+
385
+ if (gherkinContext) {
386
+ clues.push(`gherkin-context-used`);
387
+ }
388
+
389
+ return clues;
390
+ }
391
+
392
+ /**
393
+ * Detect if there's ambiguity between top candidates
394
+ */
395
+ private detectAmbiguity(
396
+ best: { score: number; element: EnhancedUIElement },
397
+ secondBest?: { score: number; element: EnhancedUIElement }
398
+ ): string | undefined {
399
+ if (!secondBest) return undefined;
400
+
401
+ const scoreDiff = best.score - secondBest.score;
402
+
403
+ if (scoreDiff < 10) {
404
+ return `⚠️ Low confidence - score difference only ${scoreDiff} points. Consider adding more specific identifiers.`;
405
+ }
406
+
407
+ if (scoreDiff < 20) {
408
+ return `⚠️ Moderate confidence - multiple similar elements found.`;
409
+ }
410
+
411
+ return undefined;
412
+ }
413
+
414
+ /**
415
+ * Select the best selector strategy for an element
416
+ */
417
+ private selectPrimaryStrategy(element: EnhancedUIElement): any {
418
+ // Priority: high-conf ARIA > high-conf semantic > testid > medium-conf ARIA > CSS
419
+ const strategies = element.selectorStrategies;
420
+
421
+ // Try high-confidence ARIA first
422
+ const highAria = strategies.find(s => s.type === 'aria' && s.confidence === 'high');
423
+ if (highAria) return highAria;
424
+
425
+ // Try high-confidence semantic
426
+ const highSemantic = strategies.find(s => s.type === 'semantic' && s.confidence === 'high');
427
+ if (highSemantic) return highSemantic;
428
+
429
+ // Try testid
430
+ const testid = strategies.find(s => s.type === 'testid');
431
+ if (testid) return testid;
432
+
433
+ // Try medium-confidence ARIA
434
+ const medAria = strategies.find(s => s.type === 'aria' && s.confidence === 'medium');
435
+ if (medAria) return medAria;
436
+
437
+ // Try any semantic
438
+ const semantic = strategies.find(s => s.type === 'semantic');
439
+ if (semantic) return semantic;
440
+
441
+ // Fallback to first available
442
+ return strategies[0];
443
+ }
444
+
445
+ /**
446
+ * Get priority score for a strategy type
447
+ */
448
+ private strategyPriority(strategy: any): number {
449
+ const priorities = {
450
+ aria: { high: 100, medium: 80, low: 60 },
451
+ semantic: { high: 90, medium: 70, low: 50 },
452
+ testid: { high: 85, medium: 85, low: 85 },
453
+ css: { high: 40, medium: 30, low: 20 },
454
+ };
455
+
456
+ const typePriority = priorities[strategy.type] || { high: 10, medium: 5, low: 1 };
457
+ return typePriority[strategy.confidence] || 1;
458
+ }
459
+
460
+ /**
461
+ * Normalize logical name for comparison
462
+ */
463
+ private normalizeLogicalName(name: string): string {
464
+ return name
465
+ .toLowerCase()
466
+ .replace(/[-_.]/g, ' ')
467
+ .replace(/\s+/g, ' ')
468
+ .trim();
469
+ }
470
+
471
+ /**
472
+ * Check if text matches keywords
473
+ */
474
+ private textMatches(text: string, keywords: string[]): boolean {
475
+ const textNorm = text.toLowerCase();
476
+ return keywords.some(keyword => textNorm.includes(keyword));
477
+ }
478
+
479
+ /**
480
+ * Map multiple logical names at once
481
+ */
482
+ mapElements(
483
+ logicalNames: string[],
484
+ elements: EnhancedUIElement[],
485
+ gherkinContexts?: Record<string, string>
486
+ ): Record<string, SelectorMapping | null> {
487
+ const mappings: Record<string, SelectorMapping | null> = {};
488
+
489
+ logicalNames.forEach(name => {
490
+ const context = gherkinContexts?.[name];
491
+ mappings[name] = this.mapElement(name, elements, context);
492
+ });
493
+
494
+ return mappings;
495
+ }
496
+
497
+ /**
498
+ * Generate statistics about mappings
499
+ */
500
+ generateStats(mappings: Record<string, SelectorMapping | null>) {
501
+ const total = Object.keys(mappings).length;
502
+ const successful = Object.values(mappings).filter(m => m !== null).length;
503
+ const failed = total - successful;
504
+
505
+ const selectorTypeBreakdown: Record<string, number> = {};
506
+ const confidenceBreakdown: Record<string, number> = {};
507
+ const ambiguityCount = Object.values(mappings).filter(
508
+ m => m && m.ambiguityWarning
509
+ ).length;
510
+
511
+ Object.values(mappings).forEach(mapping => {
512
+ if (mapping) {
513
+ selectorTypeBreakdown[mapping.primary.type] =
514
+ (selectorTypeBreakdown[mapping.primary.type] || 0) + 1;
515
+ confidenceBreakdown[mapping.primary.confidence] =
516
+ (confidenceBreakdown[mapping.primary.confidence] || 0) + 1;
517
+ }
518
+ });
519
+
520
+ return {
521
+ total,
522
+ successful,
523
+ failed,
524
+ successRate: ((successful / total) * 100).toFixed(1) + '%',
525
+ selectorTypeBreakdown,
526
+ confidenceBreakdown,
527
+ ambiguityCount,
528
+ };
529
+ }
530
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Test Generator Adapter Interface
3
+ * Defines the contract for framework-specific test code generation
4
+ */
5
+
6
+ export interface TestFileData {
7
+ imports: string;
8
+ featureName: string;
9
+ featureDescription?: string;
10
+ background?: string;
11
+ scenarios: string[];
12
+ }
13
+
14
+ export interface ScenarioData {
15
+ scenarioName: string;
16
+ steps: Array<{ comment?: string; code: string }>;
17
+ }
18
+
19
+ export interface StepTemplateData {
20
+ templateName: string;
21
+ data: Record<string, any>;
22
+ }
23
+
24
+ export interface LocatorExpression {
25
+ varName: string;
26
+ locatorCode: string;
27
+ type: string;
28
+ value: string;
29
+ nth?: number;
30
+ }
31
+
32
+ /**
33
+ * TestGeneratorAdapter
34
+ * Framework-specific code generation using template engine
35
+ */
36
+ export interface TestGeneratorAdapter {
37
+ readonly frameworkName: string;
38
+ readonly fileExtension: string;
39
+ readonly templatesDir: string;
40
+
41
+ // Template rendering methods
42
+ renderTestFile(data: TestFileData): string;
43
+ renderScenario(data: ScenarioData): string;
44
+ renderImports(): string;
45
+ renderBeforeEach(data: { steps: Array<{ comment?: string; code: string }> }): string;
46
+
47
+ // Step rendering
48
+ renderStep(templateName: string, data: any): string;
49
+ }
@@ -0,0 +1,56 @@
1
+ import { TestGeneratorAdapter } from './adapter-interface';
2
+
3
+ /**
4
+ * Adapter Registry
5
+ * Manages available test framework adapters
6
+ */
7
+ export class AdapterRegistry {
8
+ private adapters: Map<string, () => TestGeneratorAdapter> = new Map();
9
+ private static instance: AdapterRegistry;
10
+
11
+ private constructor() {}
12
+
13
+ static getInstance(): AdapterRegistry {
14
+ if (!AdapterRegistry.instance) {
15
+ AdapterRegistry.instance = new AdapterRegistry();
16
+ }
17
+ return AdapterRegistry.instance;
18
+ }
19
+
20
+ /**
21
+ * Register a new adapter
22
+ */
23
+ register(frameworkName: string, adapterFactory: () => TestGeneratorAdapter): void {
24
+ this.adapters.set(frameworkName.toLowerCase(), adapterFactory);
25
+ }
26
+
27
+ /**
28
+ * Get adapter by framework name
29
+ */
30
+ getAdapter(frameworkName: string): TestGeneratorAdapter {
31
+ const factory = this.adapters.get(frameworkName.toLowerCase());
32
+ if (!factory) {
33
+ throw new Error(
34
+ `Unknown test framework: ${frameworkName}. Available: ${Array.from(this.adapters.keys()).join(', ')}`
35
+ );
36
+ }
37
+ return factory();
38
+ }
39
+
40
+ /**
41
+ * Check if adapter is registered
42
+ */
43
+ hasAdapter(frameworkName: string): boolean {
44
+ return this.adapters.has(frameworkName.toLowerCase());
45
+ }
46
+
47
+ /**
48
+ * List all registered adapters
49
+ */
50
+ getAvailableAdapters(): string[] {
51
+ return Array.from(this.adapters.keys());
52
+ }
53
+ }
54
+
55
+ // Singleton instance
56
+ export const adapterRegistry = AdapterRegistry.getInstance();
@@ -0,0 +1,9 @@
1
+ export { TestGeneratorAdapter, TestFileData, ScenarioData, StepTemplateData, LocatorExpression } from './adapter-interface';
2
+ export { AdapterRegistry, adapterRegistry } from './adapter-registry';
3
+ export { PlaywrightAdapter } from './playwright/playwright-adapter';
4
+
5
+ // Auto-register built-in adapters
6
+ import { adapterRegistry } from './adapter-registry';
7
+ import { PlaywrightAdapter } from './playwright/playwright-adapter';
8
+
9
+ adapterRegistry.register('playwright', () => new PlaywrightAdapter());
@@ -0,0 +1,40 @@
1
+ import path from 'path';
2
+ import { TestGeneratorAdapter, TestFileData, ScenarioData } from '../adapter-interface';
3
+ import { TemplateEngine } from '../../template-engine';
4
+
5
+ /**
6
+ * PlaywrightAdapter
7
+ * Generates Playwright TypeScript test code using Handlebars templates
8
+ */
9
+ export class PlaywrightAdapter implements TestGeneratorAdapter {
10
+ readonly frameworkName = 'playwright';
11
+ readonly fileExtension = '.spec.ts';
12
+ readonly templatesDir: string;
13
+ private templateEngine: TemplateEngine;
14
+
15
+ constructor() {
16
+ // Use adapter-specific templates directory
17
+ this.templatesDir = path.join(__dirname, 'templates');
18
+ this.templateEngine = new TemplateEngine(this.templatesDir);
19
+ }
20
+
21
+ renderTestFile(data: TestFileData): string {
22
+ return this.templateEngine.renderTestFile(data);
23
+ }
24
+
25
+ renderScenario(data: ScenarioData): string {
26
+ return this.templateEngine.renderScenario(data);
27
+ }
28
+
29
+ renderImports(): string {
30
+ return this.templateEngine.renderImports();
31
+ }
32
+
33
+ renderBeforeEach(data: { steps: Array<{ comment?: string; code: string }> }): string {
34
+ return this.templateEngine.renderBeforeEach(data);
35
+ }
36
+
37
+ renderStep(templateName: string, data: any): string {
38
+ return this.templateEngine.renderStep(templateName, data);
39
+ }
40
+ }
@@ -0,0 +1,8 @@
1
+ test.beforeEach(async ({ page }) => {
2
+ {{#each steps}}
3
+ {{#if comment}}
4
+ // {{comment}}
5
+ {{/if}}
6
+ {{code}}
7
+ {{/each}}
8
+ });
@@ -0,0 +1,5 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ // This file is auto-generated from Gherkin feature files
4
+ // DO NOT EDIT MANUALLY - changes will be overwritten
5
+ // To modify tests, edit the corresponding .feature file and regenerate
@@ -0,0 +1,8 @@
1
+ test('{{scenarioName}}', async ({ page }) => {
2
+ {{#each steps}}
3
+ {{#if comment}}
4
+ // {{comment}}
5
+ {{/if}}
6
+ {{code}}
7
+ {{/each}}
8
+ });