@sun-asterisk/sungen 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +66 -37
  2. package/dist/cli/commands/update.d.ts +3 -0
  3. package/dist/cli/commands/update.d.ts.map +1 -0
  4. package/dist/cli/commands/update.js +21 -0
  5. package/dist/cli/commands/update.js.map +1 -0
  6. package/dist/cli/index.js +3 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/generators/gherkin-parser/index.d.ts +2 -0
  9. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  10. package/dist/generators/gherkin-parser/index.js +17 -3
  11. package/dist/generators/gherkin-parser/index.js.map +1 -1
  12. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
  13. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
  14. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
  15. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
  16. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  17. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
  18. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  19. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  20. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  21. package/dist/generators/test-generator/patterns/assertion-patterns.js +95 -57
  22. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  23. package/dist/generators/test-generator/patterns/index.d.ts +9 -0
  24. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  25. package/dist/generators/test-generator/patterns/index.js +32 -0
  26. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  27. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +1 -1
  28. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
  29. package/dist/generators/test-generator/patterns/interaction-patterns.js +56 -1
  30. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  31. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  32. package/dist/generators/test-generator/patterns/table-patterns.js +8 -5
  33. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  34. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  35. package/dist/generators/test-generator/utils/selector-resolver.js +16 -0
  36. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  37. package/dist/orchestrator/ai-rules-updater.d.ts +13 -0
  38. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -0
  39. package/dist/orchestrator/ai-rules-updater.js +157 -0
  40. package/dist/orchestrator/ai-rules-updater.js.map +1 -0
  41. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  42. package/dist/orchestrator/project-initializer.js +2 -27
  43. package/dist/orchestrator/project-initializer.js.map +1 -1
  44. package/dist/orchestrator/screen-manager.d.ts +1 -0
  45. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  46. package/dist/orchestrator/screen-manager.js +70 -3
  47. package/dist/orchestrator/screen-manager.js.map +1 -1
  48. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  49. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +11 -4
  50. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -6
  51. package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
  52. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +170 -24
  53. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +118 -12
  54. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
  55. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +124 -71
  56. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  57. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +12 -4
  58. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +11 -6
  59. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
  60. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +170 -24
  61. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +93 -12
  62. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
  63. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +124 -72
  64. package/dist/orchestrator/templates/readme.md +13 -8
  65. package/package.json +1 -1
  66. package/src/cli/commands/update.ts +18 -0
  67. package/src/cli/index.ts +3 -1
  68. package/src/generators/gherkin-parser/index.ts +20 -3
  69. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -0
  70. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -0
  71. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -0
  72. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +8 -0
  73. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  74. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +1 -0
  75. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  76. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  77. package/src/generators/test-generator/patterns/assertion-patterns.ts +106 -65
  78. package/src/generators/test-generator/patterns/index.ts +41 -0
  79. package/src/generators/test-generator/patterns/interaction-patterns.ts +58 -1
  80. package/src/generators/test-generator/patterns/table-patterns.ts +8 -5
  81. package/src/generators/test-generator/utils/selector-resolver.ts +16 -0
  82. package/src/orchestrator/ai-rules-updater.ts +139 -0
  83. package/src/orchestrator/project-initializer.ts +2 -32
  84. package/src/orchestrator/screen-manager.ts +72 -3
  85. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  86. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +11 -4
  87. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +11 -6
  88. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +22 -9
  89. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +170 -24
  90. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +118 -12
  91. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +16 -2
  92. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +124 -71
  93. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  94. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +12 -4
  95. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +11 -6
  96. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +22 -9
  97. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +170 -24
  98. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +93 -12
  99. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +16 -2
  100. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +124 -72
  101. package/src/orchestrator/templates/readme.md +13 -8
  102. package/docs/gherkin standards/gherkin-core-standard.md +0 -428
  103. package/docs/gherkin standards/gherkin-core-standard.vi.md +0 -513
  104. package/docs/gherkin-dictionary.md +0 -1071
  105. package/docs/makeauth.md +0 -225
