@sun-asterisk/sungen 2.4.5 → 2.5.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 (201) hide show
  1. package/dist/cli/commands/delivery.d.ts +7 -0
  2. package/dist/cli/commands/delivery.d.ts.map +1 -0
  3. package/dist/cli/commands/delivery.js +348 -0
  4. package/dist/cli/commands/delivery.js.map +1 -0
  5. package/dist/cli/commands/generate.d.ts.map +1 -1
  6. package/dist/cli/commands/generate.js +2 -0
  7. package/dist/cli/commands/generate.js.map +1 -1
  8. package/dist/cli/commands/update.d.ts.map +1 -1
  9. package/dist/cli/commands/update.js +64 -1
  10. package/dist/cli/commands/update.js.map +1 -1
  11. package/dist/cli/index.js +4 -2
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/exporters/csv-exporter.d.ts +32 -0
  14. package/dist/exporters/csv-exporter.d.ts.map +1 -0
  15. package/dist/exporters/csv-exporter.js +311 -0
  16. package/dist/exporters/csv-exporter.js.map +1 -0
  17. package/dist/exporters/feature-parser.d.ts +48 -0
  18. package/dist/exporters/feature-parser.d.ts.map +1 -0
  19. package/dist/exporters/feature-parser.js +178 -0
  20. package/dist/exporters/feature-parser.js.map +1 -0
  21. package/dist/exporters/package-info.d.ts +9 -0
  22. package/dist/exporters/package-info.d.ts.map +1 -0
  23. package/dist/exporters/package-info.js +73 -0
  24. package/dist/exporters/package-info.js.map +1 -0
  25. package/dist/exporters/playwright-report-parser.d.ts +21 -0
  26. package/dist/exporters/playwright-report-parser.d.ts.map +1 -0
  27. package/dist/exporters/playwright-report-parser.js +184 -0
  28. package/dist/exporters/playwright-report-parser.js.map +1 -0
  29. package/dist/exporters/scenario-merger.d.ts +21 -0
  30. package/dist/exporters/scenario-merger.d.ts.map +1 -0
  31. package/dist/exporters/scenario-merger.js +51 -0
  32. package/dist/exporters/scenario-merger.js.map +1 -0
  33. package/dist/exporters/spec-parser.d.ts +20 -0
  34. package/dist/exporters/spec-parser.d.ts.map +1 -0
  35. package/dist/exporters/spec-parser.js +259 -0
  36. package/dist/exporters/spec-parser.js.map +1 -0
  37. package/dist/exporters/step-formatter.d.ts +32 -0
  38. package/dist/exporters/step-formatter.d.ts.map +1 -0
  39. package/dist/exporters/step-formatter.js +76 -0
  40. package/dist/exporters/step-formatter.js.map +1 -0
  41. package/dist/exporters/test-data-resolver.d.ts +20 -0
  42. package/dist/exporters/test-data-resolver.d.ts.map +1 -0
  43. package/dist/exporters/test-data-resolver.js +96 -0
  44. package/dist/exporters/test-data-resolver.js.map +1 -0
  45. package/dist/exporters/types.d.ts +104 -0
  46. package/dist/exporters/types.d.ts.map +1 -0
  47. package/dist/exporters/types.js +6 -0
  48. package/dist/exporters/types.js.map +1 -0
  49. package/dist/exporters/xlsx-exporter.d.ts +19 -0
  50. package/dist/exporters/xlsx-exporter.d.ts.map +1 -0
  51. package/dist/exporters/xlsx-exporter.js +309 -0
  52. package/dist/exporters/xlsx-exporter.js.map +1 -0
  53. package/dist/generators/gherkin-parser/index.d.ts +1 -0
  54. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  55. package/dist/generators/gherkin-parser/index.js +3 -0
  56. package/dist/generators/gherkin-parser/index.js.map +1 -1
  57. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +29 -1
  58. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
  59. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +21 -1
  60. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
  61. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js +11 -2
  62. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
  63. package/dist/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
  64. package/dist/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
  65. package/dist/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
  66. package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  67. package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
  68. package/dist/generators/test-generator/code-generator.d.ts +2 -0
  69. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  70. package/dist/generators/test-generator/code-generator.js +109 -12
  71. package/dist/generators/test-generator/code-generator.js.map +1 -1
  72. package/dist/generators/test-generator/step-mapper.d.ts +1 -0
  73. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  74. package/dist/generators/test-generator/step-mapper.js +1 -1
  75. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  76. package/dist/generators/test-generator/template-engine.d.ts +29 -1
  77. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  78. package/dist/generators/test-generator/template-engine.js +11 -2
  79. package/dist/generators/test-generator/template-engine.js.map +1 -1
  80. package/dist/generators/test-generator/utils/data-resolver.d.ts +11 -2
  81. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  82. package/dist/generators/test-generator/utils/data-resolver.js +36 -25
  83. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  84. package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts +7 -0
  85. package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts.map +1 -0
  86. package/dist/generators/test-generator/utils/runtime-data-transformer.js +42 -0
  87. package/dist/generators/test-generator/utils/runtime-data-transformer.js.map +1 -0
  88. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  89. package/dist/generators/test-generator/utils/selector-resolver.js +26 -0
  90. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  91. package/dist/generators/types.d.ts +1 -0
  92. package/dist/generators/types.d.ts.map +1 -1
  93. package/dist/generators/types.js.map +1 -1
  94. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  95. package/dist/orchestrator/ai-rules-updater.js +12 -0
  96. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  97. package/dist/orchestrator/project-initializer.d.ts +21 -1
  98. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  99. package/dist/orchestrator/project-initializer.js +158 -74
  100. package/dist/orchestrator/project-initializer.js.map +1 -1
  101. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  102. package/dist/orchestrator/screen-manager.js +2 -0
  103. package/dist/orchestrator/screen-manager.js.map +1 -1
  104. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +15 -17
  105. package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +7 -5
  106. package/dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md +71 -0
  107. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +28 -1
  108. package/dist/orchestrator/templates/ai-instructions/claude-config.md +23 -4
  109. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +142 -0
  110. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +100 -0
  111. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +73 -0
  112. package/dist/orchestrator/templates/ai-instructions/claude-skill-delivery.md +103 -0
  113. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +68 -13
  114. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
  115. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +54 -3
  116. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -15
  117. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +6 -4
  118. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +71 -0
  119. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +38 -14
  120. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +23 -4
  121. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +142 -0
  122. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +100 -0
  123. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +73 -0
  124. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +103 -0
  125. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +88 -13
  126. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
  127. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +54 -3
  128. package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -1
  129. package/dist/orchestrator/templates/playwright.config.js +6 -1
  130. package/dist/orchestrator/templates/playwright.config.js.map +1 -1
  131. package/dist/orchestrator/templates/playwright.config.ts +6 -1
  132. package/dist/orchestrator/templates/specs-base.d.ts +12 -1
  133. package/dist/orchestrator/templates/specs-base.d.ts.map +1 -1
  134. package/dist/orchestrator/templates/specs-base.js +47 -5
  135. package/dist/orchestrator/templates/specs-base.js.map +1 -1
  136. package/dist/orchestrator/templates/specs-base.ts +65 -7
  137. package/dist/orchestrator/templates/specs-test-data.d.ts +14 -0
  138. package/dist/orchestrator/templates/specs-test-data.d.ts.map +1 -0
  139. package/dist/orchestrator/templates/specs-test-data.js +100 -0
  140. package/dist/orchestrator/templates/specs-test-data.js.map +1 -0
  141. package/dist/orchestrator/templates/specs-test-data.ts +66 -0
  142. package/package.json +2 -1
  143. package/src/cli/commands/delivery.ts +348 -0
  144. package/src/cli/commands/generate.ts +2 -0
  145. package/src/cli/commands/update.ts +84 -2
  146. package/src/cli/index.ts +4 -2
  147. package/src/exporters/csv-exporter.ts +304 -0
  148. package/src/exporters/feature-parser.ts +168 -0
  149. package/src/exporters/package-info.ts +35 -0
  150. package/src/exporters/playwright-report-parser.ts +168 -0
  151. package/src/exporters/scenario-merger.ts +63 -0
  152. package/src/exporters/spec-parser.ts +247 -0
  153. package/src/exporters/step-formatter.ts +80 -0
  154. package/src/exporters/test-data-resolver.ts +59 -0
  155. package/src/exporters/types.ts +112 -0
  156. package/src/exporters/xlsx-exporter.ts +301 -0
  157. package/src/generators/gherkin-parser/index.ts +4 -0
  158. package/src/generators/test-generator/adapters/adapter-interface.ts +12 -1
  159. package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +14 -2
  160. package/src/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
  161. package/src/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
  162. package/src/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
  163. package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  164. package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
  165. package/src/generators/test-generator/code-generator.ts +122 -13
  166. package/src/generators/test-generator/step-mapper.ts +2 -2
  167. package/src/generators/test-generator/template-engine.ts +28 -2
  168. package/src/generators/test-generator/utils/data-resolver.ts +45 -27
  169. package/src/generators/test-generator/utils/runtime-data-transformer.ts +51 -0
  170. package/src/generators/test-generator/utils/selector-resolver.ts +26 -0
  171. package/src/generators/types.ts +1 -0
  172. package/src/orchestrator/ai-rules-updater.ts +12 -0
  173. package/src/orchestrator/project-initializer.ts +187 -80
  174. package/src/orchestrator/screen-manager.ts +2 -0
  175. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +15 -17
  176. package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +7 -5
  177. package/src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md +71 -0
  178. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +28 -1
  179. package/src/orchestrator/templates/ai-instructions/claude-config.md +23 -4
  180. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +142 -0
  181. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +100 -0
  182. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +73 -0
  183. package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +103 -0
  184. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +68 -13
  185. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
  186. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +54 -3
  187. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -15
  188. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +6 -4
  189. package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +71 -0
  190. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +38 -14
  191. package/src/orchestrator/templates/ai-instructions/copilot-config.md +23 -4
  192. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +142 -0
  193. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +100 -0
  194. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +73 -0
  195. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +103 -0
  196. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +88 -13
  197. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
  198. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +54 -3
  199. package/src/orchestrator/templates/playwright.config.ts +6 -1
  200. package/src/orchestrator/templates/specs-base.ts +65 -7
  201. package/src/orchestrator/templates/specs-test-data.ts +66 -0
