@sun-asterisk/sungen 2.4.6 → 2.5.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 (206) hide show
  1. package/README.md +88 -7
  2. package/dist/cli/commands/add.d.ts.map +1 -1
  3. package/dist/cli/commands/add.js +109 -9
  4. package/dist/cli/commands/add.js.map +1 -1
  5. package/dist/cli/commands/figma.d.ts +11 -0
  6. package/dist/cli/commands/figma.d.ts.map +1 -0
  7. package/dist/cli/commands/figma.js +178 -0
  8. package/dist/cli/commands/figma.js.map +1 -0
  9. package/dist/cli/commands/generate.d.ts.map +1 -1
  10. package/dist/cli/commands/generate.js +2 -0
  11. package/dist/cli/commands/generate.js.map +1 -1
  12. package/dist/cli/index.js +4 -2
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/generators/gherkin-parser/index.d.ts +1 -0
  15. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  16. package/dist/generators/gherkin-parser/index.js +3 -0
  17. package/dist/generators/gherkin-parser/index.js.map +1 -1
  18. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +29 -1
  19. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
  20. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +21 -1
  21. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
  22. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js +11 -2
  23. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
  24. package/dist/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
  25. package/dist/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
  26. package/dist/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
  27. package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  28. package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
  29. package/dist/generators/test-generator/code-generator.d.ts +2 -0
  30. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  31. package/dist/generators/test-generator/code-generator.js +109 -12
  32. package/dist/generators/test-generator/code-generator.js.map +1 -1
  33. package/dist/generators/test-generator/step-mapper.d.ts +1 -0
  34. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  35. package/dist/generators/test-generator/step-mapper.js +1 -1
  36. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  37. package/dist/generators/test-generator/template-engine.d.ts +29 -1
  38. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  39. package/dist/generators/test-generator/template-engine.js +11 -2
  40. package/dist/generators/test-generator/template-engine.js.map +1 -1
  41. package/dist/generators/test-generator/utils/data-resolver.d.ts +11 -2
  42. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  43. package/dist/generators/test-generator/utils/data-resolver.js +36 -25
  44. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  45. package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts +7 -0
  46. package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts.map +1 -0
  47. package/dist/generators/test-generator/utils/runtime-data-transformer.js +42 -0
  48. package/dist/generators/test-generator/utils/runtime-data-transformer.js.map +1 -0
  49. package/dist/generators/types.d.ts +1 -0
  50. package/dist/generators/types.d.ts.map +1 -1
  51. package/dist/generators/types.js.map +1 -1
  52. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  53. package/dist/orchestrator/ai-rules-updater.js +2 -0
  54. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  55. package/dist/orchestrator/figma/figma-scaffolder-helpers.d.ts +33 -0
  56. package/dist/orchestrator/figma/figma-scaffolder-helpers.d.ts.map +1 -0
  57. package/dist/orchestrator/figma/figma-scaffolder-helpers.js +135 -0
  58. package/dist/orchestrator/figma/figma-scaffolder-helpers.js.map +1 -0
  59. package/dist/orchestrator/figma/figma-scaffolder-types.d.ts +25 -0
  60. package/dist/orchestrator/figma/figma-scaffolder-types.d.ts.map +1 -0
  61. package/dist/orchestrator/figma/figma-scaffolder-types.js +7 -0
  62. package/dist/orchestrator/figma/figma-scaffolder-types.js.map +1 -0
  63. package/dist/orchestrator/figma/figma-scaffolder.d.ts +23 -0
  64. package/dist/orchestrator/figma/figma-scaffolder.d.ts.map +1 -0
  65. package/dist/orchestrator/figma/figma-scaffolder.js +212 -0
  66. package/dist/orchestrator/figma/figma-scaffolder.js.map +1 -0
  67. package/dist/orchestrator/figma/node-path-collapser.d.ts +16 -0
  68. package/dist/orchestrator/figma/node-path-collapser.d.ts.map +1 -0
  69. package/dist/orchestrator/figma/node-path-collapser.js +37 -0
  70. package/dist/orchestrator/figma/node-path-collapser.js.map +1 -0
  71. package/dist/orchestrator/figma/spec-figma-renderer.d.ts +44 -0
  72. package/dist/orchestrator/figma/spec-figma-renderer.d.ts.map +1 -0
  73. package/dist/orchestrator/figma/spec-figma-renderer.js +45 -0
  74. package/dist/orchestrator/figma/spec-figma-renderer.js.map +1 -0
  75. package/dist/orchestrator/figma/spec-figma-section-renderers.d.ts +23 -0
  76. package/dist/orchestrator/figma/spec-figma-section-renderers.d.ts.map +1 -0
  77. package/dist/orchestrator/figma/spec-figma-section-renderers.js +47 -0
  78. package/dist/orchestrator/figma/spec-figma-section-renderers.js.map +1 -0
  79. package/dist/orchestrator/project-initializer.d.ts +9 -0
  80. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  81. package/dist/orchestrator/project-initializer.js +74 -10
  82. package/dist/orchestrator/project-initializer.js.map +1 -1
  83. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +56 -11
  84. package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +30 -17
  85. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +4 -3
  86. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +34 -2
  87. package/dist/orchestrator/templates/ai-instructions/claude-config.md +12 -2
  88. package/dist/orchestrator/templates/ai-instructions/claude-skill-figma-source.md +151 -0
  89. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +66 -13
  90. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +93 -23
  91. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +2 -0
  92. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +53 -9
  93. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +21 -16
  94. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +4 -3
  95. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +34 -2
  96. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +12 -2
  97. package/dist/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md +151 -0
  98. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-figma-source.md +151 -0
  99. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +86 -13
  100. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +61 -0
  101. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +105 -28
  102. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +20 -0
  103. package/dist/orchestrator/templates/specs-base.d.ts +12 -1
  104. package/dist/orchestrator/templates/specs-base.d.ts.map +1 -1
  105. package/dist/orchestrator/templates/specs-base.js +47 -5
  106. package/dist/orchestrator/templates/specs-base.js.map +1 -1
  107. package/dist/orchestrator/templates/specs-base.ts +65 -7
  108. package/dist/orchestrator/templates/specs-test-data.d.ts +14 -0
  109. package/dist/orchestrator/templates/specs-test-data.d.ts.map +1 -0
  110. package/dist/orchestrator/templates/specs-test-data.js +100 -0
  111. package/dist/orchestrator/templates/specs-test-data.js.map +1 -0
  112. package/dist/orchestrator/templates/specs-test-data.ts +66 -0
  113. package/dist/tools/figma/figma-auth.d.ts +36 -0
  114. package/dist/tools/figma/figma-auth.d.ts.map +1 -0
  115. package/dist/tools/figma/figma-auth.js +182 -0
  116. package/dist/tools/figma/figma-auth.js.map +1 -0
  117. package/dist/tools/figma/figma-cache.d.ts +45 -0
  118. package/dist/tools/figma/figma-cache.d.ts.map +1 -0
  119. package/dist/tools/figma/figma-cache.js +191 -0
  120. package/dist/tools/figma/figma-cache.js.map +1 -0
  121. package/dist/tools/figma/figma-client-types.d.ts +112 -0
  122. package/dist/tools/figma/figma-client-types.d.ts.map +1 -0
  123. package/dist/tools/figma/figma-client-types.js +7 -0
  124. package/dist/tools/figma/figma-client-types.js.map +1 -0
  125. package/dist/tools/figma/figma-errors.d.ts +49 -0
  126. package/dist/tools/figma/figma-errors.d.ts.map +1 -0
  127. package/dist/tools/figma/figma-errors.js +105 -0
  128. package/dist/tools/figma/figma-errors.js.map +1 -0
  129. package/dist/tools/figma/figma-image-downloader.d.ts +25 -0
  130. package/dist/tools/figma/figma-image-downloader.d.ts.map +1 -0
  131. package/dist/tools/figma/figma-image-downloader.js +128 -0
  132. package/dist/tools/figma/figma-image-downloader.js.map +1 -0
  133. package/dist/tools/figma/figma-node-filter.d.ts +26 -0
  134. package/dist/tools/figma/figma-node-filter.d.ts.map +1 -0
  135. package/dist/tools/figma/figma-node-filter.js +164 -0
  136. package/dist/tools/figma/figma-node-filter.js.map +1 -0
  137. package/dist/tools/figma/figma-rest-client.d.ts +24 -0
  138. package/dist/tools/figma/figma-rest-client.d.ts.map +1 -0
  139. package/dist/tools/figma/figma-rest-client.js +154 -0
  140. package/dist/tools/figma/figma-rest-client.js.map +1 -0
  141. package/dist/tools/figma/figma-url-parser.d.ts +18 -0
  142. package/dist/tools/figma/figma-url-parser.d.ts.map +1 -0
  143. package/dist/tools/figma/figma-url-parser.js +51 -0
  144. package/dist/tools/figma/figma-url-parser.js.map +1 -0
  145. package/dist/utils/exec-file-no-throw.d.ts +20 -0
  146. package/dist/utils/exec-file-no-throw.d.ts.map +1 -0
  147. package/dist/utils/exec-file-no-throw.js +36 -0
  148. package/dist/utils/exec-file-no-throw.js.map +1 -0
  149. package/package.json +1 -1
  150. package/src/cli/commands/add.ts +80 -9
  151. package/src/cli/commands/figma.ts +162 -0
  152. package/src/cli/commands/generate.ts +2 -0
  153. package/src/cli/index.ts +4 -2
  154. package/src/generators/gherkin-parser/index.ts +4 -0
  155. package/src/generators/test-generator/adapters/adapter-interface.ts +12 -1
  156. package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +14 -2
  157. package/src/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
  158. package/src/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
  159. package/src/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
  160. package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  161. package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
  162. package/src/generators/test-generator/code-generator.ts +122 -13
  163. package/src/generators/test-generator/step-mapper.ts +2 -2
  164. package/src/generators/test-generator/template-engine.ts +28 -2
  165. package/src/generators/test-generator/utils/data-resolver.ts +45 -27
  166. package/src/generators/test-generator/utils/runtime-data-transformer.ts +51 -0
  167. package/src/generators/types.ts +1 -0
  168. package/src/orchestrator/ai-rules-updater.ts +2 -0
  169. package/src/orchestrator/figma/figma-scaffolder-helpers.ts +126 -0
  170. package/src/orchestrator/figma/figma-scaffolder-types.ts +26 -0
  171. package/src/orchestrator/figma/figma-scaffolder.ts +209 -0
  172. package/src/orchestrator/figma/node-path-collapser.ts +38 -0
  173. package/src/orchestrator/figma/spec-figma-renderer.ts +80 -0
  174. package/src/orchestrator/figma/spec-figma-section-renderers.ts +46 -0
  175. package/src/orchestrator/project-initializer.ts +84 -10
  176. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +56 -11
  177. package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +30 -17
  178. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +4 -3
  179. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +34 -2
  180. package/src/orchestrator/templates/ai-instructions/claude-config.md +12 -2
  181. package/src/orchestrator/templates/ai-instructions/claude-skill-figma-source.md +151 -0
  182. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +66 -13
  183. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +93 -23
  184. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +2 -0
  185. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +53 -9
  186. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +21 -16
  187. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +4 -3
  188. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +34 -2
  189. package/src/orchestrator/templates/ai-instructions/copilot-config.md +12 -2
  190. package/src/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md +151 -0
  191. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-figma-source.md +151 -0
  192. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +86 -13
  193. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +61 -0
  194. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +105 -28
  195. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +20 -0
  196. package/src/orchestrator/templates/specs-base.ts +65 -7
  197. package/src/orchestrator/templates/specs-test-data.ts +66 -0
  198. package/src/tools/figma/figma-auth.ts +161 -0
  199. package/src/tools/figma/figma-cache.ts +184 -0
  200. package/src/tools/figma/figma-client-types.ts +125 -0
  201. package/src/tools/figma/figma-errors.ts +127 -0
  202. package/src/tools/figma/figma-image-downloader.ts +112 -0
  203. package/src/tools/figma/figma-node-filter.ts +198 -0
  204. package/src/tools/figma/figma-rest-client.ts +183 -0
  205. package/src/tools/figma/figma-url-parser.ts +55 -0
  206. package/src/utils/exec-file-no-throw.ts +45 -0
