@sun-asterisk/sungen 2.4.2 → 2.4.5

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 (73) hide show
  1. package/dist/cli/commands/add.d.ts.map +1 -1
  2. package/dist/cli/commands/add.js +7 -1
  3. package/dist/cli/commands/add.js.map +1 -1
  4. package/dist/cli/index.js +1 -1
  5. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  6. package/dist/generators/test-generator/code-generator.js +27 -4
  7. package/dist/generators/test-generator/code-generator.js.map +1 -1
  8. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  9. package/dist/orchestrator/ai-rules-updater.js +2 -0
  10. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  11. package/dist/orchestrator/project-initializer.d.ts +4 -0
  12. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  13. package/dist/orchestrator/project-initializer.js +20 -3
  14. package/dist/orchestrator/project-initializer.js.map +1 -1
  15. package/dist/orchestrator/screen-manager.d.ts +9 -0
  16. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  17. package/dist/orchestrator/screen-manager.js +120 -0
  18. package/dist/orchestrator/screen-manager.js.map +1 -1
  19. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +22 -19
  20. package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +10 -2
  21. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +5 -0
  22. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +25 -16
  23. package/dist/orchestrator/templates/ai-instructions/claude-config.md +4 -97
  24. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +48 -122
  25. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +172 -25
  26. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +62 -34
  27. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +19 -14
  28. package/dist/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +99 -0
  29. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +151 -64
  30. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +21 -15
  31. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +10 -3
  32. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +5 -0
  33. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +24 -15
  34. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +4 -97
  35. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +48 -122
  36. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +172 -25
  37. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +63 -29
  38. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +19 -14
  39. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +99 -0
  40. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +151 -64
  41. package/dist/orchestrator/templates/readme.md +1 -1
  42. package/dist/orchestrator/templates/tsconfig.json +21 -0
  43. package/package.json +1 -1
  44. package/src/cli/commands/add.ts +8 -1
  45. package/src/cli/index.ts +1 -1
  46. package/src/generators/test-generator/code-generator.ts +29 -4
  47. package/src/orchestrator/ai-rules-updater.ts +2 -0
  48. package/src/orchestrator/project-initializer.ts +24 -3
  49. package/src/orchestrator/screen-manager.ts +125 -0
  50. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +22 -19
  51. package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +10 -2
  52. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +5 -0
  53. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +25 -16
  54. package/src/orchestrator/templates/ai-instructions/claude-config.md +4 -97
  55. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +48 -122
  56. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +172 -25
  57. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +62 -34
  58. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +19 -14
  59. package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +99 -0
  60. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +151 -64
  61. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +21 -15
  62. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +10 -3
  63. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +5 -0
  64. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +24 -15
  65. package/src/orchestrator/templates/ai-instructions/copilot-config.md +4 -97
  66. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +48 -122
  67. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +172 -25
  68. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +63 -29
  69. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +19 -14
  70. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +99 -0
  71. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +151 -64
  72. package/src/orchestrator/templates/readme.md +1 -1
  73. package/src/orchestrator/templates/tsconfig.json +21 -0
@@ -20,16 +20,16 @@ user-invocable: false
20
20
 
21
21
  ### Coverage (40 pts)
22
22
 
23
- | Dimension | Pts | Min scenarios |
24
- |---|---|---|
25
- | Happy paths | 8 | 3-5 |
26
- | Negative cases | 8 | 3-5 |
27
- | Edge cases | 8 | 5-8 |
28
- | Boundary values | 6 | 3-5 |
29
- | State transitions | 5 | 2-4 |
30
- | Combinatorial | 5 | 2-4 |
23
+ | Dimension | Technique | Pts | What to check |
24
+ |---|---|---|---|
25
+ | Happy paths | — | 8 | Core success flows exist |
26
+ | Negative cases | EP | 8 | One scenario per invalid class, no redundant same-class scenarios |
27
+ | Edge cases | EP | 6 | Empty, null, whitespace, special chars covered |
28
+ | Boundary values | BVA | 8 | `min-1`, `min`, `max`, `max+1` for each spec range |
29
+ | State transitions | ST | 5 | Valid transitions + key blocked paths from spec |
30
+ | Condition combos | DT | 5 | Dependent conditions covered, distinct outcomes tested |
31
31
 
32
- Score: `(dimensions_covered / 6) * 40`. Per-pattern checklists → `sungen-viewpoint` skill.
32
+ Score: `(dimensions_covered / 6) * 40`. Validate technique application with `sungen-test-design-techniques`. Per-pattern checklists → `sungen-viewpoint` skill.
33
33
 
34
34
  ### Viewpoint (30 pts)
35
35
 
