@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,513 +1,399 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Tieu Chuan Gherkin - Cot Loi v2.1
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Ap dung cho: Kiem thu thu cong & Kiem thu tu dong**
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1️⃣
|
|
7
|
+
## 1️⃣ Dinh Dang Scenario (Cap do Flow)
|
|
8
8
|
|
|
9
|
-
###
|
|
9
|
+
### Dinh dang
|
|
10
10
|
```gherkin
|
|
11
|
-
Scenario: <Ai> <
|
|
11
|
+
Scenario: <Ai> <Lam gi> <De dat ket qua gi>
|
|
12
12
|
Given ...
|
|
13
13
|
When ...
|
|
14
14
|
Then ...
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
###
|
|
18
|
-
- **1 Scenario = 1
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
|
|
17
|
+
### Nguyen tac
|
|
18
|
+
- **Doc lap**: 1 Scenario = 1 hanh vi nghiep vu hoan chinh (khong dung chung du lieu giua cac scenario)
|
|
19
|
+
- **Hanh vi**: Mo ta "User lam gi" va "Thay gi" — tap trung vao hanh vi nguoi dung
|
|
20
|
+
- **Khach quan**: Mo ta ket qua nghiep vu. Khong chua chi tiet ky thuat (CSS, XPath)
|
|
21
|
+
|
|
22
|
+
### Luong
|
|
23
|
+
**Qua khu (Setup) → Hien tai (Tuong tac) → Tuong lai (Ket qua)**
|
|
22
24
|
|
|
23
|
-
### Ví dụ
|
|
24
25
|
```gherkin
|
|
25
26
|
Scenario: User logs in successfully with valid credentials
|
|
27
|
+
# 1. Thiet lap
|
|
26
28
|
Given User is on [Login] page
|
|
29
|
+
# 2. Tuong tac
|
|
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. Ket qua
|
|
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
|
+
### Quy tac tu khoa
|
|
40
|
+
- **Given** → chi `is on` (thiet lap ngu canh)
|
|
41
|
+
- **When / And** → `click`, `fill`, `select`, `press`, `clear`, `check`, `uncheck`, `hover`, `wait for`
|
|
42
|
+
- **Then / And** → chi `see` (xac nhan)
|
|
43
|
+
- **And** → ke thua tu khoa truoc do
|
|
44
|
+
|
|
45
|
+
> Toi da 5-7 buoc `Then/And` moi scenario. Tach thanh scenario rieng neu can nhieu hon.
|
|
46
|
+
|
|
33
47
|
---
|
|
34
48
|
|
|
35
|
-
## 2️⃣
|
|
49
|
+
## 2️⃣ Ngu Phap (Cap do Step)
|
|
36
50
|
|
|
37
|
-
###
|
|
51
|
+
### Dinh dang
|
|
38
52
|
```
|
|
39
53
|
[Keyword] User <Action> [Target Name] <Target Type> <with {{Value}}> <is State>
|
|
40
54
|
```
|
|
41
55
|
|
|
42
|
-
###
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| ④ | Trạng thái với dữ liệu | `see [Panel] dialog with {{title}} is hidden` |
|
|
50
|
-
| ⑤ | Hai đối tượng (kéo thả) | `drag [Card] to [Column]` |
|
|
51
|
-
| ⑥ | Phím toàn cục | `press Enter key` |
|
|
52
|
-
| ⑦ | Phím trên đối tượng | `press Enter on [Search] field` |
|
|
53
|
-
| ⑧ | Chờ thời gian | `wait for 3 seconds` |
|
|
54
|
-
| ⑨ | Chờ element | `wait for [Loader] spinner is hidden` |
|
|
55
|
-
| ⑩ | Cuộn trang | `scroll to [Footer] section` |
|
|
56
|
-
| ⑪ | Chuyển frame | `switch to [Payment] frame` |
|
|
57
|
-
| ⑫ | Có (số lượng/thuộc tính) | `see [Avatar] image has {{src}}` |
|
|
58
|
-
| ⑬ | Ô bảng theo chỉ số hàng | `see [Users] table row 1 [Name] cell {{name}}` |
|
|
59
|
-
| ⑭ | Ô bảng theo bộ lọc hàng | `see [Users] table row {{filter}} [Status] cell {{status}}` |
|
|
60
|
-
| ⑮ | Hành động trong hàng bảng | `click [Edit] button in [Users] table row {{filter}}` |
|
|
61
|
-
| ⑯ | Điều hướng | `is on [Dashboard] page` / `navigate to [Settings] page` |
|
|
62
|
-
| ⑰ | Xác nhận văn bản | `see [Title] heading contains {{text}}` |
|
|
63
|
-
|
|
64
|
-
### Quy tắc
|
|
65
|
-
- ✅ `Actor` + `Action` là **bắt buộc**
|
|
66
|
-
- ✅ `Target` là **bắt buộc** với hầu hết action (trừ `wait for` timeout)
|
|
67
|
-
- ✅ `with {{Value}}` chỉ dùng khi action cần dữ liệu
|
|
68
|
-
- ✅ `is State` để xác nhận trạng thái element
|
|
69
|
-
- ❌ Không viết tự do (free-text)
|
|
70
|
-
- ❌ Không dùng từ đồng nghĩa
|
|
71
|
-
|
|
72
|
-
### Cấu trúc chi tiết
|
|
73
|
-
|
|
74
|
-
| Thành phần | Bắt buộc | Ví dụ |
|
|
75
|
-
|-----------|----------|---------|
|
|
76
|
-
| Actor | ✅ Luôn luôn | `User` |
|
|
77
|
-
| Action | ✅ Luôn luôn | `click`, `fill`, `see` |
|
|
78
|
-
| Target | ✅ Hầu hết | `[Login] button` |
|
|
79
|
-
| Value | ⚠️ Khi cần | `{{valid_email}}` |
|
|
80
|
-
| State | ⚠️ Khi cần | `is disabled` |
|
|
56
|
+
### Quy tac
|
|
57
|
+
- ✅ `Actor` + `Action` la **bat buoc**
|
|
58
|
+
- ✅ `Target` la **bat buoc** voi hau het action (tru `wait for` timeout)
|
|
59
|
+
- ✅ `with {{Value}}` chi dung khi action can du lieu
|
|
60
|
+
- ✅ `is State` chi dung cho assertion va wait
|
|
61
|
+
- ❌ Khong viet tu do (free-text)
|
|
62
|
+
- ❌ Khong dung tu dong nghia
|
|
81
63
|
|
|
82
|
-
|
|
64
|
+
### Cau truc chi tiet
|
|
83
65
|
|
|
84
|
-
|
|
66
|
+
| Thanh phan | Bat buoc | Vi du |
|
|
67
|
+
|-----------|----------|---------|
|
|
68
|
+
| Actor | ✅ Luon luon | `User` |
|
|
69
|
+
| Action | ✅ Luon luon | `click`, `fill`, `see` |
|
|
70
|
+
| Target | ✅ Hau het | `[Login] button` |
|
|
71
|
+
| Value | ⚠️ Khi can | `{{valid_email}}` |
|
|
72
|
+
| State | ⚠️ Khi can | `is disabled` |
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
- ✅ **`User`** (duy nhất)
|
|
74
|
+
---
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
- **Chỉ dùng**: `User`
|
|
91
|
-
- **KHÔNG dùng**: `System`, `Backend`, `API`, `App`
|
|
92
|
-
- Hành vi của hệ thống được verify bằng `Then`, không phải Actor
|
|
76
|
+
## 3️⃣ Actor (Tac nhan)
|
|
93
77
|
|
|
94
|
-
###
|
|
95
|
-
|
|
96
|
-
✅ User is on [Login] page
|
|
97
|
-
✅ User click [Submit] button
|
|
98
|
-
❌ System sends verification email
|
|
99
|
-
❌ Backend validates password
|
|
100
|
-
❌ API returns success response
|
|
101
|
-
```
|
|
78
|
+
### Actor duoc phep
|
|
79
|
+
- ✅ **`User`** (duy nhat)
|
|
102
80
|
|
|
103
|
-
|
|
81
|
+
### Quy tac
|
|
82
|
+
- **Chi dung**: `User`
|
|
83
|
+
- **KHONG dung**: `System`, `Backend`, `API`, `App`
|
|
84
|
+
- Hanh vi cua he thong duoc verify bang `Then`, khong phai Actor
|
|
104
85
|
|
|
105
86
|
---
|
|
106
87
|
|
|
107
|
-
## 4️⃣ Action (
|
|
108
|
-
|
|
109
|
-
###
|
|
110
|
-
|
|
111
|
-
| Action |
|
|
112
|
-
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
|
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `press` |
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
### Anti-patterns (Mẫu sai)
|
|
88
|
+
## 4️⃣ Action (Hanh dong)
|
|
89
|
+
|
|
90
|
+
### Ma tran Action
|
|
91
|
+
|
|
92
|
+
| Nhom | Action | `with {{Value}}` | `is State` | Target Types |
|
|
93
|
+
|------|--------|:-:|:-:|---|
|
|
94
|
+
| **Setup** | `is on` | ❌ | ❌ | `page`, `dialog`, `modal`, `tab` |
|
|
95
|
+
| **Tuong tac** | `click` | Chi list dong ✱ | ❌ | Moi phan tu tuong tac |
|
|
96
|
+
| **Tuong tac** | `double click` | ❌ | ❌ | Bat ky |
|
|
97
|
+
| **Tuong tac** | `hover` | ❌ | ❌ | `icon`, `image`, `row`, `card`, `menuitem` |
|
|
98
|
+
| **Tuong tac** | `drag` | ❌ | ❌ | Bat ky |
|
|
99
|
+
| **Tuong tac** | `expand` / `collapse` | ❌ | ❌ | `row`, `section` |
|
|
100
|
+
| **Form** | `fill` | ✅ | ❌ | `field`, `textarea`, `search`, `uploader`, `slider`, `date-picker` |
|
|
101
|
+
| **Form** | `select` | ✅ | ❌ | `dropdown`, `select`, `option` |
|
|
102
|
+
| **Form** | `clear` | ❌ | ❌ | `field`, `textarea` |
|
|
103
|
+
| **Form** | `check` | ❌ | ❌ | `checkbox`, `toggle`, `radio` |
|
|
104
|
+
| **Form** | `uncheck` | ❌ | ❌ | `checkbox`, `toggle` (KHONG cho radio) |
|
|
105
|
+
| **Phim** | `press` | ❌ | ❌ | `key` (bat buoc) |
|
|
106
|
+
| **Cuon** | `scroll to` | ❌ | ❌ | `section`, bat ky |
|
|
107
|
+
| **Frame** | `switch to` | ❌ | ❌ | `frame` |
|
|
108
|
+
| **Cho** | `wait for` | ⚠️ | ⚠️ | `page`, `dialog`, `modal`, `message`, bat ky |
|
|
109
|
+
| **Xac nhan** | `see` | ✅ | ✅ | Tat ca |
|
|
110
|
+
| **Alert** | `click` | ❌ | ❌ | `alert` (OK/Cancel) |
|
|
111
|
+
| **Alert** | `fill` | ✅ | ❌ | `alert` (prompt) |
|
|
112
|
+
|
|
113
|
+
> ✱ **`click` + `with {{Value}}`**: Chi cho list dong (`row`, `item`, `card`, `option`). Khong dung cho phan tu tinh (`button`, `link`, `icon`, `tab`).
|
|
114
|
+
|
|
115
|
+
### Quy tac
|
|
116
|
+
- ✅ Dung **dong tu chinh xac** tu danh sach
|
|
117
|
+
- ❌ Khong dung tu dong nghia: `type`, `enter`, `input`, `verify`, `expect`, v.v.
|
|
118
|
+
- ❌ Khong dung action ket hop: `click and wait`, `fill and submit`
|
|
119
|
+
|
|
120
|
+
### Anti-patterns (Mau sai)
|
|
142
121
|
```gherkin
|
|
143
|
-
❌ User types {{password}} into [Password] field →
|
|
144
|
-
❌ User
|
|
145
|
-
❌ User
|
|
146
|
-
❌ User
|
|
122
|
+
❌ User types {{password}} into [Password] field → Dung: User fill [Password] field with {{password}}
|
|
123
|
+
❌ User opens [Home] page → Dung: User is on [Home] page
|
|
124
|
+
❌ User click [Terms] checkbox → Dung: User check [Terms] checkbox
|
|
125
|
+
❌ User uncheck [Male] radio → Radio khong the uncheck, dung: User check [Female] radio
|
|
126
|
+
❌ User verifies [Success] message → Dung: User see [Success] message
|
|
147
127
|
```
|
|
148
128
|
|
|
149
129
|
---
|
|
150
130
|
|
|
151
|
-
## 5️⃣ Target (
|
|
131
|
+
## 5️⃣ Target (Doi tuong)
|
|
152
132
|
|
|
153
|
-
###
|
|
133
|
+
### Dinh dang
|
|
154
134
|
```
|
|
155
135
|
[name] <element type>
|
|
156
136
|
```
|
|
157
137
|
|
|
158
|
-
###
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
164
|
-
| `button`
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|--------------|-------------|---------|
|
|
177
|
-
| `checkbox` | Checkbox input | `[Remember me] checkbox` |
|
|
178
|
-
| `radio` | Radio button | `[Payment method] radio` |
|
|
179
|
-
| `switch` | Toggle switch | `[Dark mode] switch` |
|
|
180
|
-
| `dropdown` | Select/combobox | `[Country] dropdown` |
|
|
181
|
-
| `option` | Option trong dropdown | `[Vietnam] option` |
|
|
182
|
-
| `slider` | Thanh trượt | `[Volume] slider` |
|
|
183
|
-
| `uploader` | Vùng upload file | `[Document] uploader` |
|
|
184
|
-
| `file` | File input | `[Avatar] file` |
|
|
185
|
-
|
|
186
|
-
#### Overlay & navigation
|
|
187
|
-
|
|
188
|
-
| Loại Element | Khi nào dùng | Ví dụ |
|
|
189
|
-
|--------------|-------------|---------|
|
|
190
|
-
| `dialog` | Hộp thoại | `[Confirm] dialog` |
|
|
191
|
-
| `modal` | Modal overlay | `[Edit] modal` |
|
|
192
|
-
| `menu` | Menu dropdown | `[Actions] menu` |
|
|
193
|
-
| `menuitem` | Mục trong menu | `[Delete] menuitem` |
|
|
194
|
-
| `tab` | Tab header | `[Settings] tab` |
|
|
195
|
-
| `tabpanel` | Nội dung tab | `[General] tabpanel` |
|
|
196
|
-
| `tooltip` | Tooltip | `[Help] tooltip` |
|
|
197
|
-
| `alert` | Thông báo | `[Error] alert` |
|
|
198
|
-
|
|
199
|
-
#### Cấu trúc & layout
|
|
200
|
-
|
|
201
|
-
| Loại Element | Khi nào dùng | Ví dụ |
|
|
202
|
-
|--------------|-------------|---------|
|
|
203
|
-
| `list` | Danh sách | `[Results] list` |
|
|
204
|
-
| `listitem` | Mục trong danh sách | `[Item 1] listitem` |
|
|
205
|
-
| `table` | Bảng dữ liệu | `[Users] table` |
|
|
206
|
-
| `row` | Hàng trong bảng | `[Row 1] row` |
|
|
207
|
-
| `cell` | Ô trong bảng | `[Name] cell` |
|
|
208
|
-
| `column` | Cột | `[Status] column` |
|
|
209
|
-
| `columnheader` | Tiêu đề cột | `[Name] columnheader` |
|
|
210
|
-
| `region` | Vùng landmark | `[Main] region` |
|
|
211
|
-
| `section` | Section | `[Footer] section` |
|
|
212
|
-
| `nav` | Thanh navigation | `[Main] nav` |
|
|
213
|
-
| `banner` | Banner | `[Top] banner` |
|
|
214
|
-
| `header` | Header | `[Page] header` |
|
|
215
|
-
| `footer` | Footer | `[Page] footer` |
|
|
216
|
-
|
|
217
|
-
#### Đặc biệt
|
|
218
|
-
|
|
219
|
-
| Loại Element | Khi nào dùng | Ví dụ |
|
|
220
|
-
|--------------|-------------|---------|
|
|
221
|
-
| `page` | Toàn bộ trang | `[Login] page` |
|
|
222
|
-
| `spinner` | Loading indicator | `[Loader] spinner` |
|
|
223
|
-
| `progressbar` | Thanh tiến trình | `[Upload] progressbar` |
|
|
224
|
-
| `tree` | Cấu trúc cây | `[Files] tree` |
|
|
225
|
-
| `treeitem` | Mục trong cây | `[Folder] treeitem` |
|
|
226
|
-
| `frame` | Iframe | `[Payment] frame` |
|
|
227
|
-
| `iframe` | Iframe (tương đương frame) | `[Embed] iframe` |
|
|
228
|
-
|
|
229
|
-
### Quy tắc
|
|
230
|
-
- ✅ Dùng **tên có nghĩa nghiệp vụ/UI**, không dùng selector kỹ thuật
|
|
231
|
-
- ✅ Giữ tên **đơn giản và mô tả rõ**
|
|
232
|
-
- ❌ Không dùng CSS selector: `#email`, `.btn-primary`
|
|
233
|
-
- ❌ Không dùng XPath: `//input[@id='email']`
|
|
234
|
-
- ❌ Không dùng ID: `email-input`, `submit-btn-123`
|
|
235
|
-
|
|
236
|
-
### Ví dụ
|
|
237
|
-
```gherkin
|
|
238
|
-
✅ User click [Login] button
|
|
239
|
-
✅ User fill [Email address] field with {{email}}
|
|
240
|
-
✅ User check [Remember me] checkbox
|
|
241
|
-
✅ User toggle [Dark mode] switch
|
|
242
|
-
✅ User see [Welcome back] heading
|
|
243
|
-
|
|
244
|
-
❌ User click [#submit-btn] button
|
|
245
|
-
❌ User fill [input.email-field] field
|
|
246
|
-
❌ User see [div.alert-success] message
|
|
247
|
-
```
|
|
138
|
+
### Cac loai Element
|
|
139
|
+
|
|
140
|
+
| Nhom | Types | Vi du |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` | `[Login] page`, `[Confirm] dialog` |
|
|
143
|
+
| **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` | `[Email] field`, `[Global] search` |
|
|
144
|
+
| **Trigger** | `button` `link` `icon` `menuitem` `tag` | `[Submit] button`, `[Close] icon` |
|
|
145
|
+
| **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` | `[Users] table`, `[Order] row` |
|
|
146
|
+
| **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` | `[Error] message`, `[Total] label` |
|
|
147
|
+
| **System** | `key` `frame` `spinner` `progressbar` | `[Enter] key`, `[Payment] frame` |
|
|
148
|
+
|
|
149
|
+
### Quy tac dat ten
|
|
150
|
+
- ✅ Dung **ten co nghia nghiep vu/UI**, khong dung selector ky thuat
|
|
151
|
+
- ✅ Co visible text → dung dung nhan UI: `[Dang nhap] button`
|
|
152
|
+
- ✅ Khong co visible text → danh tu ngan gon: `[close] icon`
|
|
153
|
+
- ✅ Ten > 30 ky tu → rut gon 1-3 tu co nghia
|
|
154
|
+
- ❌ Khong dung CSS: `#email`, `.btn-primary`
|
|
155
|
+
- ❌ Khong gop element type vao ngoac vuong: `[login button]` → `[login] button`
|
|
248
156
|
|
|
249
157
|
---
|
|
250
158
|
|
|
251
|
-
## 6️⃣ Value (
|
|
159
|
+
## 6️⃣ Value (Gia tri)
|
|
252
160
|
|
|
253
|
-
###
|
|
161
|
+
### Dinh dang
|
|
254
162
|
```
|
|
255
163
|
{{value}}
|
|
256
164
|
```
|
|
257
165
|
|
|
258
|
-
### Quy
|
|
259
|
-
- **snake_case** (
|
|
260
|
-
-
|
|
166
|
+
### Quy uoc
|
|
167
|
+
- **snake_case** (chu thuong voi dau gach duoi)
|
|
168
|
+
- Mo ta ro rang va theo ngu canh
|
|
261
169
|
|
|
262
|
-
### Quy
|
|
263
|
-
- ✅
|
|
264
|
-
- ✅
|
|
265
|
-
- ❌
|
|
266
|
-
- ❌
|
|
267
|
-
- ❌ Không chứa giá trị theo môi trường (URL, API key)
|
|
170
|
+
### Quy tac
|
|
171
|
+
- ✅ Su dung cu phap `{{variable}}`
|
|
172
|
+
- ✅ Ten phan anh **muc dich cua du lieu**, khong phai noi dung
|
|
173
|
+
- ❌ Khong hard-code du lieu trong step
|
|
174
|
+
- ❌ Khong chua du lieu that (email, password, token)
|
|
268
175
|
|
|
269
|
-
###
|
|
176
|
+
### Vi du
|
|
270
177
|
|
|
271
|
-
| ✅
|
|
178
|
+
| ✅ Dung | ❌ Sai |
|
|
272
179
|
|--------|-------|
|
|
273
180
|
| `{{valid_email}}` | `{{user@example.com}}` |
|
|
274
181
|
| `{{invalid_password}}` | `{{123456}}` |
|
|
275
|
-
| `{{expired_otp}}` | `{{999999}}` |
|
|
276
|
-
| `{{admin_username}}` | `{{admin}}` |
|
|
277
182
|
| `{{product_name}}` | `{{iPhone 15 Pro}}` |
|
|
278
183
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 7️⃣ Assertion (Xac nhan)
|
|
187
|
+
|
|
188
|
+
### Dong tu
|
|
189
|
+
- **Duy nhat**: `see`
|
|
190
|
+
|
|
191
|
+
### 7 Pattern Verify
|
|
192
|
+
|
|
193
|
+
| # | Pattern | Assertion | Vi du |
|
|
194
|
+
|---|---------|-----------|-------|
|
|
195
|
+
| 1 | **Hien thi** | `toBeVisible()` / `toBeHidden()` | `see [Success] message` / `see [Ads] modal is hidden` |
|
|
196
|
+
| 2 | **Noi dung text** | `toHaveText()` (khop chinh xac) | `see [Error] message with {{err_msg}}` |
|
|
197
|
+
| 3 | **Text mot phan** | `toContainText()` | `see [Title] heading contains {{text}}` |
|
|
198
|
+
| 4 | **Gia tri input** | `toHaveValue()` | `see [Email] field with {{user_email}}` |
|
|
199
|
+
| 5 | **Trang thai** | `toBeDisabled()` / `toBeChecked()` v.v. | `see [Submit] button is disabled` |
|
|
200
|
+
| 6 | **So luong** | `toHaveCount()` | `see [Result] row with {{result_count}}` |
|
|
201
|
+
| 7 | **Dieu huong** | `toHaveURL()` | `see [Dashboard] page` |
|
|
202
|
+
|
|
203
|
+
> **Phan biet quan trong**: `see [T] <input type> with {{v}}` → `toHaveValue()` cho input (field, textarea, search, dropdown, slider, date-picker). `see [T] <other type> with {{v}}` → `toHaveText()` cho tat ca con lai.
|
|
204
|
+
|
|
205
|
+
### States (Trang thai)
|
|
206
|
+
|
|
207
|
+
| State | Mo ta |
|
|
208
|
+
|-------|-------|
|
|
209
|
+
| `hidden` | Element bi an |
|
|
210
|
+
| `visible` | Element hien thi |
|
|
211
|
+
| `disabled` | Element bi vo hieu |
|
|
212
|
+
| `enabled` | Element co the tuong tac |
|
|
213
|
+
| `checked` | Checkbox/radio/toggle duoc chon |
|
|
214
|
+
| `unchecked` | Checkbox/radio/toggle chua chon |
|
|
215
|
+
| `focused` | Element dang duoc focus |
|
|
216
|
+
| `empty` | Element rong |
|
|
217
|
+
| `loading` | Dang tai |
|
|
218
|
+
| `selected` | Duoc chon |
|
|
219
|
+
| `sorted ascending` | Sap xep tang dan |
|
|
220
|
+
| `sorted descending` | Sap xep giam dan |
|
|
221
|
+
|
|
222
|
+
### Ket hop Value + State
|
|
223
|
+
```gherkin
|
|
224
|
+
Then User see [Ads] modal with {{promo_title}} is hidden
|
|
286
225
|
```
|
|
287
226
|
|
|
288
|
-
|
|
227
|
+
### Xac nhan bang (Table)
|
|
289
228
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
### Động từ
|
|
293
|
-
- **Chính**: `see` (xác nhận hiển thị / trạng thái)
|
|
294
|
-
|
|
295
|
-
### States (Trạng thái)
|
|
296
|
-
|
|
297
|
-
Thêm `is <state>` vào cuối step `see` hoặc `wait for` để xác nhận trạng thái:
|
|
298
|
-
|
|
299
|
-
| State | Mô tả | Ví dụ |
|
|
300
|
-
|-------|--------|-------|
|
|
301
|
-
| `hidden` | Element bị ẩn | `User see [Modal] dialog is hidden` |
|
|
302
|
-
| `visible` | Element hiển thị | `User see [Banner] section is visible` |
|
|
303
|
-
| `disabled` | Element bị vô hiệu | `User see [Submit] button is disabled` |
|
|
304
|
-
| `enabled` | Element có thể tương tác | `User see [Submit] button is enabled` |
|
|
305
|
-
| `checked` | Checkbox/radio được chọn | `User see [Terms] checkbox is checked` |
|
|
306
|
-
| `unchecked` | Checkbox/radio chưa chọn | `User see [Terms] checkbox is unchecked` |
|
|
307
|
-
| `focused` | Element đang được focus | `User see [Email] field is focused` |
|
|
308
|
-
| `empty` | Element rỗng | `User see [Search] field is empty` |
|
|
309
|
-
| `loading` | Element đang tải | `User see [Content] section is loading` |
|
|
310
|
-
| `selected` | Element được chọn | `User see [Tab 1] tab is selected` |
|
|
311
|
-
| `sorted ascending` | Sắp xếp tăng dần | `User see [Name] columnheader is sorted ascending` |
|
|
312
|
-
| `sorted descending` | Sắp xếp giảm dần | `User see [Name] columnheader is sorted descending` |
|
|
313
|
-
|
|
314
|
-
### Quy tắc
|
|
315
|
-
- ✅ Assertion **chỉ xuất hiện trong `Then`**
|
|
316
|
-
- ✅ Verify **trạng thái hệ thống / output**
|
|
317
|
-
- ✅ Mỗi step = **1 assertion**
|
|
318
|
-
- ❌ Không mô tả hành động của user
|
|
319
|
-
- ❌ Không dùng từ đồng nghĩa: `verify`, `expect`, `check`, `observe`, `validate`
|
|
320
|
-
|
|
321
|
-
### Các mẫu Assertion
|
|
322
|
-
|
|
323
|
-
| Mẫu | Trường hợp sử dụng | Ví dụ |
|
|
324
|
-
|---------|----------|---------|
|
|
325
|
-
| Hiển thị đơn giản | Element có thể nhìn thấy | `User see [Login] button` |
|
|
326
|
-
| Hiển thị với giá trị | Element chứa text cụ thể | `User see [Welcome] heading with {{username}}` |
|
|
327
|
-
| Xác nhận trạng thái | Element ở trạng thái nhất định | `User see [Submit] button is disabled` |
|
|
328
|
-
| Trạng thái với giá trị | Element có giá trị và trạng thái | `User see [Panel] dialog with {{title}} is hidden` |
|
|
329
|
-
| Chứa text | Element chứa text | `User see [Title] heading contains {{text}}` |
|
|
330
|
-
| Có thuộc tính | Element có thuộc tính/giá trị | `User see [Avatar] image has {{src}}` |
|
|
331
|
-
| Verify page | Xác nhận điều hướng | `User is on [Dashboard] page` |
|
|
332
|
-
| Chờ ẩn | Đợi element biến mất | `User wait for [Loader] spinner is hidden` |
|
|
333
|
-
|
|
334
|
-
### Xác nhận bảng (Table Assertions)
|
|
335
|
-
|
|
336
|
-
| Mẫu | Ví dụ |
|
|
229
|
+
| Mau | Vi du |
|
|
337
230
|
|------|-------|
|
|
338
|
-
|
|
|
339
|
-
|
|
|
340
|
-
|
|
|
341
|
-
|
|
|
342
|
-
|
|
|
343
|
-
|
|
|
344
|
-
|
|
345
|
-
|
|
231
|
+
| Dong ton tai | `User see [Users] table has row with {{name}}` |
|
|
232
|
+
| Khong co dong | `User see [Users] table has no row with {{name}}` |
|
|
233
|
+
| Dem dong | `User see [Users] table has {{count}} rows` |
|
|
234
|
+
| Cot ton tai | `User see [Users] table has [Email] column` |
|
|
235
|
+
| Bang rong | `User see [Users] table is empty` |
|
|
236
|
+
| O theo bo loc | `User see [Users] table row with {{filter}} has [Status] with {{status}}` |
|
|
237
|
+
| O theo chi so | `User see [Users] table row 1 [Name] cell with {{name}}` |
|
|
238
|
+
| Hanh dong trong dong | `User click [Edit] in [Users] table row with {{name}}` |
|
|
239
|
+
|
|
240
|
+
### Quy tac
|
|
241
|
+
- ✅ Assertion **chi xuat hien trong `Then`**
|
|
242
|
+
- ✅ Moi step = **1 assertion**
|
|
243
|
+
- ❌ Khong dung tu dong nghia: `verify`, `expect`, `check`, `validate`
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 8️⃣ Browser Alert (System Dialog)
|
|
248
|
+
|
|
249
|
+
Cho dialog he thong (`window.alert`, `window.confirm`, `window.prompt`):
|
|
250
|
+
|
|
346
251
|
```gherkin
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
❌ Then [Success] message appears
|
|
252
|
+
# Buoc alert phai dat TRUOC hanh dong kich hoat dialog
|
|
253
|
+
When User click [OK] alert # chap nhan (OK/Accept/Yes/Confirm)
|
|
254
|
+
And User click [Delete] button # hanh dong kich hoat alert
|
|
255
|
+
|
|
256
|
+
When User click [Cancel] alert # tu choi (Cancel/Dismiss/No)
|
|
257
|
+
And User click [Delete] button
|
|
258
|
+
|
|
259
|
+
When User fill [Name] alert with {{v}} # nhap prompt + chap nhan
|
|
260
|
+
And User click [Rename] button
|
|
357
261
|
```
|
|
358
262
|
|
|
263
|
+
> **Quan trong**: Dang ky dialog handler TRUOC hanh dong kich hoat. Sungen sinh `page.once('dialog', ...)`.
|
|
264
|
+
|
|
359
265
|
---
|
|
360
266
|
|
|
361
267
|
## 🏷️ Tags
|
|
362
268
|
|
|
363
|
-
###
|
|
269
|
+
### Tags phan loai
|
|
364
270
|
|
|
365
|
-
| Tag |
|
|
271
|
+
| Tag | Mo ta |
|
|
366
272
|
|-----|-------|
|
|
367
|
-
| `@
|
|
368
|
-
| `@
|
|
369
|
-
| `@
|
|
370
|
-
| `@
|
|
371
|
-
| `@manual` | Bỏ qua scenario khi sinh code |
|
|
273
|
+
| `@auto` | Scenario tu dong, san sang chay |
|
|
274
|
+
| `@manual` | Bo qua khi sinh code |
|
|
275
|
+
| `@smoke` | Tap kiem thu Smoke |
|
|
276
|
+
| `@regression` | Tap kiem thu Regression |
|
|
372
277
|
|
|
373
|
-
Tags
|
|
278
|
+
### Tags xac thuc
|
|
374
279
|
|
|
375
|
-
|
|
280
|
+
| Tag | Mo ta |
|
|
281
|
+
|-----|-------|
|
|
282
|
+
| `@auth:<role>` | Su dung trang thai auth Playwright cho role |
|
|
283
|
+
| `@no-auth` | Tat authentication ke thua |
|
|
376
284
|
|
|
377
|
-
|
|
285
|
+
**Thu tu uu tien Auth**: Scenario ke thua `@auth` > Scenario goc `@auth` > Feature `@auth`
|
|
378
286
|
|
|
379
|
-
|
|
287
|
+
### Tags ke thua (@steps / @extend)
|
|
380
288
|
|
|
381
289
|
```gherkin
|
|
382
|
-
@auth:user @steps:
|
|
383
|
-
Scenario:
|
|
384
|
-
Given User is on [
|
|
385
|
-
When User click [
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
When User click [Search] button
|
|
393
|
-
And User fill [Search] field with {{teammate_name}}
|
|
394
|
-
And User click [Teammate] row with {{teammate_name}}
|
|
395
|
-
And User fill [Title] field with {{teammate_title}}
|
|
396
|
-
And User fill [Message] textarea with {{teammate_message}}
|
|
397
|
-
And User click [Hashtag] button with {{hashtag_1}}
|
|
290
|
+
@auto @auth:user @steps:kudos__open_modal
|
|
291
|
+
Scenario: Setup for opening Kudos modal
|
|
292
|
+
Given User is on [Home] page
|
|
293
|
+
When User click [Today you want...] button
|
|
294
|
+
Then User see [Send thanks] dialog # ← bo qua khi @extend goi
|
|
295
|
+
|
|
296
|
+
@auto @auth:user @extend:kudos__open_modal
|
|
297
|
+
Scenario: User successfully sends a thank you message
|
|
298
|
+
Given User is on [Send thanks] dialog # ← bat buoc: xac nhan trang thai sau extend
|
|
299
|
+
When User fill [Search teammate] field with {{teammate_name}}
|
|
398
300
|
And User click [Send] button
|
|
399
|
-
|
|
400
|
-
Then User see [Panel] modal with {{kudo_title}} is hidden
|
|
301
|
+
Then User see [Success] message with {{msg_success}}
|
|
401
302
|
```
|
|
402
303
|
|
|
403
|
-
**
|
|
404
|
-
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
|
|
409
|
-
### Annotation cấp Step (cú pháp comment)
|
|
410
|
-
|
|
411
|
-
| Annotation | Hiệu lực |
|
|
412
|
-
|-----------|--------|
|
|
413
|
-
| `# @ignore` | Bỏ qua step này khi sinh code |
|
|
414
|
-
| `# @ignore-testcase` | Bỏ qua toàn bộ scenario khi sinh code |
|
|
415
|
-
| `# @skip-production` | Bỏ qua step trong môi trường production |
|
|
304
|
+
**Hanh vi:**
|
|
305
|
+
- `@extend` thuc thi **chi Given→When** cua `@steps` (bo qua Then)
|
|
306
|
+
- `Given` trong `@extend` la **assertion xac nhan trang thai** sau khi base steps chay
|
|
307
|
+
- Neu `@steps` **fail**, `@extend` se **tu dong bo qua (skip)**
|
|
308
|
+
- Dinh dang ten: `snake_case` hoac `kebab-case` voi prefix module: `@steps:kudos__open_modal`
|
|
416
309
|
|
|
417
310
|
---
|
|
418
311
|
|
|
419
|
-
## 📋
|
|
312
|
+
## 📋 Vi du hoan chinh
|
|
420
313
|
|
|
421
314
|
```gherkin
|
|
422
|
-
|
|
315
|
+
@feature_auth
|
|
316
|
+
Feature: Xac thuc nguoi dung
|
|
423
317
|
Path: /auth/login
|
|
424
318
|
|
|
425
|
-
|
|
319
|
+
# Happy Path
|
|
320
|
+
@auto @smoke @regression
|
|
426
321
|
Scenario: User logs in successfully with valid credentials
|
|
427
322
|
Given User is on [Login] page
|
|
428
323
|
When User fill [Email] field with {{valid_email}}
|
|
429
324
|
And User fill [Password] field with {{valid_password}}
|
|
430
325
|
And User check [Remember me] checkbox
|
|
431
|
-
And User click [
|
|
326
|
+
And User click [Login] button
|
|
432
327
|
Then User see [Dashboard] page
|
|
433
|
-
And User see [Welcome]
|
|
328
|
+
And User see [Welcome] message with {{user_fullname}}
|
|
329
|
+
And User see [Logout] button is enabled
|
|
434
330
|
|
|
435
|
-
|
|
436
|
-
|
|
331
|
+
# Error Path
|
|
332
|
+
@auto @regression
|
|
333
|
+
Scenario: Login fails with invalid credentials
|
|
437
334
|
Given User is on [Login] page
|
|
438
335
|
When User fill [Email] field with {{invalid_email}}
|
|
439
336
|
And User fill [Password] field with {{invalid_password}}
|
|
440
|
-
And User click [
|
|
441
|
-
Then User see [
|
|
442
|
-
And User see [
|
|
443
|
-
And User see [Login]
|
|
444
|
-
|
|
445
|
-
@
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
And User
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
And User
|
|
460
|
-
And User press Enter key
|
|
461
|
-
And User scroll to [Save] section
|
|
462
|
-
And User click [Save] button
|
|
463
|
-
And User wait for [Loader] spinner is hidden
|
|
464
|
-
Then User see [Success] alert
|
|
465
|
-
And User see [Dark mode] switch is checked
|
|
337
|
+
And User click [Login] button
|
|
338
|
+
Then User see [Login] page
|
|
339
|
+
And User see [Login error] message with {{err_invalid_credentials}}
|
|
340
|
+
And User see [Login] button is enabled
|
|
341
|
+
|
|
342
|
+
# Dung @extend
|
|
343
|
+
@auto @auth:user @steps:navigate_to_profile
|
|
344
|
+
Scenario: Setup — Navigate to Profile page
|
|
345
|
+
Given User is on [Dashboard] page
|
|
346
|
+
When User click [Avatar] icon
|
|
347
|
+
And User click [My account] menuitem
|
|
348
|
+
Then User see [Profile] page # ← @extend bo qua buoc nay
|
|
349
|
+
|
|
350
|
+
@auto @auth:user @extend:navigate_to_profile
|
|
351
|
+
Scenario: User updates display name successfully
|
|
352
|
+
Given User is on [Profile] page # ← Xac nhan trang thai sau extend
|
|
353
|
+
When User fill [Display name] field with {{new_display_name}}
|
|
354
|
+
And User click [Save changes] button
|
|
355
|
+
Then User see [Success] message with {{msg_save_success}}
|
|
356
|
+
And User see [Display name] field with {{new_display_name}}
|
|
466
357
|
```
|
|
467
358
|
|
|
468
359
|
---
|
|
469
360
|
|
|
470
|
-
## ✅ Tham
|
|
471
|
-
|
|
472
|
-
###
|
|
473
|
-
-
|
|
474
|
-
-
|
|
475
|
-
-
|
|
476
|
-
-
|
|
477
|
-
-
|
|
478
|
-
-
|
|
479
|
-
- **1 Scenario = 1 flow
|
|
480
|
-
- **1 Step = 1 action
|
|
481
|
-
|
|
482
|
-
###
|
|
483
|
-
-
|
|
484
|
-
-
|
|
485
|
-
-
|
|
486
|
-
-
|
|
487
|
-
-
|
|
488
|
-
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
|
495
|
-
|
|
496
|
-
|
|
|
497
|
-
|
|
|
498
|
-
|
|
|
499
|
-
|
|
|
500
|
-
|
|
|
501
|
-
|
|
|
502
|
-
|
|
|
503
|
-
|
|
504
|
-
---
|
|
505
|
-
|
|
506
|
-
## 📚 Tài Liệu Liên Quan
|
|
507
|
-
- [Từ điển Gherkin](../gherkin-dictionary.md) — Ngữ pháp đầy đủ, 17 mẫu pattern, quy tắc compiler
|
|
361
|
+
## ✅ Tham Khao Nhanh
|
|
362
|
+
|
|
363
|
+
### Nen lam ✅
|
|
364
|
+
- Dung **action chuan** tu ma tran action
|
|
365
|
+
- Dung **`User`** la actor duy nhat
|
|
366
|
+
- Dung dinh dang **`[Target] <element type>`**
|
|
367
|
+
- Dung **`{{snake_case}}`** cho gia tri
|
|
368
|
+
- Dung **`is <state>`** cho xac nhan trang thai
|
|
369
|
+
- Dung **tags** (`@auth`, `@steps`, `@extend`) de quan ly scenario
|
|
370
|
+
- **1 Scenario = 1 flow nghiep vu**
|
|
371
|
+
- **1 Step = 1 action hoac assertion**
|
|
372
|
+
|
|
373
|
+
### Khong nen lam ❌
|
|
374
|
+
- Khong dung tu dong nghia hoac viet tu do
|
|
375
|
+
- Khong dung system/backend/API lam actor
|
|
376
|
+
- Khong dung selector ky thuat (CSS/XPath/ID)
|
|
377
|
+
- Khong hard-code du lieu trong step
|
|
378
|
+
- Khong dung action ket hop
|
|
379
|
+
- Khong dung `verify`/`check`/`expect` thay cho `see`
|
|
380
|
+
- Khong `click` checkbox/toggle (dung `check`/`uncheck`)
|
|
381
|
+
- Khong `uncheck` radio (dung `check` option khac)
|
|
382
|
+
|
|
383
|
+
### Loi thuong gap
|
|
384
|
+
|
|
385
|
+
| ❌ Sai | ✅ Dung | Ly do |
|
|
386
|
+
|---|---|---|
|
|
387
|
+
| `Given User click [Login] button` | `When User click [Login] button` | `click` thuoc WHEN |
|
|
388
|
+
| `When User click [Terms] checkbox` | `When User check [Terms] checkbox` | Dung `check` cho checkbox |
|
|
389
|
+
| `When User press [Submit] button` | `When User press [Enter] key` | `press` chi di voi `key` |
|
|
390
|
+
| `When User uncheck [Male] radio` | `When User check [Female] radio` | Radio khong the uncheck |
|
|
391
|
+
| `fill [email] with {{admin@mail}}` | `fill [email] field with {{admin_email}}` | Khong hardcode + thieu type |
|
|
392
|
+
| `see [msg] with {{text}} hidden` | `see [msg] with {{text}} is hidden` | Thieu tu noi `is` |
|
|
393
|
+
| `see [btn] button with {{disabled}}` | `see [btn] button is disabled` | State dung `is`, khong dung `{{}}` |
|
|
508
394
|
|
|
509
395
|
---
|
|
510
396
|
|
|
511
|
-
**
|
|
512
|
-
**
|
|
513
|
-
**
|
|
397
|
+
**Phien ban**: 2.1
|
|
398
|
+
**Trang thai**: Final
|
|
399
|
+
**Cap nhat lan cuoi**: 31 thang 3, 2026
|