@@ -1,13 +1,21 @@
1
1
  ---
2
2
  name: create-test
3
- description: 'Create or update test cases for a Sungen screen — generates feature + test-data files (20+ scenarios per viewpoint)'
3
+ description: 'Create or update test cases for a Sungen screen — generates feature + test-data files (tier-based: critical+high first, expand later)'
4
4
  argument-hint: [screen-name]
5
- allowed-tools: Read, Grep, Bash, Glob, Write, AskUserQuestion, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_take_screenshot, mcp__figma__get_design_context, mcp__figma__get_variable_defs, mcp__figma__get_screenshot
5
+ allowed-tools: Read, Grep, Bash, Glob, Write, AskUserQuestion, Skill, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_take_screenshot
6
+ ---
7
+
8
+ ## ⛔ HARD RULE — No Figma MCP when PAT data exists
9
+
10
+ If `spec_figma.md` exists OR the user provides a Figma URL for the PAT flow:
11
+ - Do NOT call any `mcp__figma__*` tool. The PAT flow uses the `sungen` CLI, not MCP.
12
+ - Run `sungen add --screen <screen> --figma '<url>'` via Bash (**single-quote the URL**) then invoke `sungen-figma-source` skill.
13
+
6
14
  ---
7
15
 
8
16
  ## Role
