@sun-asterisk/sungen 2.2.2 → 2.3.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 (105) hide show
  1. package/README.md +66 -37
  2. package/dist/cli/commands/update.d.ts +3 -0
  3. package/dist/cli/commands/update.d.ts.map +1 -0
  4. package/dist/cli/commands/update.js +21 -0
  5. package/dist/cli/commands/update.js.map +1 -0
  6. package/dist/cli/index.js +3 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/generators/gherkin-parser/index.d.ts +2 -0
  9. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  10. package/dist/generators/gherkin-parser/index.js +17 -3
  11. package/dist/generators/gherkin-parser/index.js.map +1 -1
  12. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
  13. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
  14. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
  15. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
  16. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  17. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
  18. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  19. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  20. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  21. package/dist/generators/test-generator/patterns/assertion-patterns.js +95 -57
  22. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  23. package/dist/generators/test-generator/patterns/index.d.ts +9 -0
  24. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  25. package/dist/generators/test-generator/patterns/index.js +32 -0
  26. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  27. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +1 -1
  28. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
  29. package/dist/generators/test-generator/patterns/interaction-patterns.js +56 -1
  30. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  31. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  32. package/dist/generators/test-generator/patterns/table-patterns.js +8 -5
  33. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  34. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  35. package/dist/generators/test-generator/utils/selector-resolver.js +16 -0
  36. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  37. package/dist/orchestrator/ai-rules-updater.d.ts +13 -0
  38. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -0
  39. package/dist/orchestrator/ai-rules-updater.js +157 -0
  40. package/dist/orchestrator/ai-rules-updater.js.map +1 -0
  41. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  42. package/dist/orchestrator/project-initializer.js +2 -27
  43. package/dist/orchestrator/project-initializer.js.map +1 -1
  44. package/dist/orchestrator/screen-manager.d.ts +1 -0
  45. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  46. package/dist/orchestrator/screen-manager.js +70 -3
  47. package/dist/orchestrator/screen-manager.js.map +1 -1
  48. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  49. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +11 -4
  50. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -6
  51. package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
  52. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +170 -24
  53. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +118 -12
  54. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
  55. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +124 -71
  56. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  57. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +12 -4
  58. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +11 -6
  59. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
  60. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +170 -24
  61. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +93 -12
  62. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
  63. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +124 -72
  64. package/dist/orchestrator/templates/readme.md +13 -8
  65. package/package.json +1 -1
  66. package/src/cli/commands/update.ts +18 -0
  67. package/src/cli/index.ts +3 -1
  68. package/src/generators/gherkin-parser/index.ts +20 -3
  69. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
  70. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
  71. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
  72. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
  73. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  74. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
  75. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  76. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  77. package/src/generators/test-generator/patterns/assertion-patterns.ts +106 -65
  78. package/src/generators/test-generator/patterns/index.ts +41 -0
  79. package/src/generators/test-generator/patterns/interaction-patterns.ts +58 -1
  80. package/src/generators/test-generator/patterns/table-patterns.ts +8 -5
  81. package/src/generators/test-generator/utils/selector-resolver.ts +16 -0
  82. package/src/orchestrator/ai-rules-updater.ts +139 -0
  83. package/src/orchestrator/project-initializer.ts +2 -32
  84. package/src/orchestrator/screen-manager.ts +72 -3
  85. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  86. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +11 -4
  87. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -6
  88. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
  89. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +170 -24
  90. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +118 -12
  91. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
  92. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +124 -71
  93. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  94. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +12 -4
  95. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +11 -6
  96. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
  97. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +170 -24
  98. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +93 -12
  99. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
  100. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +124 -72
  101. package/src/orchestrator/templates/readme.md +13 -8
  102. package/docs/gherkin standards/gherkin-core-standard.md +0 -428
  103. package/docs/gherkin standards/gherkin-core-standard.vi.md +0 -513
  104. package/docs/gherkin-dictionary.md +0 -1071
  105. package/docs/makeauth.md +0 -225
@@ -124,6 +124,24 @@ To determine the correct `nth` offset, count how many matching elements appear b
124
124
 
125
125
  ---
126
126
 
127
+ ### Step 4b: Handle Detail Screens with Dynamic IDs
128
+
129
+ For screens like `/admin/users/:id` or `/products/:slug`:
130
+ 1. Navigate to the **list page** first via MCP browser to find a real record ID
131
+ 2. Use that ID in the page selector value
132
+ 3. Use `User is on [X] page` — sungen resolves the path from the selector
133
+
134
+ ```yaml
135
+ # selectors.yaml — full path with real ID
136
+ user detail:
137
+ type: 'page'
138
+ value: '/admin/users/de42d800-0f5a-490e-9dcf-344fedbd34a5'
139
+ ```
140
+
141
+ Note: the selector uses a hardcoded ID from the live page. If the record is deleted, update the ID in `selectors.yaml`.
142
+
143
+ ---
144
+
127
145
  ### Step 5: Handle SPA / Client-side Routing
