@sun-asterisk/sungen 1.0.20 → 1.0.21

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 (286) hide show
  1. package/dist/cli/commands/add.d.ts +3 -0
  2. package/dist/cli/commands/add.d.ts.map +1 -0
  3. package/dist/cli/commands/add.js +27 -0
  4. package/dist/cli/commands/add.js.map +1 -0
  5. package/dist/cli/commands/cache-clear.d.ts +3 -0
  6. package/dist/cli/commands/cache-clear.d.ts.map +1 -0
  7. package/dist/cli/commands/cache-clear.js +24 -0
  8. package/dist/cli/commands/cache-clear.js.map +1 -0
  9. package/dist/cli/commands/full.d.ts +3 -0
  10. package/dist/cli/commands/full.d.ts.map +1 -0
  11. package/dist/cli/commands/full.js +37 -0
  12. package/dist/cli/commands/full.js.map +1 -0
  13. package/dist/cli/commands/generate.d.ts +3 -0
  14. package/dist/cli/commands/generate.d.ts.map +1 -0
  15. package/dist/cli/commands/generate.js +53 -0
  16. package/dist/cli/commands/generate.js.map +1 -0
  17. package/dist/cli/commands/init.d.ts +3 -0
  18. package/dist/cli/commands/init.d.ts.map +1 -0
  19. package/dist/cli/commands/init.js +20 -0
  20. package/dist/cli/commands/init.js.map +1 -0
  21. package/dist/cli/commands/live-scan.d.ts +3 -0
  22. package/dist/cli/commands/live-scan.d.ts.map +1 -0
  23. package/dist/cli/commands/{live-scan-command.js → live-scan.js} +8 -15
  24. package/dist/cli/commands/live-scan.js.map +1 -0
  25. package/dist/cli/commands/makeauth.d.ts +3 -0
  26. package/dist/cli/commands/makeauth.d.ts.map +1 -0
  27. package/dist/cli/commands/makeauth.js +76 -0
  28. package/dist/cli/commands/makeauth.js.map +1 -0
  29. package/dist/cli/commands/map.d.ts +3 -0
  30. package/dist/cli/commands/map.d.ts.map +1 -0
  31. package/dist/cli/commands/map.js +93 -0
  32. package/dist/cli/commands/map.js.map +1 -0
  33. package/dist/cli/commands/validate.d.ts +3 -0
  34. package/dist/cli/commands/validate.d.ts.map +1 -0
  35. package/dist/cli/commands/validate.js +43 -0
  36. package/dist/cli/commands/validate.js.map +1 -0
  37. package/dist/cli/index.js +29 -442
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/cli/types.d.ts +9 -0
  40. package/dist/cli/types.d.ts.map +1 -0
  41. package/dist/cli/types.js +7 -0
  42. package/dist/cli/types.js.map +1 -0
  43. package/dist/cli/utils.d.ts +6 -0
  44. package/dist/cli/utils.d.ts.map +1 -0
  45. package/dist/cli/utils.js +101 -0
  46. package/dist/cli/utils.js.map +1 -0
  47. package/dist/core/live-scanner/matrix-reader.d.ts.map +1 -1
  48. package/dist/core/live-scanner/matrix-reader.js +2 -40
  49. package/dist/core/live-scanner/matrix-reader.js.map +1 -1
  50. package/dist/core/live-scanner/step-replayer.d.ts.map +1 -1
  51. package/dist/core/live-scanner/step-replayer.js +7 -0
  52. package/dist/core/live-scanner/step-replayer.js.map +1 -1
  53. package/dist/core/validator/selector-validator.d.ts.map +1 -1
  54. package/dist/core/validator/selector-validator.js +2 -1
  55. package/dist/core/validator/selector-validator.js.map +1 -1
  56. package/dist/generators/scaffold-generator/index.d.ts +2 -1
  57. package/dist/generators/scaffold-generator/index.d.ts.map +1 -1
  58. package/dist/generators/scaffold-generator/index.js +21 -1
  59. package/dist/generators/scaffold-generator/index.js.map +1 -1
  60. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +2 -0
  61. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role-with-data.hbs +1 -0
  62. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role.hbs +1 -0
  63. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +2 -1
  64. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +3 -0
  65. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +2 -1
  66. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +2 -1
  67. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -1
  68. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +2 -1
  69. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +4 -3
  70. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +2 -1
  71. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -1
  72. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -1
  73. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +2 -1
  74. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +2 -1
  75. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-dialog-heading-assertion.hbs +2 -0
  76. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +2 -1
  77. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +4 -3
  78. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +2 -1
  79. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
  80. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/list-item-count-assertion.hbs +2 -1
  81. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
  82. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/page-assertion.hbs +1 -0
  83. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +2 -1
  84. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-dialog-heading-assertion.hbs +2 -0
  85. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +2 -1
  86. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +4 -3
  87. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +2 -1
  88. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -0
  89. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -1
  90. package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -1
  91. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  92. package/dist/generators/test-generator/patterns/assertion-patterns.js +95 -58
  93. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  94. package/dist/generators/test-generator/patterns/form-patterns.d.ts +0 -2
  95. package/dist/generators/test-generator/patterns/form-patterns.d.ts.map +1 -1
  96. package/dist/generators/test-generator/patterns/form-patterns.js +34 -47
  97. package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -1
  98. package/dist/generators/test-generator/patterns/index.d.ts +3 -1
  99. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  100. package/dist/generators/test-generator/patterns/index.js +20 -3
  101. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  102. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +0 -1
  103. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
  104. package/dist/generators/test-generator/patterns/interaction-patterns.js +44 -85
  105. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  106. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts +7 -0
  107. package/dist/generators/test-generator/patterns/legacy-patterns.d.ts.map +1 -0
  108. package/dist/generators/test-generator/patterns/legacy-patterns.js +98 -0
  109. package/dist/generators/test-generator/patterns/legacy-patterns.js.map +1 -0
  110. package/dist/generators/test-generator/patterns/navigation-patterns.d.ts +0 -2
  111. package/dist/generators/test-generator/patterns/navigation-patterns.d.ts.map +1 -1
  112. package/dist/generators/test-generator/patterns/navigation-patterns.js +14 -42
  113. package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -1
  114. package/dist/generators/test-generator/patterns/setup-patterns.d.ts +0 -1
  115. package/dist/generators/test-generator/patterns/setup-patterns.d.ts.map +1 -1
  116. package/dist/generators/test-generator/patterns/setup-patterns.js +23 -35
  117. package/dist/generators/test-generator/patterns/setup-patterns.js.map +1 -1
  118. package/dist/generators/test-generator/patterns/types.d.ts +18 -3
  119. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  120. package/dist/generators/test-generator/step-mapper.d.ts +0 -15
  121. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  122. package/dist/generators/test-generator/step-mapper.js +4 -106
  123. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  124. package/dist/{executor/test-generator.d.ts → generators/test-generator/types.d.ts} +4 -25
  125. package/dist/generators/test-generator/types.d.ts.map +1 -0
  126. package/dist/generators/test-generator/types.js +106 -0
  127. package/dist/generators/test-generator/types.js.map +1 -0
  128. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  129. package/dist/generators/test-generator/utils/data-resolver.js +8 -17
  130. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  131. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  132. package/dist/generators/test-generator/utils/selector-resolver.js +10 -18
  133. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  134. package/dist/orchestrator/cache-manager.d.ts +1 -23
  135. package/dist/orchestrator/cache-manager.d.ts.map +1 -1
  136. package/dist/orchestrator/cache-manager.js +1 -87
  137. package/dist/orchestrator/cache-manager.js.map +1 -1
  138. package/dist/orchestrator/pipeline.d.ts +11 -28
  139. package/dist/orchestrator/pipeline.d.ts.map +1 -1
  140. package/dist/orchestrator/pipeline.js +52 -371
  141. package/dist/orchestrator/pipeline.js.map +1 -1
  142. package/dist/orchestrator/reporter.d.ts +1 -1
  143. package/dist/orchestrator/reporter.d.ts.map +1 -1
  144. package/dist/orchestrator/screen-manager.js +1 -1
  145. package/dist/orchestrator/screen-manager.js.map +1 -1
  146. package/dist/utils/feature-finder.d.ts +9 -0
  147. package/dist/utils/feature-finder.d.ts.map +1 -0
  148. package/dist/utils/feature-finder.js +67 -0
  149. package/dist/utils/feature-finder.js.map +1 -0
  150. package/dist/utils/screen-paths.d.ts +10 -0
  151. package/dist/utils/screen-paths.d.ts.map +1 -0
  152. package/dist/utils/screen-paths.js +73 -0
  153. package/dist/utils/screen-paths.js.map +1 -0
  154. package/dist/utils/selector-loader.d.ts +6 -0
  155. package/dist/utils/selector-loader.d.ts.map +1 -0
  156. package/dist/utils/selector-loader.js +20 -0
  157. package/dist/utils/selector-loader.js.map +1 -0
  158. package/dist/utils/selector-types.d.ts +7 -0
  159. package/dist/utils/selector-types.d.ts.map +1 -0
  160. package/dist/utils/selector-types.js +19 -0
  161. package/dist/utils/selector-types.js.map +1 -0
  162. package/dist/utils/test-data-loader.d.ts +6 -0
  163. package/dist/utils/test-data-loader.d.ts.map +1 -0
  164. package/dist/utils/test-data-loader.js +20 -0
  165. package/dist/utils/test-data-loader.js.map +1 -0
  166. package/dist/utils/yaml-io.d.ts +14 -0
  167. package/dist/utils/yaml-io.d.ts.map +1 -0
  168. package/dist/utils/yaml-io.js +72 -0
  169. package/dist/utils/yaml-io.js.map +1 -0
  170. package/package.json +1 -1
  171. package/src/cli/commands/add.ts +25 -0
  172. package/src/cli/commands/cache-clear.ts +22 -0
  173. package/src/cli/commands/full.ts +35 -0
  174. package/src/cli/commands/generate.ts +55 -0
  175. package/src/cli/commands/init.ts +17 -0
  176. package/src/cli/commands/{live-scan-command.ts → live-scan.ts} +8 -17
  177. package/src/cli/commands/makeauth.ts +77 -0
  178. package/src/cli/commands/map.ts +97 -0
  179. package/src/cli/commands/validate.ts +43 -0
  180. package/src/cli/index.ts +32 -473
  181. package/src/cli/types.ts +9 -0
  182. package/src/cli/utils.ts +106 -0
  183. package/src/core/live-scanner/matrix-reader.ts +2 -8
  184. package/src/core/live-scanner/step-replayer.ts +7 -0
  185. package/src/core/validator/selector-validator.ts +3 -2
  186. package/src/generators/scaffold-generator/index.ts +23 -2
  187. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +2 -0
  188. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role-with-data.hbs +1 -0
  189. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role.hbs +1 -0
  190. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +2 -1
  191. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +3 -0
  192. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +2 -1
  193. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +2 -1
  194. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -1
  195. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +2 -1
  196. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +4 -3
  197. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +2 -1
  198. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -1
  199. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -1
  200. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +2 -1
  201. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +2 -1
  202. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-dialog-heading-assertion.hbs +2 -0
  203. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +2 -1
  204. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +4 -3
  205. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +2 -1
  206. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
  207. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/list-item-count-assertion.hbs +2 -1
  208. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
  209. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/page-assertion.hbs +1 -0
  210. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +2 -1
  211. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-dialog-heading-assertion.hbs +2 -0
  212. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +2 -1
  213. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +4 -3
  214. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +2 -1
  215. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -0
  216. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -1
  217. package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -1
  218. package/src/generators/test-generator/patterns/assertion-patterns.ts +102 -62
  219. package/src/generators/test-generator/patterns/form-patterns.ts +38 -60
  220. package/src/generators/test-generator/patterns/index.ts +22 -4
  221. package/src/generators/test-generator/patterns/interaction-patterns.ts +47 -107
  222. package/src/generators/test-generator/patterns/legacy-patterns.ts +104 -0
  223. package/src/generators/test-generator/patterns/navigation-patterns.ts +27 -69
  224. package/src/generators/test-generator/patterns/setup-patterns.ts +23 -41
  225. package/src/generators/test-generator/patterns/types.ts +26 -9
  226. package/src/generators/test-generator/step-mapper.ts +4 -124
  227. package/src/generators/test-generator/types.ts +131 -0
  228. package/src/generators/test-generator/utils/data-resolver.ts +8 -13
  229. package/src/generators/test-generator/utils/selector-resolver.ts +15 -17
  230. package/src/orchestrator/cache-manager.ts +1 -107
  231. package/src/orchestrator/pipeline.ts +58 -433
  232. package/src/orchestrator/reporter.ts +1 -1
  233. package/src/orchestrator/screen-manager.ts +1 -1
  234. package/src/utils/feature-finder.ts +33 -0
  235. package/src/utils/screen-paths.ts +37 -0
  236. package/src/utils/selector-loader.ts +23 -0
  237. package/src/utils/selector-types.ts +17 -0
  238. package/src/utils/test-data-loader.ts +23 -0
  239. package/src/utils/yaml-io.ts +33 -0
  240. package/dist/cli/commands/auto-tag-command.d.ts +0 -8
  241. package/dist/cli/commands/auto-tag-command.d.ts.map +0 -1
  242. package/dist/cli/commands/auto-tag-command.js +0 -104
  243. package/dist/cli/commands/auto-tag-command.js.map +0 -1
  244. package/dist/cli/commands/live-scan-command.d.ts +0 -9
  245. package/dist/cli/commands/live-scan-command.d.ts.map +0 -1
  246. package/dist/cli/commands/live-scan-command.js.map +0 -1
  247. package/dist/executor/playwright/playwright-generator.d.ts +0 -33
  248. package/dist/executor/playwright/playwright-generator.d.ts.map +0 -1
  249. package/dist/executor/playwright/playwright-generator.js +0 -136
  250. package/dist/executor/playwright/playwright-generator.js.map +0 -1
  251. package/dist/executor/test-generator.d.ts.map +0 -1
  252. package/dist/executor/test-generator.js +0 -30
  253. package/dist/executor/test-generator.js.map +0 -1
  254. package/dist/generators/cli.d.ts +0 -7
  255. package/dist/generators/cli.d.ts.map +0 -1
  256. package/dist/generators/cli.js +0 -570
  257. package/dist/generators/cli.js.map +0 -1
  258. package/dist/input/cli-adapter.d.ts +0 -75
  259. package/dist/input/cli-adapter.d.ts.map +0 -1
  260. package/dist/input/cli-adapter.js +0 -218
  261. package/dist/input/cli-adapter.js.map +0 -1
  262. package/dist/input/config-adapter.d.ts +0 -25
  263. package/dist/input/config-adapter.d.ts.map +0 -1
  264. package/dist/input/config-adapter.js +0 -70
  265. package/dist/input/config-adapter.js.map +0 -1
  266. package/dist/input/input-adapter.d.ts +0 -28
  267. package/dist/input/input-adapter.d.ts.map +0 -1
  268. package/dist/input/input-adapter.js +0 -17
  269. package/dist/input/input-adapter.js.map +0 -1
  270. package/dist/input/vscode-adapter.d.ts +0 -62
  271. package/dist/input/vscode-adapter.d.ts.map +0 -1
  272. package/dist/input/vscode-adapter.js +0 -64
  273. package/dist/input/vscode-adapter.js.map +0 -1
  274. package/dist/tools/auto-tagger.d.ts +0 -107
  275. package/dist/tools/auto-tagger.d.ts.map +0 -1
  276. package/dist/tools/auto-tagger.js +0 -502
  277. package/dist/tools/auto-tagger.js.map +0 -1
  278. package/src/cli/commands/auto-tag-command.ts +0 -80
  279. package/src/executor/playwright/playwright-generator.ts +0 -125
  280. package/src/executor/test-generator.ts +0 -90
  281. package/src/generators/cli.ts +0 -640
  282. package/src/input/cli-adapter.ts +0 -233
  283. package/src/input/config-adapter.ts +0 -71
  284. package/src/input/input-adapter.ts +0 -32
  285. package/src/input/vscode-adapter.ts +0 -90
  286. package/src/tools/auto-tagger.ts +0 -572