@@ -109,6 +109,8 @@ Row scope: `see [Ref] row in [Table] table with {{v}}` enters scope. Subsequent
109
109
 
110
110
  Most elements auto-infer from `[Label] type` → `getByRole(type, { name: 'Label' })`. Only add YAML when the accessible name differs, needs `nth`, or needs `testid`. Full auto-infer table → see `sungen-selector-keys` skill.
111
111
 
112
+ **Types requiring YAML entry:** `date-picker`, `uploader`, `overlay`, `frame`, `step` - these have no standard ARIA role and need explicit selectors.
113
+
112
114
  ## YAML Keys
113
115
 
114
116
  `[Reference]` → **lowercase, keep Unicode**: `[Search Content]` → `search content:`, `[Thời gian]` → `thời gian:`
@@ -149,6 +151,14 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
149
151
  | `@no-auth` | Disable inherited auth |
150
152
  | `@steps:name` | Define reusable step block (base scenario) |
151
153
  | `@extend:name` | Prepend Given→When from @steps block (skip Then) |
154
+ | `@cleanup:overlay` | Auto-cleanup: dismiss dialogs/overlays after each test (base.ts fixture) |
155
+ | `@cleanup:forms` | Auto-cleanup: clear form fields after each test (base.ts fixture) |
156
+ | `@cleanup:scroll` | Auto-cleanup: scroll to top after each test (base.ts fixture) |
157
+ | `@cleanup:storage` | Auto-cleanup: clear sessionStorage after each test (base.ts fixture) |
158
+ | `@screenshot:on-failure` | Auto-capture screenshot when test fails (base.ts fixture) |
159
+ | `@beforeAll` | Hook: runs once before all tests → `test.beforeAll()` |
160
+ | `@afterEach` | Hook: runs after each test → `test.afterEach()` (custom cleanup) |
161
+ | `@afterAll` | Hook: runs once after all tests → `test.afterAll()` |
152
162
 