@@ -37,7 +37,8 @@ Score: `(dimensions_covered / 6) * 40`. Per-pattern checklists → `sungen-viewp
37
37
  |---|---|
38
38
  | All applicable VP present (UI/VAL/LOGIC/SEC) | 10 |
39
39
  | Correct classification | 8 |
40
- | `VP-<CAT>-<NNN>` naming + section grouping | 8 |
40
+ | `VP-<CAT>-<NNN>` naming + section grouping | 4 |
41
+ | Priority tag present and correct (`@critical`/`@high`/`@normal`/`@low`) | 4 |
41
42
  | Assertion quality (see rules below) | 4 |
42
43
 
43
44
  **Classification**: UI = static/always-same appearance. VAL = input validation/errors. LOGIC = behavior/state changes (includes persisted state without When). SEC = auth/permissions.
@@ -58,6 +59,7 @@ Score: `(dimensions_covered / 6) * 40`. Per-pattern checklists → `sungen-viewp
58
59
  2. **`When fill [X]`** → Then must assert the **visible result** (search results, validation error). Don't re-assert the field value.
59
60
  3. **UI-only scenarios** (no action needed) → use Given + Then without When.
60
61
  4. **Scenario name must match the assertion**, not the action.
62
+ 5. **Scenario name must use the same element type as the steps** — e.g., "dialog opens" + `[X] dialog`, never "modal opens" + `[X] dialog`.
61
63
 
62
64
  ### @manual Rules
63
65
 
@@ -72,13 +74,16 @@ Do NOT mark `@manual` when data is visible in snapshot or documented in spec —
72
74
 
73
75
  ## Checklist (auto-fix on detection)
74
76
 
75
- 1. **Redundant scenarios** — keep stronger assertion, remove weaker duplicate
77
+ 1. **Redundant scenarios (EP violation)** — multiple scenarios testing same equivalence class? Keep one representative, remove rest
76
78
  2. **Misclassified VP** — UI tests behavior? Move to LOGIC. Logic tests appearance? Move to UI
77
79
  3. **Dynamic content** — exact match on counters/timestamps? Use `contains` instead
78
80
  4. **Duplicate across sections** — SEC scenario identical to UI? Remove duplicate
79
- 5. **Always-enabled elements** — `is enabled` on never-disabled element? Remove
80
- 6. **Test-data completeness** — every `{{var}}` must exist in test-data.yaml
81
- 7. **Missing negative/boundary** — every form section needs at least: empty field, invalid format, boundary value
81
+ 5. **Missing/wrong priority tag** — every non-`@steps` scenario needs exactly one of `@critical`/`@high`/`@normal`/`@low`. SEC→`@critical`, VAL required→`@high`, UI layout→`@normal`, hover/tooltip→`@low`
82
+ 6. **Always-enabled elements** — `is enabled` on never-disabled element? Remove
83
+ 7. **Test-data completeness** — every `{{var}}` must exist in test-data.yaml
84
+ 8. **Missing BVA boundaries** — spec defines min/max range but scenarios only test midpoint? Add `min-1`, `min`, `max`, `max+1`
85
+ 9. **Missing state transitions** — spec defines lifecycle states but only happy path tested? Add blocked transitions
86
+ 10. **Uncovered condition combos** — spec has 2+ dependent conditions but only partial combinations tested? Build decision table
82
87
 
83
88
  ---