128
146
 
129
147
  Many modern apps (Next.js, Nuxt, SvelteKit, etc.) return the same HTML shell for all URLs and route client-side. `domcontentloaded` fires on the shell before the target page renders.
@@ -168,9 +186,16 @@ Many elements don't need a YAML entry — sungen auto-infers from the Gherkin la
168
186
  |---|---|
169
187
  | `[Submit] button` | `getByRole('button', { name: 'Submit' })` |
170
188
  | `[Home] link` | `getByRole('link', { name: 'Home' })` |
171
- | `[Welcome] heading` | `getByRole('heading', { name: 'Welcome' })` |
189
+ | `[Welcome] heading` / `header` | `getByRole('heading', { name: 'Welcome' })` |
172
190
  | `[Email] field` | `getByPlaceholder('Email')` |
173
- | `[Success] text` | `getByText('Success')` |
191
+ | `[Success] text` / `message` / `label` | `getByText('Success')` |
192
+ | `[Terms] checkbox` | `getByRole('checkbox', { name: 'Terms' })` |
193
+ | `[Global] search` | `getByRole('searchbox', { name: 'Global' })` |
194
+ | `[Vietnam] option` | `getByRole('option', { name: 'Vietnam' })` |
195
+ | `[Price] slider` | `getByRole('slider', { name: 'Price' })` |
196
+ | `[Notification] toggle` | `getByRole('switch', { name: 'Notification' })` |
197
+ | `[Profile] tab` | `getByRole('tab', { name: 'Profile' })` |
198
+ | `[Confirm] dialog` / `modal` / `drawer` | `getByRole('dialog', { name: 'Confirm' })` |
174
199
 
175
200
  **Only add a YAML entry when auto-infer won't work:**
176
201
  - The accessible name differs from the Gherkin label
@@ -181,20 +206,101 @@ Many elements don't need a YAML entry — sungen auto-infers from the Gherkin la
181
206
 
182
207
  ---
183
208
 
184
- ### Fix Loop on Test Failure
209
+ ### Proactive Selector Validation (before running tests)
210
+
211
+ **Most failures are selector mismatches.** Validate selectors against the live page BEFORE running any test — this eliminates slow compile→run→read→fix cycles.
212
+
213
+ After generating `selectors.yaml` (Step 3), verify each entry:
185
214
 
215
+ #### How to validate
216
+
217
+ Use `browser_evaluate` to check if each selector actually finds an element on the page:
218
+
219
+ ```js
220
+ // Validate a role selector
221
+ document.querySelectorAll('[role="button"]').length;
222
+ // or check accessible name exists
223
+ Array.from(document.querySelectorAll('button'))
224
+ .filter(el => el.textContent.includes('Submit') || el.getAttribute('aria-label')?.includes('Submit'))
225
+ .length;
186
226
  ```
187
- attempt = 0
188
- while attempt < 5:
189
- compile run test
190
- if pass done
191
- read error-context.md in test-results/ check exact snapshot state at failure time
192
- fix selectors.yaml or test-data.yaml
193
- recompile attempt++
194
- if still failing ask user about direct .spec.ts fix
227
+
228
+ Or use `browser_snapshot` and cross-check:
229
+ 1. Read all `[Reference]` entries from `selectors.yaml`
230
+ 2. Take a `browser_snapshot`
231
+ 3. For each entry, verify:
232
+ - **role + name**: does the snapshot contain `button "Submit"` or `link "Home"`?
233
+ - **testid**: does `browser_evaluate` find `[data-testid="xxx"]`?
234
+ - **placeholder**: does the snapshot contain a textbox with that placeholder?
235
+ - **locator**: does `browser_evaluate` find `document.querySelector('xxx')`?
236
+ 4. Fix mismatches immediately — no need to run tests
237
+
238
+ #### What to check
239
+
240
+ | Selector type | Validation method |
241
+ |---|---|
242
+ | `role` + `name` | Search snapshot for `role "name"` text |
243
+ | `testid` | `browser_evaluate`: `document.querySelector('[data-testid="xxx"]')` |
244
+ | `placeholder` | Search snapshot for textbox with placeholder |
245
+ | `locator` (CSS) | `browser_evaluate`: `document.querySelector('xxx')` |
246
+ | `page` | Verify URL path exists (navigate and check) |
247
+
248
+ #### Common proactive fixes
249
+
250
+ - Name mismatch → copy exact name from snapshot
251
+ - Element not found → check if element is inside iframe/dialog (needs `frame` or scope)
252
+ - Multiple matches → add `nth: 0` or `exact: true`
253
+ - No accessible name → switch to `testid` or `locator`
254
+
255
+ **Target: fix 80%+ of selector issues before the first test run.**
256
+
257
+ ---
258
+
259
+ ### Batched Test Execution
260
+
261
+ After proactive validation, run tests in **batches of 20** for faster feedback:
262
+
263
+ ```
264
+ 1. COMPILE — sungen generate --screen <screen>
265
+
266
+ 2. BATCH RUN — run 20 tests at a time:
267
+ npx playwright test <spec> --grep "VP-UI-001|VP-UI-002|...|VP-UI-020" --reporter=line
268
+
269
+ 3. IF FAILURES in batch:
270
+ a. Group failures by root cause (same selector, same error type)
271
+ b. Fix selectors.yaml or test-data.yaml
272
+ c. Recompile: sungen generate --screen <screen>
273
+ d. Re-run ONLY the failing tests from this batch
274
+ e. If fixed → move to next batch
275
+
276
+ 4. NEXT BATCH — repeat with next 20 tests (VP-UI-021...VP-UI-040)
277
+
278
+ 5. FINAL CONFIRMATION — after all batches pass, run ALL tests once:
279
+ npx playwright test <spec> --reporter=line
280
+ This catches regressions from selector changes.
281
+
282
+ 6. If still failing after 5 fix attempts per batch → ask user about direct .spec.ts fix
195
283
  ```