153
163
  ### @extend behavior
154
164
 
@@ -173,30 +183,28 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
173
183
  | Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
174
184
  | State as value | `with {{disabled}}` | `is disabled` |
175
185
  | Missing target type | `fill [email] with {{v}}` | `fill [email] field with {{v}}` |
176
- | Using Background | `Background: Given User is on...` | Use `@steps` + `@extend` instead |
186
+ | Background with scope | `Background: ... And User is on [X] dialog` | Use `@steps` + `@extend` for scope-dependent flows |
177
187
  | `is on` after When | `When ... And User is on [X] dialog` | `And User see [X] dialog` or separate Given |
178
188
 
179
189
  ## Background vs @steps/@extend
180
190
 
181
- **Do NOT use `Background:` block.** Use `@steps` + `@extend` instead.
191
+ Both `Background` and `@steps`/`@extend` are valid — they serve different purposes.
182
192
 
183
- **Why:**
184
- - `Background` runs before EVERY scenario but cannot set dialog/frame scope correctly
185
- - `Background` with `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When)
186
- - `@steps` + `@extend` gives explicit control: base steps run Given→When, extending scenario starts with `Given User is on [X] dialog` (correct scope setup)
193
+ | Pattern | Use when | Generates |
194
+ |---|---|---|
195
+ | `Background` | Simple shared setup (navigate to page) | `test.beforeEach()` |
196
+ | `@steps`/`@extend` | Complex reusable flows with scope (dialog, frame) | Inline merged steps in `test()` |
187
197
 
188
- **Wrong:**
198
+ **Use `Background` for simple navigation:**
189
199
  ```gherkin
190
200
  Background:
191
- Given User is on [Kudos] page
192
- When User click [Open] button
193
- And User is on [Modal] dialog ← keyword mismatch
201
+ Given User is on [Dashboard] page
194
202
 
195
- Scenario: VP-UI-001 Title visible
196
- Then User see [Title] heading
203
+ Scenario: View stats
204
+ Then User see [Revenue Chart] section
197
205
  ```
198
206
 
199
- **Correct:**
207
+ **Use `@steps`/`@extend` when scope matters (dialog, frame):**
200
208
  ```gherkin
201
209
  @steps:open_modal
202
210
  Scenario: Open modal
@@ -209,3 +217,50 @@ Scenario: VP-UI-001 Title visible
209
217
  Given User is on [Modal] dialog
210
218
  Then User see [Title] heading
211
219
  ```
220
+
221
+ **Avoid `Background` with scope-dependent steps** — `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When). Use `@steps`/`@extend` instead.
222
+
223
+ ## Hooks & Cleanup
224
+
225
+ Two layers for test lifecycle management. Prefer `@cleanup:*` tags (Layer 1) — they work with base.ts automatically. Use hook scenarios (Layer 2) only for custom logic.
226
+
227
+ ### Layer 1: `@cleanup:*` tags (automatic via base.ts)
228
+
229
+ Feature-level tags that activate cleanup fixtures in base.ts. No Gherkin steps needed.
230
+
231
+ ```gherkin
232
+ @auth:admin
233
+ @cleanup:overlay
234
+ @cleanup:forms
235
+ Feature: User Management
236
+ Path: /users
237
+
238
+ Background:
239
+ Given User is on [User Management] page
240
+
241
+ Scenario: Create user shows form
242
+ When User click [Add User] button
243
+ Then User see [Create User] dialog
244
+
245
+ Scenario: Search user by name
246
+ When User fill [Search] field with {{search_name}}
247
+ Then User see [User Row] row
248
+ ```
249
+
250
+ | Tag | What base.ts does after each test |
251
+ |---|---|
252
+ | `@cleanup:overlay` | Press Escape, click body, dismiss fixed overlays |
253
+ | `@cleanup:forms` | Clear all input/textarea fields, reset selects |
254
+ | `@cleanup:scroll` | Scroll to top of page |
255
+ | `@cleanup:storage` | Clear sessionStorage |
256
+
257
+ ### Layer 2: `@afterEach` scenario (custom cleanup)
258
+
259
+ Only when `@cleanup:*` tags aren't enough — feature-specific logic.
260
+
261
+ ### Layer 3: `@beforeAll` / `@afterAll` (optional)
262
+
263
+ For one-time setup/teardown.
264
+
265
+ **Rendering order in `.spec.ts`:**
266
+ `test.describe` → `test.use(storageState)` → `test.use(autoCleanup)` → `test.beforeAll` → `test.beforeEach` → `test.afterEach` → `test.afterAll` → `test()` blocks
@@ -102,5 +102,27 @@ If no YAML key exists, the resolver infers from the Gherkin element type:
102
102
  | `[X] list` | `getByRole('list', { name: 'X' })` |
103
103
  | `[X] column` | `getByRole('columnheader', { name: 'X' })` |
104
104
  | `[X] dialog` / `modal` / `drawer` | `getByRole('dialog', { name: 'X' })` |
105
+ | `[X] dropdown` / `select` | `getByRole('combobox', { name: 'X' })` |
106
+ | `[X] menuitem` | `getByRole('menuitem', { name: 'X' })` |
107
+ | `[X] progressbar` | `getByRole('progressbar', { name: 'X' })` |
108
+ | `[X] section` | `getByRole('region', { name: 'X' })` |
109
+ | `[X] card` | `getByRole('article', { name: 'X' })` |
110
+ | `[X] item` | `getByRole('listitem', { name: 'X' })` |
111
+ | `[X] cell` | `getByRole('cell', { name: 'X' })` |
112
+ | `[X] spinner` | `getByRole('status', { name: 'X' })` |
113
+ | `[X] breadcrumb` | `getByRole('navigation', { name: 'X' })` |
114
+ | `[X] badge` / `tooltip` / `tag` | `getByText('X')` |
105
115
 