9
17
 
10
- You are a **Senior QA Engineer** specialized in exhaustive test case design. You structure test cases by viewpoint categories and translate UI into comprehensive Gherkin test cases following the `sungen-gherkin-syntax` and `sungen-tc-generation` skills. Your focus is on **Gherkin scenarios and test data only** — selectors are handled later during `/sungen:run-test`.
18
+ You are a **Senior QA Engineer** specialized in test case design. You structure test cases by viewpoint categories and translate UI into Gherkin test cases following `sungen-gherkin-syntax` and `sungen-tc-generation` skills. **Tier 1 (critical+high) first** — expand coverage later. Focus on **Gherkin scenarios and test data only** — selectors are handled during `/sungen:run-test`.
11
19
 
12
20
  ## Parameters
13
21
 
@@ -17,27 +25,32 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
17
25
 
18
26
  1. Verify `qa/screens/<screen>/` exists. If not → `/sungen:add-screen` first.
19
27
  2. Check if `.feature` file already has scenarios. If yes → use `AskUserQuestion` to ask the update mode (see `sungen-tc-generation` skill for details). If no → fresh creation.
20
- 3. **Read requirements** — check `qa/screens/<screen>/requirements/`:
28
+ 3. **Read requirements & resolve visual source** — check `qa/screens/<screen>/requirements/`:
21
29
  - If `spec.md` exists → read it as PRIMARY source (sections, fields, validation rules, business rules, states).
22
- - If `ui/` has images → read them for visual context (layout, element positions, states).
23
30
  - If `test-viewpoint.md` exists → read it. If it only contains HTML comments (scaffold template), use `AskUserQuestion` to ask:
24
31
  - **Fill test-viewpoint.md first** — I'll help you identify edge cases, known issues, and design decisions for this screen before generating tests
25
32
  - **Continue without it** — generate tests from spec and other sources only
26
- - Summarize what you found in requirements and present to the user.
27
- 4. **Screen input** (supplements requirements, or is primary source if no requirements):
28
- - Use `AskUserQuestion` to ask the user to pick a visual source always offer all three options so pre-launch projects work:
29
- - **Figma design** (Recommended for pre-launch) invoke `sungen-capture-figma` skill
30
- - **UI images** (existing screenshots/mockups in `requirements/ui/`) invoke `sungen-capture-local` skill
31
- - **Live page scan** (dev/staging is up) invoke `sungen-capture-live` skill
32
- - Each capture skill writes outputs into `qa/screens/<screen>/requirements/ui/` and reports back a summary. Do not inline capture logic here — always delegate to the skill so behavior stays consistent across commands.
33
- - After the capture skill returns, cross-check its output against `spec.md` and flag any discrepancies before moving on.
34
- 5. Follow the `sungen-tc-generation` skill for section identification, viewpoint generation, and output format. When requirements exist, use the "Requirements-Driven Generation" strategy.
35
- 6. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
36
- 7. Show summary, then use `AskUserQuestion` to offer next steps:
33
+
34
+ **Auto-detect visual source** do NOT ask the user to pick a source. Instead, check what already exists and use it:
35
+ 1. If `spec_figma.md` exists read it as Figma supplement (PAT flow already completed during `add-screen`). Do NOT call any `mcp__figma__*` tool.
36
+ 2. If `ui/` has images (`.png`, `.jpg`, etc.) read them for visual context (layout, element positions, states).
37
+ 3. If neither exists use `AskUserQuestion` to ask: *"No visual source found. Pick one:"*
38
+ - **Figma PAT** ask for URL, run `sungen add --screen <screen> --figma '<url>'` via Bash, then invoke `sungen-figma-source` skill
39
+ - **Figma MCP** invoke `sungen-capture-figma` skill
40
+ - **Live page scan** invoke `sungen-capture-live` skill
41
+ - **Skip** generate from spec.md only
42
+
43
+ **Cross-check**: if both `spec.md` and visual sources exist, flag any discrepancies (missing fields, different labels) before moving on. When `spec_figma.md` is present, follow the Figma supplement rules in `sungen-tc-generation` skill (reading order, Text Inventory, conflict handling).
44
+
45
+ Summarize what you found in requirements and present to the user.
46
+
47
+ 4. Follow the `sungen-tc-generation` skill for section identification, viewpoint generation, and output format. When requirements exist, use the "Requirements-Driven Generation" strategy.
48
+ 5. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
49
+ 6. Show summary, then use `AskUserQuestion` to offer next steps:
37
50
 