196
284
 
197
- **Always read the error context snapshot first** — it shows the exact page state when the test failed, which is more reliable than re-navigating with MCP.
285
+ #### Building batch `--grep` patterns
286
+
287
+ Extract scenario names and batch them:
288
+ ```bash
289
+ # Batch 1: first 20
290
+ npx playwright test <spec> --grep "VP-UI-001|VP-UI-002|...|VP-UI-020" --reporter=line
291
+
292
+ # Batch 2: next 20
293
+ npx playwright test <spec> --grep "VP-VAL-001|VP-VAL-002|...|VP-VAL-020" --reporter=line
294
+ ```
295
+
296
+ #### Grouping failures by root cause
297
+
298
+ Common patterns where 1 fix resolves many failures:
299
+ - **Same selector** — e.g., all `[Email Error]` tests fail → fix `email error` in selectors.yaml once
300
+ - **Same error type** — e.g., all `strict mode violation` → add `exact: true` or `nth`
301
+ - **Same assertion** — e.g., all `toHaveText` on inputs fail → change Gherkin pattern
302
+
303
+ Fix the root cause first, verify with the batch, then move on.
198
304
 
199
305
  ---
200
306
 
@@ -51,6 +51,10 @@ Type aliases (normalized automatically):
51
51
  | logo, image, icon | `img` |
52
52
  | btn | `button` |
53
53
  | input, textbox, textarea, editor | `field` |
54
+ | search | `searchbox` |
55
+ | toggle | `switch` |
56
+ | alert | `alertdialog` |
57
+ | modal, drawer | `dialog` |
54
58
  | column | `columnheader` |
55
59
  | list-item | `listitem` |
56
60
 
@@ -83,10 +87,20 @@ If no YAML key exists, the resolver infers from the Gherkin element type:
83
87
  |---|---|
84
88
  | `[X] button` | `getByRole('button', { name: 'X' })` |
85
89
  | `[X] link` | `getByRole('link', { name: 'X' })` |
86
- | `[X] heading` | `getByRole('heading', { name: 'X' })` |
90
+ | `[X] heading` / `header` | `getByRole('heading', { name: 'X' })` |
87
91
  | `[X] checkbox` | `getByRole('checkbox', { name: 'X' })` |
92
+ | `[X] radio` | `getByRole('radio', { name: 'X' })` |
88
93
  | `[X] field` | `getByPlaceholder('X')` |
89
- | `[X] text` | `getByText('X')` |
94
+ | `[X] text` / `message` / `label` | `getByText('X')` |
90
95
  | `[X] logo/image/icon` | `getByRole('img', { name: 'X' })` |
96
+ | `[X] search` | `getByRole('searchbox', { name: 'X' })` |
97
+ | `[X] option` | `getByRole('option', { name: 'X' })` |
98
+ | `[X] slider` | `getByRole('slider', { name: 'X' })` |
99
+ | `[X] toggle` | `getByRole('switch', { name: 'X' })` |
100
+ | `[X] tab` | `getByRole('tab', { name: 'X' })` |
101
+ | `[X] table` | `getByRole('table', { name: 'X' })` |
102
+ | `[X] list` | `getByRole('list', { name: 'X' })` |
103
+ | `[X] column` | `getByRole('columnheader', { name: 'X' })` |
104
+ | `[X] dialog` / `modal` / `drawer` | `getByRole('dialog', { name: 'X' })` |
91
105
 
92
106
  **Only add a YAML entry when** the auto-inferred locator won't work (wrong name, need testid, need nth, etc.).
@@ -33,6 +33,46 @@ For options 1 and 2:
33
33
  For option 3:
34
34
  - Overwrite both `.feature` and `test-data.yaml` completely