106
116
  **Only add a YAML entry when** the auto-inferred locator won't work (wrong name, need testid, need nth, etc.).
117
+
118
+ ### Types requiring YAML entry (no auto-infer)
119
+
120
+ These types need explicit `selectors.yaml` entries:
121
+
122
+ | Type | Reason |
123
+ |------|--------|
124
+ | `date-picker` | Custom component, needs testid or CSS |
125
+ | `uploader` | File input, needs upload type selector |
126
+ | `overlay` | No standard ARIA role, needs CSS/testid |
127
+ | `frame` | Needs iframe selector |
128
+ | `step` | Custom stepper component, needs testid |
@@ -112,20 +112,59 @@ Given User is on [Screen] page
112
112
  And User wait for [Page Title] heading is visible
113
113
  ```
114
114
 
115
+ ## Cleanup & Hooks
116
+
117
+ ### Auto-assign `@cleanup:*` tags based on screen sections
118
+
119
+ After identifying screen sections, add appropriate `@cleanup:*` feature-level tags. These activate base.ts fixtures that auto-clean state between tests.
120
+
121
+ | Screen has | Add tag | Why |
122
+ |---|---|---|
123
+ | Modal / Dialog / Drawer | `@cleanup:overlay` | Dismiss leftover overlays between tests |
124
+ | Form & Inputs / Search / Filter | `@cleanup:forms` | Clear form fields, reset selects |
125
+ | Long scrollable content | `@cleanup:scroll` | Scroll to top for consistent assertions |
126
+ | Auth tokens / session data in tests | `@cleanup:storage` | Clear sessionStorage |
127
+ | CI/CD or debug-heavy screens | `@screenshot:on-failure` | Auto-capture screenshot on test failure |
128
+
129
+ **Always add `@cleanup:overlay`** if ANY section opens a dialog (Create/Add, Update/Edit, Delete confirmation). Most CRUD screens need it.
130
+
131
+ **Always add `@cleanup:forms`** if the screen has inline search, filter dropdowns, or editable forms that persist between tests.
132
+
133
+ ### When to add `@afterEach` hook scenario
134
+
135
+ Only when `@cleanup:*` tags aren't enough — feature-specific cleanup logic:
136
+ - Reset a dropdown filter to default value (not just clear)
137
+ - Navigate away from a sub-tab back to the main tab
138
+ - Close a specific sidebar panel
139
+
140
+ ```gherkin
141
+ @afterEach
142
+ Scenario: Reset filters to default
143
+ When User select [Status Filter] dropdown with {{default_status}}
144
+ ```
145
+
146
+ ### `@beforeAll` / `@afterAll` — optional, low priority
147
+
148
+ For one-time setup/teardown. Most screens don't need these.
149
+
115
150
  ## Output Format
116
151
 
117
152
  **Feature file** — `qa/screens/<screen>/features/<screen>.feature`
118
153
 
119
- **Never use `Background:`.** Use `@steps` + `@extend` for shared setup (see `sungen-gherkin-syntax` skill).
154
+ `Background` is valid for simple shared setup (navigate to page). Use `@steps`/`@extend` for complex flows with scope (dialog, frame).
120
155
 
121
156
  ```gherkin
122
157
  @auth:role
158
+ @cleanup:overlay
159
+ @cleanup:forms
123
160
  Feature: <Screen> Screen
124
161
 
162
+ Background:
163
+ Given User is on [Screen] page
164
+
125
165
  # Shared setup — NO priority tag on @steps
126
166
  @steps:open_form
127
167
  Scenario: Open form
128
- Given User is on [Screen] page
129
168
  When User click [Create] button
130
169
  Then User see [Form] dialog
131
170
 
@@ -165,6 +204,18 @@ Feature: <Screen> Screen
165
204
 
166
205
  **Naming**: `VP-<CATEGORY>-<NNN>` prefix. Scenario name must use the **same element type** as the steps — e.g., if the step uses `dialog`, write "dialog opens" not "modal opens".
167
206
 
168
- **Test data** — `qa/screens/<screen>/test-data/<screen>.yaml`, grouped by section.
207
+ **Test data** — `qa/screens/<screen>/test-data/<screen>.yaml`, grouped by section. Data is loaded **at runtime** — keys become runtime lookups, not hardcoded strings. The same compiled test works across environments.
208
+
209
+ **Environment-specific data**: For values that differ per environment (credentials, URLs, test users), create `<screen>.<env>.yaml` alongside the base file. Users run `SUNGEN_ENV=staging npx playwright test` to merge overrides. Structure env YAML with the same keys, only including values that change:
210
+
211
+ ```yaml
212
+ # login.yaml (base)
213
+ valid_email: admin@dev.example.com
214
+ valid_password: DevPass123
215
+
216
+ # login.staging.yaml (override for staging)
217
+ valid_email: admin@staging.example.com
218
+ valid_password: StagingPass456
219
+ ```
169
220
 
170
221
  **Do NOT generate**: `selectors.yaml` (created during run-test), Playwright code (sungen compiles).
@@ -24,27 +24,25 @@ Run with #tool:terminal:
24
24
  sungen add --screen ${input:screen} --path ${input:path}