84
89
 
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: sungen-test-design-techniques
3
+ description: 'Test design techniques (EP, BVA, Decision Table, State Transition) for systematic scenario generation from spec constraints. Auto-loaded by create-test command.'
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## When to Apply
8
+
9
+ | Technique | Apply when spec mentions |
10
+ |---|---|
11
+ | EP (Equivalence Partitioning) | Input types, categories, roles, valid/invalid ranges |
12
+ | BVA (Boundary Value Analysis) | Numeric range, string length, date range, count limit |
13
+ | Decision Table | 2+ mutually dependent conditions with different outcomes |
14
+ | State Transition | Entity lifecycle, workflow states, status changes |
15
+
16
+ **Rule:** These techniques determine **how many** and **which** scenarios to generate. `sungen-viewpoint` determines **which viewpoints** to cover.
17
+
18
+ ---
19
+
20
+ ## 1. Equivalence Partitioning (EP)
21
+
22
+ **Goal:** One representative per input class. If one value in a partition passes, all values in that partition pass.
23
+
24
+ **How to apply:**
25
+ 1. Extract partitions from `spec.md` constraints (e.g., field accepts 1-100)
26
+ 2. Valid class: 1 <= value <= 100
27
+ 3. Invalid class (below): value < 1
28
+ 4. Invalid class (above): value > 100
29
+ 5. Write **one** scenario per class
30
+
31
+ **Anti-pattern:**
32
+ ```gherkin
33
+ # BAD — 3 scenarios, same class, same result:
34
+ Scenario: VP-VAL-001 Enter value 10
35
+ Scenario: VP-VAL-002 Enter value 50
36
+ Scenario: VP-VAL-003 Enter value 80
37
+ ```
38
+ ```gherkin
39
+ # GOOD — one representative per class:
40
+ Scenario: VP-VAL-001 Valid range value is accepted # value = 50
41
+ Scenario: VP-VAL-002 Below minimum is rejected # value = 0
42
+ Scenario: VP-VAL-003 Above maximum is rejected # value = 101
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. Boundary Value Analysis (BVA)
48
+
49
+ **Goal:** Test exact edges where off-by-one errors occur (`>` vs `>=`, `<` vs `<=`).
50
+
51
+ ### Two modes
52
+
53
+ | Mode | Values | Use when |
54
+ |---|---|---|
55
+ | **Compact (default)** | `min-1`, `min`, `max`, `max+1` | Most fields |
56
+ | **Full 6-point** | `min-1`, `min`, `min+1`, `max-1`, `max`, `max+1` | Critical fields with `@critical`/`@high` priority |
57
+
58
+ **How to apply** (example: "quantity must be 1-10"):
59
+ - `min-1` = 0 -> invalid
60
+ - `min` = 1 -> valid (lower boundary)
61
+ - `max` = 10 -> valid (upper boundary)
62
+ - `max+1` = 11 -> invalid
63
+ - Midpoint (e.g., 5) already covered by EP valid class
64
+
65
+ **BVA scenarios** (example: quantity 1-10):
66
+ - `@high VP-VAL-010 Below minimum (0) is rejected`
67
+ - `@high VP-VAL-011 Minimum boundary (1) is accepted`
68
+ - `@high VP-VAL-012 Maximum boundary (10) is accepted`
69
+ - `@high VP-VAL-013 Above maximum (11) is rejected`
70
+
71
+ ---
72
+
73
+ ## 3. Decision Table
74
+
75
+ **Goal:** Cover all condition combinations when 2+ conditions constrain each other.
76
+
77
+ **How to apply:** List conditions from `spec.md` → build combination→outcome table → one scenario per row.
78
+
79
+ **Cap:** When >3 boolean conditions (>8 rows), prioritize rows with **distinct outcomes** and add `@manual` for exhaustive combos.
80
+
81
+ **Example** — Submit requires valid form AND permission → 4 combos, 2 distinct outcomes:
82
+ - `@normal` Form invalid + no permission → disabled
83
+ - `@normal` Form valid + no permission → disabled
84
+ - `@normal` Has permission + form invalid → disabled
85
+ - `@critical` Form valid + has permission → succeeds
86
+
87
+ ---
88
+
89
+ ## 4. State Transition
90
+
91
+ **Goal:** Verify every valid transition AND block invalid ones.
92
+
93
+ **How to apply:** Extract state diagram from `spec.md` → one scenario per valid transition + key invalid transitions.
94
+
95
+ **Example** — Order lifecycle (Draft→Pending→Approved→Completed):
96
+ - `@high` Valid: Draft → Pending, Pending → Approved, Approved → Completed
97
+ - `@normal` Invalid: Completed → Draft (blocked), Pending → Completed (skip approval)
98
+
99
+ **test-data:** Use named state keys (`order_in_draft`, `order_in_pending`).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sungen-viewpoint
3
- description: '7 UI patterns x 4 viewpoints — structured checklist for test case generation and review. Auto-loaded by make-tc and review commands.'
3
+ description: '10 UI patterns x 4 viewpoints — structured checklist for test case generation and review. Auto-loaded by create-test and review commands.'
4
4
  user-invocable: false
5
5
  ---
6
6
 
@@ -13,148 +13,234 @@ user-invocable: false
13
13
  | **Logic** | Business rules, interactions, state changes | VP-LOGIC |
14
14
  | **Security** | Auth, injection, permissions | VP-SEC |
15
15
 
16
+ ## Shared Checks (apply across all patterns)
17
+
18
+ These appear in multiple patterns — test once per screen, not per pattern:
19
+
20
+ | Check | ER |
21
+ |---|---|
22
+ | **Loading State** | Spinner/skeleton shown, UI interaction locked during fetch |
23
+ | **Empty State** | Clear message when no data, layout intact |
24
+ | **XSS/Injection** | Malicious input sanitized to plain text, never executed |
25
+ | **URL Manipulation** | Invalid URL params fallback to defaults, no server crash |
26
+
16
27
  ---
17
28
 
18
- ## 1. Form & Inputs
29
+ ## GROUP 1: DATA ENTRY
30
+
31
+ ### 1. Form & Inputs
19
32
 
20
33
  **UI/UX**
21
- - Field States: disabled/readonly fields are dimmed and locked
22
- - Button States: Submit disabled when invalid, enabled when valid
23
- - Loading States: Spinner + block UI while waiting for server
24
- - Keyboard Navigation: Tab order correct, Enter submits form
34
+ - Field States: disabled/readonly fields dimmed and locked, no interaction allowed
35
+ - Button States: Submit disabled when form invalid, auto-enabled when valid
36
+ - Keyboard Nav: Tab order correct, Enter submits form
25
37
 
26
38
  **Data & Validate**
27
- - Requirements: required field blank shows error, optional allowed blank
28
- - Boundaries & Types: min/max length, format (email, number) with error messages
29
- - Whitespace: trims excess whitespace or errors on spaces-only
30
- - Error Messaging: error at correct location, disappears on correction (Error Recovery)
39
+ - Required/Optional: blank required field shows error; optional allows blank
40
+ - Boundaries & Format: min/max length, format (email, number) with error messages
41
+ - Whitespace: auto-trim or reject spaces-only input
42
+ - Error Recovery: error at correct field, disappears immediately when user corrects data
31
43
 
32
44
  **Logic**
33
- - Dependencies: Field A value determines Field B status/data
34
- - Submission Control: prevent double submit (disable button after first click)
35
- - Success Flow: redirect / success toast / reset form
45
+ - Field Dependencies: Field A value determines Field B status/options
46
+ - Double Submit Prevention: button disabled after first click, only 1 request sent
47
+ - Success Flow: redirect / success toast / form reset
36
48
  - Failure Flow: server error retains form data + shows system error
37
49
 
38
50
  **Security**
39
- - Injection Protection: XSS/SQL injection sanitized to plain text, never executed
51
+ - Shared: XSS/Injection
40
52
 
41
53
  ---
42
54
 
43
- ## 2. Data Table
55
+ ## GROUP 2: DATA MANAGEMENT
56
+
57
+ ### 2. Data Table
44
58
 
45
59
  **UI/UX**
46
- - Empty State: clear message when no data, layout intact
47
- - Loading State: skeleton/spinner, table interaction locked during fetch
48
- - Layout & Truncation: long content truncated with tooltip, column width stable
60
+ - Shared: Empty State, Loading State
61
+ - Truncation: long content shows `...` with tooltip on hover, column width stable
49
62
  - Sticky Elements: fixed header on vertical scroll, fixed action column on horizontal scroll
50
63
 
51
64
  **Data & Validate**
52
- - Consistency: total record count on UI matches server data
53
- - Row Limit: displayed rows never exceed page size/limit
54
- - Cell Integrity: cell data matches database, correct format (date, currency, status)
55
- - **Use `table match data:` with inline DataTable** for multi-row content verification (filter-based, resilient to data changes)
56
- - Use row scope (`row in [Table] table with {{v}}` + `column with {{v}}`) for single-row detail checks or when you need actions on a row
65
+ - Record Count: "Total records" on UI matches server data exactly
66
+ - Row Limit: displayed rows never exceed configured page size
67
+ - Cell Integrity: cell data matches database, correct format (date, currency, status label)
57
68
 
58
69
  **Logic**
59
- - Sorting: column sort refreshes data with correct order, updates header icon
70
+ - Sorting: column sort refreshes table with correct order, updates header icon
60
71
  - Row Actions: Edit/Delete/View buttons act on correct row ID
61
72
 
62
73
  **Security**
63
- - UI-level RBAC: hide sensitive columns or privileged buttons without authority
64
- - XSS Rendering: malicious code in database displayed as plain text
74
+ - RBAC: hide sensitive columns or privileged action buttons without authority
75
+ - Shared: XSS/Injection (data from DB displayed safely)
76
+
77
+ ---
78
+
79
+ ### 3. Create / Add
80
+
81
+ **UI/UX**
82
+ - Blank Slate: all fields empty or BA-specified defaults, NO cache from previous operation
83
+ - Required Indicator: required fields marked with visual cue (e.g., red *)
84
+ - Unsaved Changes: navigate away with dirty form → browser/system warning popup
85
+
86
+ **Data & Validate**
87
+ - → Inherited: all Form & Inputs validation rules apply
88
+ - Unique Constraint: duplicate unique field (e.g., Employee ID) → reject save, inline error
89
+ - Data Dependency: selecting parent field loads correct child options
90
+
91
+ **Logic**
92
+ - Save & Close: toast notification, redirect to list, new record visible per sort rule
93
+ - Save & Add Another: save to DB, form resets to blank for next entry
94
+ - Double Submit Prevention: → same as Form & Inputs
95
+ - Cancel: form closes, NO garbage record in DB, next open shows blank form
96
+
97
+ **Security**
98
+ - API Bypass / 403: unauthorized POST → system blocks (403 Forbidden), no record created
99
+ - → Shared: XSS/Injection (persisted safely, not executed on display)
100
+
101
+ ---
102
+
103
+ ### 4. Update / Edit
104
+
105
+ **UI/UX**
106
+ - Pre-fill / Data Binding: all fields display exact current DB data (text, dropdown, radio, date...)
107
+ - Readonly Fields: identity fields (ID, username, employee code) disabled, no interaction
108
+ - Cancel: no data changed in DB; if dirty → unsaved changes warning
109
+
110
+ **Data & Validate**
111
+ - → Inherited: all Form & Inputs validation rules apply
112
+ - Unique Self: saving without changing unique field → success, no self-duplicate error
113
+ - Unique Conflict: changing unique field to existing value → duplicate error, block save
114
+ - Unchanged Submit: Save disabled until dirty, or success without DB UPDATE
115
+
116
+ **Logic**
117
+ - Update Success: toast "Updated successfully", new data reflects on UI immediately without reload
118
+ - Concurrent Edit: another user already edited → conflict warning, require reload
119
+
120
+ **Security**
121
+ - Authorization / 403: access edit without permission → 403 page
122
+ - Not Found / 404: edit deleted object → 404
65
123
 
66
124
  ---
67
125
 
68
- ## 3. Search
126
+ ### 5. Delete
69
127
 
70
128
  **UI/UX**
71
- - No Results: "No results found" message, list empty, Clear button visible
72
- - Loading State: spinner/skeleton, list dimmed, interaction locked
129
+ - Confirmation: click Delete MUST show confirmation dialog, delete button in warning color
130
+ - Cancel: popup closes, record intact on UI and DB, no API called
131
+ - Success Update: toast "Deleted successfully", record disappears immediately without reload
132
+ - Pagination Fallback: delete only record on current page → auto-navigate to previous page
133
+
134
+ **Data & Validate — Dependencies**
135
+ - Independent: delete succeeds normally
136
+ - Referenced (Restrict): delete parent with children → blocked, clear error "in use at [Module]"
137
+ - Referenced (Cascade): warning first, then deletes parent AND all related children
138
+ - Referenced (Set Null): parent deleted, child reference set to Unassigned/Empty
139
+
140
+ **Logic — Storage**
141
+ - Soft Delete: record hidden from UI, DB retains with status flag (is_deleted, deleted_at)
142
+ - Hard Delete: record removed from UI AND permanently deleted from DB
143
+
144
+ **Security**
145
+ - Deleted Access / 404: soft or hard delete → direct URL/API returns 404
146
+ - API Bypass: API delete on restricted object → backend rejects with business error, no 500
147
+
148
+ ---
149
+
150
+ ### 6. Search
151
+
152
+ **UI/UX**
153
+ - → Shared: Empty State ("No results found"), Loading State
73
154
  - Clear Action: search box empties, list reloads default data
74
155
 
75
156
  **Data & Validate**
76
- - Cleanup: auto-trim whitespace, results match cleaned keyword
77
- - Input Limits: prevent input beyond max length or show error
78
- - Normalization: case-insensitive matching, handles Vietnamese accents
157
+ - Whitespace: auto-trim, results match cleaned keyword
158
+ - Input Limits: prevent beyond max length or show error
159
+ - Normalization: case-insensitive, handles accented characters correctly
79
160
 
80
161
  **Logic**
81
- - Matching: partial/exact match returns correct results, no 500 errors
82
- - Multi-keyword: results based on AND/OR logic
83
- - Performance: debounce ~300ms before API call
162
+ - Matching: partial/exact match returns correct results, no 500
163
+ - Multi-keyword: results based on AND/OR logic per spec
164
+ - Debounce: ~300ms delay before API call
84
165
 
85
166
  **Security**
86
- - Injection: XSS/SQL encoded as plain text, never executed
87
- - Wildcards: `%, _, *` treated as normal text (escaped)
167
+ - → Shared: XSS/Injection
168
+ - Wildcards: `%`, `_`, `*` treated as literal text (escaped), not DB commands
88
169
 
89
170
  ---
90
171
 
91
- ## 4. Filter
172
+ ### 7. Filter
92
173
 
93
174
  **UI/UX**
94
175
  - Feedback: selected filters displayed as tags/badges
95
176
  - Persistence: collapse/expand retains selected values
96
- - Conflicts: conflicting conditions show "No data" message, header layout intact
177
+ - Conflicts: conflicting conditions show "No data" message, layout intact
97
178
 
98
179
  **Data & Validate**
99
- - Range Validation: start > end or min > max shows field error, Apply button disabled
180
+ - Range Validation: start > end or min > max field error, Apply disabled
100
181
  - Dropdown Integrity: options match 100% of actual data, hide unauthorized values
101
182
 
102
183
  **Logic**
103
- - Logic AND/OR: results satisfy correct filter logic, Total Count updated
184
+ - AND/OR Logic: results satisfy correct filter logic, total count updated
104
185
  - Dependent Filters: selecting Filter A updates Filter B options
105
- - Reset & Navigation: reset returns original data or preserves state depending on action
186
+ - Reset & Navigation: reset returns original data or preserves state per spec
106
187
 
107
188
  **Security**
108
- - URL Manipulation: erroneous URL params ignored, defaults assigned, no 500 error
189
+ - Shared: URL Manipulation
109
190
 
110
191
  ---
111
192
 
112
- ## 5. Pagination
193
+ ### 8. Pagination
113
194
 
114
195
  **UI/UX**
115
196
  - Boundary States: Previous/First disabled on page 1, Next/Last disabled on last page
116
- - Active & Loading: active page highlighted, loading effect during page transition
117
- - Hidden State: pagination bar hidden when data fits one page
197
+ - Active Page: highlighted, loading effect during page transition
198
+ - Hidden: pagination bar hidden when data fits one page
118
199
 
119
200
  **Data & Validate**
120
- - Label Consistency: "Viewing X of Y" matches actual data
201
+ - Label Consistency: "Viewing X of Y" matches actual data exactly
121
202
  - Zero Records: pagination hidden, empty state displayed
122
203
 
123
204
  **Logic**
124
205
  - Navigation: loads correct dataset for page (page 2, limit 10 = records 11-20)
125
206
  - Change Page Size: shows correct quantity, resets to page 1
126
207
  - Interaction Resets: new search/filter resets to page 1
127
- - Delete Fallback: deleting all records on last page pushes to previous page
128
208
 
129
209
  **Security**
130
- - URL Manipulation: invalid page/size in URL fallbacks to defaults, no server crash
210
+ - Shared: URL Manipulation
131
211
 
132
212
  ---
133
213
 
134
- ## 6. Modal / Dialog
214
+ ## GROUP 3: NAVIGATION & CONTAINERS
215
+
216
+ ### 9. Modal / Dialog
135
217
 
136
218
  **UI/UX**
137
- - Overlay & Backdrop: centered modal, backdrop blur, background scroll locked
219
+ - Overlay: centered modal, backdrop blur, background scroll locked
138
220
  - Focus Trapping: Tab key cycles only within modal elements
139
221
  - Responsive: modal resizes, action buttons always visible or scrollable
140
222
 
141
223
  **Data & Validate**
142
- - Dismiss Actions: close via X, Cancel, Escape, backdrop click. Resets data on reopen
224
+ - Dismiss Actions: close via X, Cancel, Escape, backdrop click resets data to default on reopen
143
225
 
144
226
  **Logic**
145
- - Submissions: action button shows loading, modal closes on success, background data updated
146
- - Failure: modal stays open on API error, shows error message, retains entered data
227
+ - Submit Success: action button shows loading, modal closes, background data updated
228
+ - Submit Failure: modal stays open, shows error message, retains entered data
147
229
  - Stacked Modals: Modal B over A has higher z-index, closing B keeps A intact
148
230
 
149
231
  **Security**
150
- - Reload & Security: handles deep linking if present, removes HTML from DOM on close (protect sensitive data)
232
+ - DOM Cleanup: remove HTML from DOM on close to protect sensitive data
233
+ - Reload: handles deep linking if present
151
234
 
152
235
  ---
153
236
 
154
- ## 7. List / Card
237
+ ## GROUP 4: DISPLAY PATTERNS
238
+
239
+ ### 10. List / Card
155
240
 
156
241
  **UI/UX**
157
- - Visual States: empty state when empty, skeleton when loading, hover effect (shadow/scale) on card
242
+ - Shared: Empty State, Loading State
243
+ - Hover Effect: shadow/scale on card hover
158
244
  - Content: text truncation without breaking card height, placeholder image on broken image
159
245
 
160
246
  **Data & Validate**
@@ -164,25 +250,26 @@ user-invocable: false
164
250
  **Logic**
165
251
  - Navigation: clicking card navigates to correct detail page
166
252
  - Direct Actions: Like/Add to Cart updates immediately without reloading list
167
- - Loading Flows: Load More / Infinite Scroll appends records, maintains scroll position
253
+ - Infinite Scroll / Load More: appends records, maintains scroll position
168
254
  - Layout Toggle: Grid/List view switch changes UI but preserves data
169
255
 
170
256
  **Security**
171
- - RBAC & Resilience: hide sensitive data/privileged buttons from DOM. Network loss shows error + "Try again" button
257
+ - RBAC: hide sensitive data or privileged buttons from DOM
258
+ - Network Resilience: error message + "Retry" button on connection loss
172
259
 
173
260
  ---
174
261
 
175
262
  ## Security Tag Rules
176
263
 
177
- For VP-SEC scenarios testing **unauthorized access** (no login, wrong role, direct URL access):
178
- - Use **`@no-auth`** tag — this runs the test without authentication, which is exactly what you want to verify.
179
- - Do NOT use `@manual` for these — they are automatable with `@no-auth`.
264
+ For VP-SEC scenarios testing **unauthorized access** (no login, wrong role, direct URL):
265
+ - Use **`@no-auth`** tag — runs without authentication to verify redirect/block.
266
+ - Do NOT use `@manual` for these — they are automatable.
180
267
 
181
268
  ```gherkin
