@sun-asterisk/sungen 2.2.3 → 2.3.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.
- package/README.md +6 -6
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +21 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +2 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +16 -2
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +12 -0
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts +9 -0
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +32 -0
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +0 -13
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.js +8 -5
- package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts +13 -0
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -0
- package/dist/orchestrator/ai-rules-updater.js +159 -0
- package/dist/orchestrator/ai-rules-updater.js.map +1 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +2 -27
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts +1 -0
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +70 -3
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +12 -4
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +9 -11
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +228 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +30 -11
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +91 -25
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -71
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +13 -4
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +9 -11
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +228 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +30 -11
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -31
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +92 -72
- package/dist/orchestrator/templates/readme.md +13 -8
- package/package.json +1 -1
- package/src/cli/commands/update.ts +18 -0
- package/src/cli/index.ts +3 -1
- package/src/generators/gherkin-parser/index.ts +19 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
- package/src/generators/test-generator/patterns/assertion-patterns.ts +13 -0
- package/src/generators/test-generator/patterns/index.ts +41 -0
- package/src/generators/test-generator/patterns/interaction-patterns.ts +0 -14
- package/src/generators/test-generator/patterns/table-patterns.ts +8 -5
- package/src/orchestrator/ai-rules-updater.ts +141 -0
- package/src/orchestrator/project-initializer.ts +2 -32
- package/src/orchestrator/screen-manager.ts +72 -3
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +12 -4
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +9 -11
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +228 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +30 -11
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +91 -25
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -71
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +13 -4
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +9 -11
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +228 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +30 -11
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -31
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +92 -72
- package/src/orchestrator/templates/readme.md +13 -8
- package/docs/gherkin standards/gherkin-core-standard.md +0 -431
- package/docs/gherkin standards/gherkin-core-standard.vi.md +0 -399
- package/docs/gherkin-dictionary.md +0 -1126
- package/docs/makeauth.md +0 -225
|
@@ -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,58 @@ 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 & Review Quality
|
|
138
|
+
|
|
139
|
+
For assertion quality rules, action-result coherence rules, and the 9-point quality review checklist, see the `sungen-gherkin-review` skill. That skill is auto-loaded during the self-review step.
|
|
140
|
+
|
|
116
141
|
### Viewpoint Categories
|
|
117
142
|
|
|
118
143
|
| VP Category | Description |
|
|
119
144
|
|---|---|
|
|
120
|
-
| **UI/UX** | Default appearance,
|
|
121
|
-
| **Validation** | Input validation, error messages, edge cases. **
|
|
145
|
+
| **UI/UX** | Default appearance, default values/text, default states. Group related elements per scenario. |
|
|
146
|
+
| **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
147
|
| **Logic** | Business logic, interactions, state changes |
|
|
123
148
|
| **Security** | Auth guards, injection, permission checks |
|
|
124
149
|
|
|
125
150
|
### Coverage Checklist per Section Pattern
|
|
126
151
|
|
|
127
|
-
Apply the relevant checklist based on the section pattern:
|
|
128
|
-
|
|
129
152
|
#### Form sections
|
|
130
|
-
- **UI/UX**: All fields
|
|
131
|
-
- **Validation**: Empty submit
|
|
132
|
-
- **Logic**: Successful submit
|
|
133
|
-
- **Security**:
|
|
153
|
+
- **UI/UX**: All fields + labels + default values in 1-2 grouped scenarios. Default states (button enabled/disabled, checkbox unchecked). Placeholder text via `with {{placeholder}}`.
|
|
154
|
+
- **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.
|
|
155
|
+
- **Logic**: Successful submit → verify success state/redirect. Edit existing → verify pre-filled values. Cancel → verify form resets. Field dependencies (show/hide).
|
|
156
|
+
- **Security**: Unauthorized submit, role-based field visibility, input sanitization
|
|
134
157
|
|
|
135
158
|
#### Data Table sections
|
|
136
|
-
- **UI/UX**: All
|
|
137
|
-
- **
|
|
138
|
-
- **
|
|
139
|
-
- **Security**: Cannot access other users' data, action permissions per role, data not exposed in DOM
|
|
159
|
+
- **UI/UX**: All column headers in one scenario. Row data displays with correct values. Empty state message. Action buttons per row.
|
|
160
|
+
- **Logic**: Sort ascending/descending. Filter by column. Search. Row actions (edit/delete/view). Bulk select + action.
|
|
161
|
+
- **Security**: Action permissions per role
|
|
140
162
|
|
|
141
163
|
#### Search & Filter sections
|
|
142
|
-
- **UI/UX**: Search field
|
|
143
|
-
- **Validation**: Empty search, special chars,
|
|
144
|
-
- **Logic**: Apply single filter, combine
|
|
145
|
-
- **Security**: Injection via search
|
|
164
|
+
- **UI/UX**: Search field + filter buttons + clear button states in one scenario
|
|
165
|
+
- **Validation**: Empty search, special chars, injection, long text, unicode
|
|
166
|
+
- **Logic**: Apply/clear single filter, combine filters, no results state with message
|
|
167
|
+
- **Security**: Injection via search/filter params
|
|
146
168
|
|
|
147
169
|
#### Pagination sections
|
|
148
|
-
- **UI/UX**: Page indicator
|
|
149
|
-
- **Logic**:
|
|
150
|
-
- **Security**: Filters persist across pages, search persists, cannot access page beyond max
|
|
170
|
+
- **UI/UX**: Page indicator + button states (previous disabled on page 1, next enabled)
|
|
171
|
+
- **Logic**: Navigate pages, boundary behavior, indicator updates
|
|
151
172
|
|
|
152
173
|
#### Modal / Dialog sections
|
|
153
|
-
- **UI/UX**: Modal
|
|
154
|
-
- **Validation**:
|
|
155
|
-
- **Logic**: 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
|
|
174
|
+
- **UI/UX**: Modal content + all fields + close button in one scenario
|
|
175
|
+
- **Validation**: Field validation inside modal with exact errors
|
|
176
|
+
- **Logic**: Open/close methods (X, Escape, overlay), submit success/error behavior
|
|
167
177
|
|
|
168
178
|
#### Tabs / Accordion sections
|
|
169
|
-
- **UI/UX**: All
|
|
170
|
-
- **Logic**: Switch tabs
|
|
171
|
-
- **Security**: Tab content respects permissions
|
|
179
|
+
- **UI/UX**: All tab labels + active tab highlighted + default tab content
|
|
180
|
+
- **Logic**: Switch tabs → verify content changes, accordion expand/collapse
|
|
172
181
|
|
|
173
182
|
### General Coverage Dimensions (aim for 20+ total per viewpoint)
|
|
174
183
|
|
|
175
|
-
**Happy paths (3-5):** Standard flow
|
|
176
|
-
**Edge cases (5-8):** Empty, max length, special chars, unicode
|
|
177
|
-
**
|
|
178
|
-
**
|
|
179
|
-
**
|
|
180
|
-
**Combinatorial (2-4):** Multiple invalid fields, valid+invalid combos, different roles
|
|
184
|
+
**Happy paths (3-5):** Standard flow with full assertion of result state
|
|
185
|
+
**Edge cases (5-8):** Empty, max length, special chars, unicode, whitespace, boundary values
|
|
186
|
+
**Negative cases (3-5):** Invalid format, missing required, wrong type, exact error messages
|
|
187
|
+
**State transitions (2-4):** Before/after action, verify both old and new state
|
|
188
|
+
**Combinatorial (2-4):** Multiple invalid fields, valid+invalid combos
|
|
181
189
|
|
|
182
190
|
### SPA Wait-For Steps
|
|
183
191
|
|
|
@@ -208,24 +216,37 @@ Feature: <Screen> Screen
|
|
|
208
216
|
# Section: Create User Form
|
|
209
217
|
# ============================================================
|
|
210
218
|
|
|
211
|
-
# --- UI/UX
|
|
219
|
+
# --- UI/UX ---
|
|
212
220
|
|
|
213
|
-
Scenario: VP-UI-001
|
|
214
|
-
|
|
221
|
+
Scenario: VP-UI-001 Form displays all fields with correct defaults
|
|
222
|
+
Given User is on [Create User] page
|
|
223
|
+
Then User see [Create User] heading with {{form_title}}
|
|
224
|
+
And User see [Name] field
|
|
225
|
+
And User see [Email] field
|
|
226
|
+
And User see [Role] dropdown with {{default_role}}
|
|
227
|
+
And User see [Submit] button is disabled
|
|
228
|
+
And User see [Cancel] button is enabled
|
|
215
229
|
|
|
216
|
-
# --- Validation
|
|
230
|
+
# --- Validation ---
|
|
217
231
|
|
|
218
|
-
Scenario: VP-VAL-001 Submit with empty
|
|
219
|
-
|
|
232
|
+
Scenario: VP-VAL-001 Submit with all empty fields shows errors
|
|
233
|
+
Given User is on [Create User] page
|
|
234
|
+
When User click [Submit] button
|
|
235
|
+
Then User see [Name error] message with {{name_required_error}}
|
|
236
|
+
And User see [Email error] message with {{email_required_error}}
|
|
220
237
|
|
|
221
238
|
# ============================================================
|
|
222
239
|
# Section: User Table
|
|
223
240
|
# ============================================================
|
|
224
241
|
|
|
225
|
-
# --- UI/UX
|
|
242
|
+
# --- UI/UX ---
|
|
226
243
|
|
|
227
|
-
Scenario: VP-UI-
|
|
228
|
-
|
|
244
|
+
Scenario: VP-UI-010 Table displays all columns
|
|
245
|
+
Given User is on [Users] page
|
|
246
|
+
Then User see [Name] column in [Users] table
|
|
247
|
+
And User see [Email] column in [Users] table
|
|
248
|
+
And User see [Status] column in [Users] table
|
|
249
|
+
And User see [Actions] column in [Users] table
|
|
229
250
|
```
|
|
230
251
|
|
|
231
252
|
**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.
|
|
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
|
|
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
|
-
###
|
|
41
|
+
### 4. Confirm
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
-
|
|
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,18 @@ 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.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
3. **Read requirements** — check `qa/screens/${input:screen}/requirements/`:
|
|
24
|
+
- If `spec.md` exists → read 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` exists → read 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. **Self-review** — re-read the `.feature` file and apply the full **`sungen-gherkin-review` skill**: assertion quality rules (4 rules), action-result coherence (5 rules), and the 9-point quality checklist. **Auto-fix any issues found**, then re-read to verify.
|
|
35
|
+
8. Show summary → next: `/sungen-make-test ${input:screen}`
|
|
27
36
|
|
|
28
37
|
**No selectors.yaml** — selectors are generated during `/sungen-make-test`.
|
|
@@ -19,16 +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.
|
|
23
|
-
3.
|
|
24
|
-
4. **
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
- Repeat until no failures remain or max attempts reached
|
|
32
|
-
6. **Final confirmation** — run ALL tests once to ensure no regressions.
|
|
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.
|
|
33
31
|
7. After 5 fix attempts still failing → ask user about direct `.spec.ts` fix.
|
|
34
32
|
8. Show: pass/fail, attempt count, files changed.
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-gherkin-review
|
|
3
|
+
description: 'Quality review checklist for Gherkin test cases — assertion quality rules, action-result coherence, and 9-point checklist. Auto-loaded during self-review step of make-tc.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Assertion Quality Rules
|
|
8
|
+
|
|
9
|
+
**CRITICAL** — these rules prevent shallow, low-value test cases:
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
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.
|
|
13
|
+
3. **Assert content, not just existence** — verify values, text, states, not just "it's there". Every assertion should answer: what EXACTLY should the user see? Add `with {{value}}` or `is state` whenever the expected content/state is known.
|
|
14
|
+
- `User see [Title] heading with {{page_title}}` — verify text
|
|
15
|
+
- `User see [Email] field with {{default_email}}` — verify default value
|
|
16
|
+
- `User see [Submit] button is disabled` — verify state
|
|
17
|
+
- `User see [Error] message with {{error_text}}` — verify exact error
|
|
18
|
+
4. **Don't assume element roles** — never guess the element type (`button`, `option`, `link`, etc.) based on the label or expected behavior. Developers create custom components that don't match standard HTML roles (e.g., a `<div>` styled as a button, a custom dropdown built from `<li>` elements). Always use the **live-page selector scan result** or the selector YAML to determine the correct type. If you haven't scanned the page and the type is uncertain, use a generic type (`text`) or mark the scenario `@manual` until selectors are confirmed.
|
|
19
|
+
|
|
20
|
+
**Bad** (shallow — just checks existence):
|
|
21
|
+
```gherkin
|
|
22
|
+
Scenario: VP-UI-001 Email field is visible
|
|
23
|
+
Given User is on [Login] page
|
|
24
|
+
Then User see [Email] field is visible
|
|
25
|
+
|
|
26
|
+
Scenario: VP-UI-002 Password field is visible
|
|
27
|
+
Given User is on [Login] page
|
|
28
|
+
Then User see [Password] field is visible
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Good** (rich — verifies content, states, groups related checks):
|
|
32
|
+
```gherkin
|
|
33
|
+
Scenario: VP-UI-001 Login form displays all fields with correct defaults
|
|
34
|
+
Given User is on [Login] page
|
|
35
|
+
Then User see [Login] heading with {{login_title}}
|
|
36
|
+
And User see [Email] field
|
|
37
|
+
And User see [Password] field
|
|
38
|
+
And User see [Remember me] checkbox is unchecked
|
|
39
|
+
And User see [Submit] button is enabled
|
|
40
|
+
And User see [Forgot password] link
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Action-Result Coherence Rules
|
|
44
|
+
|
|
45
|
+
Every scenario with a `When` action **must** assert the *result* of that action in `Then` — not just re-assert something already visible.
|
|
46
|
+
|
|
47
|
+
**Anti-patterns (WRONG):**
|
|
48
|
+
```gherkin
|
|
49
|
+
# BAD: click then assert the same element unchanged
|
|
50
|
+
When User click [Select language] button
|
|
51
|
+
Then User see [Select language] button
|
|
52
|
+
|
|
53
|
+
# BAD: fill then assert unrelated page (fill doesn't navigate)
|
|
54
|
+
When User fill [Search] field with {{term}}
|
|
55
|
+
Then User see [Home] page
|
|
56
|
+
|
|
57
|
+
# BAD: action with no meaningful result check
|
|
58
|
+
When User click [Submit] button
|
|
59
|
+
Then User see [Submit] button
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Correct patterns:**
|
|
63
|
+
```gherkin
|
|
64
|
+
# GOOD: click opens something new (dropdown, dialog, page)
|
|
65
|
+
When User click [Select language] button
|
|
66
|
+
Then User see [VN] button
|
|
67
|
+
|
|
68
|
+
# GOOD: click changes state on the element itself
|
|
69
|
+
When User click [Submit] button
|
|
70
|
+
Then User see [Submit] button is disabled
|
|
71
|
+
|
|
72
|
+
# GOOD: click navigates to different page
|
|
73
|
+
When User click [Login] button
|
|
74
|
+
Then User see [Dashboard] page
|
|
75
|
+
|
|
76
|
+
# GOOD: fill triggers visible result (search results, validation)
|
|
77
|
+
When User fill [Search] field with {{term}}
|
|
78
|
+
Then User see [search result] text with {{result_name}}
|
|
79
|
+
|
|
80
|
+
# GOOD: fill then submit, assert result of submission
|
|
81
|
+
When User fill [Email] field with {{invalid_email}}
|
|
82
|
+
And User click [Submit] button
|
|
83
|
+
Then User see [email error] message with {{email_error_text}}
|
|
84
|
+
|
|
85
|
+
# GOOD: click opens dialog
|
|
86
|
+
When User click [Submit] button
|
|
87
|
+
Then User see [Confirm] dialog
|
|
88
|
+
|
|
89
|
+
# GOOD: visibility-only scenario has no When (just Given + Then)
|
|
90
|
+
Given User is on [Login] page
|
|
91
|
+
Then User see [Email] field
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Rules:**
|
|
95
|
+
1. `When click [X]` → `Then` must assert either a **new element appears** (dialog, dropdown, page change, new content) or a **state change on `[X]` itself** (e.g., `is disabled`, `is checked`). Never assert `[X]` unchanged. Asserting something already visible before the click is a pre-existing state error — if the result is uncertain, mark `@manual`.
|
|
96
|
+
2. `When fill [X] field` → `Then` must assert the **visible result of the input** (search results appear, validation message shows, dropdown filters). Do NOT just assert the field has the value — `see [X] field with {{v}}` after fill is a **weak test** (Playwright fill already guarantees the value is set). Only use field value assertion when the field transforms the input (e.g., auto-format phone number, currency mask).
|
|
97
|
+
- **Search fields need a wait step** — search inputs typically have debounce/delay before results appear. After filling a search field, add `User wait for {{search_delay}}` before asserting results. Without this, the assertion fires before results render and the test flakes.
|
|
98
|
+
```gherkin
|
|
99
|
+
# GOOD: wait for debounce before asserting search results
|
|
100
|
+
When User fill [Search] field with {{term}}
|
|
101
|
+
And User wait for {{search_delay}}
|
|
102
|
+
Then User see [search result] text with {{result_name}}
|
|
103
|
+
```
|
|
104
|
+
3. If you only want to verify an element **exists/is visible** — use a UI/UX scenario with **no `When`** (just `Given` + `Then`)
|
|
105
|
+
4. If the result of an action is **unknown or uncertain** (e.g., what appears after filling a search, what dialog opens after click), either **explore via MCP first** to see the actual result, or **mark the scenario `@manual`**. Never guess the result — wrong assertions cause test failures that waste fix cycles.
|
|
106
|
+
5. Scenario **name must match the actual assertion**, not the action. "Fill searchbox shows search results" must assert search results — not field value.
|
|
107
|
+
|
|
108
|
+
## Quality Review Checklist (9 checks, auto-fix on detection)
|
|
109
|
+
|
|
110
|
+
After generating scenarios, review every scenario against these checks. **If an issue is detected, fix it immediately** — do not just flag it.
|
|
111
|
+
|
|
112
|
+
### 1. Redundant scenarios
|
|
113
|
+
|
|
114
|
+
**Problem:** Two scenarios test the same element with overlapping assertions.
|
|
115
|
+
```gherkin
|
|
116
|
+
# REDUNDANT: VP-UI-009 and VP-UI-010 both test CTA button
|
|
117
|
+
Scenario: CTA button is visible → Then see [cta] button
|
|
118
|
+
Scenario: CTA button shows text → Then see [cta] button with {{text}}
|
|
119
|
+
```
|
|
120
|
+
**Fix:** Keep only the stronger assertion (`with {{text}}` implies visibility). Remove the weaker one.
|
|
121
|
+
|
|
122
|
+
### 2. Misclassified viewpoint
|
|
123
|
+
|
|
124
|
+
**Problem:** A scenario classified in the wrong viewpoint category.
|
|
125
|
+
|
|
126
|
+
**Classification rules:**
|
|
127
|
+
- **UI/UX** = Given + Then asserting **static, always-the-same** defaults (layout, placeholder text, initial state on first-ever load)
|
|
128
|
+
- **Logic** = Given + When + Then (action causes a result), OR Given + Then asserting **behavior-dependent state** (persisted values, dynamic content, conditional defaults)
|
|
129
|
+
|
|
130
|
+
**Key distinction:** If the element's state depends on **previous user interaction, saved preferences, or business rules** — it's Logic even without a `When`, because it verifies behavior, not layout.
|
|
131
|
+
|
|
132
|
+
```gherkin
|
|
133
|
+
# UI/UX — static default, always the same for every user
|
|
134
|
+
Given User is on [Settings] page
|
|
135
|
+
Then User see [Language] dropdown with {{default_language}}
|
|
136
|
+
|
|
137
|
+
# Logic — checkbox remembers last user choice (persisted state)
|
|
138
|
+
Given User is on [Settings] page
|
|
139
|
+
Then User see [Newsletter] checkbox is checked
|
|
140
|
+
|
|
141
|
+
# Logic — empty state text depends on business rule (no data yet)
|
|
142
|
+
Given User is on [Orders] page
|
|
143
|
+
Then User see [empty state] text with {{no_orders_message}}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Fix:** Check whether the asserted state is truly static (same for all users, all times) or depends on data/behavior. Move accordingly.
|
|
147
|
+
|
|
148
|
+
### 3. Dynamic/data-dependent content
|
|
149
|
+
|
|
150
|
+
**Problem:** Asserting content that depends on live data which may change.
|
|
151
|
+
```gherkin
|
|
152
|
+
# FRAGILE: "Attachment 1" only exists if first card has an attachment
|
|
153
|
+
Scenario: Card shows attachment image
|
|
154
|
+
Then User see [Attachment 1] image
|
|
155
|
+
```
|
|
156
|
+
**Fix:** Mark as `@manual` with a comment explaining the data dependency.
|
|
157
|
+
|
|
158
|
+
### 4. Duplicate across sections
|
|
159
|
+
|
|
160
|
+
**Problem:** Security scenario has identical steps to a UI scenario.
|
|
161
|
+
```gherkin
|
|
162
|
+
# VP-UI-006 and VP-SEC-002 are identical
|
|
163
|
+
Scenario: VP-UI-006 User profile button is visible
|
|
164
|
+
Scenario: VP-SEC-002 Authenticated user sees profile button
|
|
165
|
+
```
|
|
166
|
+
**Fix:** Remove the duplicate. Security scenarios should test **auth boundaries** (e.g., `@no-auth` → redirect), not re-test visibility.
|
|
167
|
+
|
|
168
|
+
### 5. "Enabled" state on always-enabled elements
|
|
169
|
+
|
|
170
|
+
**Problem:** Testing `is enabled` on elements that have no disabled state in the application.
|
|
171
|
+
```gherkin
|
|
172
|
+
# BAD: this button is never disabled — the assertion adds no value
|
|
173
|
+
Then User see [Home] button is enabled
|
|
174
|
+
```
|
|
175
|
+
**Fix:** Remove. Only assert `is enabled` or `is disabled` when the element **actually toggles** between states based on conditions (e.g., form validity, permissions).
|
|
176
|
+
|
|
177
|
+
### 6. Exact match on dynamic counters/numbers
|
|
178
|
+
|
|
179
|
+
**Problem:** Using exact match (`with {{value}}`) on data that changes (counters, totals, timestamps).
|
|
180
|
+
```gherkin
|
|
181
|
+
# FRAGILE: "+61 KUDOS" changes when new kudos are sent
|
|
182
|
+
Then User see [kudos count] text with {{kudos_count}}
|
|
183
|
+
```
|
|
184
|
+
**Fix:** Use partial match (`text contains`) with a stable keyword:
|
|
185
|
+
```gherkin
|
|
186
|
+
Then User see [kudos count] text contains {{kudos_count_keyword}}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 7. Current active page link
|
|
190
|
+
|
|
191
|
+
**Problem:** Testing visibility of a nav link pointing to the current page.
|
|
192
|
+
```gherkin
|
|
193
|
+
# LOW VALUE: we are ON /kudos, Sun* Kudos link is always there
|
|
194
|
+
Scenario: Nav link Sun Kudos is visible
|
|
195
|
+
Given User is on [kudos] page
|
|
196
|
+
Then User see [Sun* Kudos] link
|
|
197
|
+
```
|
|
198
|
+
**Fix:** Remove or replace with active state test.
|
|
199
|
+
|
|
200
|
+
### 8. Test-data completeness
|
|
201
|
+
|
|
202
|
+
**Problem:** Feature file references `{{variable}}` but the corresponding key is missing in `test-data.yaml`.
|
|
203
|
+
```gherkin
|
|
204
|
+
# Feature uses {{login_error}} but test-data.yaml has no "login_error" key
|
|
205
|
+
When User fill [Email] field with {{invalid_email}}
|
|
206
|
+
And User click [Submit] button
|
|
207
|
+
Then User see [error] message with {{login_error}}
|
|
208
|
+
```
|
|
209
|
+
**Fix:** After generation, verify every `{{variable}}` in the `.feature` file has a matching entry in `test-data.yaml`. Add missing entries with realistic values. This is a **mandatory post-generation check** — missing test data causes compile failures.
|
|
210
|
+
|
|
211
|
+
### 9. Negative/boundary coverage
|
|
212
|
+
|
|
213
|
+
**Problem:** All scenarios are happy-path. No validation, error, or boundary cases exist.
|
|
214
|
+
```gherkin
|
|
215
|
+
# BAD: only tests successful login — what about invalid credentials?
|
|
216
|
+
Scenario: VP-LOGIC-001 User logs in successfully
|
|
217
|
+
Given User is on [Login] page
|
|
218
|
+
When User fill [Email] field with {{valid_email}}
|
|
219
|
+
And User fill [Password] field with {{valid_password}}
|
|
220
|
+
And User click [Submit] button
|
|
221
|
+
Then User see [Dashboard] page
|
|
222
|
+
```
|
|
223
|
+
**Fix:** For every form/input section, ensure at least one scenario covers:
|
|
224
|
+
- **Required field empty** → validation message appears
|
|
225
|
+
- **Invalid format** (email, phone, etc.) → format error appears
|
|
226
|
+
- **Boundary values** (max length, min value) → when relevant
|
|
227
|
+
|
|
228
|
+
If specific error messages are unknown, mark validation scenarios `@manual` rather than omitting them entirely.
|
|
@@ -7,12 +7,13 @@ user-invocable: false
|
|
|
7
7
|
## Standard Syntax
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
[Keyword] User <Action> [Target Name] <Target Type> <with {{Value}}> <is State>
|
|
10
|
+
[Keyword] User <Action> [Target Name] <Target Type> <in [Parent Name] <Parent Type>> <with {{Value}}> <is State>
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
- **Actor**: Always `User`, always active voice.
|
|
14
14
|
- **Value**: `with {{snake_case}}` — never hardcode static data.
|
|
15
15
|
- **State**: `is <keyword>` — never use `{{}}` for states.
|
|
16
|
+
- **Parent scope**: `in [Parent] parentType` — optional, only when page has 2+ similar blocks needing disambiguation.
|
|
16
17
|
|
|
17
18
|
## Keyword → Action Rules
|
|
18
19
|
|
|
@@ -88,8 +89,8 @@ User see [message text] alert # assert dialog message
|
|
|
88
89
|
### Keyboard
|
|
89
90
|
|
|
90
91
|
```
|
|
91
|
-
User press
|
|
92
|
-
User press
|
|
92
|
+
User press Escape key # global key press
|
|
93
|
+
User press Enter on [T] field # key on element
|
|
93
94
|
```
|
|
94
95
|
|
|
95
96
|
### Wait
|
|
@@ -112,11 +113,11 @@ User switch to [T] frame # enter iframe
|
|
|
112
113
|
User switch to [main] frame # exit iframe
|
|
113
114
|
```
|
|
114
115
|
|
|
115
|
-
### Assertions (
|
|
116
|
+
### Assertions (8 verify patterns)
|
|
116
117
|
|
|
117
118
|
```
|
|
118
119
|
# 1. Visibility
|
|
119
|
-
User see [T] message # visible (default)
|
|
120
|
+
User see [T] message # visible (default — NEVER add "is visible")
|
|
120
121
|
User see [T] modal is hidden # hidden
|
|
121
122
|
|
|
122
123
|
# 2. Text Content (exact full match — toHaveText)
|
|
@@ -140,26 +141,44 @@ User see [T] checkbox is checked # checked state
|
|
|
140
141
|
User see [T] toggle is unchecked # unchecked state
|
|
141
142
|
User see [T] dialog with {{v}} is hidden # text + state combined
|
|
142
143
|
|
|
143
|
-
# 6.
|
|
144
|
+
# 6. Attribute (toHaveAttribute — when selector YAML has `attribute` field)
|
|
145
|
+
User see [T] image with {{v}} # image src
|
|
146
|
+
User see [T] link with {{v}} # link href
|
|
147
|
+
|
|
148
|
+
# 7. Count
|
|
144
149
|
User see [T] row with {{count}} # element count
|
|
145
150
|
|
|
146
|
-
#
|
|
151
|
+
# 8. Page Context
|
|
147
152
|
User see [T] page # URL assertion
|
|
148
153
|
```
|
|
149
154
|
|
|
150
155
|
### Table
|
|
151
156
|
|
|
152
157
|
```
|
|
153
|
-
User see [
|
|
158
|
+
User see [Col] column in [Table] table # column exists (parent scoping)
|
|
159
|
+
User see [Table] table row with {{f}} # row exists
|
|
154
160
|
User see [Table] table has no row with {{f}} # row not exists
|
|
155
|
-
User see [Table] table
|
|
156
|
-
User see [Table] table has [Col] column # column exists
|
|
161
|
+
User see [Table] table with {{count}} rows # row count
|
|
157
162
|
User see [Table] table is empty # empty table
|
|
158
163
|
User see [Table] table row with {{f}} has [Col] with {{v}} # cell by filter
|
|
159
164
|
User see [Table] table row 1 [Col] cell with {{v}} # cell by index
|
|
160
165
|
User click [Act] in [Table] table row with {{f}} # action in row
|
|
161
166
|
```
|
|
162
167
|
|
|
168
|
+
### Parent Scoping (disambiguation)
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
User click [Submit] button in [User Info] form # button inside specific form
|
|
172
|
+
User fill [Email] field in [Registration] form with {{v}} # field inside specific form
|
|
173
|
+
User see [Total] text in [Summary] section with {{v}} # text inside specific section
|
|
174
|
+
User click [Delete] button in [Active Users] table # button inside specific table
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- **Optional** — only use when page has 2+ similar UI blocks
|
|
178
|
+
- **Valid parent types**: `table`, `list`, `section`, `dialog`, `form`
|
|
179
|
+
- **Max 2 levels**: `[Target] in [Parent]`. **NEVER** nest 3 levels: `[A] in [B] in [C]`
|
|
180
|
+
- Parent resolves from selectors YAML first, falls back to auto-infer `getByRole(parentType, { name })`
|
|
181
|
+
|
|
163
182
|
### States
|
|
164
183
|
|
|
165
184
|
`hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
|
|
@@ -246,7 +265,7 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
|
|
|
246
265
|
|---|---|---|
|
|
247
266
|
| Wrong keyword | `Given User click [T] button` | `When User click [T] button` |
|
|
248
267
|
| Wrong action for type | `When User click [T] checkbox` | `When User check [T] checkbox` |
|
|
249
|
-
| press wrong target | `When User press [Submit] button` | `When User press
|
|
268
|
+
| press wrong target | `When User press [Submit] button` | `When User press Enter key` |
|
|
250
269
|
| uncheck radio | `When User uncheck [Male] radio` | `When User check [Female] radio` |
|
|
251
270
|
| Hardcode data | `with {{admin@mail.com}}` | `with {{invalid_email}}` |
|
|
252
271
|
| Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
|