25
25
  ```
26
26
 
27
- ### 2. Prepare requirements
27
+ ### 2. Fill spec.md
28
28
 
29
- Ask the user to choose how to prepare requirements this is the foundation for high-quality test generation:
29
+ Ask: *"Fill `spec.md` now?"* offer **1) Yes, fill now (Recommended)** / **2) Skip, fill later**.
30
30
 
31
- - **Fill `spec.md` + capture live-page screenshot** (Recommended)best test quality
32
- - **Fill `spec.md` only** — app not live yet, or no need for visuals
33
- - **Capture live-page screenshot only** — spec will come later
34
- - **Skip requirements prep** — proceed to `/sungen-create-test` immediately
31
+ If yes → open `qa/screens/${input:screen}/requirements/spec.md` and help the user fill sections, fields, validation rules, business rules, and states. Especially prompt for the optional **Figma URL** and **Live URL** fields in Overview those unlock auto-capture without re-asking next run.
35
32
 
36
- **If "Fill `spec.md`" is chosen**: open `qa/screens/${input:screen}/requirements/spec.md` and help the user fill sections, fields, validation rules, business rules, and states.
33
+ ### 3. Capture visual source
37
34
 
38
- **If "Capture live-page screenshot" is chosen**:
39
- 1. Read `baseURL` from `playwright.config.ts` (fall back to `APP_BASE_URL` env, then ask the user).
40
- 2. `browser_navigate` to `<baseURL>${input:path}`.
41
- 3. If redirected to login → ask the user to log in manually in the MCP browser, wait for confirmation, then re-navigate. (No auth persistence needed here — that's handled by Phase 0.5 in `sungen-selector-fix` when tests run.)
42
- 4. `browser_take_screenshot` with `filename: "qa/screens/${input:screen}/requirements/ui/${input:screen}.png"`.
43
- 5. If the screen has multiple important states (empty, loaded, error, modal open), offer additional captures named `${input:screen}-<state>.png`.
35
+ Ask the user to pick a visual source. Always offer all three so pre-launch projects work:
44
36
 
45
- If the user has additional UI designs (Figma exports, mockups), suggest copying them to `requirements/ui/`.
37
+ - **1) Figma design** (Recommended for pre-launch) invoke `sungen-capture-figma` skill
38
+ - **2) Live page scan** (dev/staging is up) — invoke `sungen-capture-live` skill
39
+ - **3) Skip** — user will drop images manually into `requirements/ui/` later, or rely on `/sungen-create-test` to prompt again
46
40
 
47
- ### 3. Next steps
41
+ Each capture skill writes outputs into `qa/screens/${input:screen}/requirements/ui/` and reports back. Do not inline capture logic here — delegate to the skill so behavior stays consistent with `/sungen-create-test`.
42
+
43
+ If the user has additional UI designs (mockups, hand-drawn sketches), suggest copying them to `requirements/ui/` — `sungen-capture-local` will pick them up during `/sungen-create-test`.
44
+
45
+ ### 4. Next steps
48
46
 
49
47
  Tell the user what was created and offer next steps:
50
48
 
@@ -28,10 +28,12 @@ You are a **Senior QA Engineer**. You structure test cases by viewpoint categori
28
28
  - **2) Continue without it** — generate tests from spec and other sources only
29
29
  - Summarize what you found in requirements and present to the user.
30
30
  4. **Screen input** (supplements requirements, or is primary source if no requirements):
31
- - Ask: "How should I get the screen design? **1) Figma design** (provide Figma URL recommended), **2) UI images** (screenshots/mockups in `requirements/ui/`), or **3) Live page scan** (optional, via Playwright MCP)?"
32
- - Recommend Figma or UI images first. Live page scan is optional useful to verify specs vs actual UI or capture real data.
33
- - If live page: `browser_navigate` ONE `browser_snapshot`. If auth redirect → ask user to log in manually. Never use `browser_run_code` or `browser_evaluate` to inject cookies.
34
- - If exploring, verify and supplement requirementsflag any discrepancies found.
31
+ - Ask the user to pick a visual source. Always offer all three so pre-launch projects work:
32
+ - **1) Figma design** (Recommended for pre-launch)invoke `sungen-capture-figma` skill
33
+ - **2) UI images** (existing screenshots/mockups in `requirements/ui/`) invoke `sungen-capture-local` skill
34
+ - **3) Live page scan** (dev/staging is up) invoke `sungen-capture-live` skill
35
+ - Each capture skill writes outputs into `qa/screens/${input:screen}/requirements/ui/` and reports back. Do not inline capture logic here — delegate to the skill so behavior stays consistent.
36
+ - After the capture skill returns, cross-check its output against `spec.md` and flag any discrepancies before moving on.
35
37
  5. Identify screen sections → ask user which to focus on (per `sungen-tc-generation` skill). When requirements exist, use the "Requirements-Driven Generation" strategy. Present sections as a numbered list and let user pick.
36
38
  6. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
37
39
  7. Show summary and offer next steps:
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: delivery
3
+ description: 'Export Gherkin scenarios + Playwright results to CSV test case file for QA delivery.'
4
+ argument-hint: "[screen-name...] (omit for all screens)"
5
+ allowed-tools: Bash, Read, AskUserQuestion
6
+ ---
7
+
8
+ ## Role
9
+
10
+ You are a **QA Test Delivery Engineer**. Your job is to invoke the deterministic `sungen delivery` CLI that performs all parsing and CSV export. Your role is minimal — just run the CLI and help the user if pre-flight checks fail.
11
+
12
+ ## Parameters
13
+
14
+ Parse **screens** from `$ARGUMENTS`:
15
+ - If empty → CLI will process **all** screens in `qa/screens/`
16
+ - If provided → pass them through to the CLI
17
+
18
+ ## Steps
19
+
20
+ ### 1. Invoke the CLI
21
+
22
+ Run via Bash (single command, no extra parsing):
23
+
24
+ ```bash
25
+ npx sungen delivery <screens>
26
+ ```
27
+
28
+ - If no screen args → just run `npx sungen delivery`
29
+ - If screen args → pass them as positional arguments
30
+
31
+ The CLI handles:
32
+ - Scope detection (all screens vs specific)
33
+ - Pre-flight source checks with colorful output
34
+ - Parsing `.feature`, `.spec.ts`, `test-data.yaml`, `test-results/results.json`
35
+ - Generating CSV at `qa/deliverables/<screen>-testcases.csv`
36
+ - Printing summary table
37
+
38
+ ### 2. Handle pre-flight failures (if CLI exits non-zero)
39
+
40
+ If the CLI exits with blocking issues, it will have already printed a clear table showing exactly what's missing per screen.
41
+
42
+ Use `AskUserQuestion` to offer next steps:
43
+
44
+ **Options:**
45
+ - **Fix missing sources** (Recommended) — Print the suggested commands from CLI output and stop. User will run those commands manually, then re-invoke `/sungen:delivery`.
46
+ - **Continue with available screens** — Re-run as `npx sungen delivery <screens> --continue-on-missing` to skip screens with blocking issues.
47
+ - **Cancel** — Exit.
48
+
49
+ ### 3. Show summary + offer next steps (on success)
50
+
51
+ Forward the CLI's summary table to the user verbatim. Then use `AskUserQuestion`:
52
+
53
+ - **Open a specific CSV** — Help user inspect one of the exported files with Read tool.
54
+ - **Run tests to refresh results** — Suggest `/sungen:run-test <screen>` to update `test-results/results.json`, then re-run delivery.
55
+ - **Export another screen** — User can run `/sungen:delivery <other-screen>`.
56
+ - **Done** — Exit.
57
+
58
+ ## Important notes
59
+
60
+ - **Do NOT parse files yourself** — the CLI is the source of truth for parsing logic. Your job is orchestration + user interaction.
61
+ - **Do NOT modify feature/spec.ts/test-data files** — the delivery is read-only.
62
+ - **The CLI already respects `@manual` tags, skips `@steps:` base scenarios, groups by Category 2, and generates UTF-8 BOM CSV for Excel compatibility with Vietnamese.**
63
+ - **Pre-flight check is built into the CLI** — use `--skip-preflight` only in CI/automated pipelines where checks are done externally.
64
+
65
+ ## CLI Reference
66
+
67
+ ```
68
+ sungen delivery [screens...]
69
+ [--skip-preflight] Skip pre-flight checks (not recommended)
70
+ [--continue-on-missing] Skip screens with blocking misses
71
+ ```
@@ -1,27 +1,24 @@
1
1
  ---
2
- name: sungen-run-test
3
- description: 'Generate selectors + auth state via Playwright MCP, compile, and run Playwright tests — auto-fixes selectors on failure. Uses sungen-selector-fix, sungen-selector-keys, and sungen-error-mapping skills.'
4
- argument-hint: '[screen-name]'
5
- agent: 'agent'
6
- tools: [vscode, execute, read, agent, edit, search, web, browser, todo, 'playwright/*']
2
+ name: run-test
3
+ description: 'Generate selectors + auth state via Playwright MCP, compile, and run Playwright tests — auto-fixes selectors on failure'
4
+ argument-hint: [screen-name]
5
+ allowed-tools: Read, Grep, Bash, Glob, Edit, Write, AskUserQuestion, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_wait_for, mcp__playwright__browser_evaluate, mcp__playwright__browser_run_code, mcp__playwright__browser_storage_state, mcp__playwright__browser_set_storage_state
7
6
  ---
8
7
 
9
- **Input**: Screen name (e.g., `/sungen-run-test admin-users`).
10
-
11
8
  ## Role
12
9
 
13
10
  You are a **Senior Developer**. Use `sungen-selector-fix`, `sungen-selector-keys`, and `sungen-error-mapping` skills.
14
11
 
15
12
  ## Parameters
16
13
 
17
- - **screen** ${input:screen:screen name (e.g., login, dashboard)}
14
+ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
18
15
 
19
16
  ## Pre-run (phased — per `sungen-selector-fix` skill)
20
17
 
21
- 1. Verify `qa/screens/${input:screen}/` has `.feature` + `test-data.yaml`.
18
+ 1. Verify `qa/screens/<screen>/` has `.feature` + `test-data.yaml`.
22
19
  2. **Phase 0 — Selector Pre-gen**: if `selectors.yaml` is missing/empty or doesn't cover the feature file's `[Reference]`s, run Phase 0 from `sungen-selector-fix` — confirm with user, `browser_navigate` → one `browser_snapshot` → merge YAML entries.
23
20
  3. **Phase 0.5 — Auth Persistence**: if the feature has `@auth:<role>` tags and `specs/.auth/<role>.json` is missing/expired, run Phase 0.5 from `sungen-selector-fix` — user logs in manually in MCP browser → `browser_storage_state` → `specs/.auth/<role>.json`. Offer `sungen makeauth <role>` as CLI fallback only if `browser_storage_state` isn't available in this MCP version.
24
- 4. Compile: `sungen generate --screen ${input:screen}`.
21
+ 4. Compile: `sungen generate --screen <screen>` (default: runtime data loading from YAML). Use `--inline-data` only if user requests compile-time hardcoded values.
25
22
 
26
23
  ## Run & Fix (phased — per `sungen-selector-fix` skill)
27
24
 
@@ -30,15 +27,42 @@ You are a **Senior Developer**. Use `sungen-selector-fix`, `sungen-selector-keys
30
27
  7. **Phase 3 — Full Run**: Run all tests. Fix only **new** failures (elements unique to `@normal`/`@low`). Max 1 attempt. Don't loop on low-priority failures.