182
- @no-auth
269
+ @critical @no-auth
183
270
  Scenario: VP-SEC-001 Unauthenticated user cannot access admin page
184
271
  Given User is on [Admin] page
185
272
  Then User see [Login] page
186
273
  ```
187
274
 
188
- Use `@manual` only when the environment truly cannot be set up automatically (e.g., third-party OAuth, physical device).
275
+ Use `@manual` only when the environment truly cannot be set up automatically.
@@ -19,7 +19,7 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
19
19
  │ └── requirements/ # Screen specs, UI designs, notes
20
20
  │ ├── spec.md # Structured screen specification
21
21
  │ ├── ui/ # Screenshots, mockups, design images
22
- │ └── notes.md # Edge cases, decisions (optional)
22
+ │ └── test-viewpoint.md # Edge cases, decisions (optional)
23
23
  ├── specs/
24
24
  │ └── generated/ # Auto-generated Playwright tests
25
25
  ├── .claude/
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "lib": ["ES2020"],
5
+ "module": "commonjs",
6
+ "moduleResolution": "node",
7
+ "types": ["node", "@playwright/test"],
8
+ "strict": false,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "outDir": "./dist",
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "@/*": ["./*"]
17
+ }
18
+ },
19
+ "include": ["specs/**/*.ts", "playwright.config.ts"],
20
+ "exclude": ["node_modules"]
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sungen",
3
- "version": "2.4.2",
3
+ "version": "2.4.5",
4
4
  "description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,19 +3,26 @@ import { Command } from 'commander';
3
3
  export function registerAddCommand(program: Command): void {
4
4
  program
5
5
  .command('add')
6
- .description('Add screen or feature definition with scaffolded files')
6
+ .description('Add screen or feature definition with scaffolded files. Use --capture to auto-capture a live-page screenshot.')
7
7
  .requiredOption('--screen <name>', 'Screen name')
8
8
  .option('-p, --path <path>', 'Screen route path (e.g. /awards)')
9
+ .option('-c, --capture', 'Auto-capture a live-page screenshot to requirements/ui/ (requires --path)')
9
10
  .option('-f, --feature <name>', 'Add additional feature file to existing screen')
10
11
  .option('-d, --description <text>', 'Screen description')
11
12
  .action(async (options) => {
12
13
  try {
14
+ if (options.capture && !options.path) {
15
+ console.error('Error: --capture requires --path to be set');
16
+ process.exit(1);
17
+ }
18
+
13
19
  const { ScreenManager } = require('../../orchestrator/screen-manager');
14
20
  const manager = new ScreenManager();
15
21
 
16
22
  await manager.addScreen({
17
23
  name: options.screen,
18
24
  path: options.path,
25
+ capture: options.capture,
19
26
  feature: options.feature,
20
27
  description: options.description,
21
28
  });
package/src/cli/index.ts CHANGED
@@ -17,7 +17,7 @@ async function main() {
17
17
  program
18
18
  .name('sungen')
19
19
  .description('Deterministic E2E Test Compiler — Gherkin + Selectors → Playwright')
20
- .version('2.4.2');
20
+ .version('2.4.5');
21
21
 
22
22
  // Global options
23
23
  program
@@ -4,6 +4,29 @@ import { ParsedFeature, ParsedScenario, ParsedStep } from '../gherkin-parser';
4
4
  import { StepMapper } from './step-mapper';
5
5
  import { TestGeneratorAdapter, adapterRegistry } from './adapters';
6
6
 
7
+ /**
8
+ * Filter base scenario steps for @extend: only keep Given→When steps.
9
+ * Skips Then and any And/But that follow Then (since And/But inherit
10
+ * from the preceding primary keyword).
11
+ */
12
+ function filterBaseStepsForExtend(steps: ParsedStep[]): ParsedStep[] {
13
+ const result: ParsedStep[] = [];
14
+ let lastPrimaryKeyword = 'Given';
15
+
16
+ for (const step of steps) {
17
+ const kw = step.keyword.trim();
18
+ if (kw === 'Given' || kw === 'When' || kw === 'Then') {
19
+ lastPrimaryKeyword = kw;
20
+ }
21
+ // Skip Then and any And/But that follow Then
22
+ if (lastPrimaryKeyword === 'Then') {
23
+ continue;
24
+ }
25
+ result.push(step);
26
+ }
27
+ return result;
28
+ }
29
+
7
30
  /**
8
31
  * Extract auth role from tags
9
32
  * @auth:admin → 'admin'
@@ -345,8 +368,9 @@ export class CodeGenerator {
345
368
  if (scenario.extendsName) {
346
369
  const baseScenario = this.stepsRegistry.get(scenario.extendsName);
347
370
  if (baseScenario) {
348
- // Prepend base steps inline — fully self-contained, no beforeEach
349
- stepsToMap = [...baseScenario.steps, ...scenario.steps];
371
+ // Prepend base steps inline — only Given→When (skip Then per @extend contract)
372
+ const filteredBaseSteps = filterBaseStepsForExtend(baseScenario.steps);
373
+ stepsToMap = [...filteredBaseSteps, ...scenario.steps];
350
374
  // Auth precedence: extending @auth > base @auth > feature @auth
351
375
  authFeatureTags = [...baseScenario.tags, ...featureTags];
352
376
  } else {
@@ -370,9 +394,10 @@ export class CodeGenerator {
370
394
  if (scenario.extendsName && this.stepsRegistry.has(scenario.extendsName)) {
371
395
  const baseScenario = this.stepsRegistry.get(scenario.extendsName)!;
372
396
 
373
- // Section header: base steps
397
+ // Section header: base steps (only Given→When, skip Then per @extend contract)
398
+ const filteredSteps = filterBaseStepsForExtend(baseScenario.steps);
374
399
  steps.push({ code: ` // [from @steps:${scenario.extendsName}]` });