@@ -1,513 +0,0 @@
1
- # Tiêu Chuẩn Gherkin - Cốt Lõi v2
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 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️⃣ Ngữ Pháp (Cấp độ Step)
36
-
37
- ### Định dạng
38
- ```
39
- [Keyword] User <Action> [Target Name] <Target Type> <with {{Value}}> <is State>
40
- ```
41
-
42
- ### 17 Mẫu Pattern
43
-
44
- | # | Mẫu | Ví dụ |
45
- |---|------|-------|
46
- | ① | Hành động đơn giản | `click [Submit] button` |
47
- | ② | Hành động với dữ liệu | `fill [Email] field with {{email}}` |
48
- | ③ | Xác nhận trạng thái | `see [Submit] button is disabled` |
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` |
81
-
82
- ---
83
-
84
- ## 3️⃣ Actor (Tác nhân)
85
-
86
- ### Actor được phép
87
- - ✅ **`User`** (duy nhất)
88
-
89
- ### Quy tắc
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
93
-
94
- ### Ví dụ
95
- ```gherkin
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
- ```
102
-
103
- > **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.
104
-
105
- ---
106
-
107
- ## 4️⃣ Action (Hành động)
108
-
109
- ### Các Action được phép (20 loại)
110
-
111
- | Action | Trường hợp sử dụng | Ví dụ |
112
- |--------|----------|---------|
113
- | `click` | Click button/link/element | `User click [Submit] button` |
114
- | `fill` | Nhập text vào input field | `User fill [Email] field with {{email}}` |
115
- | `select` | Chọn option từ dropdown | `User select [Country] dropdown with {{country}}` |
116
- | `check` | Đánh dấu checkbox | `User check [Remember me] checkbox` |
117
- | `uncheck` | Bỏ đánh dấu checkbox | `User uncheck [Newsletter] checkbox` |
118
- | `toggle` | Bật/tắt switch | `User toggle [Dark mode] switch` |
119
- | `upload` | Tải file lên | `User upload [Avatar] file with {{avatar_path}}` |
120
- | `hover` | Di chuột lên element | `User hover [Info] icon` |
121
- | `drag` | Kéo thả element | `User drag [Card] to [Column]` |
122
- | `clear` | Xóa nội dung input | `User clear [Search] field` |
123
- | `see` | Verify hiển thị / trạng thái | `User see [Error] message` |
124
- | `press` | Nhấn phím bàn phím | `User press Enter key` |
125
- | `expand` | Mở rộng element | `User expand [Details] row` |
126
- | `collapse` | Thu gọn element | `User collapse [Details] row` |
127
- | `double click` | Double click element | `User double click [Cell] cell` |
128
- | `scroll to` | Cuộn đến element | `User scroll to [Footer] section` |
129
- | `switch to` | Chuyển sang frame | `User switch to [Payment] frame` |
130
- | `wait for` | Đợi element/điều kiện | `User wait for [Loader] spinner` |
131
- | `is on` | Xác nhận đang ở trang | `User is on [Login] page` |
132
- | `navigate to` | Điều hướng đến trang | `User navigate to [Settings] page` |
133
-
134
- > **Ghi chú**: `is on` và `navigate to` đều dùng cho điều hướng. `is on` là dạng ưu tiên cho step `Given`.
135
-
136
- ### Quy tắc
137
- - ✅ Sử dụng **động từ chính xác** từ danh sách trên
138
- - ❌ Không dùng từ đồng nghĩa: `type`, `enter`, `input`, `verify`, `expect`, v.v.
139
- - ❌ Không dùng action kết hợp: `click and wait`, `fill and submit`
140
-
141
- ### Anti-patterns (Mẫu sai)
142
- ```gherkin
143
- ❌ User types {{password}} into [Password] field → Dùng: User fill [Password] field with {{password}}
144
- ❌ User presses [Enter] key → Dùng: User press Enter key
145
- ❌ User checks [Terms] checkbox → Dùng: User check [Terms] checkbox
146
- ❌ User verifies [Success] message appears → Dùng: User see [Success] message
147
- ```
148
-
149
- ---
150
-
151
- ## 5️⃣ Target (Đối tượng)
152
-
153
- ### Định dạng
154
- ```
155
- [name] <element type>
156
- ```
157
-
158
- ### Các loại Element (40+)
159
-
160
- #### Tương tác cơ bản
161
-
162
- | Loại Element | Khi nào dùng | Ví dụ |
163
- |--------------|-------------|---------|
164
- | `button` | Nút có thể click | `[Submit] button` |
165
- | `link` | Hyperlink | `[Forgot password] link` |
166
- | `field` | Text input | `[Email] field` |
167
- | `textarea` | Text area nhiều dòng | `[Message] textarea` |
168
- | `heading` | Tiêu đề (h1-h6) | `[Welcome] heading` |
169
- | `text` | Nội dung text | `[Price] text` |
170
- | `image` | Hình ảnh | `[Avatar] image` |
171
- | `icon` | Icon/hình ảnh nhỏ | `[Close] icon` |
172
-
173
- #### Form controls
174
-
175
- | Loại Element | Khi nào dùng | Ví dụ |
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
- ```
248
-
249
- ---
250
-
251
- ## 6️⃣ Value (Giá trị)
252
-
253
- ### Định dạng
254
- ```
255
- {{value}}
256
- ```
257
-
258
- ### Quy ước đặt tên
259
- - **snake_case** (chữ thường với dấu gạch dưới)
260
- - Mô tả rõ ràng và theo ngữ cảnh
261
-
262
- ### Quy tắc
263
- - ✅ Sử dụng cú pháp `{{variable}}`
264
- - ✅ Tên phản ánh **mục đích của dữ liệu**, không phải nội dung
265
- - ❌ Không hard-code dữ liệu trong step
266
- - ❌ Không chứa dữ liệu thật (email, password, token)
267
- - ❌ Không chứa giá trị theo môi trường (URL, API key)
268
-
269
- ### Ví dụ
270
-
271
- | ✅ Đúng | ❌ Sai |
272
- |--------|-------|
273
- | `{{valid_email}}` | `{{user@example.com}}` |
274
- | `{{invalid_password}}` | `{{123456}}` |
275
- | `{{expired_otp}}` | `{{999999}}` |
276
- | `{{admin_username}}` | `{{admin}}` |
277
- | `{{product_name}}` | `{{iPhone 15 Pro}}` |
278
-
279
- ### Tổ chức dữ liệu
280
- ```yaml
281
- # test-data/login.yaml
282
- valid_email: "user@example.com"
283
- valid_password: "SecurePass123!"
284
- invalid_email: "not-an-email"
285
- expired_otp: "000000"
286
- ```
287
-
288
- ---
289
-
290
- ## 7️⃣ Assertion (Xác nhận)
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ụ |
337
- |------|-------|
338
- | Ô theo chỉ số hàng | `User see [Users] table row 1 [Name] cell {{name}}` |
339
- | Ô theo bộ lọc hàng | `User see [Users] table row {{filter}} [Status] cell {{status}}` |
340
- | Hành động trong hàng | `User click [Edit] button in [Users] table row {{filter}}` |
341
- | Đếm số hàng | `User see [Users] table has {{count}} rows` |
342
- | Bảng rỗng | `User see [Users] table is empty` |
343
- | Có cột | `User see [Users] table has [Email] column` |
344
-
345
- ### Ví dụ
346
- ```gherkin
347
- ✅ Then User see [Error] alert
348
- ✅ And User see [Dashboard] page
349
- ✅ And User see [Welcome] heading with {{username}}
350
- ✅ And User see [Submit] button is disabled
351
- ✅ And User see [Terms] checkbox is checked
352
- ✅ And User see [Users] table row 1 [Name] cell {{name}}
353
-
354
- ❌ Then User verifies [Error] message
355
- ❌ Then System displays [Dashboard] page
356
- ❌ Then [Success] message appears
357
- ```
358
-
359
- ---
360
-
361
- ## 🏷️ Tags
362
-
363
- ### Scenario Tags
364
-
365
- | Tag | Mô tả |
366
- |-----|-------|
367
- | `@auth:<role>` | Sử dụng trạng thái auth Playwright cho role đã cho |
368
- | `@no-auth` | Tắt authentication kế thừa |
369
- | `@steps:<name>` | Đánh dấu scenario là khối step tái sử dụng |
370
- | `@extend:<name>` | Chèn step từ khối `@steps` trước step hiện tại |
371
- | `@manual` | Bỏ qua scenario khi sinh code |
372
-
373
- Tags có thể áp dụng ở **cấp Feature** (kế thừa cho tất cả scenario) hoặc **cấp Scenario** (ghi đè Feature).
374
-
375
- **Thứ tự ưu tiên Auth**: Scenario kế thừa `@auth` > Scenario gốc `@auth` > Feature `@auth`
376
-
377
- ### Step tái sử dụng (@steps / @extend)
378
-
379
- Dùng `@steps:<name>` để định nghĩa khối tái sử dụng và `@extend:<name>` để kế thừa:
380
-
381
- ```gherkin
382
- @auth:user @steps:open-dialog
383
- Scenario: Open kudos dialog
384
- Given User is on [Kudo] page
385
- When User click [Notifications] button
386
- And User click [Write Kudos] menuitem
387
- Then User see [Panel] dialog with {{kudo_title}}
388
-
389
- @auth:user @extend:open-dialog
390
- Scenario: User sends a thank you message
391
- Given User is on [Panel] dialog with {{kudo_title}}
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}}
398
- And User click [Send] button
399
- And User wait for [Panel] dialog with {{kudo_title}} is hidden
400
- Then User see [Panel] modal with {{kudo_title}} is hidden
401
- ```
402
-
403
- **Hành vi:**
404
- - Scenario `@steps` sinh test riêng VÀ đăng ký step để tái sử dụng
405
- - Scenario `@extend` nhận step gốc chèn vào đầu — test hoàn toàn độc lập
406
- - Nhiều scenario có thể extend cùng một khối `@steps`
407
- - Code sinh ra có comment phân đoạn: `// [from @steps:<name>]`
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 |
416
-
417
- ---
418
-
419
- ## 📋 Ví Dụ Hoàn Chỉnh
420
-
421
- ```gherkin
422
- Feature: User Authentication
423
- Path: /auth/login
424
-
425
- @auth:admin
426
- Scenario: User logs in successfully with valid credentials
427
- Given User is on [Login] page
428
- When User fill [Email] field with {{valid_email}}
429
- And User fill [Password] field with {{valid_password}}
430
- And User check [Remember me] checkbox
431
- And User click [Submit] button
432
- Then User see [Dashboard] page
433
- And User see [Welcome] heading with {{username}}
434
-
435
- @no-auth
436
- Scenario: User fails to login with invalid credentials
437
- Given User is on [Login] page
438
- When User fill [Email] field with {{invalid_email}}
439
- And User fill [Password] field with {{invalid_password}}
440
- And User click [Submit] button
441
- Then User see [Error] alert
442
- And User see [Submit] button is enabled
443
- And User see [Login] page
444
-
445
- @no-auth
446
- Scenario: User registers with preferred language
447
- Given User is on [Registration] page
448
- When User fill [Email] field with {{new_email}}
449
- And User fill [Password] field with {{new_password}}
450
- And User select [Language] dropdown with {{preferred_language}}
451
- And User check [Terms] checkbox
452
- And User click [Sign up] button
453
- Then User see [Verification] page
454
-
455
- Scenario: User manages settings with various controls
456
- Given User is on [Settings] page
457
- When User toggle [Dark mode] switch
458
- And User select [Timezone] dropdown with {{timezone}}
459
- And User upload [Avatar] file with {{avatar_path}}
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
466
- ```
467
-
468
- ---
469
-
470
- ## ✅ Tham Khảo Nhanh
471
-
472
- ### Nên làm ✅
473
- - Dùng **20 action chuẩn** từ danh sách action
474
- - Dùng **`User`** là actor duy nhất
475
- - Dùng định dạng **`[Target] <element type>`**
476
- - Dùng **`{{snake_case}}`** cho giá trị
477
- - Dùng **`is <state>`** cho xác nhận trạng thái
478
- - Dùng **tags** (`@auth`, `@steps`, `@extend`) để quản lý scenario
479
- - **1 Scenario = 1 flow nghiệp vụ**
480
- - **1 Step = 1 action hoặc assertion**
481
-
482
- ### Không nên làm ❌
483
- - Không dùng từ đồng nghĩa hoặc viết tự do
484
- - Không dùng system/backend/API làm actor
485
- - Không dùng selector kỹ thuật (CSS/XPath/ID)
486
- - Không hard-code dữ liệu trong step
487
- - Không dùng action kết hợp
488
- - Không dùng `verify`/`check`/`expect` thay cho `see`
489
-
490
- ---
491
-
492
- ## 🎯 Lợi Ích
493
-
494
- | Lợi ích | Mô tả |
495
- |---------|-------------|
496
- | **Nhất quán** | Cùng 17 mẫu pattern cho tất cả test case |
497
- | **Dễ đọc** | Người không kỹ thuật cũng hiểu được |
498
- | **Dễ bảo trì** | Dễ cập nhật khi UI thay đổi |
499
- | **Sẵn sàng tự động** | Ánh xạ trực tiếp sang Playwright code |
500
- | **Không mơ hồ** | Mỗi step chỉ có một cách hiểu |
501
- | **Hỗ trợ công cụ** | Tương thích với framework Sungen v2 |
502
- | **Tái sử dụng** | `@steps` / `@extend` giúp tái sử dụng flow |
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
508
-
509
- ---
510
-
511
- **Phiên bản**: 2.0
512
- **Trạng thái**: Final
513
- **Cập nhật lần cuối**: 19 tháng 3, 2026