31
28
  8. **Phase 4 — Regression**: One final full run. Report results. No more fix loops.
32
29
 
30
+ ## Playwright command guidelines
31
+
32
+ **Per-screen JSON results** — each run must write its JSON report to a dedicated path co-located with the `.spec.ts`, so `sungen delivery` can read the correct results per screen:
33
+
34
+ ```bash
35
+ # ✅ Correct — per-screen output file via env var
36
+ PLAYWRIGHT_JSON_OUTPUT_NAME=specs/generated/<screen>/<screen>-test-result.json \
37
+ npx playwright test specs/generated/<screen>/<screen>.spec.ts
38
+ ```
39
+
40
+ Output: `specs/generated/<screen>/<screen>-test-result.json`
41
+
42
+ **DO NOT** pass `--reporter=...` flag — it overrides the reporters from `playwright.config.ts` and disables the JSON reporter that `sungen delivery` depends on.
43
+
44
+ ```bash
45
+ # ❌ Wrong — --reporter flag disables the config's JSON reporter
46
+ npx playwright test specs/generated/<screen>/<screen>.spec.ts --reporter=list
47
+
48
+ # ❌ Wrong — no env var → writes to default test-results/results.json
49
+ # (overwritten on every screen run, loses per-screen tracking)
50
+ npx playwright test specs/generated/<screen>/<screen>.spec.ts
51
+ ```
52
+
53
+ If you want to filter scenarios, use `-g "<pattern>"` instead of a reporter override.
54
+
55
+ `sungen delivery` reads the per-screen file first, falls back to the global `test-results/results.json` if missing.
56
+
33
57
  ## Next steps