35
35
 
36
+ ### Requirements-Driven Generation
37
+
38
+ When `qa/screens/<screen>/requirements/` exists, use it as the **primary source** for test case generation. This produces higher quality tests because requirements contain exact validation messages, field constraints, business rules, and states.
39
+
40
+ #### Reading Requirements
41
+
42
+ 1. **`spec.md`** (primary) — structured screen specification:
43
+ - **Sections** → map directly to test case sections
44
+ - **Fields table** → generate boundary value tests (min/max constraints), required field tests, format tests
45
+ - **Validation Rules table** → generate exact assertion tests using the error messages as `{{test_data}}` values
46
+ - **Actions table** → generate interaction tests (click, submit, navigate)
47
+ - **States table** → generate state transition tests (loading, error, success, disabled)
48
+ - **Business Rules** → generate logic tests (limits, permissions, conditional behavior)
49
+ - **Accessibility** → generate tab-order and aria tests
50
+
51
+ 2. **`ui/`** (supplementary) — screenshots, mockups, design images:
52
+ - Read images to understand layout, element positions, visual states
53
+ - Cross-reference with spec.md — identify elements visible in UI but missing from spec
54
+ - Use for UI/UX viewpoint tests (element visibility, placement, responsive)
55
+
56
+ 3. **`notes.md`** (supplementary) — free-form edge cases, decisions, known issues:
57
+ - Extract edge cases → add to test coverage
58
+ - Flag known issues → add TODO scenarios
59
+
60
+ #### How Requirements Improve Each Viewpoint
61
+
62
+ | Viewpoint | Without Requirements | With Requirements |
63
+ |-----------|---------------------|-------------------|
64
+ | **UI/UX** | "see [Field] is visible" (generic) | "see [Field] field" + verify label, placeholder, default from spec |
65
+ | **Validation** | "submit empty → see error" (vague) | "submit empty email → see {{email_required_error}}" with exact message from spec |
66
+ | **Logic** | Based on observed page behavior | Business rules drive specific tests (lockout after N attempts, session expiry) |
67
+ | **Security** | Generic injection tests | Role-based tests from auth requirements, permission-specific scenarios |
68
+
69
+ #### Merging Requirements + Live Page
70
+
71
+ If the user also explores the live page:
72
+ - **Verify** spec.md against actual page — flag mismatches (e.g., field in spec but not on page)
73
+ - **Supplement** — discover elements on page not in spec (e.g., footer links, tooltips)
74
+ - **Exact text** — capture actual placeholder text, button labels, error messages from live page and update test-data accordingly
75
+
36
76
  ### Page Exploration & Auth
37
77
 
38
78
  Use Playwright MCP to explore the live page. If the page requires authentication:
@@ -55,26 +95,7 @@ Use Playwright MCP to explore the live page. If the page requires authentication
55
95
 
56
96
  #### Detail screens with dynamic IDs
57
97
 
58
- For screens like `/admin/users/:id` or `/products/:slug`:
59
- 1. Navigate to the **list page** first via MCP browser to find a real record ID
60
- 2. Use that ID in the page selector value
61
- 3. Use `User is on [X] page` — sungen resolves the path from the selector
62
-
63
- ```yaml
64
- # selectors.yaml — full path with real ID (generated during make-test)
65
- user detail:
66
- type: 'page'
67
- value: '/admin/users/de42d800-0f5a-490e-9dcf-344fedbd34a5'
68
- ```
69
-
70
- ```gherkin
71
- Scenario: VP-UI-001 User detail displays name
72
- Given User is on [User Detail] page
73
- And User wait for [User Name] heading is visible
74
- Then User see [User Name] heading with {{user_name}}
75
- ```
76
-
77
- Note: the selector uses a hardcoded ID from the live page. If the record is deleted, update the ID in `selectors.yaml`.
98
+ For screens like `/admin/users/:id` or `/products/:slug`, write Gherkin normally (`User is on [User Detail] page`). The real ID will be resolved during `/sungen:make-test` when selectors are generated from the live page. See `sungen-selector-fix` skill for details.
78
99
 
79
100
  ### Section-Focused Approach
80
101
 
@@ -113,71 +134,90 @@ For each selected section, generate **20+ scenarios per applicable viewpoint**.
113
134
 
114
135
  Present a test plan summary and wait for user confirmation before generating files.
115
136
 
