@sun-asterisk/sungen 2.2.1 → 2.2.3
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 +63 -34
- package/dist/cli/index.js +1 -1
- package/dist/generators/gherkin-parser/index.js +1 -1
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +83 -57
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +56 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +16 -0
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -4
- package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +148 -21
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +51 -11
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +12 -5
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +148 -21
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +51 -11
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
- package/docs/gherkin standards/gherkin-core-standard.md +163 -160
- package/docs/gherkin standards/gherkin-core-standard.vi.md +290 -404
- package/docs/gherkin-dictionary.md +71 -16
- package/package.json +1 -1
- package/src/cli/index.ts +1 -1
- package/src/generators/gherkin-parser/index.ts +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
- package/src/generators/test-generator/patterns/assertion-patterns.ts +93 -65
- package/src/generators/test-generator/patterns/interaction-patterns.ts +58 -1
- package/src/generators/test-generator/utils/selector-resolver.ts +16 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -4
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +148 -21
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +51 -11
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +1 -1
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +1 -1
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +12 -5
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +148 -21
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +51 -11
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Gherkin Standard - Core (v2)
|
|
1
|
+
# Gherkin Standard - Core (v2.1)
|
|
2
2
|
|
|
3
3
|
**Applies to: Manual Testing & Automation Testing**
|
|
4
4
|
|
|
@@ -15,28 +15,42 @@ Scenario: <Who> <Does What> <For What Result>
|
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Principles
|
|
18
|
-
- **1 Scenario = 1 complete business behavior
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
|
|
18
|
+
- **Independent**: 1 Scenario = 1 complete business behavior (no shared data between scenarios)
|
|
19
|
+
- **Behavioral**: Describe "User does what" and "sees what" — focus on user behavior
|
|
20
|
+
- **Objective**: Describe business outcomes. No technical details (CSS, XPath)
|
|
21
|
+
|
|
22
|
+
### Flow
|
|
23
|
+
**Past (Setup) → Present (Interaction) → Future (Result)**
|
|
22
24
|
|
|
23
|
-
### Example
|
|
24
25
|
```gherkin
|
|
25
26
|
Scenario: User logs in successfully with valid credentials
|
|
27
|
+
# 1. Setup
|
|
26
28
|
Given User is on [Login] page
|
|
29
|
+
# 2. Interaction
|
|
27
30
|
When User fill [Email] field with {{valid_email}}
|
|
28
31
|
And User fill [Password] field with {{valid_password}}
|
|
29
32
|
And User click [Submit] button
|
|
33
|
+
# 3. Result
|
|
30
34
|
Then User see [Dashboard] page
|
|
35
|
+
And User see [Welcome] heading with {{username}}
|
|
36
|
+
And User see [Logout] button is enabled
|
|
31
37
|
```
|
|
32
38
|
|
|
39
|
+
### Keyword Rules
|
|
40
|
+
- **Given** → `is on` only (setup context)
|
|
41
|
+
- **When / And** → `click`, `fill`, `select`, `press`, `clear`, `check`, `uncheck`, `hover`, `wait for`
|
|
42
|
+
- **Then / And** → `see` only (assertions)
|
|
43
|
+
- **And** → inherits from preceding keyword
|
|
44
|
+
|
|
45
|
+
> Max 5–7 `Then/And` assertions per scenario. Split into separate scenarios if more needed.
|
|
46
|
+
|
|
33
47
|
---
|
|
34
48
|
|
|
35
49
|
## 2️⃣ Grammar (Step Level)
|
|
36
50
|
|
|
37
51
|
### Format
|
|
38
52
|
```
|
|
39
|
-
[Keyword] User <Action> [
|
|
53
|
+
[Keyword] User <Action> [Target Name] <Target Type> <with {{Value}}> <is State>
|
|
40
54
|
```
|
|
41
55
|
|
|
42
56
|
### Rules
|
|
@@ -75,38 +89,36 @@ Scenario: User logs in successfully with valid credentials
|
|
|
75
89
|
✅ User click [Submit] button
|
|
76
90
|
❌ System sends verification email
|
|
77
91
|
❌ Backend validates password
|
|
78
|
-
❌ API returns success response
|
|
79
92
|
```
|
|
80
93
|
|
|
81
|
-
> **Rationale**: System behavior is an *outcome* to verify, not an actor performing steps.
|
|
82
|
-
|
|
83
94
|
---
|
|
84
95
|
|
|
85
96
|
## 4️⃣ Action
|
|
86
97
|
|
|
87
|
-
###
|
|
88
|
-
|
|
89
|
-
| Group | Action |
|
|
90
|
-
|
|
91
|
-
| **Setup** | `is on` |
|
|
92
|
-
| **
|
|
93
|
-
| **Interaction** | `click` |
|
|
94
|
-
| **Interaction** | `
|
|
95
|
-
| **Interaction** | `
|
|
96
|
-
| **Interaction** | `
|
|
97
|
-
| **Form** | `fill` |
|
|
98
|
-
| **Form** | `
|
|
99
|
-
| **Form** | `
|
|
100
|
-
| **Form** | `check` |
|
|
101
|
-
| **Form** | `uncheck` |
|
|
102
|
-
| **
|
|
103
|
-
| **
|
|
104
|
-
| **
|
|
105
|
-
| **
|
|
106
|
-
| **
|
|
107
|
-
| **
|
|
108
|
-
| **
|
|
109
|
-
|
|
98
|
+
### Action Matrix
|
|
99
|
+
|
|
100
|
+
| Group | Action | `with {{Value}}` | `is State` | Target Types |
|
|
101
|
+
|-------|--------|:-:|:-:|---|
|
|
102
|
+
| **Setup** | `is on` | ❌ | ❌ | `page`, `dialog`, `modal`, `tab` |
|
|
103
|
+
| **Interaction** | `click` | Only dynamic lists ✱ | ❌ | All interactive elements |
|
|
104
|
+
| **Interaction** | `double click` | ❌ | ❌ | Any element |
|
|
105
|
+
| **Interaction** | `hover` | ❌ | ❌ | `icon`, `image`, `row`, `card`, `menuitem` |
|
|
106
|
+
| **Interaction** | `drag` | ❌ | ❌ | Any to any |
|
|
107
|
+
| **Interaction** | `expand` / `collapse` | ❌ | ❌ | `row`, `section` |
|
|
108
|
+
| **Form** | `fill` | ✅ | ❌ | `field`, `textarea`, `search`, `uploader`, `slider`, `date-picker` |
|
|
109
|
+
| **Form** | `select` | ✅ | ❌ | `dropdown`, `select`, `option` |
|
|
110
|
+
| **Form** | `clear` | ❌ | ❌ | `field`, `textarea` |
|
|
111
|
+
| **Form** | `check` | ❌ | ❌ | `checkbox`, `toggle`, `radio` |
|
|
112
|
+
| **Form** | `uncheck` | ❌ | ❌ | `checkbox`, `toggle` (NOT radio) |
|
|
113
|
+
| **Keyboard** | `press` | ❌ | ❌ | `key` (mandatory) |
|
|
114
|
+
| **Scroll** | `scroll to` | ❌ | ❌ | `section`, any element |
|
|
115
|
+
| **Frame** | `switch to` | ❌ | ❌ | `frame` |
|
|
116
|
+
| **Wait** | `wait for` | ⚠️ Optional | ⚠️ Optional | `page`, `dialog`, `modal`, `message`, any element |
|
|
117
|
+
| **Assertion** | `see` | ✅ | ✅ | All types |
|
|
118
|
+
| **Alert** | `click` | ❌ | ❌ | `alert` (OK/Cancel) |
|
|
119
|
+
| **Alert** | `fill` | ✅ | ❌ | `alert` (prompt) |
|
|
120
|
+
|
|
121
|
+
> ✱ **`click` + `with {{Value}}`**: Only for dynamic lists (`row`, `item`, `card`, `option`). Never for static elements (`button`, `link`, `icon`, `tab`).
|
|
110
122
|
|
|
111
123
|
### Rules
|
|
112
124
|
- ✅ Use **exact verbs** from the list above
|
|
@@ -119,6 +131,8 @@ Scenario: User logs in successfully with valid credentials
|
|
|
119
131
|
❌ User opens [Home] page → use "is on"
|
|
120
132
|
❌ User checks [Terms] checkbox → use "check" (no "s")
|
|
121
133
|
❌ User verifies [Success] message appears → use "see"
|
|
134
|
+
❌ User click [Terms] checkbox → use "check", not "click"
|
|
135
|
+
❌ User uncheck [Male] radio → radio cannot uncheck, use "check [Female] radio"
|
|
122
136
|
```
|
|
123
137
|
|
|
124
138
|
---
|
|
@@ -132,41 +146,23 @@ Scenario: User logs in successfully with valid credentials
|
|
|
132
146
|
|
|
133
147
|
### Element Types
|
|
134
148
|
|
|
135
|
-
|
|
|
136
|
-
|
|
137
|
-
| `page`
|
|
138
|
-
| `
|
|
139
|
-
| `link`
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `text` | Text content | `[Price] text` |
|
|
144
|
-
| `checkbox` | Checkbox input | `[Remember me] checkbox` |
|
|
145
|
-
| `radio` | Radio button | `[Payment method] radio` |
|
|
146
|
-
| `switch` | Toggle switch | `[Dark mode] switch` |
|
|
147
|
-
| `dropdown` | Select / combobox | `[Country] dropdown` |
|
|
148
|
-
| `dialog` / `modal` | Modal / dialog overlay | `[Confirm] dialog` |
|
|
149
|
-
| `menu` / `menuitem` | Menu elements | `[Write Kudos] menuitem` |
|
|
150
|
-
| `tab` / `tabpanel` | Tab elements | `[Settings] tab` |
|
|
151
|
-
| `table` / `row` / `cell` | Table elements | `[Users] table` |
|
|
152
|
-
| `list` / `listitem` | List elements | `[Results] list` |
|
|
153
|
-
| `icon` / `image` | Visual icon/image | `[Close] icon` |
|
|
154
|
-
| `alert` | Alert/notification | `[Error] alert` |
|
|
155
|
-
| `spinner` / `progressbar` | Loading indicators | `[Loading] spinner` |
|
|
156
|
-
| `section` / `region` / `nav` | Layout landmarks | `[Footer] section` |
|
|
157
|
-
| `frame` / `iframe` | Iframe elements | `[Payment] frame` |
|
|
158
|
-
| `uploader` / `file` | File upload | `[Avatar] uploader` |
|
|
159
|
-
| `columnheader` | Table column header | `[Name] columnheader` |
|
|
160
|
-
| `tooltip` | Tooltip | `[Help] tooltip` |
|
|
161
|
-
| `slider` | Slider/range | `[Volume] slider` |
|
|
162
|
-
| `tree` / `treeitem` | Tree elements | `[Folder] treeitem` |
|
|
149
|
+
| Group | Types | Example |
|
|
150
|
+
|---|---|---|
|
|
151
|
+
| **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` | `[Login] page`, `[Confirm] dialog` |
|
|
152
|
+
| **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` | `[Email] field`, `[Global] search` |
|
|
153
|
+
| **Trigger** | `button` `link` `icon` `menuitem` `tag` | `[Submit] button`, `[Close] icon` |
|
|
154
|
+
| **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` | `[Users] table`, `[Order] row` |
|
|
155
|
+
| **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` | `[Error] message`, `[Total] label` |
|
|
156
|
+
| **System** | `key` `frame` `spinner` `progressbar` | `[Enter] key`, `[Payment] frame` |
|
|
163
157
|
|
|
164
|
-
### Rules
|
|
158
|
+
### Naming Rules
|
|
165
159
|
- ✅ Use **business/UI meaningful names**, not technical selectors
|
|
166
|
-
- ✅
|
|
160
|
+
- ✅ Visible text → use exact UI label: `[Đăng nhập] button`
|
|
161
|
+
- ✅ No visible text → short descriptive noun: `[close] icon`
|
|
162
|
+
- ✅ Name > 30 chars → shorten to 1–3 meaningful words
|
|
167
163
|
- ❌ No CSS selectors: `#email`, `.btn-primary`
|
|
168
164
|
- ❌ No XPath: `//input[@id='email']`
|
|
169
|
-
- ❌ No
|
|
165
|
+
- ❌ No element type in brackets: `[login button]` → `[login] button`
|
|
170
166
|
|
|
171
167
|
### Examples
|
|
172
168
|
```gherkin
|
|
@@ -198,7 +194,6 @@ Scenario: User logs in successfully with valid credentials
|
|
|
198
194
|
- ✅ Name reflects **data purpose**, not data content
|
|
199
195
|
- ❌ No hard-coded data in steps
|
|
200
196
|
- ❌ No real data (emails, passwords, tokens)
|
|
201
|
-
- ❌ No environment-specific values (URLs, API keys)
|
|
202
197
|
|
|
203
198
|
### Examples
|
|
204
199
|
|
|
@@ -207,18 +202,8 @@ Scenario: User logs in successfully with valid credentials
|
|
|
207
202
|
| `{{valid_email}}` | `{{user@example.com}}` |
|
|
208
203
|
| `{{invalid_password}}` | `{{123456}}` |
|
|
209
204
|
| `{{expired_otp}}` | `{{999999}}` |
|
|
210
|
-
| `{{admin_username}}` | `{{admin}}` |
|
|
211
205
|
| `{{product_name}}` | `{{iPhone 15 Pro}}` |
|
|
212
206
|
|
|
213
|
-
### Data Organization
|
|
214
|
-
```yaml
|
|
215
|
-
# test-data/login.yaml
|
|
216
|
-
valid_email: "user@example.com"
|
|
217
|
-
valid_password: "SecurePass123!"
|
|
218
|
-
invalid_email: "not-an-email"
|
|
219
|
-
expired_otp: "000000"
|
|
220
|
-
```
|
|
221
|
-
|
|
222
207
|
---
|
|
223
208
|
|
|
224
209
|
## 7️⃣ Assertion
|
|
@@ -226,36 +211,19 @@ expired_otp: "000000"
|
|
|
226
211
|
### Verb
|
|
227
212
|
- **Only**: `see`
|
|
228
213
|
|
|
229
|
-
###
|
|
230
|
-
- ✅ Assertions **only appear in `Then`** steps
|
|
231
|
-
- ✅ Verify **system state / output**
|
|
232
|
-
- ✅ Each step = **1 assertion**
|
|
233
|
-
- ❌ Do not describe user actions
|
|
234
|
-
- ❌ No synonyms: `verify`, `expect`, `check`, `observe`, `validate`
|
|
235
|
-
|
|
236
|
-
### Examples
|
|
237
|
-
```gherkin
|
|
238
|
-
✅ Then User see [Error] message
|
|
239
|
-
✅ And User see [Dashboard] page
|
|
240
|
-
✅ And User see [Welcome] heading with {{username}}
|
|
241
|
-
✅ And User see [Submit] button is disabled
|
|
242
|
-
|
|
243
|
-
❌ Then User verifies [Error] message
|
|
244
|
-
❌ Then System displays [Dashboard] page
|
|
245
|
-
❌ Then [Success] message appears
|
|
246
|
-
```
|
|
214
|
+
### 7 Verify Patterns
|
|
247
215
|
|
|
248
|
-
|
|
216
|
+
| # | Pattern | Assertion | Example |
|
|
217
|
+
|---|---------|-----------|---------|
|
|
218
|
+
| 1 | **Visibility** | `toBeVisible()` / `toBeHidden()` | `see [Success] message` / `see [Ads] modal is hidden` |
|
|
219
|
+
| 2 | **Text Content** | `toHaveText()` (exact match) | `see [Error] message with {{err_msg}}` |
|
|
220
|
+
| 3 | **Partial Text** | `toContainText()` | `see [Title] heading contains {{text}}` |
|
|
221
|
+
| 4 | **Input Value** | `toHaveValue()` | `see [Email] field with {{user_email}}` |
|
|
222
|
+
| 5 | **Component State** | `toBeDisabled()` / `toBeChecked()` etc. | `see [Submit] button is disabled` |
|
|
223
|
+
| 6 | **Count** | `toHaveCount()` | `see [Result] row with {{result_count}}` |
|
|
224
|
+
| 7 | **Page Context** | `toHaveURL()` | `see [Dashboard] page` |
|
|
249
225
|
|
|
250
|
-
|
|
251
|
-
|---------|----------|---------|
|
|
252
|
-
| Simple visibility | Element is visible | `User see [Login] button` |
|
|
253
|
-
| Visibility with value | Element has specific text | `User see [Welcome] heading with {{username}}` |
|
|
254
|
-
| State assertion | Element state | `User see [Submit] button is disabled` |
|
|
255
|
-
| State with value | Element with text + state | `User see [Panel] dialog with {{title}} is hidden` |
|
|
256
|
-
| Text contains | Partial text match | `User see [Message] text contains {{partial}}` |
|
|
257
|
-
| Text has text | Exact text match | `User see [Counter] text has text {{count}}` |
|
|
258
|
-
| Has attribute | Attribute check | `User see [Avatar] image has {{avatar_url}}` |
|
|
226
|
+
> **Key distinction**: `see [T] <input type> with {{v}}` → `toHaveValue()` for inputs (field, textarea, search, dropdown, slider, date-picker). `see [T] <other type> with {{v}}` → `toHaveText()` for everything else.
|
|
259
227
|
|
|
260
228
|
### State Modifiers
|
|
261
229
|
|
|
@@ -265,74 +233,108 @@ expired_otp: "000000"
|
|
|
265
233
|
| `visible` | Element is visible |
|
|
266
234
|
| `disabled` | Element is disabled |
|
|
267
235
|
| `enabled` | Element is enabled |
|
|
268
|
-
| `checked` | Checkbox/radio is checked |
|
|
269
|
-
| `unchecked` | Checkbox/radio is unchecked |
|
|
236
|
+
| `checked` | Checkbox/radio/toggle is checked |
|
|
237
|
+
| `unchecked` | Checkbox/radio/toggle is unchecked |
|
|
270
238
|
| `focused` | Element has focus |
|
|
271
|
-
| `empty` | Element has no text |
|
|
239
|
+
| `empty` | Element has no text/value |
|
|
272
240
|
| `loading` | Loading indicator is visible |
|
|
273
241
|
| `selected` | Element is selected |
|
|
274
242
|
| `sorted ascending` | Column sorted ascending |
|
|
275
243
|
| `sorted descending` | Column sorted descending |
|
|
276
244
|
|
|
245
|
+
### Combined Value + State
|
|
246
|
+
```gherkin
|
|
247
|
+
# Value and state can be combined:
|
|
248
|
+
Then User see [Ads] modal with {{promo_title}} is hidden
|
|
249
|
+
```
|
|
250
|
+
|
|
277
251
|
### Table Assertions
|
|
278
252
|
|
|
279
253
|
| Pattern | Example |
|
|
280
254
|
|---------|---------|
|
|
281
|
-
| Row exists | `User see [Users] table row with {{name}}
|
|
255
|
+
| Row exists | `User see [Users] table has row with {{name}}` |
|
|
282
256
|
| No row | `User see [Users] table has no row with {{name}}` |
|
|
283
257
|
| Row count | `User see [Users] table has {{count}} rows` |
|
|
284
258
|
| Column exists | `User see [Users] table has [Email] column` |
|
|
285
|
-
| Cell by index | `User see [Users] table row 1 [Name] cell with {{name}}` |
|
|
286
259
|
| Empty table | `User see [Users] table is empty` |
|
|
260
|
+
| Cell by filter | `User see [Users] table row with {{filter}} has [Status] with {{status}}` |
|
|
261
|
+
| Cell by index | `User see [Users] table row 1 [Name] cell with {{name}}` |
|
|
287
262
|
| Action in row | `User click [Edit] in [Users] table row with {{name}}` |
|
|
288
263
|
|
|
264
|
+
### Rules
|
|
265
|
+
- ✅ Assertions **only appear in `Then`** steps
|
|
266
|
+
- ✅ Verify **system state / output**
|
|
267
|
+
- ✅ Each step = **1 assertion**
|
|
268
|
+
- ❌ No synonyms: `verify`, `expect`, `check`, `observe`, `validate`
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 8️⃣ Browser Alert (System Dialog)
|
|
273
|
+
|
|
274
|
+
For native browser dialogs (`window.alert`, `window.confirm`, `window.prompt`):
|
|
275
|
+
|
|
276
|
+
```gherkin
|
|
277
|
+
# Alert steps must appear BEFORE the action that triggers the dialog
|
|
278
|
+
When User click [OK] alert # accept (OK/Accept/Yes/Confirm)
|
|
279
|
+
And User click [Delete] button # this triggers the alert
|
|
280
|
+
|
|
281
|
+
When User click [Cancel] alert # dismiss (Cancel/Dismiss/No)
|
|
282
|
+
And User click [Delete] button
|
|
283
|
+
|
|
284
|
+
When User fill [Name] alert with {{v}} # fill prompt + accept
|
|
285
|
+
And User click [Rename] button
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
> **Important**: Register the dialog handler BEFORE the triggering action. Sungen generates `page.once('dialog', ...)` for these steps.
|
|
289
|
+
|
|
289
290
|
---
|
|
290
291
|
|
|
291
292
|
## 🏷️ Tags
|
|
292
293
|
|
|
293
|
-
###
|
|
294
|
+
### Classification Tags
|
|
295
|
+
|
|
296
|
+
| Tag | Description |
|
|
297
|
+
|-----|-------------|
|
|
298
|
+
| `@auto` | Standard scenario, ready for automation |
|
|
299
|
+
| `@manual` | Skip scenario from generation |
|
|
300
|
+
| `@smoke` | Smoke test suite |
|
|
301
|
+
| `@regression` | Regression test suite |
|
|
302
|
+
|
|
303
|
+
### Authentication Tags
|
|
294
304
|
|
|
295
305
|
| Tag | Description |
|
|
296
306
|
|-----|-------------|
|
|
297
307
|
| `@auth:<role>` | Use Playwright auth storage state for the given role |
|
|
298
308
|
| `@no-auth` | Disable inherited authentication |
|
|
299
|
-
| `@steps:<name>` | Mark scenario as a reusable step block |
|
|
300
|
-
| `@extend:<name>` | Prepend steps from a `@steps` block before own steps |
|
|
301
|
-
| `@manual` | Skip scenario from generation |
|
|
302
309
|
|
|
303
310
|
Tags can be applied at **feature level** (inherited by all scenarios) or **scenario level** (overrides feature).
|
|
304
311
|
|
|
305
312
|
**Auth precedence**: Extending scenario `@auth` > Base scenario `@auth` > Feature `@auth`
|
|
306
313
|
|
|
307
|
-
###
|
|
314
|
+
### Inheritance Tags (@steps / @extend)
|
|
308
315
|
|
|
309
316
|
Use `@steps:<name>` to define a reusable block and `@extend:<name>` to inherit those steps:
|
|
310
317
|
|
|
311
318
|
```gherkin
|
|
312
|
-
@auth:user @steps:
|
|
313
|
-
Scenario:
|
|
314
|
-
Given User is on [
|
|
315
|
-
When User click [
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
When User click [Search] button
|
|
323
|
-
And User fill [Search] field with {{teammate_name}}
|
|
324
|
-
And User click [teammate] row with {{teammate_name}}
|
|
325
|
-
And User fill [Title] field with {{teammate_title}}
|
|
319
|
+
@auto @auth:user @steps:kudos__open_modal
|
|
320
|
+
Scenario: Setup for opening Kudos modal
|
|
321
|
+
Given User is on [Home] page
|
|
322
|
+
When User click [Today you want...] button
|
|
323
|
+
Then User see [Send thanks] dialog # ← skipped when @extend calls
|
|
324
|
+
|
|
325
|
+
@auto @auth:user @extend:kudos__open_modal
|
|
326
|
+
Scenario: User successfully sends a thank you message
|
|
327
|
+
Given User is on [Send thanks] dialog # ← required: verify state after extend
|
|
328
|
+
When User fill [Search teammate] field with {{teammate_name}}
|
|
326
329
|
And User click [Send] button
|
|
327
|
-
|
|
328
|
-
Then User see [panel] modal with {{kudo_title}} is hidden
|
|
330
|
+
Then User see [Success] message with {{msg_success}}
|
|
329
331
|
```
|
|
330
332
|
|
|
331
333
|
**Behavior:**
|
|
332
|
-
- `@
|
|
333
|
-
- `@extend`
|
|
334
|
-
-
|
|
335
|
-
-
|
|
334
|
+
- `@extend` executes **only Given→When** of `@steps` scenario (skips Then)
|
|
335
|
+
- The `Given` in `@extend` scenario is the **entry assertion** — confirms state after base steps ran
|
|
336
|
+
- If `@steps` scenario **fails**, `@extend` scenario is **automatically skipped**
|
|
337
|
+
- Name format: `snake_case` or `kebab-case` with module prefix: `@steps:kudos__open_modal`, `@steps:cart__add_item`
|
|
336
338
|
|
|
337
339
|
### Step-Level Annotations (comment syntax)
|
|
338
340
|
|
|
@@ -340,17 +342,18 @@ Scenario: User sends a thank you message
|
|
|
340
342
|
|-----------|--------|
|
|
341
343
|
| `# @ignore` | Skip this step in generation |
|
|
342
344
|
| `# @ignore-testcase` | Skip entire scenario in generation |
|
|
343
|
-
| `# @skip-production` | Skip step in production environment |
|
|
344
345
|
|
|
345
346
|
---
|
|
346
347
|
|
|
347
348
|
## 📋 Complete Example
|
|
348
349
|
|
|
349
350
|
```gherkin
|
|
350
|
-
@
|
|
351
|
+
@feature_auth
|
|
351
352
|
Feature: User Authentication
|
|
352
353
|
Path: /auth/login
|
|
353
354
|
|
|
355
|
+
# Happy Path
|
|
356
|
+
@auto @smoke @regression
|
|
354
357
|
Scenario: User logs in successfully with valid credentials
|
|
355
358
|
Given User is on [Login] page
|
|
356
359
|
When User fill [Email] field with {{valid_email}}
|
|
@@ -359,17 +362,22 @@ Feature: User Authentication
|
|
|
359
362
|
And User click [Submit] button
|
|
360
363
|
Then User see [Dashboard] page
|
|
361
364
|
And User see [Welcome] heading with {{username}}
|
|
365
|
+
And User see [Logout] button is enabled
|
|
362
366
|
|
|
363
|
-
|
|
367
|
+
# Error Path
|
|
368
|
+
@auto @regression
|
|
369
|
+
Scenario: Login fails with invalid credentials
|
|
364
370
|
Given User is on [Login] page
|
|
365
371
|
When User fill [Email] field with {{invalid_email}}
|
|
366
372
|
And User fill [Password] field with {{invalid_password}}
|
|
367
373
|
And User click [Submit] button
|
|
368
|
-
Then User see [
|
|
369
|
-
And User see [Login]
|
|
374
|
+
Then User see [Login] page
|
|
375
|
+
And User see [Login error] message with {{err_invalid_credentials}}
|
|
370
376
|
And User see [Submit] button is enabled
|
|
371
377
|
|
|
372
|
-
|
|
378
|
+
# Registration with form controls
|
|
379
|
+
@auto @regression
|
|
380
|
+
Scenario: User registers with preferred language
|
|
373
381
|
Given User is on [Registration] page
|
|
374
382
|
When User fill [Email] field with {{new_email}}
|
|
375
383
|
And User fill [Password] field with {{new_password}}
|
|
@@ -384,11 +392,12 @@ Feature: User Authentication
|
|
|
384
392
|
## ✅ Quick Reference
|
|
385
393
|
|
|
386
394
|
### Do's ✅
|
|
387
|
-
- Use **standard actions** from
|
|
395
|
+
- Use **standard actions** from the action matrix
|
|
388
396
|
- Use **`User`** as the only actor
|
|
389
397
|
- Use **`[Target] <element type>`** format
|
|
390
398
|
- Use **`{{snake_case}}`** for values
|
|
391
399
|
- Use **`is <state>`** for state assertions
|
|
400
|
+
- Use **tags** (`@auth`, `@steps`, `@extend`) for scenario management
|
|
392
401
|
- **1 Scenario = 1 business flow**
|
|
393
402
|
- **1 Step = 1 action or assertion**
|
|
394
403
|
|
|
@@ -400,29 +409,23 @@ Feature: User Authentication
|
|
|
400
409
|
- No compound actions
|
|
401
410
|
- No `verify`/`check`/`expect` (use `see`)
|
|
402
411
|
- No `open` (use `is on`)
|
|
412
|
+
- No `click` on checkbox/toggle (use `check`/`uncheck`)
|
|
413
|
+
- No `uncheck` on radio (use `check` on another option)
|
|
403
414
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
## 🎯 Benefits
|
|
407
|
-
|
|
408
|
-
| Benefit | Description |
|
|
409
|
-
|---------|-------------|
|
|
410
|
-
| **Consistency** | Same patterns across all test cases |
|
|
411
|
-
| **Readability** | Non-technical stakeholders can understand |
|
|
412
|
-
| **Maintainability** | Easy to update when UI changes |
|
|
413
|
-
| **Automation-Ready** | Direct mapping to Playwright code via 17 pattern shapes |
|
|
414
|
-
| **No Ambiguity** | Single interpretation per step |
|
|
415
|
-
| **Tool Support** | Compatible with Sungen v2 compiler |
|
|
416
|
-
|
|
417
|
-
---
|
|
415
|
+
### Common Errors
|
|
418
416
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
417
|
+
| ❌ Wrong | ✅ Correct | Reason |
|
|
418
|
+
|---|---|---|
|
|
419
|
+
| `Given User click [Login] button` | `When User click [Login] button` | `click` belongs to WHEN |
|
|
420
|
+
| `When User click [Terms] checkbox` | `When User check [Terms] checkbox` | Use `check` for checkbox |
|
|
421
|
+
| `When User press [Submit] button` | `When User press [Enter] key` | `press` only with `key` |
|
|
422
|
+
| `When User uncheck [Male] radio` | `When User check [Female] radio` | Radio cannot uncheck |
|
|
423
|
+
| `fill [email] with {{admin@mail}}` | `fill [email] field with {{admin_email}}` | No hardcode + missing type |
|
|
424
|
+
| `see [msg] with {{text}} hidden` | `see [msg] with {{text}} is hidden` | Missing `is` keyword |
|
|
425
|
+
| `see [btn] button with {{disabled}}` | `see [btn] button is disabled` | State uses `is`, not `{{}}` |
|
|
423
426
|
|
|
424
427
|
---
|
|
425
428
|
|
|
426
|
-
**Version**: 2.
|
|
429
|
+
**Version**: 2.1
|
|
427
430
|
**Status**: Final
|
|
428
|
-
**Last Updated**: March
|
|
431
|
+
**Last Updated**: March 31, 2026
|