34
58
 
35
- After showing results, offer next steps:
59
+ After showing results, use `AskUserQuestion` to offer next steps:
36
60
 
37
61
  If all tests **passed**:
38
- - **`/sungen-create-test ${input:screen}`** — Add more test cases (Recommended)
62
+ - **`/sungen:create-test <screen>`** — Add more test cases (Recommended)
39
63
  - **Done** — All tests passed, I'm finished
40
64
 
41
65
  If tests **failed** (after retries):
42
- - **`/sungen-run-test ${input:screen}`** — Re-run after manual fixes
43
- - **`/sungen-create-test ${input:screen}`** — Revise test cases
66
+ - **`/sungen:run-test <screen>`** — Re-run after manual fixes
67
+ - **`/sungen:create-test <screen>`** — Revise test cases
44
68
  - **Done for now** — I'll fix manually later
@@ -15,8 +15,12 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
15
15
  | `sungen-viewpoint` | 10 UI patterns x 4 viewpoints — coverage checklists |
16
16
  | `sungen-selector-keys` | YAML key generation from `[Reference]` names, suffixes, lookup priority |
17
17
  | `sungen-selector-fix` | Selector generation from live page, auto-fix strategy |
18
+ | `sungen-delivery` | Export Gherkin + Playwright results → CSV test case deliverable |
19
+ | `sungen-capture-figma` | Fetch design context + PNG from a Figma frame URL via Figma Dev Mode MCP |
20
+ | `sungen-capture-local` | Load existing UI assets (screenshots, mockups, Figma exports) from `requirements/ui/` |
21
+ | `sungen-capture-live` | Capture a live running page via Playwright MCP (snapshot + screenshot) |
18
22
 
19
- ## Workflow (4 AI commands)
23
+ ## Workflow (5 AI commands)
20
24
 
21
25
  | Command | What it does |
22
26
  |---|---|
@@ -24,8 +28,9 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
24
28
  | `/sungen-create-test <name>` | Generate `.feature` + `test-data.yaml` (no selectors) |
25
29
  | `/sungen-review <name>` | Score syntax, coverage, viewpoint quality (60% threshold) |
26
30
  | `/sungen-run-test <name>` | Generate `selectors.yaml` from live page, compile, run, auto-fix |
31
+ | `/sungen-delivery [name...]` | Export test cases → CSV for QA delivery (all screens if no arg) |
27
32
 
28
- **Order:** add-screen → create-test → review → run-test.
33
+ **Order:** add-screen → create-test → review → run-test → delivery.
29
34
 
30
35
  After each command completes, present the next actions as selectable options. Never just print text — always give clickable choices so the user can continue the workflow seamlessly.
31
36
 
@@ -35,17 +40,31 @@ After each command completes, present the next actions as selectable options. Ne
35
40
  qa/screens/<screen-name>/
36
41
  ├── features/<screen>.feature # Gherkin scenarios
37
42
  ├── selectors/<screen>.yaml # Element locators (generated during run-test)
38
- ├── test-data/<screen>.yaml # Test data variables
43
+ ├── test-data/<screen>.yaml # Test data variables (loaded at runtime)
44
+ ├── test-data/<screen>.staging.yaml # Environment override (optional)
45
+ ├── test-data/<screen>.production.yaml # Environment override (optional)
39
46
  └── requirements/
40
47
  ├── spec.md # Screen specification (primary source)
41
48
  └── ui/ # Screenshots, mockups
49
+
50
+ qa/deliverables/<screen>-testcases.csv # Exported test cases (from /sungen-delivery)
51
+ qa/deliverables/<screen>-testcases.xlsx # Styled workbook for client hand-off
42
52
  ```
43
53
 
54
+ ## Test Data
55
+
56
+ `{{variable}}` references in `.feature` map to keys in `test-data/<screen>.yaml`. Data is loaded **at runtime** — the same generated `.spec.ts` works across environments without recompiling.
57
+
58
+ **Environment overrides**: `SUNGEN_ENV=staging npx playwright test` merges `<screen>.staging.yaml` on top of `<screen>.yaml`. Create `<screen>.<env>.yaml` for environment-specific values (different credentials, URLs, test users).
59
+
44
60
  ## CLI Commands
45
61
 
46
62
  ```bash
47
63
  sungen add --screen <name> --path <url-path> # Scaffold screen directories
48
64
  sungen add --screen <name> --path <path> --feature <name> # Scaffold with sub-feature
49
- sungen generate --screen <name> # Compile .feature → .spec.ts
65
+ sungen generate --screen <name> # Compile .feature → .spec.ts (runtime data)
66
+ sungen generate --screen <name> --inline-data # Compile with hardcoded data (legacy)
50
67
  sungen generate --all # Compile all screens