@@ -0,0 +1,104 @@
1
+ import { ParsedStep } from '../../gherkin-parser';
2
+ import { StepPattern } from './types';
3
+
4
+ /**
5
+ * Helper to extract screen ID from selector reference.
6
+ */
7
+ function extractScreenId(selectorRef: string): string {
8
+ const match = selectorRef.match(/\[([\w-]+)\./);
9
+ return match ? match[1] : 'unknown';
10
+ }
11
+
12
+ /**
13
+ * Legacy patterns migrated from step-mapper.ts tryLegacyPatterns().
14
+ * These use templates that already exist (login, error-message-assertion, etc.)
15
+ */
16
+ export const legacyPatterns: StepPattern[] = [
17
+ {
18
+ name: 'legacy-login',
19
+ matcher: (step: ParsedStep) =>
20
+ step.text.includes('user is logged in as') && !!step.dataRef,
21
+ resolver: (step, context) => {
22
+ const varName = step.dataRef!.replace(/[^a-zA-Z0-9]/g, '_') + '_' + context.stepCounter;
23
+ return {
24
+ templateName: 'login',
25
+ data: { varName, dataRef: step.dataRef },
26
+ comment: `Login as ${step.dataRef}`,
27
+ };
28
+ },
29
+ priority: 9,
30
+ },
31
+ {
32
+ name: 'legacy-error-message',
33
+ matcher: (step: ParsedStep) =>
34
+ step.text.includes('error message') && step.text.includes('should'),
35
+ resolver: (step, context) => ({
36
+ templateName: 'error-message-assertion',
37
+ data: {},
38
+ comment: 'Assert error message is displayed',
39
+ }),
40
+ priority: 6,
41
+ },
42
+ {
43
+ name: 'legacy-generic-message',
44
+ matcher: (step: ParsedStep) =>
45
+ step.text.includes('message') && step.text.includes('should be displayed'),
46
+ resolver: (step, context) => {
47
+ const messageType = step.text.includes('welcome') ? 'welcome' :
48
+ step.text.includes('success') ? 'success' : 'message';
49
+ return {
50
+ templateName: 'generic-message-assertion',
51
+ data: { messageType },
52
+ comment: `Assert ${messageType} message is displayed`,
53
+ };
54
+ },
55
+ priority: 6,
56
+ },
57
+ {
58
+ name: 'legacy-message-with-value',
59
+ matcher: (step: ParsedStep) =>
60
+ step.text.includes('should see message') && !!step.value,
61
+ resolver: (step, context) => {
62
+ const varName = (step.selectorRef || 'message').replace(/[^a-zA-Z0-9]/g, '_') + '_' + context.stepCounter;
63
+ return {
64
+ templateName: 'message-assertion-body',
65
+ data: { varName, value: step.value, selectorRef: step.selectorRef },
66
+ comment: `Assert message: ${step.value}`,
67
+ };
68
+ },
69
+ priority: 6,
70
+ },
71
+ {
72
+ name: 'legacy-ai-response',
73
+ matcher: (step: ParsedStep) =>
74
+ step.text.includes('user should see') && step.text.includes('AI response') && !!step.selectorRef,
75
+ resolver: (step, context) => {
76
+ const screenId = extractScreenId(step.selectorRef!);
77
+ const varName = step.selectorRef!.replace(/[^a-zA-Z0-9]/g, '_') + '_' + context.stepCounter;
78
+ return {
79
+ templateName: 'ai-response-assertion-selector',
80
+ data: { varName, selectorRef: step.selectorRef, screenId },
81
+ comment: `Assert AI response in ${step.selectorRef}`,
82
+ };
83
+ },
84
+ priority: 6,
85
+ },
86
+ {
87
+ name: 'legacy-message-count',
88
+ matcher: (step: ParsedStep) =>
89
+ (step.text.includes('messages in') || (step.text.includes('should contain') && step.text.includes('messages'))) &&
90
+ !!step.selectorRef,
91
+ resolver: (step, context) => {
92
+ const match = step.text.match(/(\d+)\s+messages?/);
93
+ const expectedCount = match ? parseInt(match[1]) : 1;
94
+ const screenId = extractScreenId(step.selectorRef!);
95
+ const varName = step.selectorRef!.replace(/[^a-zA-Z0-9]/g, '_') + '_' + context.stepCounter;
96
+ return {
97
+ templateName: 'message-count-assertion',
98
+ data: { varName, selectorRef: step.selectorRef, screenId, expectedCount },
99
+ comment: `Assert ${expectedCount} messages in ${step.selectorRef}`,
100
+ };
101
+ },
102
+ priority: 6,
103
+ },
104
+ ];
@@ -4,82 +4,58 @@ import { inferPath, resolvePathVariables, getPathCode } from '../utils/path-infe
4
4
 
5
5
  /**
6
6
  * Navigation patterns: goto, navigate, open page
7
- * Uses baseURL from config (optional) + path from feature metadata
8
- * Templates handle URL construction
9
7
  */
10
8
  export const navigationPatterns: StepPattern[] = [
11
- // Open page type pattern (open [home] page) - resolve selector value or use feature path
12
9
  {
13
10
  name: 'open-page-type',
14
11
  matcher: (step: ParsedStep) =>
15
12
  (step.text.includes('open') || step.text.includes('opens') || step.text.includes('is on')) &&
16
13
  step.elementType === 'page',
17
- generator: (step, context) => {
14
+ resolver: (step, context) => {
18
15
  let path = context.featurePath || '/';
19
-
20
- // If selector is present, extract path from selector's value attribute
16
+
21
17
  if (step.selectorRef) {
22
18
  try {
23
19
  const resolved = context.selectorResolver.resolveSelector(
24
- step.selectorRef,
25
- context.featureName,
26
- step.elementType,
27
- step.nth
20
+ step.selectorRef, context.featureName, step.elementType, step.nth
28
21
  );
29
- // Use selector's value as the path for navigation
30
22
  path = resolved.value || path;
31
23
  } catch (error) {
32
- // Fallback to feature path if selector not found
33
24
  path = context.featurePath || '/';
34
25
  }
35
26
  }
36
-
37
- // Resolve path variables if present
27
+
38
28
  const finalPath = resolvePathVariables(path, context.scenarioSteps || []);
39
-
40
- const code = context.templateEngine.renderStep('navigation', {
41
- baseURL: context.baseURL,
42
- path: finalPath,
43
- });
44
-
29
+
45
30
  return {
46
- code,
31
+ templateName: 'navigation',
32
+ data: { baseURL: context.baseURL, path: finalPath },
47
33
  comment: step.selectorRef ? `Open ${step.selectorRef} page` : `Navigate to page`,
48
34
  };
49
35
  },
50
- priority: 16, // Higher priority than regular open-page
36
+ priority: 16,
51
37
  },
52
38
  {
53
39
  name: 'open-page',
54
40
  matcher: (step: ParsedStep) =>
55
41
  (step.text.includes('open') || step.text.includes('opens')) &&
56
42
  step.text.includes('page') &&
57
- step.elementType !== 'page', // Only match if NOT page type (avoid conflict with open-page-type)
58
- generator: (step, context) => {
59
- // Extract page/screen reference
60
- const pageMatch = step.text.match(/open[s]?\s+\[([^\]]+)\]/i) ||
43
+ step.elementType !== 'page',
44
+ resolver: (step, context) => {
45
+ const pageMatch = step.text.match(/open[s]?\s+\[([^\]]+)\]/i) ||
61
46
  step.text.match(/open[s]?\s+"([^"]+)"/i);
62
47
  const pageName = pageMatch ? pageMatch[1] : 'page';
63
-
64
- // Infer path with smart defaults
48
+
65
49
  const inferredPath = inferPath(context.featurePath, {
66
50
  featureName: context.featureName,
67
51
  screenName: context.screenName,
68
52
  });
69
-
70
- // Resolve path variables if present (e.g., /user/:id)
71
53
  const resolvedPath = resolvePathVariables(inferredPath, context.scenarioSteps || []);
72
-
73
- // Get path code (template literal or string)
74
54
  const pathCode = getPathCode(resolvedPath);
75
-
76
- const code = context.templateEngine.renderStep('navigation', {
77
- baseURL: context.baseURL, // null or URL from config
78
- path: pathCode.replace(/^['`]|['`]$/g, ''), // Remove quotes for template
79
- });
80
-
55
+
81
56
  return {
82
- code,
57
+ templateName: 'navigation',
58
+ data: { baseURL: context.baseURL, path: pathCode.replace(/^['`]|['`]$/g, '') },
83
59
  comment: `Open ${pageName}`,
84
60
  };
85
61
  },
@@ -87,31 +63,22 @@ export const navigationPatterns: StepPattern[] = [
87
63
  },
88
64
  {
89
65
  name: 'navigate-to-route',
90
- matcher: (step: ParsedStep) =>
91
- (step.text.includes('navigates to') || step.text.includes('is on')) &&
66
+ matcher: (step: ParsedStep) =>
67
+ (step.text.includes('navigates to') || step.text.includes('is on')) &&
92
68
  !!(step.selectorRef || step.dataRef),
93
- generator: (step, context) => {
69
+ resolver: (step, context) => {
94
70
  const route = step.selectorRef || step.dataRef;
95
-
96
- // Infer path with smart defaults
71
+
97
72
  const inferredPath = inferPath(context.featurePath, {
98
73
  featureName: context.featureName,
99
74
  screenName: context.screenName,
100
75
  });
101
-
102
- // Resolve path variables if present
103
76
  const resolvedPath = resolvePathVariables(inferredPath, context.scenarioSteps || []);
104
-
105
- // Get path code
106
77
  const pathCode = getPathCode(resolvedPath);
107
-
108
- const code = context.templateEngine.renderStep('navigation', {
109
- baseURL: context.baseURL, // null or URL from config
110
- path: pathCode.replace(/^['`]|['`]$/g, ''),
111
- });
112
-
78
+
113
79
  return {
114
- code,
80
+ templateName: 'navigation',
81
+ data: { baseURL: context.baseURL, path: pathCode.replace(/^['`]|['`]$/g, '') },
115
82
  comment: `Navigate to ${route}`,
116
83
  };
117
84
  },
@@ -122,31 +89,22 @@ export const navigationPatterns: StepPattern[] = [
122
89
  matcher: (step: ParsedStep) =>
123
90
  (step.text.includes('should see route') || step.text.includes('should remain on')) &&
124
91
  !!(step.selectorRef || step.dataRef),
125
- generator: (step, context) => {
92
+ resolver: (step, context) => {
126
93
  const route = step.selectorRef || step.dataRef;
127
-
128
- // Infer path with smart defaults
94
+
129
95
  const inferredPath = inferPath(context.featurePath, {
130
96
  featureName: context.featureName,
131
97
  screenName: context.screenName,
132
98
  });
133
-
134
- // Resolve path variables if present
135
99
  const resolvedPath = resolvePathVariables(inferredPath, context.scenarioSteps || []);
136
-
137
- // Get path code
138
100
  const pathCode = getPathCode(resolvedPath);
139
-
140
- const code = context.templateEngine.renderStep('route-assertion', {
141
- path: pathCode.replace(/^['`]|['`]$/g, ''),
142
- });
143
-
101
+
144
102
  return {
145
- code,
103
+ templateName: 'route-assertion',
104
+ data: { path: pathCode.replace(/^['`]|['`]$/g, '') },
146
105
  comment: `Assert current route is ${route}`,
147
106
  };
148
107
  },
149
108
  priority: 10,
150
109
  },
151
110
  ];
152
-
@@ -3,7 +3,6 @@ import { StepPattern } from './types';
3
3
 
4
4
  /**
5
5
  * Setup and precondition patterns: application setup, authentication state, etc.
6
- * Uses templates for framework-agnostic code generation
7
6
  */
8
7
  export const setupPatterns: StepPattern[] = [
9
8
  {
@@ -12,14 +11,11 @@ export const setupPatterns: StepPattern[] = [
12
11
  step.text.includes('application is running') ||
13
12
  step.text.includes('application running') ||
14
13
  step.text.includes('app is running'),
15
- generator: (step, context) => {
16
- const code = context.templateEngine.renderStep('application-running', {});
17
-
18
- return {
19
- code,
20
- comment: `Setup: Application is running`,
21
- };
22
- },
14
+ resolver: (step, context) => ({
15
+ templateName: 'application-running',
16
+ data: {},
17
+ comment: `Setup: Application is running`,
18
+ }),
23
19
  priority: 5,
24
20
  },
25
21
  {
@@ -28,14 +24,11 @@ export const setupPatterns: StepPattern[] = [
28
24
  step.text.includes('user is not logged in') ||
29
25
  step.text.includes('not logged in') ||
30
26
  step.text.includes('logged out'),
31
- generator: (step, context) => {
32
- const code = context.templateEngine.renderStep('clear-auth', {});
33
-
34
- return {
35
- code,
36
- comment: `Clear authentication state (ensure user is logged out)`,
37
- };
38
- },
27
+ resolver: (step, context) => ({
28
+ templateName: 'clear-auth',
29
+ data: {},
30
+ comment: `Clear authentication state (ensure user is logged out)`,
31
+ }),
39
32
  priority: 9,
40
33
  },
41
34
  {
@@ -44,16 +37,11 @@ export const setupPatterns: StepPattern[] = [
44
37
  (step.text.includes('user is logged in') ||
45
38
  step.text.includes('logged in as')) &&
46
39
  !step.text.includes('not logged in'),
47
- generator: (step, context) => {
48
- // Check if there's a data reference for user credentials
40
+ resolver: (step, context) => {
49
41
  const userRef = step.dataRef || 'valid_user';
50
-
51
- const code = context.templateEngine.renderStep('user-login-todo', {
52
- userRef,
53
- });
54
-
55
42
  return {
56
- code,
43
+ templateName: 'user-login-todo',
44
+ data: { userRef },
57
45
  comment: `Setup: User logged in as ${userRef}`,
58
46
  };
59
47
  },
@@ -65,14 +53,11 @@ export const setupPatterns: StepPattern[] = [
65
53
  step.text.includes('database is empty') ||
66
54
  step.text.includes('database is cleared') ||
67
55
  step.text.includes('clear database'),
68
- generator: (step, context) => {
69
- const code = context.templateEngine.renderStep('clear-database', {});
70
-
71
- return {
72
- code,
73
- comment: `Setup: Clear/reset database`,
74
- };
75
- },
56
+ resolver: (step, context) => ({
57
+ templateName: 'clear-database',
58
+ data: {},
59
+ comment: `Setup: Clear/reset database`,
60
+ }),
76
61
  priority: 7,
77
62
  },
78
63
  {
@@ -81,14 +66,11 @@ export const setupPatterns: StepPattern[] = [
81
66
  step.text.includes('clean browser state') ||
82
67
  step.text.includes('fresh browser') ||
83
68
  step.text.includes('new browser session'),
84
- generator: (step, context) => {
85
- const code = context.templateEngine.renderStep('clear-browser-state', {});
86
-
87
- return {
88
- code,
89
- comment: `Clear browser state (cookies, storage)`,
90
- };
91
- },
69
+ resolver: (step, context) => ({
70
+ templateName: 'clear-browser-state',
71
+ data: {},
72
+ comment: `Clear browser state (cookies, storage)`,
73
+ }),
92
74
  priority: 8,
93
75
  },
94
76
  ];
@@ -9,12 +9,26 @@ import { DataResolver } from '../utils/data-resolver';
9
9
  export type PatternMatcher = RegExp | ((step: ParsedStep) => boolean);
10
10
 
11
11
  /**
12
- * Pattern generator function
12
+ * Pattern generator function (legacy — calls templateEngine directly)
13
13
  */
14
14
  export type PatternGenerator = (step: ParsedStep, context: PatternContext) => MappedStep;
15
15
 
16
16
  /**
17
- * Context passed to pattern generators
17
+ * Resolved step template data — framework-agnostic
18
+ */
19
+ export interface StepTemplateData {
20
+ templateName: string;
21
+ data: Record<string, any>;
22
+ comment?: string;
23
+ }
24
+
25
+ /**
26
+ * Pattern resolver function — returns template name + data, does NOT render
27
+ */
28
+ export type PatternResolver = (step: ParsedStep, context: PatternContext) => StepTemplateData;
29
+
30
+ /**
31
+ * Context passed to pattern generators/resolvers
18
32
  */
19
33
  export interface PatternContext {
20
34
  stepCounter: number;
@@ -23,19 +37,22 @@ export interface PatternContext {
23
37
  selectorResolver: SelectorResolver;
24
38
  dataResolver: DataResolver;
25
39
  renderLocator: (resolved: any) => string;
26
- baseURL?: string; // Base URL from config (e.g., 'http://localhost:3000')
27
- featureName?: string; // Feature name for data resolution (e.g., 'login')
28
- screenName?: string; // Screen name for path inference (e.g., 'sign-in')
29
- featurePath?: string; // Path metadata from feature file (e.g., '/login')
30
- scenarioSteps?: ParsedStep[]; // All steps in scenario for path variable extraction
40
+ baseURL?: string;
41
+ featureName?: string;
42
+ screenName?: string;
43
+ featurePath?: string;
44
+ scenarioSteps?: ParsedStep[];
31
45
  }
32
46
 
33
47
  /**
34
48
  * Step pattern definition
49
+ * Supports both `resolver` (preferred) and `generator` (legacy).
50
+ * If both are provided, `resolver` takes precedence.
35
51
  */
36
52
  export interface StepPattern {
37
53
  name: string;
38
54
  matcher: PatternMatcher;
39
- generator: PatternGenerator;
40
- priority?: number; // Higher priority = checked first (default: 0)
55
+ resolver?: PatternResolver;
56
+ generator?: PatternGenerator;
57
+ priority?: number;
41
58
  }
@@ -140,15 +140,6 @@ export class StepMapper {
140
140
  return mappedStep;
141
141
  }
142
142
 
143
- // Fallback: Try legacy patterns for backward compatibility
144
- const legacyStep = this.tryLegacyPatterns(step);
145
- if (legacyStep) {
146
- if (this.verbose) {
147
- console.log(` ✓ Legacy pattern matched: ${step.text.substring(0, 50)}...`);
148
- }
149
- return legacyStep;
150
- }
151
-
152
143
  // Fallback to AI if enabled
153
144
  if (this.useAI && this.aiMapper) {
154
145
  if (this.verbose) {
@@ -170,7 +161,10 @@ export class StepMapper {
170
161
  private createPatternContext(): PatternContext {
171
162
  return {
172
163
  stepCounter: this.stepCounter,
173
- extractScreenId: this.extractScreenId.bind(this),
164
+ extractScreenId: (selectorRef: string) => {
165
+ const match = selectorRef.match(/\[([\w-]+)\./);
166
+ return match ? match[1] : 'unknown';
167
+ },
174
168
  templateEngine: this.templateEngine,
175
169
  selectorResolver: this.selectorResolver,
176
170
  dataResolver: this.dataResolver,
@@ -183,118 +177,4 @@ export class StepMapper {
183
177
  };
184
178
  }
185
179
 
186
- /**
187
- * Extract screen ID from selector reference
188
- */
189
- private extractScreenId(selectorRef: string): string {
190
- const match = selectorRef.match(/\[([\w-]+)\./);
191
- return match ? match[1] : 'unknown';
192
- }
193
-
194
- /**
195
- * Try legacy patterns for backward compatibility
196
- * These are patterns not yet migrated to the pattern registry
197
- */
198
- private tryLegacyPatterns(step: ParsedStep): MappedStep | null {
199
- const { text, selectorRef, dataRef, value } = step;
200
-
201
- // Login pattern
202
- if (text.includes('user is logged in as') && dataRef) {
203
- return this.mapLoginStep(dataRef);
204
- }
205
-
206
- // Error message assertions
207
- if (text.includes('error message') && text.includes('should')) {
208
- return this.mapErrorMessageAssertion();
209
- }
210
-
211
- // Generic message assertions
212
- if (text.includes('message') && text.includes('should be displayed')) {
213
- return this.mapGenericMessageAssertion(text);
214
- }
215
-
216
- // Message with value assertions
217
- if (text.includes('should see message') && value) {
218
- return this.mapMessageAssertion(value, selectorRef);
219
- }
220
-
221
- // AI response assertions
222
- if (text.includes('user should see') && text.includes('AI response') && selectorRef) {
223
- return this.mapAIResponseAssertion(selectorRef);
224
- }
225
-
226
- // Message count assertions
227
- if (text.includes('messages in') && selectorRef) {
228
- return this.mapMessageCountAssertion(text, selectorRef);
229
- }
230
-
231
- // Message contains assertions
232
- if (text.includes('should contain') && text.includes('messages') && selectorRef) {
233
- return this.mapMessageCountAssertion(text, selectorRef);
234
- }
235
-
236
- return null;
237
- }
238
-
239
- // ========================================
240
- // LEGACY METHODS (to be migrated to patterns)
241
- // ========================================
242
-
243
- private mapLoginStep(dataRef: string): MappedStep {
244
- const varName = dataRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
245
- return {
246
- code: this.templateEngine.renderStep('login', { varName, dataRef }),
247
- comment: `Login as ${dataRef}`,
248
- };
249
- }
250
-
251
- private mapErrorMessageAssertion(): MappedStep {
252
- return {
253
- code: this.templateEngine.renderStep('error-message-assertion', {}),
254
- comment: 'Assert error message is displayed',
255
- };
256
- }
257
-
258
- private mapGenericMessageAssertion(text: string): MappedStep {
259
- const messageType = text.includes('welcome') ? 'welcome' :
260
- text.includes('success') ? 'success' : 'message';
261
- return {
262
- code: this.templateEngine.renderStep('generic-message-assertion', { messageType }),
263
- comment: `Assert ${messageType} message is displayed`,
264
- };
265
- }
266
-
267
- private mapMessageAssertion(value: string, selectorRef?: string): MappedStep {
268
- const varName = (selectorRef || 'message').replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
269
- return {
270
- code: this.templateEngine.renderStep('message-assertion-body', { varName, value, selectorRef }),
271
- comment: `Assert message: ${value}`,
272
- };
273
- }
274
-
275
- private mapAIResponseAssertion(selectorRef: string): MappedStep {
276
- const screenId = this.extractScreenId(selectorRef);
277
- const varName = selectorRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
278
- return {
279
- code: this.templateEngine.renderStep('ai-response-assertion-selector', { varName, selectorRef, screenId }),
280
- comment: `Assert AI response in ${selectorRef}`,
281
- };
282
- }
283
-
284
- private mapMessageCountAssertion(text: string, selectorRef: string): MappedStep {
285
- const match = text.match(/(\d+)\s+messages?/);
286
- const expectedCount = match ? parseInt(match[1]) : 1;
287
- const screenId = this.extractScreenId(selectorRef);
288
- const varName = selectorRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
289
-
290
- return {
291
- code: this.templateEngine.renderStep('message-count-assertion', {
292
- varName,
293
- selectorRef,
294
- screenId,
295
- expectedCount,
296
- }),
297
- comment: `Assert ${expectedCount} messages in ${selectorRef}`,
298
- };
299
- }
300
180
  }