137
+ ### Assertion Quality Rules
138
+
139
+ **CRITICAL** — these rules prevent shallow, low-value test cases:
140
+
141
+ 1. **NEVER use `is visible`** — `User see [T] type` already asserts visibility. Writing `is visible` is redundant noise. Only use `is hidden` to assert something is NOT shown.
142
+ 2. **Group related assertions** — one scenario can have 3-7 `Then/And` steps. Don't waste a whole scenario on one element. Group elements that verify the same concern.
143
+ 3. **Assert content, not just existence** — verify values, text, states, not just "it's there":
144
+ - `User see [Title] heading with {{page_title}}` — verify text
145
+ - `User see [Email] field with {{default_email}}` — verify default value
146
+ - `User see [Submit] button is disabled` — verify state
147
+ - `User see [Error] message with {{error_text}}` — verify exact error
148
+ 4. **Every assertion must have test value** — if you write `User see [T] type`, ask: what EXACTLY should the user see? Add `with {{value}}` or `is state` whenever the expected content/state is known.
149
+
150
+ **Bad** (shallow — just checks existence):
151
+ ```gherkin
152
+ Scenario: VP-UI-001 Email field is visible
153
+ Given User is on [Login] page
154
+ Then User see [Email] field is visible
155
+
156
+ Scenario: VP-UI-002 Password field is visible
157
+ Given User is on [Login] page
158
+ Then User see [Password] field is visible
159
+ ```
160
+
161
+ **Good** (rich — verifies content, states, groups related checks):
162
+ ```gherkin
163
+ Scenario: VP-UI-001 Login form displays all fields with correct defaults
164
+ Given User is on [Login] page
165
+ Then User see [Login] heading with {{login_title}}
166
+ And User see [Email] field
167
+ And User see [Password] field
168
+ And User see [Remember me] checkbox is unchecked
169
+ And User see [Submit] button is enabled
170
+ And User see [Forgot password] link
171
+ ```
172
+
116
173
  ### Viewpoint Categories
117
174
 
118
175
  | VP Category | Description |
119
176
  |---|---|
120
- | **UI/UX** | Default appearance, element visibility, default states |
121
- | **Validation** | Input validation, error messages, edge cases. **Must explore live page via MCP to capture actual error messages before writing tests. Use `User see {{error_var}}` pattern never assert just "is visible".** |
177
+ | **UI/UX** | Default appearance, default values/text, default states. Group related elements per scenario. |
178
+ | **Validation** | Input validation, error messages, edge cases. **Assert exact error messages via `User see [T] with {{error_var}}`**store texts in test-data.yaml. |
122
179
  | **Logic** | Business logic, interactions, state changes |
123
180
  | **Security** | Auth guards, injection, permission checks |
124
181
 
125
182
  ### Coverage Checklist per Section Pattern
126
183
 
127
- Apply the relevant checklist based on the section pattern:
128
-
129
184
  #### Form sections
130
- - **UI/UX**: All fields visible, labels correct, default values, placeholder text, required indicators
131
- - **Validation**: Empty submit, each required field empty, invalid format (email, phone, URL), min/max length, special chars, unicode, XSS, SQL injection, whitespace-only, boundary values — **assert exact error messages via `User see {{error_var}}`**, store texts in test-data.yaml
132
- - **Logic**: Successful submit, submit with all optional fields, edit existing record, cancel resets form, field dependencies (show/hide), auto-complete, date range validation
133
- - **Security**: CSRF protection, unauthorized submit, role-based field visibility, input sanitization
185
+ - **UI/UX**: All fields + labels + default values in 1-2 grouped scenarios. Default states (button enabled/disabled, checkbox unchecked). Placeholder text via `with {{placeholder}}`.
186
+ - **Validation**: Empty submit verify all error messages. Each required field empty individually verify specific error. Invalid formats → verify specific error. Boundary values (min/max length). Special chars, unicode, XSS, SQL injection.
187
+ - **Logic**: Successful submit verify success state/redirect. Edit existing verify pre-filled values. Cancel → verify form resets. Field dependencies (show/hide).
188
+ - **Security**: Unauthorized submit, role-based field visibility, input sanitization
134
189
 
135
190
  #### Data Table sections
136
- - **UI/UX**: All columns visible, column headers, row data displays correctly, empty state, loading state, action buttons visible
137
- - **Validation**: N/A (read-only) or inline edit validation
138
- - **Logic**: Sort ascending/descending per sortable column, filter by each column, search within table, row action menu (edit/delete/view), bulk select, bulk action, row click navigation, column resize
139
- - **Security**: Cannot access other users' data, action permissions per role, data not exposed in DOM
191
+ - **UI/UX**: All column headers in one scenario. Row data displays with correct values. Empty state message. Action buttons per row.
192
+ - **Logic**: Sort ascending/descending. Filter by column. Search. Row actions (edit/delete/view). Bulk select + action.
193
+ - **Security**: Action permissions per role
140
194
 
141
195
  #### Search & Filter sections
142
- - **UI/UX**: Search field visible, filter buttons visible, clear button state
143
- - **Validation**: Empty search, special chars, SQL injection, XSS, very long text, unicode/emoji, whitespace, partial match, case insensitive
144
- - **Logic**: Apply single filter, combine multiple filters, clear single filter, clear all filters, search + filter combined, filter persists across pagination, no results state
145
- - **Security**: Injection via search, injection via filter params
196
+ - **UI/UX**: Search field + filter buttons + clear button states in one scenario
197
+ - **Validation**: Empty search, special chars, injection, long text, unicode
198
+ - **Logic**: Apply/clear single filter, combine filters, no results state with message
199
+ - **Security**: Injection via search/filter params
146
200
 