68
+ sungen delivery # Export all screens → CSV + XLSX
69
+ sungen delivery <screen> # Export a single screen
51
70
  ```
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: sungen-capture-figma
3
+ description: 'Fetch design context + PNG from a Figma frame URL via Figma Dev Mode MCP. Auto-loaded by create-test when user picks Figma as the visual source.'
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## Purpose
8
+
9
+ Pull **structured design data** (layout, typography, colors, component tree, design tokens) and a **PNG screenshot** from a Figma frame URL, so `sungen-tc-generation` can author Gherkin + test-data before a live domain exists.
10
+
11
+ Use this when the project is pre-launch, or when Figma is the source of truth and the live build lags the design.
12
+
13
+ ---
14
+
15
+ ## Prerequisites
16
+
17
+ - **Figma MCP server** (`https://mcp.figma.com/mcp`, HTTP transport) connected in `.vscode/mcp.json` — `sungen init` scaffolds this automatically. On first use, VS Code / Copilot opens a browser for Figma OAuth. Official tools: `get_design_context`, `get_variable_defs`, `get_screenshot`.
18
+ - Figma account signed in with access to the file. **Dev/Full seats** get per-minute rate limits; **Starter/View seats** get monthly tool-call limits.
19
+ - A Figma URL with both **fileKey** and **nodeId** in it.
20
+
21
+ If the MCP is not connected, **do not fail silently** — tell the user:
22
+ > "Figma MCP not detected. Run `sungen init` to scaffold the config, or manually add `figma` with `url: https://mcp.figma.com/mcp` to `.vscode/mcp.json`. Then sign in when VS Code prompts."
23
+
24
+ Then stop.
25
+
26
+ ---
27
+
28
+ ## Steps
29
+
30
+ ### 1. Resolve Figma URL
31
+
32
+ Prefer in this order:
33
+
34
+ 1. `Figma URL` field in `qa/screens/<screen>/requirements/spec.md` (Overview section)
35
+ 2. If empty or missing → ask the user: *"Paste the Figma frame URL"*
36
+
37
+ Accept any of these URL shapes:
38
+
39
+ ```
40
+ https://www.figma.com/file/<fileKey>/<title>?node-id=<nodeId>
41
+ https://www.figma.com/design/<fileKey>/<title>?node-id=<nodeId>
42
+ https://www.figma.com/proto/<fileKey>/<title>?node-id=<nodeId>
43
+ ```
44
+
45
+ Parse:
46
+ - `fileKey` = the segment after `/file/`, `/design/`, or `/proto/`
47
+ - `nodeId` = the `node-id` query param (may use `-` or `:` — pass through as-is; MCP accepts both)
48
+
49
+ If `node-id` is missing, ask the user to select a frame in Figma and copy the **frame URL** specifically (not the file root URL).
50
+
51
+ ### 2. Fetch design context
52
+
53
+ Call **both** in parallel:
54
+
55
+ ```
56
+ get_design_context({ fileKey, nodeId })
57
+ get_variable_defs({ fileKey, nodeId })
58
+ ```
59
+
60
+ `get_design_context` returns layout, typography, color values, component structure, spacing.
61
+ `get_variable_defs` returns named design tokens (color/spacing/typography variables).
62
+
63
+ ### 3. Fetch screenshot
64
+
65
+ ```
66
+ get_screenshot({ fileKey, nodeId })
67
+ ```
68
+
69
+ Save the returned PNG to:
70
+
71
+ ```
72
+ qa/screens/<screen>/requirements/ui/figma-<sanitized-nodeId>.png
73
+ ```
74
+
75
+ Sanitize `nodeId` for filesystem: replace `:` and `-` with `_`. Example: `42-15` → `figma-42_15.png`.
76
+
77
+ ### 4. Write metadata dump
78
+
79
+ Combine the design context + variables into a Markdown summary at:
80
+
81
+ ```
82
+ qa/screens/<screen>/requirements/ui/figma-meta.md
83
+ ```
84
+
85
+ Format:
86
+
87
+ ```markdown
88
+ # Figma Capture — <nodeId>
89
+
90
+ **Source:** <full Figma URL>
91
+ **Captured:** <ISO date>
92
+
93
+ ## Components
94
+ <hierarchical list of component names + variants from get_design_context>
95
+
96
+ ## Typography
97
+ <font families, sizes, weights, line heights>
98
+
99
+ ## Colors
100
+ <color tokens + raw hex values>
101
+
102
+ ## Spacing & Layout
103
+ <spacing tokens, auto-layout specs>
104
+
105
+ ## Text Content
106
+ <visible text strings from the frame — used by tc-generation to populate test-data>
107
+ ```
108
+
109
+ This file is consumed by `sungen-tc-generation` as a secondary source alongside `spec.md`.
110
+
111
+ ### 5. Report back
112
+
113
+ Output a short summary to the user:
114
+
115
+ > Captured Figma frame `<nodeId>`:
116
+ > - Components: N
117
+ > - Text strings: M
118
+ > - Design tokens: K
119
+ > - Screenshot: `qa/screens/<screen>/requirements/ui/figma-<nodeId>.png`
120
+ > - Metadata: `requirements/ui/figma-meta.md`
121
+
122
+ Then hand back to the calling command.
123
+
124
+ ---
125
+
126
+ ## Error handling
127
+
128
+ | Error | Action |
129
+ |---|---|
130
+ | MCP tool not available | Print setup instructions, stop, do not fall back silently |
131
+ | `fileKey` missing from URL | Ask user to paste a valid frame URL |
132
+ | `nodeId` missing from URL | Ask user to right-click a frame in Figma → *Copy link to selection* |
133
+ | `get_design_context` 403 | Ask user to check Dev Mode seat on that file |
134
+ | `get_screenshot` returns no image | Continue with metadata only; warn user no PNG was captured |
135
+
136
+ ---
137
+
138
+ ## What this skill does NOT do
139
+
140
+ - Does not generate Gherkin (that's `sungen-tc-generation`)
141
+ - Does not write `selectors.yaml` (that's `/sungen-run-test`)
142
+ - Does not validate the design against live UI (future skill: `sungen-capture-live` can be run afterwards for cross-check)