@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,410 @@
1
+ # Selector DSL Generator Framework
2
+
3
+ > **AI-Native QA Framework** for multi-platform E2E testing with automated selector discovery
4
+
5
+ ## 🎯 Overview
6
+
7
+ This framework enables:
8
+ - **AI-powered selector generation** from source code (no manual mapping!)
9
+ - **Multi-platform support** (Web, Android, iOS, Flutter, Compose, SwiftUI)
10
+ - **Gherkin-compatible** element references `[screen.element]`
11
+ - **Framework-agnostic** architecture (Playwright, Appium, Flutter Driver, etc.)
12
+ - **Cache-first** approach to minimize AI API costs
13
+ - **Override mechanism** for manual fine-tuning
14
+
15
+ ## 🏗️ Architecture
16
+
17
+ ```
18
+ Gherkin Test Scenarios
19
+
20
+ [screen.element] References
21
+
22
+ Selector DSL (YAML) ← AI-generated + Manual overrides
23
+
24
+ Executor Adapter (Playwright/Appium/etc.)
25
+
26
+ Actual UI Tests
27
+ ```
28
+
29
+ ## 📁 Directory Structure
30
+
31
+ ```
32
+ qa/
33
+ ├── generators/ # Core framework code
34
+ │ ├── types.ts # TypeScript types
35
+ │ ├── ui-model-builder/ # Source code scanners
36
+ │ │ └── react-scanner.ts
37
+ │ ├── selector-mapper/ # AI mapping engine
38
+ │ │ └── ai-mapper.ts
39
+ │ ├── dsl-writer/ # YAML writer/loader
40
+ │ ├── cache/ # Cache management
41
+ │ └── cli.ts # Command-line interface
42
+ ├── helpers/
43
+ │ └── selector-loader.ts # Executor adapters
44
+ ├── selectors/
45
+ │ ├── screens/ # Generated selector DSL files
46
+ │ │ ├── auth-login.yaml
47
+ │ │ ├── auth-login.override.yaml # Manual overrides
48
+ │ │ └── ...
49
+ │ └── .cache/ # AI response cache
50
+ ├── ui-models/ # Extracted UI models
51
+ └── specs/ # Test files
52
+ └── login-dsl.spec.ts # Example tests
53
+ ```
54
+
55
+ ## 🚀 Quick Start
56
+
57
+ ### 1. Discover Screens
58
+
59
+ Scan your application and extract UI models:
60
+
61
+ ```bash
62
+ # Discover all screens
63
+ npm run qa:dsl:discover -- --all --verbose
64
+
65
+ # Discover specific screen
66
+ npm run qa:dsl:discover -- --screen auth-login
67
+ ```
68
+
69
+ **Output:** `qa/ui-models/auth-login.json`
70
+
71
+ ### 2. Generate Selectors
72
+
73
+ Use AI to map element IDs to CSS selectors:
74
+
75
+ ```bash
76
+ # Generate for all screens
77
+ npm run qa:dsl:generate -- --all --provider anthropic
78
+
79
+ # Generate for specific screen
80
+ npm run qa:dsl:generate -- --screen auth-login --provider google
81
+
82
+ # Force re-generation (skip cache)
83
+ npm run qa:dsl:generate -- --all --force
84
+ ```
85
+
86
+ **Output:** `qa/selectors/screens/auth-login.yaml`
87
+
88
+ ### 3. Validate Selectors
89
+
90
+ Check if generated selectors are valid:
91
+
92
+ ```bash
93
+ npm run qa:dsl:validate -- --all
94
+ ```
95
+
96
+ ### 4. View Statistics
97
+
98
+ ```bash
99
+ npm run qa:dsl:info
100
+ ```
101
+
102
+ Output:
103
+ ```
104
+ 📊 Cache Statistics:
105
+ Screens cached: 4
106
+ Cache entries: 4
107
+ Total size: 5.02 KB
108
+
109
+ 📁 Selector Files:
110
+ Total screens: 7
111
+ - auth-login: 5 selectors
112
+ - auth-register: 7 selectors
113
+ - chat: 2 selectors
114
+ ```
115
+
116
+ ### 5. Clear Cache
117
+
118
+ ```bash
119
+ # Clear specific screen
120
+ npm run qa:dsl:cache-clear -- --screen auth-login
121
+
122
+ # Clear all cache
123
+ npm run qa:dsl:cache-clear -- --all
124
+ ```
125
+
126
+ ## 📝 Writing Tests
127
+
128
+ ### Using Selector Loader (Recommended)
129
+
130
+ ```typescript
131
+ import { test, expect } from '@playwright/test';
132
+ import { createPlaywrightSelectors } from '../helpers/selector-loader';
133
+
134
+ test('login test', async ({ page }) => {
135
+ await page.goto('http://localhost:3000/auth/login');
136
+
137
+ // Create Playwright helper
138
+ const pw = createPlaywrightSelectors(page);
139
+
140
+ // Use DSL selectors
141
+ await pw.fill('[auth-login.email]', 'test@example.com', 'auth-login');
142
+ await pw.fill('[auth-login.password]', 'password123', 'auth-login');
143
+ await pw.click('[auth-login.submit]', 'auth-login');
144
+
145
+ // Verify
146
+ expect(page.url()).toContain('/chat');
147
+ });
148
+ ```
149
+
150
+ ### Using Raw Selector Strings
151
+
152
+ ```typescript
153
+ import { getSelector } from '../helpers/selector-loader';
154
+
155
+ test('login test', async ({ page }) => {
156
+ await page.goto('http://localhost:3000/auth/login');
157
+
158
+ // Get raw selector string
159
+ const emailSelector = await getSelector('[auth-login.email]', 'auth-login');
160
+
161
+ // Use with Playwright directly
162
+ await page.fill(emailSelector, 'test@example.com');
163
+ });
164
+ ```
165
+
166
+ ## 🔧 Manual Override
167
+
168
+ If AI-generated selectors are incorrect, create an override file:
169
+
170
+ ```bash
171
+ # This will be done automatically by the framework when needed
172
+ # Or create manually:
173
+ touch qa/selectors/screens/auth-login.override.yaml
174
+ ```
175
+
176
+ **Override file format:**
177
+
178
+ ```yaml
179
+ # qa/selectors/screens/auth-login.override.yaml
180
+
181
+ "[auth-login.submit]":
182
+ selector: "button[type='submit']"
183
+ type: "button"
184
+ description: "Login submit button (manually fixed)"
185
+ discoveryMethod: manual
186
+ locatorType: css
187
+ ```
188
+
189
+ The override will automatically merge with the base file, taking precedence.
190
+
191
+ ## 🌍 Multi-Platform Support
192
+
193
+ ### Folder Structure for Multi-Platform
194
+
195
+ ```
196
+ qa/selectors/
197
+ ├── web/
198
+ │ └── screens/
199
+ │ └── login.yaml
200
+ ├── android/
201
+ │ └── screens/
202
+ │ └── login.yaml
203
+ └── ios/
204
+ └── screens/
205
+ └── login.yaml
206
+ ```
207
+
208
+ ### Platform-Specific Selectors
209
+
210
+ **Web (Playwright):**
211
+ ```yaml
212
+ "[login.email]":
213
+ selector: "input[name='email']"
214
+ locatorType: css
215
+ ```
216
+
217
+ **Android (Appium):**
218
+ ```yaml
219
+ "[login.email]":
220
+ selector: "com.example:id/email_input"
221
+ locatorType: resource-id
222
+ ```
223
+
224
+ **iOS (Appium):**
225
+ ```yaml
226
+ "[login.email]":
227
+ selector: "emailTextField"
228
+ locatorType: accessibility-id
229
+ ```
230
+
231
+ **Flutter:**
232
+ ```yaml
233
+ "[login.email]":
234
+ selector: "emailInput"
235
+ locatorType: key
236
+ ```
237
+
238
+ ## 🤖 AI Providers
239
+
240
+ The framework supports multiple AI providers:
241
+
242
+ ### Anthropic (Claude)
243
+
244
+ ```bash
245
+ export ANTHROPIC_API_KEY=sk-ant-...
246
+ npm run qa:dsl:generate -- --provider anthropic --model claude-3-5-haiku-20241022
247
+ ```
248
+
249
+ ### Google (Gemini)
250
+
251
+ ```bash
252
+ export GEMINI_API_KEY=AIza...
253
+ npm run qa:dsl:generate -- --provider google --model gemini-2.0-flash-exp
254
+ ```
255
+
256
+ ### OpenAI (Future)
257
+
258
+ ```bash
259
+ export OPENAI_API_KEY=sk-...
260
+ npm run qa:dsl:generate -- --provider openai --model gpt-4o-mini
261
+ ```
262
+
263
+ ## 💰 Cost Optimization
264
+
265
+ ### Cache Strategy
266
+
267
+ The framework automatically caches AI responses based on:
268
+ - UI Model content hash
269
+ - Element IDs list
270
+ - Screen ID
271
+
272
+ **Cache hit = $0 cost!**
273
+
274
+ ### Token Usage
275
+
276
+ Typical usage per screen:
277
+ - Small screen (2-5 elements): ~600-800 tokens
278
+ - Medium screen (5-10 elements): ~800-1200 tokens
279
+ - Large screen (10+ elements): ~1200-2000 tokens
280
+
281
+ **Cost example (Claude Haiku):**
282
+ - 1000 tokens ≈ $0.0005
283
+ - 100 screens ≈ $0.05 - $0.10 (one-time generation)
284
+ - Subsequent runs = $0 (cached)
285
+
286
+ ## 🔍 Troubleshooting
287
+
288
+ ### Selectors not found
289
+
290
+ ```bash
291
+ # Re-discover screens
292
+ npm run qa:dsl:discover -- --all --force
293
+
294
+ # Re-generate selectors
295
+ npm run qa:dsl:generate -- --all --force
296
+
297
+ # Check generated selectors
298
+ cat qa/selectors/screens/auth-login.yaml
299
+ ```
300
+
301
+ ### AI-generated selectors are incorrect
302
+
303
+ Create an override file:
304
+
305
+ ```yaml
306
+ # qa/selectors/screens/auth-login.override.yaml
307
+ "[auth-login.email]":
308
+ selector: "#email-address" # Fixed selector
309
+ type: "input"
310
+ description: "Email input (manually corrected)"
311
+ discoveryMethod: manual
312
+ ```
313
+
314
+ ### Cache issues
315
+
316
+ ```bash
317
+ # Clear cache for specific screen
318
+ npm run qa:dsl:cache-clear -- --screen auth-login
319
+
320
+ # Clear all cache
321
+ npm run qa:dsl:cache-clear -- --all
322
+ ```
323
+
324
+ ## 🎓 Best Practices
325
+
326
+ ### 1. Use Meaningful Element IDs
327
+
328
+ **Good:**
329
+ ```
330
+ [login.email-input]
331
+ [login.password-input]
332
+ [login.submit-button]
333
+ ```
334
+
335
+ **Bad:**
336
+ ```
337
+ [login.e1]
338
+ [login.e2]
339
+ [login.e3]
340
+ ```
341
+
342
+ ### 2. Add `data-testid` Attributes
343
+
344
+ ```tsx
345
+ <input
346
+ name="email"
347
+ data-testid="login-email-input" // Helps AI generate better selectors
348
+ placeholder="Email"
349
+ />
350
+ ```
351
+
352
+ ### 3. Use Override Files for Flaky Selectors
353
+
354
+ If a selector is unstable, override it with a more robust one.
355
+
356
+ ### 4. Commit Generated Files to Git
357
+
358
+ ```bash
359
+ git add qa/selectors/screens/*.yaml
360
+ git add qa/ui-models/*.json
361
+ git commit -m "chore: update selector DSL"
362
+ ```
363
+
364
+ **Do NOT commit:**
365
+ - `qa/selectors/.cache/` (gitignored)
366
+
367
+ ## 📊 Workflow
368
+
369
+ ```mermaid
370
+ graph LR
371
+ A[Write Code] --> B[Discover Screens]
372
+ B --> C[Generate Selectors]
373
+ C --> D[Review Generated Selectors]
374
+ D --> E{Need Override?}
375
+ E -->|Yes| F[Create Override File]
376
+ E -->|No| G[Write Tests]
377
+ F --> G
378
+ G --> H[Run Tests]
379
+ H --> I{Tests Pass?}
380
+ I -->|No| J[Fix Selectors]
381
+ J --> F
382
+ I -->|Yes| K[Commit & Deploy]
383
+ ```
384
+
385
+ ## 🚧 Roadmap
386
+
387
+ - [x] React/Next.js scanner
388
+ - [x] Playwright executor adapter
389
+ - [x] Cache layer
390
+ - [x] Override mechanism
391
+ - [x] CLI tools
392
+ - [ ] Vue.js scanner
393
+ - [ ] Angular scanner
394
+ - [ ] Appium executor adapter
395
+ - [ ] Flutter Driver executor
396
+ - [ ] Runtime discovery (Vision AI)
397
+ - [ ] Selector health monitoring
398
+ - [ ] Auto-healing selectors
399
+
400
+ ## 📚 API Reference
401
+
402
+ See [types.ts](./types.ts) for complete API documentation.
403
+
404
+ ## 🤝 Contributing
405
+
406
+ This is an internal framework. For questions or feature requests, contact the QA team.
407
+
408
+ ## 📄 License
409
+
410
+ Proprietary - Internal Use Only
@@ -0,0 +1,322 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Cache Manager
4
+ * Manages caching of UI models and selector mappings to reduce AI API calls
5
+ */
6
+
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import * as crypto from 'crypto';
10
+ import { UIModel, SelectorDSL, CacheEntry } from '../types';
11
+
12
+ // ============================================================================
13
+ // Cache Configuration
14
+ // ============================================================================
15
+
16
+ export interface CacheConfig {
17
+ cachePath: string;
18
+ enabled: boolean;
19
+ expiryMs?: number; // Cache expiry in milliseconds (default: no expiry)
20
+ }
21
+
22
+ // ============================================================================
23
+ // Cache Manager Class
24
+ // ============================================================================
25
+
26
+ export class CacheManager {
27
+ private config: CacheConfig;
28
+
29
+ constructor(config: CacheConfig) {
30
+ this.config = config;
31
+
32
+ // Ensure cache directory exists
33
+ if (config.enabled) {
34
+ fs.mkdirSync(config.cachePath, { recursive: true });
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Generate cache key from UI model and element IDs
40
+ */
41
+ generateCacheKey(
42
+ screenId: string,
43
+ uiModel: UIModel,
44
+ elementIds: string[]
45
+ ): string {
46
+ // Create content for hash
47
+ const content = JSON.stringify({
48
+ screenId,
49
+ elements: uiModel.elements,
50
+ elementIds: elementIds.sort() // Sort for consistent hash
51
+ });
52
+
53
+ // Generate SHA-256 hash
54
+ const hash = crypto.createHash('sha256').update(content).digest('hex');
55
+
56
+ return hash;
57
+ }
58
+
59
+ /**
60
+ * Get cache file path
61
+ */
62
+ private getCachePath(screenId: string, hash: string): string {
63
+ const screenDir = path.join(this.config.cachePath, screenId);
64
+ return path.join(screenDir, `${hash}.json`);
65
+ }
66
+
67
+ /**
68
+ * Check if cache exists and is valid
69
+ */
70
+ has(screenId: string, hash: string): boolean {
71
+ if (!this.config.enabled) return false;
72
+
73
+ const cachePath = this.getCachePath(screenId, hash);
74
+
75
+ if (!fs.existsSync(cachePath)) return false;
76
+
77
+ // Check expiry if configured
78
+ if (this.config.expiryMs) {
79
+ const stats = fs.statSync(cachePath);
80
+ const age = Date.now() - stats.mtimeMs;
81
+
82
+ if (age > this.config.expiryMs) {
83
+ // Cache expired, delete it
84
+ fs.unlinkSync(cachePath);
85
+ return false;
86
+ }
87
+ }
88
+
89
+ return true;
90
+ }
91
+
92
+ /**
93
+ * Get cached selectors
94
+ */
95
+ get(screenId: string, hash: string): CacheEntry | null {
96
+ if (!this.config.enabled) return null;
97
+
98
+ const cachePath = this.getCachePath(screenId, hash);
99
+
100
+ if (!this.has(screenId, hash)) return null;
101
+
102
+ try {
103
+ const content = fs.readFileSync(cachePath, 'utf-8');
104
+ return JSON.parse(content) as CacheEntry;
105
+ } catch (error) {
106
+ console.error(`Failed to read cache: ${cachePath}`, error);
107
+ return null;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Save selectors to cache
113
+ */
114
+ set(
115
+ screenId: string,
116
+ hash: string,
117
+ selectors: SelectorDSL,
118
+ metadata: {
119
+ aiModel?: string;
120
+ tokenCost?: number;
121
+ framework: string;
122
+ }
123
+ ): void {
124
+ if (!this.config.enabled) return;
125
+
126
+ const cachePath = this.getCachePath(screenId, hash);
127
+ const screenDir = path.dirname(cachePath);
128
+
129
+ // Ensure screen directory exists
130
+ fs.mkdirSync(screenDir, { recursive: true });
131
+
132
+ // Create cache entry
133
+ const cacheEntry: CacheEntry = {
134
+ screenId,
135
+ hash,
136
+ selectors,
137
+ metadata: {
138
+ createdAt: new Date().toISOString(),
139
+ aiModel: metadata.aiModel,
140
+ tokenCost: metadata.tokenCost,
141
+ framework: metadata.framework
142
+ }
143
+ };
144
+
145
+ // Write to cache
146
+ fs.writeFileSync(cachePath, JSON.stringify(cacheEntry, null, 2), 'utf-8');
147
+ }
148
+
149
+ /**
150
+ * Invalidate cache for a screen
151
+ */
152
+ invalidate(screenId: string): number {
153
+ if (!this.config.enabled) return 0;
154
+
155
+ const screenDir = path.join(this.config.cachePath, screenId);
156
+
157
+ if (!fs.existsSync(screenDir)) return 0;
158
+
159
+ // Delete all cache files in screen directory
160
+ const files = fs.readdirSync(screenDir);
161
+ let deletedCount = 0;
162
+
163
+ for (const file of files) {
164
+ if (file.endsWith('.json')) {
165
+ fs.unlinkSync(path.join(screenDir, file));
166
+ deletedCount++;
167
+ }
168
+ }
169
+
170
+ // Remove directory if empty
171
+ if (deletedCount > 0) {
172
+ try {
173
+ fs.rmdirSync(screenDir);
174
+ } catch {
175
+ // Directory might not be empty, ignore
176
+ }
177
+ }
178
+
179
+ return deletedCount;
180
+ }
181
+
182
+ /**
183
+ * Clear all cache
184
+ */
185
+ clearAll(): number {
186
+ if (!this.config.enabled) return 0;
187
+
188
+ if (!fs.existsSync(this.config.cachePath)) return 0;
189
+
190
+ let deletedCount = 0;
191
+
192
+ // Get all screen directories
193
+ const screenDirs = fs.readdirSync(this.config.cachePath);
194
+
195
+ for (const screenDir of screenDirs) {
196
+ const screenPath = path.join(this.config.cachePath, screenDir);
197
+ const stat = fs.statSync(screenPath);
198
+
199
+ if (stat.isDirectory()) {
200
+ const count = this.invalidate(screenDir);
201
+ deletedCount += count;
202
+ }
203
+ }
204
+
205
+ return deletedCount;
206
+ }
207
+
208
+ /**
209
+ * Get cache statistics
210
+ */
211
+ getStats(): {
212
+ totalScreens: number;
213
+ totalEntries: number;
214
+ totalSize: number;
215
+ oldestEntry?: string;
216
+ newestEntry?: string;
217
+ } {
218
+ if (!this.config.enabled || !fs.existsSync(this.config.cachePath)) {
219
+ return {
220
+ totalScreens: 0,
221
+ totalEntries: 0,
222
+ totalSize: 0
223
+ };
224
+ }
225
+
226
+ let totalEntries = 0;
227
+ let totalSize = 0;
228
+ let oldestTime = Infinity;
229
+ let newestTime = 0;
230
+
231
+ const screenDirs = fs.readdirSync(this.config.cachePath);
232
+ const totalScreens = screenDirs.filter(dir => {
233
+ const stat = fs.statSync(path.join(this.config.cachePath, dir));
234
+ return stat.isDirectory();
235
+ }).length;
236
+
237
+ for (const screenDir of screenDirs) {
238
+ const screenPath = path.join(this.config.cachePath, screenDir);
239
+ const stat = fs.statSync(screenPath);
240
+
241
+ if (!stat.isDirectory()) continue;
242
+
243
+ const files = fs.readdirSync(screenPath);
244
+
245
+ for (const file of files) {
246
+ if (!file.endsWith('.json')) continue;
247
+
248
+ const filePath = path.join(screenPath, file);
249
+ const fileStat = fs.statSync(filePath);
250
+
251
+ totalEntries++;
252
+ totalSize += fileStat.size;
253
+
254
+ if (fileStat.mtimeMs < oldestTime) {
255
+ oldestTime = fileStat.mtimeMs;
256
+ }
257
+ if (fileStat.mtimeMs > newestTime) {
258
+ newestTime = fileStat.mtimeMs;
259
+ }
260
+ }
261
+ }
262
+
263
+ return {
264
+ totalScreens,
265
+ totalEntries,
266
+ totalSize,
267
+ oldestEntry: oldestTime !== Infinity ? new Date(oldestTime).toISOString() : undefined,
268
+ newestEntry: newestTime !== 0 ? new Date(newestTime).toISOString() : undefined
269
+ };
270
+ }
271
+
272
+ /**
273
+ * List all cached screens
274
+ */
275
+ listScreens(): string[] {
276
+ if (!this.config.enabled || !fs.existsSync(this.config.cachePath)) {
277
+ return [];
278
+ }
279
+
280
+ const screenDirs = fs.readdirSync(this.config.cachePath);
281
+
282
+ return screenDirs.filter(dir => {
283
+ const stat = fs.statSync(path.join(this.config.cachePath, dir));
284
+ return stat.isDirectory();
285
+ });
286
+ }
287
+
288
+ /**
289
+ * Get all cache entries for a screen
290
+ */
291
+ getScreenEntries(screenId: string): CacheEntry[] {
292
+ if (!this.config.enabled) return [];
293
+
294
+ const screenDir = path.join(this.config.cachePath, screenId);
295
+
296
+ if (!fs.existsSync(screenDir)) return [];
297
+
298
+ const files = fs.readdirSync(screenDir);
299
+ const entries: CacheEntry[] = [];
300
+
301
+ for (const file of files) {
302
+ if (!file.endsWith('.json')) continue;
303
+
304
+ try {
305
+ const content = fs.readFileSync(path.join(screenDir, file), 'utf-8');
306
+ entries.push(JSON.parse(content));
307
+ } catch (error) {
308
+ console.error(`Failed to read cache entry: ${file}`, error);
309
+ }
310
+ }
311
+
312
+ return entries;
313
+ }
314
+ }
315
+
316
+ // ============================================================================
317
+ // Factory Function
318
+ // ============================================================================
319
+
320
+ export function createCacheManager(config: CacheConfig): CacheManager {
321
+ return new CacheManager(config);
322
+ }