375
- for (const step of baseScenario.steps) {
400
+ for (const step of filteredSteps) {
376
401
  const mapped = await Promise.resolve(this.stepMapper.mapStep(step));
377
402
  steps.push({ comment: mapped.comment, code: this.indentCode(mapped.code, 4) });
378
403
  }
@@ -29,6 +29,7 @@ export const AI_RULES_FILE_MAPPING: [string, string][] = [
29
29
  ['claude-skill-selector-keys.md', '.claude/skills/sungen-selector-keys/SKILL.md'],
30
30
  ['claude-skill-error-mapping.md', '.claude/skills/sungen-error-mapping/SKILL.md'],
31
31
  ['claude-skill-tc-generation.md', '.claude/skills/sungen-tc-generation/SKILL.md'],
32
+ ['claude-skill-test-design-techniques.md', '.claude/skills/sungen-test-design-techniques/SKILL.md'],
32
33
  ['claude-skill-selector-fix.md', '.claude/skills/sungen-selector-fix/SKILL.md'],
33
34
  ['claude-skill-tc-review.md', '.claude/skills/sungen-tc-review/SKILL.md'],
34
35
  ['claude-skill-viewpoint.md', '.claude/skills/sungen-viewpoint/SKILL.md'],
@@ -38,6 +39,7 @@ export const AI_RULES_FILE_MAPPING: [string, string][] = [
38
39
  ['github-skill-sungen-selector-keys.md', '.github/skills/sungen-selector-keys/SKILL.md'],
39
40
  ['github-skill-sungen-error-mapping.md', '.github/skills/sungen-error-mapping/SKILL.md'],
40
41
  ['github-skill-sungen-tc-generation.md', '.github/skills/sungen-tc-generation/SKILL.md'],
42
+ ['github-skill-sungen-test-design-techniques.md', '.github/skills/sungen-test-design-techniques/SKILL.md'],
41
43
  ['github-skill-sungen-selector-fix.md', '.github/skills/sungen-selector-fix/SKILL.md'],
42
44
  ['github-skill-sungen-tc-review.md', '.github/skills/sungen-tc-review/SKILL.md'],
43
45
  ['github-skill-sungen-viewpoint.md', '.github/skills/sungen-viewpoint/SKILL.md'],