38
51
  - **`/sungen:review <screen>`** — Review syntax, coverage, viewpoint quality (Recommended)
39
52
  - **`/sungen:run-test <screen>`** — Skip review, generate selectors and run tests now
40
- - **`/sungen:create-test <screen>`** — Add more test cases for another section/viewpoint
53
+ - **`/sungen:create-test <screen>`** — Expand coverage: add @normal + @low scenarios
41
54
  - **Done for now** — I'll come back later
42
55
 
43
56
  **No selectors.yaml** — selectors are generated during `/sungen:run-test`.
@@ -17,9 +17,10 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
17
17
 
18
18
  1. Read `qa/screens/<screen>/features/<screen>.feature` and `qa/screens/<screen>/test-data/<screen>.yaml`. If missing → `/sungen:create-test` first.
19
19
  2. Follow the `sungen-tc-review` skill — score 3 dimensions: Syntax (30pts), Coverage (40pts), Viewpoint (30pts). Use `sungen-viewpoint` for pattern checklists.
20
- 3. Output review report per `sungen-tc-review` format. **>= 60%**: PASS. **< 60%**: FAIL with recommendations.
21
- 4. If FAIL and user confirms → update test cases following `sungen-gherkin-syntax` and `sungen-tc-generation` skills, then re-review.
22
- 5. After PASS (or user decides to proceed), use `AskUserQuestion` to offer next steps:
20
+ 3. **Unverified Selectors check** — if `qa/screens/<screen>/selectors/<screen>.yaml` exists, count lines matching `@needs-live-verify`. Include in the review report as a non-scoring metric (see `sungen-tc-review` skill for report format). Does NOT affect the 60% threshold.
21
+ 4. Output review report per `sungen-tc-review` format. **>= 60%**: PASS. **< 60%**: FAIL with recommendations.
22
+ 5. If FAIL and user confirms update test cases following `sungen-gherkin-syntax` and `sungen-tc-generation` skills, then re-review.
23
+ 6. After PASS (or user decides to proceed), use `AskUserQuestion` to offer next steps:
23
24
 
24
25
  - **`/sungen:run-test <screen>`** — Generate selectors, compile, and run tests (Recommended)
25
26
  - **`/sungen:create-test <screen>`** — Add more test cases before running
@@ -16,9 +16,41 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
16
16
  ## Pre-run (phased — per `sungen-selector-fix` skill)
17
17
 
18
18
  1. Verify `qa/screens/<screen>/` has `.feature` + `test-data.yaml`.
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.
19
+ 2. **Phase 0 — Selector Pre-gen**: if `selectors.yaml` is missing/empty or doesn't cover the feature file's `[Reference]`s, apply the following decision tree before running Phase 0 from `sungen-selector-fix`:
20
+
21
+ ```
22
+ Phase 0 — Selector Generation decision tree
23
+
24
+ Live page reachable? (URL provided and loads without error)
25
+ YES → existing flow: browser_navigate → one browser_snapshot → generate selectors.yaml (verified entries)
26
+ NO → spec_figma.md exists in requirements/?
27
+ YES → provisional flow (sungen-figma-source + sungen-selector-fix skills):
28
+ 1. Read filtered Figma node data from spec_figma.md (## Components + ## Text Inventory)
29
+ 2. Apply selector heuristics from sungen-figma-source skill (testid > role+name > placeholder > label > locator > text)
30
+ 3. Write selectors.yaml — every provisional entry gets this comment on the line above:
31
+ # @needs-live-verify source=figma node_id=<id>
32
+ 4. Compile: sungen generate --screen <screen> — must succeed
33
+ 5. Phase 1 smoke check runs; tests using unverified selectors may fail
34
+ → auto-fix triggers on next run-test invocation when a live page is available
35
+ NO → hard stop: print the following message and stop:
36
+ "Cannot generate selectors: no live page URL and no spec_figma.md found.
37
+ Options:
38
+ • Provide the live URL so Playwright MCP can snapshot the page, OR
39
+ • Run: sungen add --screen <screen> --figma <figma-url> to generate spec_figma.md first"
40
+ ```
41
+
42
+ **Auto-fix on subsequent runs**: when `run-test` is invoked again with a reachable live page, Phase 0 compares the DOM snapshot against existing `selectors.yaml` entries. Entries tagged `# @needs-live-verify` are treated as candidates — if the actual selector differs, the entry is replaced and the comment removed (entry becomes verified). Entries that already match are also promoted to verified (comment removed).
43
+
44
+ **`@needs-live-verify` comment format** (one comment line, directly above the YAML key):
45
+ ```yaml
46
+ # @needs-live-verify source=figma node_id=<figma-node-id>
47
+ submit-button:
48
+ type: role
49
+ value: button
50
+ name: "Submit"
51
+ ```
20
52
  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.
21
- 4. Compile: `sungen generate --screen <screen>`.
53
+ 4. Compile: `sungen generate --screen <screen>` (default: runtime data loading from YAML). Use `--inline-data` only if user requests compile-time hardcoded values.
22
54
 
23
55
  ## Run & Fix (phased — per `sungen-selector-fix` skill)