147
201
  #### Pagination sections
148
- - **UI/UX**: Page indicator visible, previous disabled on page 1, next enabled
149
- - **Logic**: Next page, previous page, navigate to last page, boundary (first/last), page indicator updates, data refreshes on navigation
150
- - **Security**: Filters persist across pages, search persists, cannot access page beyond max
202
+ - **UI/UX**: Page indicator + button states (previous disabled on page 1, next enabled)
203
+ - **Logic**: Navigate pages, boundary behavior, indicator updates
151
204
 
152
205
  #### Modal / Dialog sections
153
- - **UI/UX**: Modal opens, close button visible, overlay visible, form fields inside modal
154
- - **Validation**: Submit empty form in modal, field validation inside modal
155
- - **Logic**: Open modal, close with X, close with Escape, close with overlay click, submit success closes modal, submit error keeps modal open
156
- - **Security**: Cannot open unauthorized modals, CSRF on modal submit
157
-
158
- #### Card Grid / List sections
159
- - **UI/UX**: Cards display all expected fields (title, image, description, metadata), empty state, loading state
160
- - **Logic**: Click card navigates to detail, load more / infinite scroll, card action buttons (like, share, delete), responsive layout
161
- - **Security**: User-generated content sanitized, cannot access other users' cards
162
-
163
- #### Carousel / Slider sections
164
- - **UI/UX**: Arrows visible, indicators visible, current slide highlighted
165
- - **Logic**: Next slide, previous slide, wrap at end, auto-play, indicator click navigates, swipe gesture
166
- - **Security**: N/A
206
+ - **UI/UX**: Modal content + all fields + close button in one scenario
207
+ - **Validation**: Field validation inside modal with exact errors
208
+ - **Logic**: Open/close methods (X, Escape, overlay), submit success/error behavior
167
209
 
168
210
  #### Tabs / Accordion sections
169
- - **UI/UX**: All tabs visible, active tab highlighted, default tab selected
170
- - **Logic**: Switch tabs, content updates per tab, deep link to tab, accordion expand/collapse, only one accordion open at a time
171
- - **Security**: Tab content respects permissions
211
+ - **UI/UX**: All tab labels + active tab highlighted + default tab content
212
+ - **Logic**: Switch tabs verify content changes, accordion expand/collapse
172
213
 
173
214
  ### General Coverage Dimensions (aim for 20+ total per viewpoint)
174
215
 
175
- **Happy paths (3-5):** Standard flow, all optional fields, minimum required
176
- **Edge cases (5-8):** Empty, max length, special chars, unicode/CJK/emoji, whitespace, leading/trailing spaces, overflow
177
- **Boundary values (3-5):** At min/max limit, one above/below, zero/null
178
- **Negative cases (3-5):** Invalid format, missing required, wrong type, injection attempts
179
- **State transitions (2-4):** Before/after action, undo, cancel mid-flow
180
- **Combinatorial (2-4):** Multiple invalid fields, valid+invalid combos, different roles
216
+ **Happy paths (3-5):** Standard flow with full assertion of result state
217
+ **Edge cases (5-8):** Empty, max length, special chars, unicode, whitespace, boundary values
218
+ **Negative cases (3-5):** Invalid format, missing required, wrong type, exact error messages
219
+ **State transitions (2-4):** Before/after action, verify both old and new state
220
+ **Combinatorial (2-4):** Multiple invalid fields, valid+invalid combos
181
221
 
182
222
  ### SPA Wait-For Steps
183
223
 
@@ -208,24 +248,37 @@ Feature: <Screen> Screen
208
248
  # Section: Create User Form
209
249
  # ============================================================
210
250
 
211
- # --- UI/UX (20+) ---
251
+ # --- UI/UX ---
212
252
 
213
- Scenario: VP-UI-001 Name field is visible
214
- ...
253
+ Scenario: VP-UI-001 Form displays all fields with correct defaults
254
+ Given User is on [Create User] page
255
+ Then User see [Create User] heading with {{form_title}}
256
+ And User see [Name] field
257
+ And User see [Email] field
258
+ And User see [Role] dropdown with {{default_role}}
259
+ And User see [Submit] button is disabled
260
+ And User see [Cancel] button is enabled
215
261
 
216
- # --- Validation (20+) ---
262
+ # --- Validation ---
217
263
 
218
- Scenario: VP-VAL-001 Submit with empty name
219
- ...
264
+ Scenario: VP-VAL-001 Submit with all empty fields shows errors
265
+ Given User is on [Create User] page
266
+ When User click [Submit] button
267
+ Then User see [Name error] message with {{name_required_error}}
268
+ And User see [Email error] message with {{email_required_error}}
220
269
 
