@sun-asterisk/sungen 1.0.24 → 2.0.1

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