@sun-asterisk/sungen 2.0.0 → 2.0.2
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/dist/cli/index.js +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +2 -2
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +10 -0
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +4 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +8 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +4 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +11 -410
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/templates/ai-rules.md +189 -0
- package/dist/orchestrator/templates/gitignore +16 -0
- package/dist/orchestrator/templates/playwright.config.d.ts +10 -0
- package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -0
- package/dist/orchestrator/templates/playwright.config.js +77 -0
- package/dist/orchestrator/templates/playwright.config.js.map +1 -0
- package/dist/orchestrator/templates/playwright.config.ts +80 -0
- package/dist/orchestrator/templates/readme.md +197 -0
- package/docs/gherkin standards/gherkin-core-standard.md +377 -0
- package/docs/gherkin standards/gherkin-core-standard.vi.md +303 -0
- package/docs/gherkin-dictionary.md +1071 -0
- package/docs/makeauth.md +225 -0
- package/package.json +3 -2
- package/src/cli/index.ts +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +2 -2
- package/src/generators/test-generator/code-generator.ts +11 -0
- package/src/generators/test-generator/step-mapper.ts +9 -0
- package/src/orchestrator/project-initializer.ts +12 -410
- package/src/orchestrator/templates/ai-rules.md +189 -0
- package/src/orchestrator/templates/gitignore +16 -0
- package/src/orchestrator/templates/playwright.config.ts +80 -0
- package/src/orchestrator/templates/readme.md +197 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# Gherkin Standard - Core (Final)
|
|
2
|
+
|
|
3
|
+
**Applies to: Manual Testing & Automation Testing**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1️⃣ Scenario Format (Flow Level)
|
|
8
|
+
|
|
9
|
+
### Format
|
|
10
|
+
```gherkin
|
|
11
|
+
Scenario: <Who> <Does What> <For What Result>
|
|
12
|
+
Given ...
|
|
13
|
+
When ...
|
|
14
|
+
Then ...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Principles
|
|
18
|
+
- **1 Scenario = 1 complete business behavior**
|
|
19
|
+
- **Given**: Initial state / preconditions
|
|
20
|
+
- **When**: Main action (trigger)
|
|
21
|
+
- **Then**: Observable result (assertion)
|
|
22
|
+
|
|
23
|
+
### Example
|
|
24
|
+
```gherkin
|
|
25
|
+
Scenario: User logs in successfully with valid credentials
|
|
26
|
+
Given User is on [Login] page
|
|
27
|
+
When User fill [Email] field with {{valid_email}}
|
|
28
|
+
And User fill [Password] field with {{valid_password}}
|
|
29
|
+
And User click [Submit] button
|
|
30
|
+
Then User see [Dashboard] page
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2️⃣ Grammar (Step Level)
|
|
36
|
+
|
|
37
|
+
### Format
|
|
38
|
+
```
|
|
39
|
+
<Actor> <Action> [<Target>] with {{<Value>}}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Rules
|
|
43
|
+
- ✅ `Actor` + `Action` are **mandatory**
|
|
44
|
+
- ✅ `Target` is **required** for most actions (except `open` / `wait for`)
|
|
45
|
+
- ✅ `with {{Value}}` only used when action requires data
|
|
46
|
+
- ❌ No free-text variations
|
|
47
|
+
- ❌ No synonyms
|
|
48
|
+
|
|
49
|
+
### Structure Breakdown
|
|
50
|
+
|
|
51
|
+
| Component | Required | Example |
|
|
52
|
+
|-----------|----------|---------|
|
|
53
|
+
| Actor | ✅ Always | `User` |
|
|
54
|
+
| Action | ✅ Always | `click`, `fill`, `see` |
|
|
55
|
+
| Target | ✅ Most cases | `[Login] button` |
|
|
56
|
+
| Value | ⚠️ When needed | `{{valid_email}}` |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 3️⃣ Actor
|
|
61
|
+
|
|
62
|
+
### Allowed Actor
|
|
63
|
+
- ✅ **`User`** (only)
|
|
64
|
+
|
|
65
|
+
### Rules
|
|
66
|
+
- **Only use**: `User`
|
|
67
|
+
- **Do NOT use**: `System`, `Backend`, `API`, `App`
|
|
68
|
+
- System behavior is verified using `Then`, not as an Actor
|
|
69
|
+
|
|
70
|
+
### Examples
|
|
71
|
+
```gherkin
|
|
72
|
+
✅ User is on [Login] page
|
|
73
|
+
✅ User click [Submit] button
|
|
74
|
+
❌ System sends verification email
|
|
75
|
+
❌ Backend validates password
|
|
76
|
+
❌ API returns success response
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> **Rationale**: System behavior is an *outcome* to verify, not an actor performing steps.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 4️⃣ Action
|
|
84
|
+
|
|
85
|
+
### Allowed Actions (7 only)
|
|
86
|
+
|
|
87
|
+
| Action | Use Case | Example |
|
|
88
|
+
|--------|----------|---------|
|
|
89
|
+
| `is on` | Navigate to page (preferred) | `User is on [Login] page` |
|
|
90
|
+
| `open` | Navigate to page/screen | `User open [Login] page` |
|
|
91
|
+
| `click` | Click button/link/element | `User click [Submit] button` |
|
|
92
|
+
| `fill` | Enter text in input field | `User fill [Email] field with {{email}}` |
|
|
93
|
+
| `select` | Choose option from dropdown/radio | `User select [Country] dropdown with {{country}}` |
|
|
94
|
+
| `wait for` | Wait for element/condition | `User wait for [Loader] icon` |
|
|
95
|
+
| `see` | Verify element visibility | `User see [Error] message` |
|
|
96
|
+
|
|
97
|
+
> **Note**: `is on` and `open` are interchangeable for navigation. `is on` is the preferred form for `Given` steps.
|
|
98
|
+
|
|
99
|
+
### Rules
|
|
100
|
+
- ✅ Use **exact verbs** from the list above
|
|
101
|
+
- ❌ No synonyms: `type`, `enter`, `input`, `press`, `check`, `verify`, `expect`, etc.
|
|
102
|
+
- ❌ No compound actions: `click and wait`, `fill and submit`
|
|
103
|
+
|
|
104
|
+
### Anti-patterns
|
|
105
|
+
```gherkin
|
|
106
|
+
❌ User types {{password}} into [Password] field
|
|
107
|
+
❌ User presses [Enter] key
|
|
108
|
+
❌ User checks [Terms] checkbox
|
|
109
|
+
❌ User verifies [Success] message appears
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 5️⃣ Target
|
|
115
|
+
|
|
116
|
+
### Format
|
|
117
|
+
```
|
|
118
|
+
[name] <element type>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Element Types
|
|
122
|
+
|
|
123
|
+
| Element Type | When to Use | Example |
|
|
124
|
+
|--------------|-------------|---------|
|
|
125
|
+
| `field` | Text input, textarea | `[Email] field`, `[Password] field` |
|
|
126
|
+
| `button` | Clickable button | `[Submit] button`, `[Cancel] button` |
|
|
127
|
+
| `checkbox` | Checkbox input | `[Remember me] checkbox` |
|
|
128
|
+
| `dropdown` | Select element | `[Country] dropdown` |
|
|
129
|
+
| `radio` | Radio button | `[Payment method] radio` |
|
|
130
|
+
| `link` | Hyperlink | `[Forgot password] link` |
|
|
131
|
+
| `message` | Alert/notification | `[Error] message`, `[Success] message` |
|
|
132
|
+
| `page` | Entire screen/page | `[Login] page`, `[Dashboard] page` |
|
|
133
|
+
| `icon` | Visual icon/image | `[Loader] icon`, `[Close] icon` |
|
|
134
|
+
| `label` | Text label | `[Username] label` |
|
|
135
|
+
|
|
136
|
+
### Rules
|
|
137
|
+
- ✅ Use **business/UI meaningful names**, not technical selectors
|
|
138
|
+
- ✅ Keep names **simple and descriptive**
|
|
139
|
+
- ❌ No CSS selectors: `#email`, `.btn-primary`
|
|
140
|
+
- ❌ No XPath: `//input[@id='email']`
|
|
141
|
+
- ❌ No IDs: `email-input`, `submit-btn-123`
|
|
142
|
+
|
|
143
|
+
### Examples
|
|
144
|
+
```gherkin
|
|
145
|
+
✅ User click [Login] button
|
|
146
|
+
✅ User fill [Email address] field with {{email}}
|
|
147
|
+
✅ User select [United States] dropdown
|
|
148
|
+
✅ User see [Welcome back] message
|
|
149
|
+
|
|
150
|
+
❌ User click [#submit-btn] button
|
|
151
|
+
❌ User fill [input.email-field] field
|
|
152
|
+
❌ User see [div.alert-success] message
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 6️⃣ Value
|
|
158
|
+
|
|
159
|
+
### Format
|
|
160
|
+
```
|
|
161
|
+
{{value}}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Naming Convention
|
|
165
|
+
- **snake_case** (lowercase with underscores)
|
|
166
|
+
- Descriptive and context-aware
|
|
167
|
+
|
|
168
|
+
### Rules
|
|
169
|
+
- ✅ Use `{{variable}}` syntax
|
|
170
|
+
- ✅ Name reflects **data purpose**, not data content
|
|
171
|
+
- ❌ No hard-coded data in steps
|
|
172
|
+
- ❌ No real data (emails, passwords, tokens)
|
|
173
|
+
- ❌ No environment-specific values (URLs, API keys)
|
|
174
|
+
|
|
175
|
+
### Examples
|
|
176
|
+
|
|
177
|
+
| ✅ Good | ❌ Bad |
|
|
178
|
+
|--------|-------|
|
|
179
|
+
| `{{valid_email}}` | `{{user@example.com}}` |
|
|
180
|
+
| `{{invalid_password}}` | `{{123456}}` |
|
|
181
|
+
| `{{expired_otp}}` | `{{999999}}` |
|
|
182
|
+
| `{{admin_username}}` | `{{admin}}` |
|
|
183
|
+
| `{{product_name}}` | `{{iPhone 15 Pro}}` |
|
|
184
|
+
|
|
185
|
+
### Data Organization
|
|
186
|
+
```yaml
|
|
187
|
+
# test-data/login.yaml
|
|
188
|
+
valid_email: "user@example.com"
|
|
189
|
+
valid_password: "SecurePass123!"
|
|
190
|
+
invalid_email: "not-an-email"
|
|
191
|
+
expired_otp: "000000"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 7️⃣ Assertion
|
|
197
|
+
|
|
198
|
+
### Verb
|
|
199
|
+
- **Only**: `see`
|
|
200
|
+
|
|
201
|
+
### Rules
|
|
202
|
+
- ✅ Assertions **only appear in `Then`** steps
|
|
203
|
+
- ✅ Verify **system state / output**
|
|
204
|
+
- ✅ Each step = **1 assertion**
|
|
205
|
+
- ❌ Do not describe user actions
|
|
206
|
+
- ❌ No synonyms: `verify`, `expect`, `check`, `observe`, `validate`
|
|
207
|
+
|
|
208
|
+
### Examples
|
|
209
|
+
```gherkin
|
|
210
|
+
✅ Then User see [Error] message
|
|
211
|
+
✅ And User see [Dashboard] page
|
|
212
|
+
✅ And User see [Welcome] text
|
|
213
|
+
✅ And User see [Logout] button
|
|
214
|
+
|
|
215
|
+
❌ Then User verifies [Error] message
|
|
216
|
+
❌ Then System displays [Dashboard] page
|
|
217
|
+
❌ Then [Success] message appears
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Assertion Patterns
|
|
221
|
+
|
|
222
|
+
| Pattern | Use Case | Example |
|
|
223
|
+
|---------|----------|---------|
|
|
224
|
+
| Simple visibility | Element is visible | `User see [Login] button` |
|
|
225
|
+
| Visibility with value | Element contains specific text | `User see [Welcome] text with {{username}}` |
|
|
226
|
+
| Hidden state | Element is hidden | `User see [panel] dialog with {{title}} is hidden` |
|
|
227
|
+
| Hidden (no value) | Element is hidden | `User see [Modal] dialog is hidden` |
|
|
228
|
+
| Page/state verification | Confirm navigation | `User see [Dashboard] page` |
|
|
229
|
+
| Message verification | Confirm feedback | `User see [Error] message` |
|
|
230
|
+
| Wait for hidden | Wait until element disappears | `User wait for dialog with {{title}} is hidden` |
|
|
231
|
+
|
|
232
|
+
### State Modifiers
|
|
233
|
+
|
|
234
|
+
Append `is hidden` to any `see` or `wait for` step to assert/wait for an element to be hidden:
|
|
235
|
+
|
|
236
|
+
```gherkin
|
|
237
|
+
✅ Then User see [panel] dialog with {{title}} is hidden
|
|
238
|
+
✅ And User wait for dialog with {{title}} is hidden
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 📋 Complete Example
|
|
244
|
+
|
|
245
|
+
```gherkin
|
|
246
|
+
Feature: User Authentication
|
|
247
|
+
Path: /auth/login
|
|
248
|
+
|
|
249
|
+
Scenario: User logs in successfully with valid credentials
|
|
250
|
+
Given User is on [Login] page
|
|
251
|
+
When User fill [Email] field with {{valid_email}}
|
|
252
|
+
And User fill [Password] field with {{valid_password}}
|
|
253
|
+
And User click [Remember me] checkbox
|
|
254
|
+
And User click [Submit] button
|
|
255
|
+
Then User see [Dashboard] page
|
|
256
|
+
And User see [Welcome] message with {{username}}
|
|
257
|
+
|
|
258
|
+
Scenario: User fails to login with invalid credentials
|
|
259
|
+
Given User is on [Login] page
|
|
260
|
+
When User fill [Email] field with {{invalid_email}}
|
|
261
|
+
And User fill [Password] field with {{invalid_password}}
|
|
262
|
+
And User click [Submit] button
|
|
263
|
+
Then User see [Error] message
|
|
264
|
+
And User see [Login] page
|
|
265
|
+
|
|
266
|
+
Scenario: User selects preferred language during registration
|
|
267
|
+
Given User is on [Registration] page
|
|
268
|
+
When User fill [Email] field with {{new_email}}
|
|
269
|
+
And User fill [Password] field with {{new_password}}
|
|
270
|
+
And User select [Language] dropdown with {{preferred_language}}
|
|
271
|
+
And User click [Sign up] button
|
|
272
|
+
Then User see [Verification] page
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🏷️ Tags
|
|
278
|
+
|
|
279
|
+
### Scenario Tags
|
|
280
|
+
|
|
281
|
+
| Tag | Description |
|
|
282
|
+
|-----|-------------|
|
|
283
|
+
| `@auth:<role>` | Use Playwright auth storage state for the given role |
|
|
284
|
+
| `@no-auth` | Disable inherited authentication |
|
|
285
|
+
| `@steps:<name>` | Mark scenario as a reusable step block |
|
|
286
|
+
| `@extend:<name>` | Prepend steps from a `@steps` block before own steps |
|
|
287
|
+
| `@manual` | Skip scenario from generation |
|
|
288
|
+
|
|
289
|
+
Tags can be applied at **feature level** (inherited by all scenarios) or **scenario level** (overrides feature).
|
|
290
|
+
|
|
291
|
+
**Auth precedence**: Extending scenario `@auth` > Base scenario `@auth` > Feature `@auth`
|
|
292
|
+
|
|
293
|
+
### Reusable Steps (@steps / @extend)
|
|
294
|
+
|
|
295
|
+
Use `@steps:<name>` to define a reusable block and `@extend:<name>` to inherit those steps:
|
|
296
|
+
|
|
297
|
+
```gherkin
|
|
298
|
+
@auth:user @steps:open-dialog
|
|
299
|
+
Scenario: Open kudos dialog
|
|
300
|
+
Given User is on [kudo] page
|
|
301
|
+
When User click [Notifications] button
|
|
302
|
+
And User click [Write Kudos] menuitem
|
|
303
|
+
Then User see [panel] dialog with {{kudo_title}}
|
|
304
|
+
|
|
305
|
+
@auth:user @extend:open-dialog
|
|
306
|
+
Scenario: User sends a thank you message
|
|
307
|
+
Given User is on [panel] dialog with {{kudo_title}}
|
|
308
|
+
When User click [Search] button
|
|
309
|
+
And User fill [Search] field with {{teammate_name}}
|
|
310
|
+
And User click [teammate] row with {{teammate_name}}
|
|
311
|
+
And User fill [Title] field with {{teammate_title}}
|
|
312
|
+
And User fill [Message] textarea 2 with {{teammate_message}}
|
|
313
|
+
And User click [Hashtag] tag with {{hashtag_1}}
|
|
314
|
+
And User click [Send] button
|
|
315
|
+
And User wait for dialog with {{kudo_title}} is hidden
|
|
316
|
+
Then User see [panel] modal with {{kudo_title}} is hidden
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Behavior:**
|
|
320
|
+
- `@steps` scenarios generate their own test AND register steps for reuse
|
|
321
|
+
- `@extend` scenarios get base steps prepended inline — fully self-contained test
|
|
322
|
+
- Multiple scenarios can extend the same `@steps` block
|
|
323
|
+
- Generated code includes section comments: `// [from @steps:<name>]`
|
|
324
|
+
|
|
325
|
+
### Step-Level Annotations (comment syntax)
|
|
326
|
+
|
|
327
|
+
| Annotation | Effect |
|
|
328
|
+
|-----------|--------|
|
|
329
|
+
| `# @ignore` | Skip this step in generation |
|
|
330
|
+
| `# @ignore-testcase` | Skip entire scenario in generation |
|
|
331
|
+
| `# @skip-production` | Skip step in production environment |
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## ✅ Quick Reference
|
|
336
|
+
|
|
337
|
+
### Do's ✅
|
|
338
|
+
- Use **standard 6 actions**: open, click, fill, select, wait for, see
|
|
339
|
+
- Use **`User`** as the only actor
|
|
340
|
+
- Use **`[Target] <element type>`** format
|
|
341
|
+
- Use **`{{snake_case}}`** for values
|
|
342
|
+
- **1 Scenario = 1 business flow**
|
|
343
|
+
- **1 Step = 1 action or assertion**
|
|
344
|
+
|
|
345
|
+
### Don'ts ❌
|
|
346
|
+
- No synonyms or free-text variations
|
|
347
|
+
- No system/backend/API as actors
|
|
348
|
+
- No technical selectors (CSS/XPath/ID)
|
|
349
|
+
- No hard-coded data in steps
|
|
350
|
+
- No compound actions
|
|
351
|
+
- No `verify`/`check`/`expect` (use `see`)
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 🎯 Benefits
|
|
356
|
+
|
|
357
|
+
| Benefit | Description |
|
|
358
|
+
|---------|-------------|
|
|
359
|
+
| **Consistency** | Same patterns across all test cases |
|
|
360
|
+
| **Readability** | Non-technical stakeholders can understand |
|
|
361
|
+
| **Maintainability** | Easy to update when UI changes |
|
|
362
|
+
| **Automation-Ready** | Direct mapping to code patterns |
|
|
363
|
+
| **No Ambiguity** | Single interpretation per step |
|
|
364
|
+
| **Tool Support** | Compatible with Sungen framework |
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 📚 Related Documentation
|
|
369
|
+
- [Selector Override Guide](selector-override.md) - Customize element selectors
|
|
370
|
+
- [Validation Guide](validate.md) - Validate Gherkin files
|
|
371
|
+
- [Auth Setup](makeauth.md) - Configure authentication states
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
**Version**: 1.1
|
|
376
|
+
**Status**: Final
|
|
377
|
+
**Last Updated**: March 11, 2026
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Tiêu Chuẩn Gherkin - Cốt Lõi (Phiên Bản Cuối)
|
|
2
|
+
|
|
3
|
+
**Áp dụng cho: Kiểm thử thủ công & Kiểm thử tự động**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1️⃣ Định Dạng Scenario (Cấp độ Flow)
|
|
8
|
+
|
|
9
|
+
### Định dạng
|
|
10
|
+
```gherkin
|
|
11
|
+
Scenario: <Ai> <Làm gì> <Để đạt kết quả gì>
|
|
12
|
+
Given ...
|
|
13
|
+
When ...
|
|
14
|
+
Then ...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Nguyên tắc
|
|
18
|
+
- **1 Scenario = 1 hành vi nghiệp vụ hoàn chỉnh**
|
|
19
|
+
- **Given**: Trạng thái / điều kiện ban đầu
|
|
20
|
+
- **When**: Hành động chính (trigger)
|
|
21
|
+
- **Then**: Kết quả quan sát được (assertion)
|
|
22
|
+
|
|
23
|
+
### Ví dụ
|
|
24
|
+
```gherkin
|
|
25
|
+
Scenario: User logs in successfully with valid credentials
|
|
26
|
+
Given User open [Login] page
|
|
27
|
+
When User fill [Email] field with {{valid_email}}
|
|
28
|
+
And User fill [Password] field with {{valid_password}}
|
|
29
|
+
And User click [Submit] button
|
|
30
|
+
Then User see [Dashboard] page
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2️⃣ Ngữ Pháp (Cấp độ Step)
|
|
36
|
+
|
|
37
|
+
### Định dạng
|
|
38
|
+
```
|
|
39
|
+
<Actor> <Action> [<Target>] with {{<Value>}}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Quy tắc
|
|
43
|
+
- ✅ `Actor` + `Action` là **bắt buộc**
|
|
44
|
+
- ✅ `Target` là **bắt buộc** với hầu hết action (trừ `open` / `wait for`)
|
|
45
|
+
- ✅ `with {{Value}}` chỉ dùng khi action cần dữ liệu
|
|
46
|
+
- ❌ Không viết tự do (free-text)
|
|
47
|
+
- ❌ Không dùng từ đồng nghĩa
|
|
48
|
+
|
|
49
|
+
### Cấu trúc chi tiết
|
|
50
|
+
|
|
51
|
+
| Thành phần | Bắt buộc | Ví dụ |
|
|
52
|
+
|-----------|----------|---------|
|
|
53
|
+
| Actor | ✅ Luôn luôn | `User` |
|
|
54
|
+
| Action | ✅ Luôn luôn | `click`, `fill`, `see` |
|
|
55
|
+
| Target | ✅ Hầu hết | `[Login] button` |
|
|
56
|
+
| Value | ⚠️ Khi cần | `{{valid_email}}` |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 3️⃣ Actor (Tác nhân)
|
|
61
|
+
|
|
62
|
+
### Actor được phép
|
|
63
|
+
- ✅ **`User`** (duy nhất)
|
|
64
|
+
|
|
65
|
+
### Quy tắc
|
|
66
|
+
- **Chỉ dùng**: `User`
|
|
67
|
+
- **KHÔNG dùng**: `System`, `Backend`, `API`, `App`
|
|
68
|
+
- Hành vi của hệ thống được verify bằng `Then`, không phải Actor
|
|
69
|
+
|
|
70
|
+
### Ví dụ
|
|
71
|
+
```gherkin
|
|
72
|
+
✅ User click [Submit] button
|
|
73
|
+
❌ System sends verification email
|
|
74
|
+
❌ Backend validates password
|
|
75
|
+
❌ API returns success response
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **Lý do**: Hành vi hệ thống là *kết quả* cần verify, không phải là actor thực hiện bước.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 4️⃣ Action (Hành động)
|
|
83
|
+
|
|
84
|
+
### Các Action được phép (chỉ 6 loại)
|
|
85
|
+
|
|
86
|
+
| Action | Trường hợp sử dụng | Ví dụ |
|
|
87
|
+
|--------|----------|---------|
|
|
88
|
+
| `open` | Điều hướng đến page/screen | `User open [Login] page` |
|
|
89
|
+
| `click` | Click button/link/element | `User click [Submit] button` |
|
|
90
|
+
| `fill` | Nhập text vào input field | `User fill [Email] field with {{email}}` |
|
|
91
|
+
| `select` | Chọn option từ dropdown/radio | `User select [Country] dropdown with {{country}}` |
|
|
92
|
+
| `wait for` | Đợi element/điều kiện | `User wait for [Loader] icon` |
|
|
93
|
+
| `see` | Verify khả năng hiển thị element | `User see [Error] message` |
|
|
94
|
+
|
|
95
|
+
### Quy tắc
|
|
96
|
+
- ✅ Sử dụng **động từ chính xác** từ danh sách trên
|
|
97
|
+
- ❌ Không dùng từ đồng nghĩa: `type`, `enter`, `input`, `press`, `check`, `verify`, `expect`, v.v.
|
|
98
|
+
- ❌ Không dùng action kết hợp: `click and wait`, `fill and submit`
|
|
99
|
+
|
|
100
|
+
### Anti-patterns (Mẫu sai)
|
|
101
|
+
```gherkin
|
|
102
|
+
❌ User types {{password}} into [Password] field
|
|
103
|
+
❌ User presses [Enter] key
|
|
104
|
+
❌ User checks [Terms] checkbox
|
|
105
|
+
❌ User verifies [Success] message appears
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 5️⃣ Target (Đối tượng)
|
|
111
|
+
|
|
112
|
+
### Định dạng
|
|
113
|
+
```
|
|
114
|
+
[name] <element type>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Các loại Element
|
|
118
|
+
|
|
119
|
+
| Loại Element | Khi nào dùng | Ví dụ |
|
|
120
|
+
|--------------|-------------|---------|
|
|
121
|
+
| `field` | Text input, textarea | `[Email] field`, `[Password] field` |
|
|
122
|
+
| `button` | Button có thể click | `[Submit] button`, `[Cancel] button` |
|
|
123
|
+
| `checkbox` | Checkbox input | `[Remember me] checkbox` |
|
|
124
|
+
| `dropdown` | Select element | `[Country] dropdown` |
|
|
125
|
+
| `radio` | Radio button | `[Payment method] radio` |
|
|
126
|
+
| `link` | Hyperlink | `[Forgot password] link` |
|
|
127
|
+
| `message` | Alert/notification | `[Error] message`, `[Success] message` |
|
|
128
|
+
| `page` | Toàn bộ màn hình/page | `[Login] page`, `[Dashboard] page` |
|
|
129
|
+
| `icon` | Icon/hình ảnh hiển thị | `[Loader] icon`, `[Close] icon` |
|
|
130
|
+
| `label` | Text label | `[Username] label` |
|
|
131
|
+
|
|
132
|
+
### Quy tắc
|
|
133
|
+
- ✅ Dùng **tên có nghĩa nghiệp vụ/UI**, không dùng selector kỹ thuật
|
|
134
|
+
- ✅ Giữ tên **đơn giản và mô tả rõ**
|
|
135
|
+
- ❌ Không dùng CSS selector: `#email`, `.btn-primary`
|
|
136
|
+
- ❌ Không dùng XPath: `//input[@id='email']`
|
|
137
|
+
- ❌ Không dùng ID: `email-input`, `submit-btn-123`
|
|
138
|
+
|
|
139
|
+
### Ví dụ
|
|
140
|
+
```gherkin
|
|
141
|
+
✅ User click [Login] button
|
|
142
|
+
✅ User fill [Email address] field with {{email}}
|
|
143
|
+
✅ User select [United States] dropdown
|
|
144
|
+
✅ User see [Welcome back] message
|
|
145
|
+
|
|
146
|
+
❌ User click [#submit-btn] button
|
|
147
|
+
❌ User fill [input.email-field] field
|
|
148
|
+
❌ User see [div.alert-success] message
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 6️⃣ Value (Giá trị)
|
|
154
|
+
|
|
155
|
+
### Định dạng
|
|
156
|
+
```
|
|
157
|
+
{{value}}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Quy ước đặt tên
|
|
161
|
+
- **snake_case** (chữ thường với dấu gạch dưới)
|
|
162
|
+
- Mô tả rõ ràng và theo ngữ cảnh
|
|
163
|
+
|
|
164
|
+
### Quy tắc
|
|
165
|
+
- ✅ Sử dụng cú pháp `{{variable}}`
|
|
166
|
+
- ✅ Tên phản ánh **mục đích của dữ liệu**, không phải nội dung
|
|
167
|
+
- ❌ Không hard-code dữ liệu trong step
|
|
168
|
+
- ❌ Không chứa dữ liệu thật (email, password, token)
|
|
169
|
+
- ❌ Không chứa giá trị theo môi trường (URL, API key)
|
|
170
|
+
|
|
171
|
+
### Ví dụ
|
|
172
|
+
|
|
173
|
+
| ✅ Đúng | ❌ Sai |
|
|
174
|
+
|--------|-------|
|
|
175
|
+
| `{{valid_email}}` | `{{user@example.com}}` |
|
|
176
|
+
| `{{invalid_password}}` | `{{123456}}` |
|
|
177
|
+
| `{{expired_otp}}` | `{{999999}}` |
|
|
178
|
+
| `{{admin_username}}` | `{{admin}}` |
|
|
179
|
+
| `{{product_name}}` | `{{iPhone 15 Pro}}` |
|
|
180
|
+
|
|
181
|
+
### Tổ chức dữ liệu
|
|
182
|
+
```yaml
|
|
183
|
+
# test-data/login.yaml
|
|
184
|
+
valid_email: "user@example.com"
|
|
185
|
+
valid_password: "SecurePass123!"
|
|
186
|
+
invalid_email: "not-an-email"
|
|
187
|
+
expired_otp: "000000"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 7️⃣ Assertion (Xác nhận)
|
|
193
|
+
|
|
194
|
+
### Động từ
|
|
195
|
+
- **Chỉ dùng**: `see`
|
|
196
|
+
|
|
197
|
+
### Quy tắc
|
|
198
|
+
- ✅ Assertion **chỉ xuất hiện trong `Then`**
|
|
199
|
+
- ✅ Verify **trạng thái hệ thống / output**
|
|
200
|
+
- ✅ Mỗi step = **1 assertion**
|
|
201
|
+
- ❌ Không mô tả hành động của user
|
|
202
|
+
- ❌ Không dùng từ đồng nghĩa: `verify`, `expect`, `check`, `observe`, `validate`
|
|
203
|
+
|
|
204
|
+
### Ví dụ
|
|
205
|
+
```gherkin
|
|
206
|
+
✅ Then User see [Error] message
|
|
207
|
+
✅ And User see [Dashboard] page
|
|
208
|
+
✅ And User see [Welcome] text
|
|
209
|
+
✅ And User see [Logout] button
|
|
210
|
+
|
|
211
|
+
❌ Then User verifies [Error] message
|
|
212
|
+
❌ Then System displays [Dashboard] page
|
|
213
|
+
❌ Then [Success] message appears
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Các mẫu Assertion
|
|
217
|
+
|
|
218
|
+
| Mẫu | Trường hợp sử dụng | Ví dụ |
|
|
219
|
+
|---------|----------|---------|
|
|
220
|
+
| Hiển thị đơn giản | Element có thể nhìn thấy | `User see [Login] button` |
|
|
221
|
+
| Hiển thị với giá trị | Element chứa text cụ thể | `User see [Welcome] text with {{username}}` |
|
|
222
|
+
| Verify page/trạng thái | Xác nhận điều hướng | `User see [Dashboard] page` |
|
|
223
|
+
| Verify message | Xác nhận phản hồi | `User see [Error] message` |
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 📋 Ví Dụ Hoàn Chỉnh
|
|
228
|
+
|
|
229
|
+
```gherkin
|
|
230
|
+
Feature: User Authentication
|
|
231
|
+
Path: /auth/login
|
|
232
|
+
|
|
233
|
+
Scenario: User logs in successfully with valid credentials
|
|
234
|
+
Given User open [Login] page
|
|
235
|
+
When User fill [Email] field with {{valid_email}}
|
|
236
|
+
And User fill [Password] field with {{valid_password}}
|
|
237
|
+
And User click [Remember me] checkbox
|
|
238
|
+
And User click [Submit] button
|
|
239
|
+
Then User see [Dashboard] page
|
|
240
|
+
And User see [Welcome] message with {{username}}
|
|
241
|
+
|
|
242
|
+
Scenario: User fails to login with invalid credentials
|
|
243
|
+
Given User open [Login] page
|
|
244
|
+
When User fill [Email] field with {{invalid_email}}
|
|
245
|
+
And User fill [Password] field with {{invalid_password}}
|
|
246
|
+
And User click [Submit] button
|
|
247
|
+
Then User see [Error] message
|
|
248
|
+
And User see [Login] page
|
|
249
|
+
|
|
250
|
+
Scenario: User selects preferred language during registration
|
|
251
|
+
Given User open [Registration] page
|
|
252
|
+
When User fill [Email] field with {{new_email}}
|
|
253
|
+
And User fill [Password] field with {{new_password}}
|
|
254
|
+
And User select [Language] dropdown with {{preferred_language}}
|
|
255
|
+
And User click [Sign up] button
|
|
256
|
+
Then User see [Verification] page
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## ✅ Tham Khảo Nhanh
|
|
262
|
+
|
|
263
|
+
### Nên làm ✅
|
|
264
|
+
- Dùng **6 action chuẩn**: open, click, fill, select, wait for, see
|
|
265
|
+
- Dùng **`User`** là actor duy nhất
|
|
266
|
+
- Dùng định dạng **`[Target] <element type>`**
|
|
267
|
+
- Dùng **`{{snake_case}}`** cho giá trị
|
|
268
|
+
- **1 Scenario = 1 flow nghiệp vụ**
|
|
269
|
+
- **1 Step = 1 action hoặc assertion**
|
|
270
|
+
|
|
271
|
+
### Không nên làm ❌
|
|
272
|
+
- Không dùng từ đồng nghĩa hoặc viết tự do
|
|
273
|
+
- Không dùng system/backend/API làm actor
|
|
274
|
+
- Không dùng selector kỹ thuật (CSS/XPath/ID)
|
|
275
|
+
- Không hard-code dữ liệu trong step
|
|
276
|
+
- Không dùng action kết hợp
|
|
277
|
+
- Không dùng `verify`/`check`/`expect` (dùng `see`)
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 🎯 Lợi Ích
|
|
282
|
+
|
|
283
|
+
| Lợi ích | Mô tả |
|
|
284
|
+
|---------|-------------|
|
|
285
|
+
| **Nhất quán** | Cùng một mẫu cho tất cả test case |
|
|
286
|
+
| **Dễ đọc** | Người không kỹ thuật cũng hiểu được |
|
|
287
|
+
| **Dễ bảo trì** | Dễ cập nhật khi UI thay đổi |
|
|
288
|
+
| **Sẵn sàng tự động** | Ánh xạ trực tiếp sang code pattern |
|
|
289
|
+
| **Không mơ hồ** | Mỗi step chỉ có một cách hiểu |
|
|
290
|
+
| **Hỗ trợ công cụ** | Tương thích với framework Sungen |
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## 📚 Tài Liệu Liên Quan
|
|
295
|
+
- [Hướng dẫn Selector Override](selector-override.md) - Tùy chỉnh selector element
|
|
296
|
+
- [Hướng dẫn Validation](validate.md) - Validate file Gherkin
|
|
297
|
+
- [Thiết lập Auth](makeauth.md) - Cấu hình trạng thái authentication
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
**Phiên bản**: 1.0
|
|
302
|
+
**Trạng thái**: Final
|
|
303
|
+
**Cập nhật lần cuối**: 11 tháng 2, 2026
|