221
270
  # ============================================================
222
271
  # Section: User Table
223
272
  # ============================================================
224
273
 
225
- # --- UI/UX (20+) ---
274
+ # --- UI/UX ---
226
275
 
227
- Scenario: VP-UI-025 Table displays all columns
228
- ...
276
+ Scenario: VP-UI-010 Table displays all columns
277
+ Given User is on [Users] page
278
+ Then User see [Name] column in [Users] table
279
+ And User see [Email] column in [Users] table
280
+ And User see [Status] column in [Users] table
281
+ And User see [Actions] column in [Users] table
229
282
  ```
230
283
 
231
284
  **Naming convention:** `VP-<CATEGORY>-<NNN>` prefix in Scenario name.
@@ -24,15 +24,23 @@ Run with #tool:terminal:
24
24
  sungen add --screen ${input:screen} --path ${input:path}
25
25
  ```
26
26
 
27
- ### 2. Create test cases
27
+ ### 2. Fill requirements (recommended)
28
+
29
+ Ask the user: "Would you like to fill in `requirements/spec.md` now? This helps generate higher quality test cases."
30
+
31
+ - If yes → open `qa/screens/${input:screen}/requirements/spec.md` and help the user fill sections, fields, validation rules, business rules, and states.
32
+ - If they have UI designs (screenshots, Figma exports, mockups) → suggest copying them to `requirements/ui/`.
33
+ - If no → proceed to step 3.
34
+
35
+ ### 3. Create test cases
28
36
 
29
37
  Ask the user: "Would you like to create test cases now?"
30
38
 
31
- If yes, tell the user to run `/sungen-make-tc ${input:screen}`.
39
+ If yes → **tell the user to run `/sungen-make-tc ${input:screen}` as a separate command.** Do NOT attempt to generate test cases yourself in this session — the `make-tc` command auto-loads the `sungen-gherkin-syntax` and `sungen-tc-generation` skills which contain the full Gherkin syntax rules, pattern shapes, viewpoint checklists, and output format.
32
40
 
33
- ### 3. Confirm
41
+ ### 4. Confirm
34
42
 
35
- Tell the user what was created and next steps:
36
- - If the page requires authentication, the user will be asked to log in via the MCP browser during `/sungen-make-tc`
43
+ If the user declined test case creation, tell them next steps:
44
+ - Fill `requirements/spec.md` with screen specs (if not done)
37
45
  - Run `/sungen-make-tc` to create test cases
38
46
  - Run `/sungen-make-test` to generate selectors, compile, and run tests
@@ -20,9 +20,17 @@ You are a **Senior QA Engineer**. You structure test cases by viewpoint categori
20
20
 
21
21
  1. Verify `qa/screens/${input:screen}/` exists. If not → run `/sungen-add-screen` first.
22
22
  2. Check if `.feature` already has scenarios. If yes → summarize existing coverage and ask: **1) Add new sections**, **2) Add viewpoints to existing sections**, or **3) Replace all**. See `sungen-tc-generation` skill for update mode details.
23
- 3. Ask the user: "How should I explore the page? **1) Live page** (via Playwright MCP) or **2) Static designs** (screenshots, Figma)?". If live page, explore via #tool:playwright (see [copilot-instructions.md](../../copilot-instructions.md) for MCP rules). If auth needed, ask user to log in manually.
24
- 4. Identify screen sectionsask user which to focus on (per `sungen-tc-generation` skill). Present sections as a numbered list and let user pick.
25
- 5. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
26
- 6. Show summary next: `/sungen-make-test ${input:screen}`
23
+ 3. **Read requirements** check `qa/screens/${input:screen}/requirements/`:
24
+ - If `spec.md` existsread it as PRIMARY source (sections, fields, validation rules, business rules, states).
25
+ - If `ui/` has images read them for visual context (layout, element positions, states).
26
+ - If `notes.md` existsread for edge cases and additional context.
27
+ - Summarize what you found in requirements and present to the user.
28
+ 4. **Explore page** (supplements requirements, or is primary source if no requirements):
29
+ - Ask: "How should I explore the page? **1) Live page** (via Playwright MCP) or **2) Static designs** (screenshots, Figma) or **3) Skip** (if requirements are sufficient)?"
30
+ - If live page, explore via #tool:playwright (see [copilot-instructions.md](../../copilot-instructions.md) for MCP rules). If auth needed, ask user to log in manually.
31
+ - If exploring, verify and supplement requirements — flag any discrepancies found.
32
+ 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.
33
+ 6. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
34
+ 7. Show summary → next: `/sungen-make-test ${input:screen}`
27
35
 
28
36
  **No selectors.yaml** — selectors are generated during `/sungen-make-test`.