24
56
 
@@ -19,6 +19,7 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
19
19
  | `sungen-capture-figma` | Fetch design context + PNG from a Figma frame URL via Figma Dev Mode MCP |
20
20
  | `sungen-capture-local` | Load existing UI assets (screenshots, mockups, Figma exports) from `requirements/ui/` |
21
21
  | `sungen-capture-live` | Capture a live running page via Playwright MCP (snapshot + screenshot) |
22
+ | `sungen-figma-source` | Figma URL → spec_figma.md + ui/*.png + provisional selectors |
22
23
 
23
24
  ## Workflow (5 AI commands)
24
25
 
@@ -40,7 +41,9 @@ After each command completes, use `AskUserQuestion` to present the next actions
40
41
  qa/screens/<screen-name>/
41
42
  ├── features/<screen>.feature # Gherkin scenarios
42
43
  ├── selectors/<screen>.yaml # Element locators (generated during run-test)
43
- ├── test-data/<screen>.yaml # Test data variables
44
+ ├── test-data/<screen>.yaml # Test data variables (loaded at runtime)
45
+ ├── test-data/<screen>.staging.yaml # Environment override (optional)
46
+ ├── test-data/<screen>.production.yaml # Environment override (optional)
44
47
  └── requirements/
45
48
  ├── spec.md # Screen specification (primary source)
46
49
  └── ui/ # Screenshots, mockups
@@ -49,12 +52,19 @@ qa/deliverables/<screen>-testcases.csv # Exported test cases (from /sungen:deli
49
52
  qa/deliverables/<screen>-testcases.xlsx # Styled workbook for client hand-off
50
53
  ```
51
54
 
55
+ ## Test Data
56
+
57
+ `{{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.
58
+
59
+ **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).
60
+
52
61
  ## CLI Commands
53
62
 
54
63
  ```bash
55
64
  sungen add --screen <name> --path <url-path> # Scaffold screen directories
56
65
  sungen add --screen <name> --path <path> --feature <name> # Scaffold with sub-feature
57
- sungen generate --screen <name> # Compile .feature → .spec.ts
66
+ sungen generate --screen <name> # Compile .feature → .spec.ts (runtime data)
67
+ sungen generate --screen <name> --inline-data # Compile with hardcoded data (legacy)
58
68
  sungen generate --all # Compile all screens
59
69
  sungen delivery # Export all screens → CSV + XLSX
60
70
  sungen delivery <screen> # Export a single screen
@@ -0,0 +1,151 @@
1
+ ---
2
+ name: sungen-figma-source
3
+ description: 'Figma URL → spec_figma.md envelope + LLM-synthesized narrative from cached raw node JSON. Auto-loaded when --figma flag present or spec_figma.md exists.'
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## When This Skill Loads
8
+
9
+ Auto-load triggers (any one is sufficient):
10
+
11
+ - Any sungen AI command invoked with `--figma` flag
12
+ - `requirements/spec_figma.md` exists in the screen directory
13
+ - User mentions a Figma URL or says "generate from Figma"
14
+
15
+ ---
16
+
17
+ ## Prerequisites
18
+
19
+ - [ ] `sungen figma auth check` succeeds — PAT is stored and valid
20
+ - [ ] Figma file URL is available (shared file or frame link)
21
+ - [ ] If auth missing → run `sungen figma auth set` and follow the walkthrough
22
+
23
+ **Never paste the PAT into any transcript, spec file, or commit.**
24
+
25
+ ---
26
+
27
+ ## Two-Layer Architecture
28
+
29
+ `spec_figma.md` has two layers separated by the `<!-- SYNTHESIS-BELOW -->` marker:
30
+
31
+ | Layer | Producer | Overwrite Rule |
32
+ |---|---|---|
33
+ | **Envelope** (above marker) | sungen CLI | Regenerated each `sungen figma` run — deterministic |
34
+ | **Narrative** (below marker) | This skill (LLM) | Replaced on re-synthesis — everything from marker to EOF |
35
+
36
+ The envelope contains: YAML frontmatter, Frame metadata, Screenshots. The narrative is synthesized by YOU from the cached raw Figma node JSON.
37
+
38
+ ---
39
+
40
+ ## Inputs You Read
41
+
42
+ The scaffolder persists a raw (unfiltered) Figma node tree to:
43
+
44
+ ```
45
+ .sungen/figma-cache/<fileKey>/<versionId>/<nodeId>-raw.json
46
+ ```
47
+
48
+ Read this file + the envelope frontmatter of `requirements/spec_figma.md` + any PNGs under `requirements/ui/`. You MUST NOT call the Figma REST API directly — the PAT is not available to you.
49
+
50
+ ---
51
+
52
+ ## Synthesis Task
53
+
54
+ Append 7 narrative sections below `<!-- SYNTHESIS-BELOW -->`. Each section is inferred from the raw node tree (names, types, `characters`, layout bounds, auto-layout direction, componentProperties):
55
+
56
+ ### 1. Purpose
57
+ One paragraph. What screen is this? Primary user goal? Infer from frame name + top-level text + dominant CTA.
58
+
59
+ ### 2. ASCII Layout
60
+ Rough spatial sketch using box characters. Reflect top-bottom / left-right ordering from absoluteBoundingBox. Keep under ~20 lines. Example:
61
+
62
+ ```
63
+ ┌──────────────────────────────────────┐
64
+ │ [Logo] [Sign In] │
65
+ ├──────────────────────────────────────┤
66
+ │ Welcome back │
67
+ │ ┌────────────────────────────────┐ │
68
+ │ │ email@example.com │ │
69
+ │ └────────────────────────────────┘ │
70
+ │ [ Continue ] │
71
+ └──────────────────────────────────────┘
72
+ ```
73
+
74
+ ### 3. Regions
75
+ Bulleted list of the major layout regions (header, sidebar, main, footer, modal, etc.) with a one-line purpose each. Use auto-layout frames as region hints.
76
+
77
+ ### 4. Actions
78
+ Every interactive element the user can trigger. Derive from nodes whose name/type suggests a button, link, icon-button, menu-item, toggle, etc. Format:
79
+
80
+ ```
81
+ - **<Action name>** — <what it does> (source: <node name>)
82
+ ```
83
+
84
+ ### 5. Form Fields
85
+ Every input the user can fill. Include label, type (text/email/password/select/checkbox/radio/textarea/date), required hint if inferable, and placeholder.
86
+
87
+ ```
88
+ | Label | Type | Required | Placeholder |
89
+ |---|---|---|---|
90
+ ```
91
+
92
+ Omit entirely (write `_none_`) if no inputs exist.
93
+
94
+ ### 6. Data Columns
95
+ If the screen shows a table, list, or card grid — enumerate the columns/fields displayed per row. Otherwise write `_none_`.
96
+
97
+ ### 7. Navigation
98
+ Outgoing links, tab bars, breadcrumbs, back buttons — anything that moves the user to another screen. Include both explicit navigation components and implicit CTAs that navigate.
99
+
100
+ ---
101
+
102
+ ## Synthesis Workflow
103
+
104
+ 1. Read `requirements/spec_figma.md` — note `file_key`, `node_id`, `figma_version_id` from frontmatter
105
+ 2. Read `.sungen/figma-cache/<file_key>/<figma_version_id>/<safe_node_id>-raw.json` (colons in node_id become underscores)
106
+ 3. Traverse the tree. Collect: names, types, `characters`, `componentProperties`, `absoluteBoundingBox`
107
+ 4. Produce the 7 sections above
108
+ 5. **Locate the insertion point** in `spec_figma.md`:
109
+ - **If `<!-- SYNTHESIS-BELOW -->` is present** → replace everything from the marker (inclusive) to EOF with: the marker line, a blank line, then the 7 sections.
110
+ - **If the marker is NOT present** (older `spec_figma.md` pre-envelope-refactor, or hand-edited file) → locate the last non-empty line of the envelope (usually the end of `## Screenshots`), append a blank line, then write the marker, another blank line, then the 7 sections. Do NOT delete any existing envelope content.
111
+ - **If the file is missing entirely** → advise the user to re-run `sungen add --screen <screen> --figma <url> --refresh` to regenerate the envelope first. Do not fabricate one.
112
+ 6. Preserve the envelope (frontmatter + Frame + Screenshots) byte-for-byte. Never touch content above the marker.
113
+
114
+ ---
115
+
116
+ ## Re-synthesis
117
+
118
+ - If the envelope's `figma_version_id` changed → envelope is fresh; re-run synthesis
119
+ - If only the narrative is stale (user wants a rewrite) → truncate from marker to EOF and regenerate
120
+ - Never edit content ABOVE the marker — that is the scaffolder's territory
121
+
122
+ ---
123
+
124
+ ## Selector Heuristics (for downstream `run-test`)
125
+
126
+ During `run-test` Phase 0, provisional selectors can be seeded from the raw JSON:
127
+
128
+ | Figma Signal | Provisional YAML Entry |
129
+ |---|---|
130
+ | Node name ends `Button`, has text | `role: button` + `name: "<text>"` |
131
+ | Node name ends `Input`/`Field` | `placeholder: "<placeholder text>"` |
132
+ | Node name ends `Link`, has text | `role: link` + `name: "<text>"` |
133
+ | componentProperties has `data-testid` | `testid: <value>` |
134
+ | Plain text leaf (outside interactive) | `text: "<content>"` |
135
+ | Node name ends `Icon` | `role: img` + `name: "<accessible name>"` |
136
+
137
+ Every provisional entry MUST carry:
138
+
139
+ ```
140
+ # @needs-live-verify source=figma node_id=<id>
141
+ ```
142
+
143
+ Provisional selectors feed `selectors.yaml` as candidates. `run-test` Phase 0 verifies them against the live page and overwrites incorrect entries.
144
+
145
+ ---
146
+
147
+ ## Security
148
+
149
+ - Never include the PAT in `spec_figma.md`, selectors, test data, or any committed file
150
+ - Never log or echo the PAT in terminal output
151
+ - Read only from `.sungen/figma-cache/` and screen directories — never from `.env`
@@ -151,6 +151,14 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
151
151
  | `@no-auth` | Disable inherited auth |
152
152
  | `@steps:name` | Define reusable step block (base scenario) |
153
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()` |
154
162
 
155
163
  ### @extend behavior
156
164
 
@@ -175,30 +183,28 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
175
183
  | Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
176
184
  | State as value | `with {{disabled}}` | `is disabled` |
177
185
  | Missing target type | `fill [email] with {{v}}` | `fill [email] field with {{v}}` |
178
- | 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 |
179
187
  | `is on` after When | `When ... And User is on [X] dialog` | `And User see [X] dialog` or separate Given |
180
188
 
181
189
  ## Background vs @steps/@extend
182
190
 
183
- **Do NOT use `Background:` block.** Use `@steps` + `@extend` instead.
191
+ Both `Background` and `@steps`/`@extend` are valid — they serve different purposes.
184
192
 
185
- **Why:**
186
- - `Background` runs before EVERY scenario but cannot set dialog/frame scope correctly
187
- - `Background` with `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When)
188
- - `@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()` |
189
197
 
190
- **Wrong:**
198
+ **Use `Background` for simple navigation:**
191
199
  ```gherkin
192
200
  Background:
193
- Given User is on [Kudos] page
194
- When User click [Open] button
195
- And User is on [Modal] dialog ← keyword mismatch
201
+ Given User is on [Dashboard] page
196
202
 
197
- Scenario: VP-UI-001 Title visible
198
- Then User see [Title] heading
203
+ Scenario: View stats
204
+ Then User see [Revenue Chart] section
199
205
  ```
200
206
 
201
- **Correct:**
207
+ **Use `@steps`/`@extend` when scope matters (dialog, frame):**
202
208
  ```gherkin
203
209
  @steps:open_modal
204
210
  Scenario: Open modal
@@ -211,3 +217,50 @@ Scenario: VP-UI-001 Title visible
211
217
  Given User is on [Modal] dialog
212
218
  Then User see [Title] heading
213
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
@@ -6,14 +6,25 @@ user-invocable: false
6
6
 
7
7
  ## Goal
8
8
 
9
- Generate **focused test cases per screen section** with **20+ scenarios per viewpoint**. Output `.feature` + `test-data.yaml` only — selectors are deferred to `/sungen:run-test`.
9
+ Generate **focused test cases per screen section** using a **tier-based approach** for faster results. Output `.feature` + `test-data.yaml` only — selectors are deferred to `/sungen:run-test`.
10
+
11
+ ### Tier System
12
+
13
+ | Tier | Priority | What to generate | When |
14
+ |---|---|---|---|
15
+ | **Tier 1** (default) | `@critical` + `@high` | Happy paths, required validation, core business rules, security basics | First run of `create-test` |
16
+ | **Tier 2** (expand) | `@normal` + `@low` | UI presence, optional validation, edge cases, cosmetic checks | User runs `create-test` again with "Add viewpoints" mode |
17
+
18
+ **Round 1 (Tier 1)** targets **~10-15 scenarios per section** — enough to cover critical flows and catch real bugs. This is the default behavior.
19
+
20
+ **Round 2 (Tier 2)** expands to full coverage when the user explicitly chooses "Add viewpoints" or "Add new sections" update mode. Only then generate `@normal` + `@low` scenarios to fill coverage gaps.
10
21
 
11
22
  ## Update Mode
12
23
 
13
24
  When `.feature` already has scenarios, summarize and ask:
14
- 1. **Add new sections** — append, continue numbering
15
- 2. **Add viewpoints** — add to existing sections
16
- 3. **Replace all** — overwrite
25
+ 1. **Add new sections** — append new sections with Tier 2 (`@normal` + `@low`) scenarios, continue numbering
26
+ 2. **Add viewpoints** — expand existing sections with Tier 2 (`@normal` + `@low`) scenarios
27
+ 3. **Replace all** — overwrite with fresh Tier 1 (`@critical` + `@high`) generation
17
28
 
18
29
  For append: read highest `VP-<CAT>-<NNN>`, continue from next number. Never modify existing scenarios.
19
30
 
@@ -30,12 +41,13 @@ If also exploring live page: verify spec vs actual, flag mismatches, capture exa
30
41
 
31
42
  ## Screen Input Sources
32
43
 
33
- **Recommended** (in priority order):
34
- 1. **Figma designs** use Figma MCP to read design context, screenshots, and component metadata
35
- 2. **UI images** screenshots or mockups in `qa/screens/<screen>/requirements/ui/`
36
- 3. **`spec.md`**written specification with sections, fields, validation rules
44
+ **Auto-detect** — the parent command (`create-test`) resolves visual sources before invoking this skill. By the time generation starts, the available sources are already determined:
45
+ - `spec.md`primary, always read if present
46
+ - `spec_figma.md` Figma supplement, read if present (PAT flow already completed)
47
+ - `ui/*.png`visual context, read if present
48
+ - `test-viewpoint.md` — edge cases and known issues, read if present
37
49
 
38
- **Optional**: **Live page scan** via Playwright MCP — useful to verify specs vs actual UI, capture real data (error messages, labels). If auth needed ask user to log in manually via MCP browser.
50
+ **IMPORTANT:** If `spec_figma.md` exists, do NOT call any `mcp__figma__*` tool. The PAT flow is complete just read the file.
39
51
 
40
52
  **Single screen focus**: one URL = one screen. Don't explore sibling paths. Modals on same page = part of this screen.
41
53
 
@@ -76,7 +88,9 @@ Apply `sungen-test-design-techniques` to spec-extracted conditions:
76
88
 
77
89
  Use `sungen-viewpoint` skill for per-pattern checklists across 4 viewpoints: UI/UX, Data & Validate, Logic, Security.
78
90
 
79
- Add scenarios for generic UI coverage that spec didn't explicitly state (empty states, loading states, keyboard nav, hover effects). Skip viewpoints truly N/A.
91
+ **Tier-aware gap filling:**
92
+ - **Tier 1 (first run)**: only add `@critical` and `@high` items from the checklists — core security checks (VP-SEC), required field validation (VP-VAL), key state transitions (VP-LOGIC). Skip `@normal`/`@low` items like hover states, empty states, tooltips.
93
+ - **Tier 2 (expand run)**: add `@normal` + `@low` scenarios — UI presence, optional validation, edge cases, cosmetic checks, keyboard nav, hover effects.
80
94
 
81
95
  **Validation rule**: capture actual error messages from live page or spec.md. Use `User see {{error_var}}` — never assert just "is visible".
82
96
 
@@ -112,30 +126,70 @@ Given User is on [Screen] page
112
126
  And User wait for [Page Title] heading is visible
113
127
  ```
114
128
 
129
+ ## Cleanup & Hooks
130
+
131
+ ### Auto-assign `@cleanup:*` tags based on screen sections
132
+
133
+ After identifying screen sections, add appropriate `@cleanup:*` feature-level tags. These activate base.ts fixtures that auto-clean state between tests.
134
+
135
+ | Screen has | Add tag | Why |
136
+ |---|---|---|
137
+ | Modal / Dialog / Drawer | `@cleanup:overlay` | Dismiss leftover overlays between tests |
138
+ | Form & Inputs / Search / Filter | `@cleanup:forms` | Clear form fields, reset selects |
139
+ | Long scrollable content | `@cleanup:scroll` | Scroll to top for consistent assertions |
140
+ | Auth tokens / session data in tests | `@cleanup:storage` | Clear sessionStorage |
141
+ | CI/CD or debug-heavy screens | `@screenshot:on-failure` | Auto-capture screenshot on test failure |
142
+
143
+ **Always add `@cleanup:overlay`** if ANY section opens a dialog (Create/Add, Update/Edit, Delete confirmation). Most CRUD screens need it.
144
+
145
+ **Always add `@cleanup:forms`** if the screen has inline search, filter dropdowns, or editable forms that persist between tests.
146
+
147
+ ### When to add `@afterEach` hook scenario
148
+
149
+ Only when `@cleanup:*` tags aren't enough — feature-specific cleanup logic:
150
+ - Reset a dropdown filter to default value (not just clear)
151
+ - Navigate away from a sub-tab back to the main tab
152
+ - Close a specific sidebar panel
153
+
154
+ ```gherkin
155
+ @afterEach
156
+ Scenario: Reset filters to default
157
+ When User select [Status Filter] dropdown with {{default_status}}
158
+ ```
159
+
160
+ ### `@beforeAll` / `@afterAll` — optional, low priority
161
+
162
+ For one-time setup/teardown. Most screens don't need these.
163
+
115
164
  ## Output Format
116
165
 
117
166
  **Feature file** — `qa/screens/<screen>/features/<screen>.feature`
118
167
 
119
- **Never use `Background:`.** Use `@steps` + `@extend` for shared setup (see `sungen-gherkin-syntax` skill).
168
+ `Background` is valid for simple shared setup (navigate to page). Use `@steps`/`@extend` for complex flows with scope (dialog, frame).
120
169
 
121
170
  ```gherkin
122
171
  @auth:role
172
+ @cleanup:overlay
173
+ @cleanup:forms
123
174
  Feature: <Screen> Screen
124
175
 
176
+ Background:
177
+ Given User is on [Screen] page
178
+
125
179
  # Shared setup — NO priority tag on @steps
126
180
  @steps:open_form
127
181
  Scenario: Open form
128
- Given User is on [Screen] page
129
182
  When User click [Create] button
130
183
  Then User see [Form] dialog
131
184
 
132
- # --- Section: Create User Form ---
185
+ # --- Section: Create User Form (Tier 1: @critical + @high) ---
133
186
 
134
- @normal @extend:open_form
135
- Scenario: VP-UI-001 Form displays all fields with correct defaults
187
+ @critical @extend:open_form
188
+ Scenario: VP-LOGIC-001 Submit form with valid data creates record
136
189
  Given User is on [Form] dialog
137
- Then User see [Name] field
138
- And User see [Submit] button is disabled
190
+ When User fill [Name] field with {{valid_name}}
191
+ And User click [Submit] button
192
+ Then User see {{success_message}} message
139
193
 
140
194
  @high @extend:open_form
141
195
  Scenario: VP-VAL-001 Submit with all empty fields shows errors
@@ -143,19 +197,23 @@ Feature: <Screen> Screen
143
197
  When User click [Submit] button
144
198
  Then User see [Name error] message with {{name_required_error}}
145
199
 
146
- # --- Section: User Table ---
147
-
148
- @normal
149
- Scenario: VP-UI-010 Table displays all columns
150
- Then User see [Name] column in [Users] table
200
+ # --- Section: User Table (Tier 1: @critical + @high) ---
151
201
 
152
202
  @high
153
203
  Scenario: VP-VAL-010 Table displays correct data
154
204
  Then User see [Users] table match data:
155
205
  | Name | Email |
156
206
  | {{name_1}} | {{email_1}} |
207
+
208
+ @critical
209
+ Scenario: VP-SEC-010 Unauthorized user cannot access page
210
+ Given User is not logged in
211
+ When User navigate to [Screen] page
212
+ Then User is on [Login] page
157
213
  ```
158
214
 
215
+ **Tier 2 (expand run)** adds `@normal` + `@low` scenarios like UI field presence, hover states, tooltips, empty states.
216
+
159
217
  ### When to use DataTable vs Row Scope
160
218
 
161
219
  | Pattern | Use when |
@@ -165,6 +223,18 @@ Feature: <Screen> Screen
165
223
 
166
224
  **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
225
 
168
- **Test data** — `qa/screens/<screen>/test-data/<screen>.yaml`, grouped by section.
226
+ **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.
227
+
228
+ **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:
229
+
230
+ ```yaml
231
+ # login.yaml (base)
232
+ valid_email: admin@dev.example.com
233
+ valid_password: DevPass123
234
+
235
+ # login.staging.yaml (override for staging)
236
+ valid_email: admin@staging.example.com
237
+ valid_password: StagingPass456
238
+ ```
169
239
 
170
240
  **Do NOT generate**: `selectors.yaml` (created during run-test), Playwright code (sungen compiles).
@@ -43,6 +43,8 @@ Score: `(dimensions_covered / 6) * 40`. Validate technique application with `sun
43
43
 
44
44
  **Classification**: UI = static/always-same appearance. VAL = input validation/errors. LOGIC = behavior/state changes (includes persisted state without When). SEC = auth/permissions.
45
45
 
46
+ **Tier-aware scoring**: If the feature file only contains `@critical` + `@high` scenarios (Tier 1), do NOT penalize for missing VP-UI viewpoint — UI scenarios are intentionally deferred to Tier 2. Score "All applicable VP present" based on Tier 1-relevant viewpoints only (VAL, LOGIC, SEC). Note in the review output: *"VP-UI deferred to Tier 2 — run `/sungen:create-test` with 'Add viewpoints' to expand."*
47
+
46
48
  ---
47
49
 
48
50
  ## Quality Rules