@@ -19,9 +19,14 @@ You are a **Senior Developer** specialized in Playwright test debugging. You gen
19
19
  ## Steps
20
20
 
21
21
  1. Verify `qa/screens/${input:screen}/` has `.feature` + `test-data.yaml`. If not → run `/sungen-make-tc` first.
22
- 2. Explore live page via #tool:playwright to generate `selectors.yaml` (per `sungen-selector-fix` skill).
23
- 3. Compile with #tool:terminal: `sungen generate --screen ${input:screen}`
24
- 4. Run with #tool:terminal: `npx playwright test specs/generated/${input:screen}/*.spec.ts`
25
- 5. If fail fix selectors/test-data per `sungen-selector-fix` + `sungen-error-mapping` skills, retry (max 5).
26
- 6. After 5 fails ask user about direct `.spec.ts` fix.
27
- 7. Show: pass/fail, attempt count, files changed.
22
+ 2. **Generate selectors** — explore live page via #tool:playwright, build `selectors.yaml` (per `sungen-selector-fix` skill).
23
+ 3. **Proactive validation** verify EVERY selector against the live page using `browser_snapshot` + `browser_evaluate` BEFORE running any test. Fix mismatches immediately. See `sungen-selector-fix` skill "Proactive Selector Validation" section. Target: 80%+ issues fixed before first run.
24
+ 4. **Compile** with #tool:terminal: `sungen generate --screen ${input:screen}`
25
+ 5. **Batched test run** run tests in batches of 20 via `--grep`:
26
+ `npx playwright test specs/generated/${input:screen}/*.spec.ts --grep "VP-UI-001|...|VP-UI-020" --reporter=line`
27
+ - If failures in batch → group by root cause, fix, recompile, re-run only failing tests
28
+ - If batch passes → move to next 20 tests
29
+ - Max 5 fix attempts per batch
30
+ 6. **Final confirmation** — run ALL tests once to catch regressions.
31
+ 7. After 5 fix attempts still failing → ask user about direct `.spec.ts` fix.
32
+ 8. Show: pass/fail, attempt count, files changed.
@@ -6,16 +6,29 @@ user-invocable: false
6
6
 
7
7
  ## Playwright Errors → Fix
8
8
 
9
- | Error | Fix in `selectors.yaml` |
9
+ | Error | Fix |
10
10
  |---|---|
11
- | strict mode violation | add `nth`, `exact: true`, or specific `name` |
12
- | Element is not an input | change `type` or `value` |
13
- | Timeout waiting for selector | fix `type`/`value`/`name` to match element |
14
- | toBeVisible Timeout | verify accessible name or use `testid` |
15
- | toHaveText mismatch | fix in `test-data.yaml` |
16
- | Navigation failed | fix page `value` path |
17
- | not a select | set `variant: 'custom'` |
18
- | Frame not found | fix `frame` value |
11
+ | strict mode violation | add `nth`, `exact: true`, or specific `name` in selectors.yaml |
12
+ | Element is not an input | change `type` or `value` in selectors.yaml |
13
+ | Timeout waiting for selector | fix `type`/`value`/`name` to match element in selectors.yaml |
14
+ | toBeVisible Timeout | verify accessible name or use `testid` in selectors.yaml |
15
+ | toHaveText mismatch | fix expected text in `test-data.yaml` — OR if element is an input (field/textarea/search/dropdown), change Gherkin type so compiler uses `toHaveValue` instead |
16
+ | toHaveValue mismatch | fix expected value in `test-data.yaml` this is for input elements (field, textarea, search, dropdown, slider, date-picker) |
17
+ | toContainText mismatch | fix expected partial text in `test-data.yaml` |
18
+ | Navigation failed | fix page `value` path in selectors.yaml |
19
+ | not a select | set `variant: 'custom'` in selectors.yaml |
20
+ | Frame not found | fix `frame` value in selectors.yaml |
21
+ | dialog was dismissed | alert step is AFTER the trigger — move `click [OK] alert` BEFORE the button click that opens the dialog |
22
+ | page.once('dialog') never fired | no browser dialog appeared — check if the action actually triggers a `window.alert/confirm/prompt`, not a CSS modal |
23
+
24
+ ### Assertion type mismatch (toHaveText vs toHaveValue)
25
+
26
+ Sungen picks the assertion based on element type:
27
+ - **Input types** (`field`, `textarea`, `search`, `dropdown`, `slider`, `date-picker`) → `toHaveValue()`
28
+ - **Text types** (everything else: `message`, `header`, `label`, `row`, etc.) → `toHaveText()`
29
+ - **Partial match** (uses `contains` keyword) → `toContainText()`
30
+
31
+ If you see `toHaveText` failing on an input element, the Gherkin step has the wrong target type. Fix: change the target type in the `.feature` file (e.g., `see [Email] message with {{v}}` → `see [Email] field with {{v}}`).
19
32
 
20
33
  ## Auth Errors → Fix
21
34