@educa-corp/sdd-framework 0.9.7 → 0.9.8
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/bin/qc-base-map.json +13 -11
- package/bin/self-check.js +49 -4
- package/bin/trace-schema.json +3226 -3187
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/qc-analyze.md +2 -2
- package/core/commands/qc-automation-assess.md +3 -3
- package/core/commands/qc-design-script.md +60 -30
- package/core/commands/qc-design-test.md +79 -7
- package/core/commands/qc-plan.md +1 -1
- package/core/commands/qc-report.md +85 -76
- package/core/commands/qc-review-script.md +25 -16
- package/core/commands/qc-review-testcase.md +8 -7
- package/core/commands/qc-run-manualtest.md +1 -1
- package/core/commands/qc-run-script.md +15 -8
- package/core/modules/qc-playwright-ts/module.yaml +13 -0
- package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
- package/core/modules/qc-wdio-appium/module.yaml +20 -0
- package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
- package/core/skills/qc/qa-analyst/data-flow.md +1 -1
- package/core/skills/qc/qa-automation-assess/matrix.md +6 -3
- package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
- package/core/skills/qc/qa-designer/functional/api.md +1 -1
- package/core/skills/qc/qa-designer/functional/job.md +128 -0
- package/core/skills/qc/qa-designer/integration/api.md +1 -1
- package/core/skills/qc/qa-designer/integration/db.md +1 -1
- package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +20 -4
- package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +17 -0
- package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
- package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
- package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
- package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
- package/core/skills/qc/qa-reviewer/script/exploratory.md +2 -2
- package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
- package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
- package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
- package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
- package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
- package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
- package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
- package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
- package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
- package/core/skills/qc/qa-reviewer/shared/review-file-template.md +26 -7
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
- package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
- package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
- package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
- package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
- package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
- package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
- package/core/skills/qc/qa-script-designer/api/security.md +41 -0
- package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
- package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
- package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
- package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
- package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
- package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
- package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
- package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
- package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
- package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
- package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
- package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
- package/core/skills/qc/qa-script-runner/report.md +41 -0
- package/core/skills/qc/qa-script-runner/web/run.md +48 -0
- package/core/steps/qc-scope.md +43 -0
- package/core/steps/report-footer.md +2 -2
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +10 -10
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +1 -1
- package/docs/02-concepts/traceability.md +1 -1
- package/docs/03-guides/developer.md +1 -1
- package/docs/03-guides/tester-qa.md +40 -12
- package/docs/04-reference/commands.md +1 -1
- package/docs/04-reference/modules.md +2 -1
- package/docs/explain/17-qc-design-test.md +2 -2
- package/docs/explain/19-qc-run-test.md +4 -4
- package/docs/explain/20-qc-report.md +1 -1
- package/docs/explain/23-fix-bug.md +2 -2
- package/docs/plans/qc-surgery/01-checklist.md +18 -6
- package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
- package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
- package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
- package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
- package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
- package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
- package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
- package/package.json +1 -1
- package/core/modules/qc-playwright/stack-profile.yaml +0 -66
- package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
- package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
- package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
- package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
- package/core/skills/qc/qa-runner/e2e.md +0 -49
- package/core/skills/qc/qa-runner/functional/api.md +0 -35
- package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
- package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
- package/core/skills/qc/qa-runner/integration.md +0 -47
- package/core/skills/qc/qa-runner/non-functional.md +0 -49
- package/core/skills/qc/qa-runner/report/report.md +0 -37
package/core/FRAMEWORK_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.8
|
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-analyze — QC Requirement Analysis
|
|
8
8
|
|
|
9
|
-
>
|
|
9
|
+
> Trạm 1/9 của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ qa-analyst của team QC. Markdown-first: không có script ở đây.
|
|
10
10
|
|
|
11
11
|
## Gate
|
|
12
12
|
|
|
@@ -284,7 +284,7 @@ ngược về `{id}` của §12 để không đếm hai lần.
|
|
|
284
284
|
Bạn là **QC Analyst** — stage đầu tiên của QC automation pipeline. Lấy requirement
|
|
285
285
|
chính thức (PRD + BDD `.feature` + design-spec) và phân rã thành một mô tả requirement
|
|
286
286
|
CÓ CẤU TRÚC: function, business rule, data flow, acceptance criteria. Bạn **không**
|
|
287
|
-
viết test case chi tiết hay
|
|
287
|
+
viết test case chi tiết hay script tự động (đó là qc-design-test / qc-design-script).
|
|
288
288
|
|
|
289
289
|
Ranh giới với `/qc-plan`: bạn trả lời *"requirement là gì?"*; qc-plan trả lời *"rủi ro ở đâu,
|
|
290
290
|
hỏi dev gì?"*. Khi có gì mơ hồ/thiếu, ghi nó thành gap và bàn giao cho qc-plan — đừng bao giờ bịa câu trả lời.
|
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-automation-assess — Quyết định "cái nào máy chạy, cái nào phải tay"
|
|
8
8
|
|
|
9
|
-
>
|
|
9
|
+
> **Trạm 5/9** của dây chuyền QC automation — sau `/qc-review-testcase` (chỉ nhận TC `APPROVED`), trước `/qc-design-script`.
|
|
10
10
|
> Ghi `AUTOMATION_ASSESSMENT.md` — bảng quyết định `Automatable: Y/N` kèm lý do chuẩn hoá, và là
|
|
11
11
|
> **nguồn duy nhất** cho ba trạm sau.
|
|
12
12
|
|
|
@@ -232,8 +232,8 @@ Với mỗi UC của PRD, đọc `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.m
|
|
|
232
232
|
|
|
233
233
|
| Đọc được | Làm gì |
|
|
234
234
|
|---|---|
|
|
235
|
-
| `APPROVED` | đưa TC của UC đó vào lượt đánh giá |
|
|
236
|
-
| `
|
|
235
|
+
| `APPROVED` · `APPROVED_WITH_SUGGESTIONS` | đưa TC của UC đó vào lượt đánh giá |
|
|
236
|
+
| `REVISION_REQUIRED` · `REJECTED` · không có file | **LOẠI khỏi lượt** — và **liệt kê ra trong report** kèm trạng thái thật |
|
|
237
237
|
|
|
238
238
|
> **`%Automated/Total` tính trên mẫu số CHỈ GỒM TC đã đánh giá**, và in kèm số TC bị loại. Để
|
|
239
239
|
> không ai đọc *"100%"* mà tưởng đã phủ cả PRD.
|
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-design-script — QC Script Generation (sinh script, KHÔNG chạy)
|
|
8
8
|
|
|
9
|
-
>
|
|
9
|
+
> Trạm 6/9 của dây chuyền QC automation. Chuyển `.Test.md` **đã `APPROVED`** thành script +
|
|
10
10
|
> Page Object. **Không chạy test, không ghi sổ trace** — đó là việc của `/qc-run-script`.
|
|
11
11
|
|
|
12
12
|
## Gate
|
|
@@ -214,8 +214,8 @@ Bỏ vế ghi thì trạm sau không có gì để so; bỏ vế so thì stamp t
|
|
|
214
214
|
|
|
215
215
|
| Đọc được | Làm gì |
|
|
216
216
|
|---|---|
|
|
217
|
-
| `APPROVED` |
|
|
218
|
-
| `
|
|
217
|
+
| `APPROVED` · `APPROVED_WITH_SUGGESTIONS` | **đi tiếp** — in một dòng bằng chứng:<br/>`✅ Cổng test case đã soát: {verdict} — {đường dẫn file vừa đọc}` |
|
|
218
|
+
| `REVISION_REQUIRED` · `REJECTED` | **DỪNG** — `❌ Test case chưa đạt. Sửa bằng /qc-design-test {UC-ID}, soát lại bằng /qc-review-testcase {UC-ID}.` |
|
|
219
219
|
| Không có file | **DỪNG** — `❌ Chưa soát test case. Chạy /qc-review-testcase {UC-ID} trước.` |
|
|
220
220
|
|
|
221
221
|
> **Đây là thứ `/qc-run-test` cũ KHÔNG làm được** — nó nhận `REVIEW_<FEATURE>.md` mà không biết
|
|
@@ -240,32 +240,62 @@ Bỏ vế ghi thì trạm sau không có gì để so; bỏ vế so thì stamp t
|
|
|
240
240
|
**chỉ mục ngược duy nhất** TC → file code; `/qc-run-script` đọc đúng cột này để biết chạy file
|
|
241
241
|
nào, thay vì suy đường dẫn từ quy ước đặt tên.
|
|
242
242
|
|
|
243
|
-
## Role & stack (theo
|
|
244
|
-
|
|
245
|
-
Bạn là **QC Script Designer**. Sinh
|
|
243
|
+
## Role & stack (module theo nền — bảng §2b của `steps/qc-scope.md`)
|
|
244
|
+
|
|
245
|
+
Bạn là **QC Script Designer**. Sinh script test + đối tượng trang/màn/API từ `.Test.md`, theo
|
|
246
|
+
**nền đã phân giải ở §2b** — web · app · system, mỗi nền một hình dạng code khác nhau.
|
|
247
|
+
|
|
248
|
+
Quy tắc stack (BẮT BUỘC — từ `stack-profile.yaml` của module đã phân giải ở §2b):
|
|
249
|
+
- **Markdown-first:** không bao giờ sinh script khi chưa có `.Test.md` đã review.
|
|
250
|
+
- **Phủ đúng TC `Automatable: Y`** của `AUTOMATION_ASSESSMENT.md` — mỗi TC đúng một test,
|
|
251
|
+
không hơn không kém. TC `Y` gặp rào cản kỹ thuật lúc viết → `test.fixme('TC-xxx — {lý do}')`
|
|
252
|
+
+ ghi `IMPROVE-xxx`, **không âm thầm bỏ qua**.
|
|
253
|
+
- **Locator từ hợp đồng test-id, KHÔNG scan runtime.** Đọc bảng *Test Selectors* §4.5.6 (block
|
|
254
|
+
platform) của tech-doc gộp tại
|
|
255
|
+
`{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` — lọc theo cột
|
|
256
|
+
*"Serves SC"* khớp SC của UC này. Ưu tiên map; fallback chỉ cho element có action mà **không** có
|
|
257
|
+
test-id trong §4.5.6, kèm ghi chú để gap được thêm vào tech-design.
|
|
258
|
+
- **Không hard-code** URL · credential · timeout. **Không chờ cứng.** Data để ở `data/`.
|
|
259
|
+
|
|
260
|
+
> 🔑 **Cách đọc `@trace.testid_attr` và cấu hình thuộc tính test-id KHÔNG viết ở đây** — nó nằm
|
|
261
|
+
> ở `_shared/{web|mobile|api}-conventions.md` của nền, nạp ở §Skills ngay dưới. Lý do gỡ khỏi lệnh
|
|
262
|
+
> *(Bước S · S4, 2026-09-17)*: bảng đó từng tồn tại **hai bản**, và hai bản đã lệch nhau — bản
|
|
263
|
+
> trong lệnh còn ghi API của stack cũ trong khi bản ở skill đã đúng. **Một bảng, một chỗ.**
|
|
264
|
+
>
|
|
265
|
+
> Nội dung vẫn bắt buộc, chỉ đổi chỗ đọc: thuộc tính test-id ≠ mặc định mà không cấu hình trước
|
|
266
|
+
> thì **mọi locator trượt 100 %**, và nó trượt **trông y hệt một bug sản phẩm** — QC sẽ đi mở
|
|
267
|
+
> phiếu lỗi gửi PO thay vì sửa một dòng config.
|
|
268
|
+
>
|
|
269
|
+
> **Vì sao không suy thuộc tính từ platform cho nhanh:** suy từ platform là **phát biểu lại một
|
|
270
|
+
> sự thật đã ghi ở nơi khác** — đúng lớp lỗi mà `bin/trace-schema.json` sinh ra để chống.
|
|
246
271
|
|
|
247
|
-
|
|
248
|
-
- Markdown-first: không bao giờ sinh script khi chưa có `.Test.md` đã review.
|
|
249
|
-
- Page Object extends `BasePage` gọn, 3 lớp: locator `_x()`, action `verb_noun()`, assertion `assert_x()` dùng `expect()`.
|
|
250
|
-
- **Locator từ test-id contract (không scan runtime).** Đọc bảng *Test Selectors* §4.5.6 (block platform) của tech-doc gộp tại `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` — bảng gộp mọi UC của platform, **lọc theo cột "Serves SC" khớp SC của UC này** — và dựng mỗi Page Object locator từ test-id ổn định của nó. **Ưu tiên map; fallback** về role/label/text/CSS chỉ cho element có action mà **không** có test-id trong §4.5.6, kèm ghi chú để gap được thêm vào tech-design.
|
|
251
|
-
- **TÊN THUỘC TÍNH test-id: đọc `@trace.testid_attr`, KHÔNG tự suy từ platform.**
|
|
272
|
+
## Skills — chọn NỀN rồi TẦNG, nạp MỘT file (`{paths.qc_skills_dir}/qa-script-designer/`)
|
|
252
273
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
274
|
+
> 🔴 **DỪNG nếu TC mang lane `job` hoặc `queue`.** Hai hình dạng này có TC *(trạm 3 đã hỗ trợ)*
|
|
275
|
+
> nhưng **chưa có skill sinh script**. Sinh bừa bằng lane `api` là tạo API Object cho một thứ
|
|
276
|
+
> **không có endpoint nào** — script dịch được, chạy được, và kiểm **sai thứ**.
|
|
277
|
+
>
|
|
278
|
+
> ```
|
|
279
|
+
> ⛔ {UC-ID} có {n} TC lane {job|queue} — trạm này chưa hỗ trợ hình dạng đó.
|
|
280
|
+
> TC vẫn dùng được: chạy tay qua /qc-run-manualtest, hoặc đánh Automatable: N
|
|
281
|
+
> kèm lý do "chưa có bộ sinh script cho lane {lane}".
|
|
282
|
+
> ```
|
|
283
|
+
>
|
|
284
|
+
> TC lane `api` trong cùng UC thì **vẫn sinh bình thường** — dừng theo TC, không dừng cả UC.
|
|
259
285
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- Không hard-code URL/cred/timeout (dùng `Env.*` / `CONFIG[...]`); không `time.sleep()`; không Allure.
|
|
263
|
-
- Phủ **100%** TC mang `Automatable: Y` — mỗi TC có đúng một test.
|
|
286
|
+
**Nạp trước:** `_shared/{web|mobile|api}-conventions.md` + `_shared/file-naming-and-folders.md`
|
|
287
|
+
theo nền đã phân giải ở `steps/qc-scope.md` §2b. Rồi chọn **MỘT** file lane:
|
|
264
288
|
|
|
265
|
-
|
|
289
|
+
| `active_platform` | File |
|
|
290
|
+
|---|---|
|
|
291
|
+
| `web` · `webview` | `web/functional/{gui-screen,gui-feature,api}.md` · `web/{integration,e2e,non-functional}.md` |
|
|
292
|
+
| `app` · `app-ios` · `app-android` | `mobile/functional/{screen,feature}.md` · `mobile/{integration,e2e,non-functional}.md` |
|
|
293
|
+
| `system` | `api/{endpoint,auth,security}.md` |
|
|
266
294
|
|
|
267
|
-
|
|
268
|
-
`
|
|
295
|
+
> ⚠️ **Ba nền sinh ba hình dạng code khác nhau.** Web dùng Page Object; app dùng **Screen Object**
|
|
296
|
+
> với thứ tự locator của Appium; `system` dùng **API Object** — không màn hình, không locator,
|
|
297
|
+
> không chờ, và **cấm `expect()` bên trong object**. Nạp nhầm lane là sinh ra thứ chạy được nhưng
|
|
298
|
+
> sai kiến trúc, và `/qc-review-script` sẽ chặn nó bằng `R01`.
|
|
269
299
|
|
|
270
300
|
---
|
|
271
301
|
|
|
@@ -293,11 +323,11 @@ bị **chép cứng vào một artifact bền**, và **trạm này chép nó l
|
|
|
293
323
|
|
|
294
324
|
| Đường dẫn | Nội dung | Người sửa tay? |
|
|
295
325
|
|---|---|:---:|
|
|
296
|
-
| `tests/<
|
|
297
|
-
| `pages/<feature
|
|
326
|
+
| `tests/{TICKET-ID}/<feature>-<scenario>.spec.ts` | spec, 1-1 với `test-cases/` | ✅ **có** — `script-bug` |
|
|
327
|
+
| `pages/<feature>.page.ts` *(web)* · `api/<resource>.api.ts` *(system)* · `screens/<feature>.screen.ts` *(app)* | đối tượng trang/API/màn | ✅ **có** — `script-bug` |
|
|
298
328
|
| `{qc_artifact_dir}AUTOMATION_ASSESSMENT.md` — cột `Script file` | đường dẫn script của từng TC | ❌ lệnh ghi |
|
|
299
329
|
|
|
300
|
-
*(Đường dẫn theo
|
|
330
|
+
*(Đường dẫn theo `§layout.{web|api|mobile}` của module đã phân giải ở §2b — KHÔNG viết cứng tên module.)*
|
|
301
331
|
|
|
302
332
|
**KHÔNG ghi sổ trace.** Sinh script không phải là chạy test — ghi `qc_status` ở đây là khẳng định
|
|
303
333
|
một điều chưa xảy ra. Đó là việc của `/qc-run-script` và `/qc-run-manualtest`.
|
|
@@ -306,9 +336,9 @@ một điều chưa xảy ra. Đó là việc của `/qc-run-script` và `/qc-ru
|
|
|
306
336
|
|
|
307
337
|
Mỗi test được sinh ra mang scenario nó verify, lấy từ Trace matrix của `.Test.md`:
|
|
308
338
|
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
|
|
339
|
+
```typescript
|
|
340
|
+
// @trace.verifies={UC-ID}-SC{N}
|
|
341
|
+
test('TC_<FEATURE>_001 — …', async ({ page }) => { … });
|
|
312
342
|
```
|
|
313
343
|
|
|
314
344
|
## Tag ưu tiên — `@smoke` / `@regression`
|
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-design-test — QC Test-Case Design
|
|
8
8
|
|
|
9
|
-
>
|
|
9
|
+
> Trạm 3/9 của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ qa-designer của team QC. Sinh test case Markdown (`.Test.md`) — script tự động đến sau ở /qc-design-script.
|
|
10
10
|
|
|
11
11
|
## Gate
|
|
12
12
|
|
|
@@ -234,9 +234,26 @@ Kiểm sự tồn tại của cả ba file dưới `{qc_artifact_dir}`:
|
|
|
234
234
|
rồi: /qc-plan {TICKET-ID} {active_platform}
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
-
**Đủ cả ba →
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
**Đủ cả ba → IN MỘT DÒNG BẰNG CHỨNG rồi đi tiếp:**
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
✅ Đầu vào trạm 3: 3/3 — {qc_artifact_dir}{REQUIREMENT_ANALYSIS,DOC_GAP,TEST_PLAN}.md
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
> **Vì sao cổng vào cửa PHẢI in, dù "đủ file" không phải một phát hiện** *(sửa 2026-09-17, sau một
|
|
244
|
+
> ca thật)*. Bản trước ghi *"đủ cả ba → im lặng, đi tiếp"* với lý do nghe hợp lý: cổng là điều kiện,
|
|
245
|
+
> không phải phép đo. Cái giá không ai tính: **cổng đạt trong im lặng KHÔNG phân biệt được với cổng
|
|
246
|
+
> chưa bao giờ chạy** — cả hai đều không in gì.
|
|
247
|
+
>
|
|
248
|
+
> **Ca thật:** lệnh chạy trên một PRD mà `{qc_artifact_dir}` **chưa tồn tại**, tự tường thuật
|
|
249
|
+
> *"đủ ba file đầu vào"*, rồi đi tiếp. Không dấu vết nào để đối chiếu, và người dùng chỉ phát hiện
|
|
250
|
+
> vì lệnh sau đó hỏi một câu vô lý.
|
|
251
|
+
>
|
|
252
|
+
> Một dòng in ra làm hai việc mà im lặng không làm được: **bỏ qua thì thấy ngay** *(thiếu dòng)*,
|
|
253
|
+
> và **tường thuật sai thì đối chiếu được** *(đường dẫn in ra, mở là biết)*. Đây không phải nới
|
|
254
|
+
> lỏng luật *"đừng in cái không phải phát hiện"* — mà là phân biệt hai loại: **phép đo** in con số,
|
|
255
|
+
> **cổng vào cửa** in bằng chứng nó đã chạy. Cổng không có bằng chứng thì nó không phải cổng, nó
|
|
256
|
+
> là một lời đề nghị.
|
|
240
257
|
|
|
241
258
|
> **Vì sao DỪNG chứ không cảnh báo rồi chạy.** Guard duy nhất còn lại của trạm này —
|
|
242
259
|
> `Guard SC coverage` — đối chiếu TC với `.feature`, mà `.feature` ở spec repo thì **luôn có mặt**,
|
|
@@ -274,11 +291,65 @@ hai cái đó là phép ĐẾM, con số của chúng có giá trị ngay cả k
|
|
|
274
291
|
| `--api` | `TC_<FEATURE>_API.Test.md` | 1 Endpoint · 2 Integration API/DB/Kafka |
|
|
275
292
|
| `--all` | **cả hai file** | như trên, hai file riêng biệt |
|
|
276
293
|
| `--atomic-max` | — | bật chế độ tách tối đa (xem dưới) |
|
|
294
|
+
| `--shape=api\|job\|queue` | — | nêu tường minh hình dạng nền `system` — **bắt buộc khi chạy `--yes`** trên UC không suy được |
|
|
277
295
|
|
|
278
296
|
**Câu hỏi phân file:** *"TC này verify được mà **không cần UI** không?"* → **có** = file API ·
|
|
279
297
|
**không** = file giao diện. Đây đúng là Bước 2 của
|
|
280
298
|
`{paths.qc_skills_dir}/qa-designer/shared/skill-decision-tree.md`.
|
|
281
299
|
|
|
300
|
+
### Nền `system` — hỏi hình dạng khi không suy được
|
|
301
|
+
|
|
302
|
+
> **Chỉ hỏi khi HAI vế cùng đúng.** Hỏi mọi lần nền là `system` là kiểu hỏng **Ồn**: phần lớn UC
|
|
303
|
+
> `system` **là** API thật và BDD nói rõ; hỏi cả những lần đã rõ thì sau vài lần người ta bấm
|
|
304
|
+
> số 1 cho xong, và cổng đó chết trong khi không ai biết.
|
|
305
|
+
|
|
306
|
+
| Vế | Đo thế nào |
|
|
307
|
+
|---|---|
|
|
308
|
+
| **1** | `active_platform = system` |
|
|
309
|
+
| **2** | **0 dấu hiệu endpoint** — không tìm thấy method/path HTTP trong `.feature` của UC **lẫn** trong tech-doc |
|
|
310
|
+
|
|
311
|
+
Một trong hai vế sai → **đi tiếp, không hỏi**.
|
|
312
|
+
|
|
313
|
+
**Cả hai đúng → in bằng chứng rồi mới hỏi.** Hỏi khơi khơi thì người trả lời cũng đang đoán:
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
{UC-ID} — nền system, không tìm thấy endpoint nào.
|
|
317
|
+
|
|
318
|
+
BDD nói : "{trích nguyên văn dòng When}"
|
|
319
|
+
Tech-doc : {đã có, không khai endpoint | chưa có}
|
|
320
|
+
Tìm thấy : {n} dòng có method/path HTTP
|
|
321
|
+
|
|
322
|
+
Hình dạng nào?
|
|
323
|
+
1 API — có endpoint; chưa có trong tech-doc thì chờ tech-doc
|
|
324
|
+
2 Job chạy ngầm — tự chạy theo lịch/điều kiện, không ai gọi
|
|
325
|
+
3 Consumer hàng đợi — nằm chờ, có message tới thì xử lý
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Có `--yes`:** không hỏi — **DỪNG** với lỗi rõ ràng. Cùng luật với phân giải nền
|
|
329
|
+
*(`steps/qc-scope.md` §2)*, và cùng lý do: đoán hình dạng là viết test case kiểm sai thứ, mà
|
|
330
|
+
nó vẫn ra một file trông hợp lệ.
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
❌ {UC-ID} nền system, không suy được hình dạng (0 dấu hiệu endpoint).
|
|
334
|
+
Chạy headless thì phải nêu tường minh: /qc-design-test {UC-ID} --shape=job --yes
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Ghi câu trả lời vào `Tags` của MỌI TC sinh ra ở lượt này** — ô `<lane>` đã có sẵn trong khuôn
|
|
338
|
+
metadata:
|
|
339
|
+
|
|
340
|
+
| Trả lời | `<lane>` | Skill nạp |
|
|
341
|
+
|---|---|---|
|
|
342
|
+
| 1 API | `api` | `functional/api.md` · `integration/api.md` |
|
|
343
|
+
| 2 Job chạy ngầm | `job` | `functional/job.md` |
|
|
344
|
+
| 3 Consumer hàng đợi | `queue` | `integration/queue.md` |
|
|
345
|
+
|
|
346
|
+
> **Vì sao ghi vào từng TC chứ không một chỗ cho cả PRD.** Một PRD có UC là API và UC là job là
|
|
347
|
+
> chuyện thường. Ghi ở cấp PRD là ép cả PRD thành một kiểu.
|
|
348
|
+
>
|
|
349
|
+
> **Vì sao phải ghi, không chỉ dùng rồi thôi.** Trạm 5 và trạm 6 cũng cần biết hình dạng. Không
|
|
350
|
+
> ghi thì chúng **hỏi lại**, và có thể nhận câu trả lời khác — lúc đó test case và script kiểm
|
|
351
|
+
> hai thứ khác nhau, cả hai đều chạy được, và **không gì bắt được**.
|
|
352
|
+
|
|
282
353
|
> **Vì sao hai file riêng chứ không một file rồi ghi từng nhóm** *(B12)*. `--api` chạy sau khi
|
|
283
354
|
> file giao diện đã tồn tại là chuyện thường. Nếu chung một file, lần chạy `--api` phải **giữ
|
|
284
355
|
> nguyên** năm nhóm kia — mà viết-lại-cả-file là đúng thứ agent hay làm. Hai file thì hai chế
|
|
@@ -322,8 +393,8 @@ vế nói về **cùng một** kết cục — ví dụ *"form hiển thị đ
|
|
|
322
393
|
## Role
|
|
323
394
|
|
|
324
395
|
Bạn là **QC Designer** — stage 3. Sinh/bảo trì các file test-case Markdown
|
|
325
|
-
(`.Test.md`) từ requirement đã phân tích + plan. Output feed vào qc-
|
|
326
|
-
qc-
|
|
396
|
+
(`.Test.md`) từ requirement đã phân tích + plan. Output feed vào qc-review-testcase rồi
|
|
397
|
+
qc-automation-assess. Bạn **không** viết script tự động.
|
|
327
398
|
|
|
328
399
|
## Skills (`{paths.qc_skills_dir}/qa-designer/`)
|
|
329
400
|
|
|
@@ -348,7 +419,8 @@ qc-review. Bạn **không** viết Python.
|
|
|
348
419
|
| Feature đa-màn | `functional/gui-feature.md` | file giao diện |
|
|
349
420
|
| API endpoint | `functional/api.md` | **file API** |
|
|
350
421
|
| Integration qua UI | `integration/gui.md` | file giao diện |
|
|
351
|
-
| Integration API/DB/
|
|
422
|
+
| Integration API/DB/hàng đợi | `integration/{api,db,queue}.md` | **file API** |
|
|
423
|
+
| Job chạy ngầm *(lane `job`)* | `functional/job.md` | **file API** |
|
|
352
424
|
| End-to-end journey | `e2e/journey.md` | file giao diện |
|
|
353
425
|
| Non-functional | `non-functional.md` | theo câu hỏi phân file |
|
|
354
426
|
| Exploratory | `exploratory/{charter,explore-to-functional}.md` | file giao diện |
|
package/core/commands/qc-plan.md
CHANGED
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-plan — QC Test Plan & Risk Analysis
|
|
8
8
|
|
|
9
|
-
>
|
|
9
|
+
> Trạm 2/9 của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ qa-planner của team QC.
|
|
10
10
|
|
|
11
11
|
## Gate
|
|
12
12
|
# Gate — Quy trình vào chuẩn cho mọi lệnh
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
---
|
|
2
|
-
version: 1.0
|
|
3
|
-
updated: 2026-06-11
|
|
4
|
-
ported_from: ai-automation-qc-base
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# /qc-report — QC Test Report & Evidence
|
|
8
|
-
|
|
9
|
-
>
|
|
10
|
-
|
|
11
|
-
## Gate
|
|
1
|
+
---
|
|
2
|
+
version: 1.0
|
|
3
|
+
updated: 2026-06-11
|
|
4
|
+
ported_from: ai-automation-qc-base
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /qc-report — QC Test Report & Evidence
|
|
8
|
+
|
|
9
|
+
> Trạm 9/9 (cuối) của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ bước report của kho QC gốc (xem `bin/qc-base-map.json`).
|
|
10
|
+
|
|
11
|
+
## Gate
|
|
12
12
|
# Gate — Quy trình vào chuẩn cho mọi lệnh
|
|
13
13
|
|
|
14
14
|
Mọi lệnh PHẢI chạy gate này trước khi thực thi phần logic riêng của nó.
|
|
@@ -166,74 +166,83 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
|
|
|
166
166
|
- "N" → dừng, hỏi người dùng muốn thay đổi gì.
|
|
167
167
|
- Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
|
|
168
168
|
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Sinh report từ lần chạy `/qc-run-script` gần nhất.
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Sinh report từ lần chạy `/qc-run-script` gần nhất. **Reporter theo nền** — đọc `§reporting` của module đã phân giải ở `steps/qc-scope.md` §2b: `web`·`system` → **Playwright HTML Report + Trace**; `app` → **Allure Report v2.x**. Không dashboard viết tay.*
|
|
172
|
+
|
|
173
|
+
> ⚠️ **Hai nền KHÁC NHAU ở chỗ này — đừng "thống nhất" lại.** Luật `No Allure` cũ nay chỉ còn
|
|
174
|
+
> đúng cho web *(`Automation-Standards` §1 + `OQ-01` đóng 2026-06-02: Playwright HTML đủ Phase 1,
|
|
175
|
+
> Allure defer Phase 2)*. Nền mobile thì Allure là **bắt buộc** *(`Mobile-Automation-Standards` §1)*.
|
|
176
|
+
> Đó là quyết định của chuẩn, không phải chỗ sót.
|
|
177
|
+
|
|
178
|
+
## Context
|
|
174
179
|
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
175
180
|
rồi mới tiếp tục phần bên dưới.
|
|
176
181
|
|
|
177
182
|
Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, guardrail từ
|
|
178
183
|
`project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
|
|
179
|
-
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## Role
|
|
184
|
-
|
|
185
|
-
Bạn là stage **QC Report** — biến lần chạy gần nhất thành report + evidence chia sẻ được.
|
|
186
|
-
|
|
187
|
-
## Skill (`{paths.qc_skills_dir}/qa-runner
|
|
188
|
-
|
|
189
|
-
- `report.md` — tự
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
184
|
+
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Role
|
|
189
|
+
|
|
190
|
+
Bạn là stage **QC Report** — biến lần chạy gần nhất thành report + evidence chia sẻ được.
|
|
191
|
+
|
|
192
|
+
## Skill (`{paths.qc_skills_dir}/qa-script-runner/`)
|
|
193
|
+
|
|
194
|
+
- `report.md` — tự đủ, **theo nền**:
|
|
195
|
+
- `web` · `system` — Playwright HTML Report (`npx playwright show-report`) + Trace
|
|
196
|
+
(`test-results/<test>/trace.zip`, xem qua `npx playwright show-trace <file>`)
|
|
197
|
+
- `app` — Allure Report v2.x (`npx allure generate reports/allure-results --clean && npx allure open`)
|
|
198
|
+
|
|
199
|
+
kèm screenshot/evidence đính trên FAIL/SKIP.
|
|
200
|
+
|
|
201
|
+
## Procedure
|
|
202
|
+
|
|
203
|
+
1. Định vị artifact của lần chạy gần nhất cho `{UC-ID}` (HTML report + trace, theo nền).
|
|
204
|
+
2. Sinh/làm mới `reports/<feature>/report.html` (self-contained) và đảm bảo mỗi
|
|
205
|
+
FAIL/SKIP có trace + screenshot đính kèm.
|
|
206
|
+
3. Tóm tắt TOTAL / PASS / FAIL / SKIP; với mỗi FAIL gồm lệnh `show-trace` và
|
|
207
|
+
phân loại là script-bug hay product-gap.
|
|
208
|
+
4. **Bàn giao product-gap về spec (có nhắc).** Với mỗi FAIL phân loại **product-gap**
|
|
209
|
+
(defect thật, impl ≠ spec — không phải script-bug), in một
|
|
210
|
+
`/report-bug {UC-ID} {one-line expected-vs-actual}` sẵn-chạy để QC file nó vào spec repo dùng chung.
|
|
211
|
+
BUG_FLOW của `/report-bug` rồi định tuyến root cause (Code / BDD / PRD / Design / Env). Không bao giờ
|
|
212
|
+
fake-pass một product-gap — nó giữ FAIL trong `qc_status` cho tới khi fix + chạy lại. **script-bug
|
|
213
|
+
KHÔNG được file** (QC fix script và chạy lại). Liệt kê các lệnh; đừng tự tạo report.
|
|
214
|
+
|
|
215
|
+
## Self-Review *(trước khi in Report)*
|
|
216
|
+
|
|
217
|
+
Theo 3 nhóm ở `{paths.qc_skills_dir}/_shared/self-review-principles.md` — **không chép lại ở đây**.
|
|
218
|
+
|
|
219
|
+
- **Bịa:** mọi con số trong báo cáo trích được về **một dòng cụ thể** của sổ trace / output
|
|
220
|
+
runner / bug report — không nội suy khi thiếu mẫu?
|
|
221
|
+
- **Nhảy bước:** đã tổng hợp trên **toàn bộ** SC trong phạm vi, không chỉ những SC có kết quả
|
|
222
|
+
đẹp? Đã liệt kê cả SC `not_run` và `flaky`, không im lặng bỏ khỏi bảng?
|
|
223
|
+
- **Số liệu:** mọi `%` là phép chia thật **và nói rõ mẫu số**? Chỗ thiếu dữ liệu ghi **"chưa đủ
|
|
224
|
+
dữ liệu"** thay vì điền một số cho đủ bảng?
|
|
225
|
+
|
|
226
|
+
> **Trạm này là nơi số liệu đi ra khỏi đội QC.** Một con số sai ở các trạm trước còn người trong
|
|
227
|
+
> đội nhìn thấy; sai ở đây là đi vào báo cáo cho Lead/PM. Nhóm 3 vì vậy là nhóm nặng nhất ở đây:
|
|
228
|
+
> *"một bảng đầy số sai tệ hơn một bảng có ô trống ghi rõ lý do"*.
|
|
229
|
+
|
|
230
|
+
## Report
|
|
231
|
+
|
|
224
232
|
**Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
|
|
225
|
-
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
226
|
-
|
|
227
|
-
```
|
|
228
|
-
/qc-report Hoàn tất — {UC-ID}
|
|
229
|
-
Report: reports/<feature>/report.html (TOTAL {N} · PASS {p} · FAIL {f} · SKIP {s})
|
|
230
|
-
Trace : test-results/<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
/report-bug {UC-ID} {gap
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
233
|
+
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
/qc-report Hoàn tất — {UC-ID}
|
|
237
|
+
Report: reports/<feature>/report.html (TOTAL {N} · PASS {p} · FAIL {f} · SKIP {s})
|
|
238
|
+
Trace : test-results/<test>/trace.zip (npx playwright show-trace <file>) ← web·system
|
|
239
|
+
Report: reports/allure-results (npx allure open) ← app
|
|
240
|
+
|
|
241
|
+
Product-gap cần file ({g}): ← chạy các lệnh này để PO/Dev thấy trên /sync (script-bug bị loại)
|
|
242
|
+
/report-bug {UC-ID} {gap 1 — expected vs actual}
|
|
243
|
+
/report-bug {UC-ID} {gap 2 …}
|
|
244
|
+
(không có → skip)
|
|
245
|
+
|
|
246
|
+
Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
|
|
247
|
+
Next: /validate-traces {UC-ID} ← làm mới Living Docs (qc_status), rồi tạo PR
|
|
248
|
+
```
|
|
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
|
|
|
6
6
|
|
|
7
7
|
# /qc-review-script — QC Review Gate: script
|
|
8
8
|
|
|
9
|
-
> Soát **code test + Page Object** đã sinh: khớp `.Test.md`, cấu trúc Page Object, assertion,
|
|
9
|
+
> **Trạm 7/9** của dây chuyền QC automation. Soát **code test + Page Object** đã sinh: khớp `.Test.md`, cấu trúc Page Object, assertion,
|
|
10
10
|
> selector, hard-code. Cặp với `/qc-review-testcase` — hai lệnh, hai vai, không còn đoán.
|
|
11
11
|
|
|
12
12
|
## Gate
|
|
@@ -214,17 +214,25 @@ trạm sinh script. *Reviewer tự sửa rồi tự duyệt là bỏ mất cái
|
|
|
214
214
|
|---|---|
|
|
215
215
|
| `shared/read-doc-gap-inputs.md` | Nạp **đủ** mọi tài liệu nguồn theo bảng *Tài liệu đầu vào đã đọc* của `DOC_GAP.md` — soát mù thì kết luận "0 lỗi" là vô nghĩa |
|
|
216
216
|
| `shared/review-file-template.md` | Khuôn file kết quả · thang điểm `XX/100` · luật ghi file · nguyên tắc *mặc định hoài nghi* |
|
|
217
|
+
| `script/_shared/review-rules.md` | **Luật soát dùng chung**: R01–R07 · 4 mức severity · 4 verdict suy từ số đếm · phép kiểm cơ học · đường dẫn theo `§layout` |
|
|
217
218
|
|
|
218
|
-
**Rồi chọn theo
|
|
219
|
-
|
|
219
|
+
**Rồi chọn theo NỀN rồi theo TẦNG, nạp MỘT file** *(nền phân giải ở `steps/qc-scope.md` §2b)*:
|
|
220
|
+
|
|
221
|
+
| `active_platform` | File |
|
|
222
|
+
|---|---|
|
|
223
|
+
| `web` · `webview` | `script/web/{functional,integration,e2e,non-functional}.md` |
|
|
224
|
+
| `app` · `app-ios` · `app-android` | `script/mobile/{functional,integration,e2e,non-functional}.md` |
|
|
225
|
+
| `system` | `script/api/{endpoint,auth,security}.md` |
|
|
226
|
+
| *(mọi nền)* | `script/exploratory.md` — biên bản phiên khám phá, không phải code |
|
|
227
|
+
|
|
228
|
+
> ⚠️ **Ba nền soát ba thứ khác nhau, không phải một checklist đổi tên.** Thứ tự locator của web
|
|
229
|
+
> *(`getByRole` → … → css)* **không tồn tại** ở Appium *(`~accessibilityId` → `id` → `xpath`)*, và
|
|
230
|
+
> lane `api` **không có locator lẫn wait** — nó có API Object với luật *"không `expect()` bên
|
|
231
|
+
> trong"*. Nạp nhầm lane là đi tìm những thứ không tồn tại rồi kết luận "không có lỗi".
|
|
220
232
|
|
|
221
233
|
> ⚠️ **KHÔNG nạp `shared/review-check-groups.md` và §*Kiểm tra cấu trúc TC*.** Hai thứ đó kiểm
|
|
222
234
|
> **cấu trúc file test case** — áp vào một Page Object là bảo reviewer đi tìm `#### Expected Result`
|
|
223
235
|
> trong code, rồi gắn nhãn lỗi cho thứ đáng lẽ không có ở đó.
|
|
224
|
-
>
|
|
225
|
-
> *Ghi chú Đợt 2 · b2:* bộ `script/*` hiện **phẳng theo tầng**. Khi bước 2 chốt stack, nó sẽ tái
|
|
226
|
-
> cấu trúc thành `script/{web,mobile}/*` — tiêu chí soát khác nhau theo nền. **Cố ý chưa làm ở
|
|
227
|
-
> bước này**: viết tiêu chí cho một stack chưa chốt là viết hai lần.
|
|
228
236
|
|
|
229
237
|
---
|
|
230
238
|
|
|
@@ -233,8 +241,8 @@ trạm sinh script. *Reviewer tự sửa rồi tự duyệt là bỏ mất cái
|
|
|
233
241
|
- **Khớp `.Test.md` 1-1?** Mỗi TC có đúng một test tương ứng; không test mồ côi, không TC bị bỏ.
|
|
234
242
|
- **Page Object 3 lớp + BasePage gọn?** Logic điều hướng không rò vào file test.
|
|
235
243
|
- **`expect()` chứ không phải bare assert?** Assertion phải nói được nó kỳ vọng gì khi đỏ.
|
|
236
|
-
- **Không hard-code** URL · credential · timeout. Không `
|
|
237
|
-
- **
|
|
244
|
+
- **Không hard-code** URL · credential · timeout. Không chờ cứng (`waitForTimeout` · `browser.pause`).
|
|
245
|
+
- **Locator theo thứ tự ưu tiên CỦA NỀN** — web `getByRole → … → css` · app `~accessibilityId → id → xpath` · api không có locator. Lấy từ §4.5.6, không dò DOM.
|
|
238
246
|
- **100% TC đã script** — không còn TC ở trạng thái `Draft`.
|
|
239
247
|
|
|
240
248
|
Sinh findings (mức độ + vị trí + cách sửa), chấm điểm, ra verdict.
|
|
@@ -273,13 +281,14 @@ File **phải** chứa đúng một dòng theo khuôn này, ở §Tổng quan:
|
|
|
273
281
|
```
|
|
274
282
|
hoặc
|
|
275
283
|
```
|
|
276
|
-
**Verdict:**
|
|
284
|
+
**Verdict:** REVISION_REQUIRED ← hoặc REJECTED khi có BLOCKER
|
|
277
285
|
```
|
|
278
286
|
|
|
279
|
-
`
|
|
287
|
+
Verdict suy từ **số đếm lỗi**, không từ điểm — `≥1 BLOCKER` → `REJECTED` · `≥1 MAJOR` → `REVISION_REQUIRED` · chỉ MINOR/SUGGESTION → `APPROVED_WITH_SUGGESTIONS` · sạch → `APPROVED`. Xem `qa-reviewer/shared/review-file-template.md` §Verdict.
|
|
280
288
|
|
|
281
289
|
> **Đây là contract, không phải định dạng cho đẹp.** `/qc-run-script` (Đợt 2 · b2) **DỪNG** khi
|
|
282
|
-
> verdict là `
|
|
290
|
+
> verdict là `REVISION_REQUIRED` / `REJECTED`, hoặc chưa có file này. Ngưỡng đi tiếp:
|
|
291
|
+
> **`≥ APPROVED_WITH_SUGGESTIONS`** (`AGT-005:132`). Đổi chuỗi này là làm trạm đó mù — nên nếu phải
|
|
283
292
|
> đổi, đổi ở cả hai nơi trong cùng một commit.
|
|
284
293
|
|
|
285
294
|
### Chạy lại — ghi đè ở đây AN TOÀN, và đây là lý do
|
|
@@ -312,7 +321,7 @@ Theo 3 nhóm ở `{paths.qc_skills_dir}/_shared/self-review-principles.md` — *
|
|
|
312
321
|
field `quote` của finding làm bằng chứng cho nó** — mở lại file đọc lại đoạn đó.
|
|
313
322
|
- **Nhảy bước:** đã đi hết bộ tiêu chí `script/*`, **không** trộn tiêu chí test case vào? Verdict
|
|
314
323
|
`APPROVED` phát ra **sau** khi soát đủ, không phải vì "trông ổn"?
|
|
315
|
-
- **Số liệu:** số finding theo mức (
|
|
324
|
+
- **Số liệu:** số finding theo **bốn mức** (BLOCKER/MAJOR/MINOR/SUGGESTION) = đếm thật trên file vừa ghi, và verdict khớp đúng số đếm đó *(R06)*?
|
|
316
325
|
|
|
317
326
|
> **Verdict của lệnh này là cổng cho trạm chạy.** Một `APPROVED` phát ra sớm cho chạy một bộ script
|
|
318
327
|
> chưa đạt, và kết quả chạy đó đi thẳng vào `/qc-report` thành số liệu người ta tin.
|
|
@@ -325,9 +334,9 @@ Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
|
325
334
|
```
|
|
326
335
|
/qc-review-script Hoàn tất — {UC-ID} vòng #{N}
|
|
327
336
|
Điểm : {XX}/100 ({fail} FAIL × −5đ · {warn} WARN × −2đ){nếu có vòng trước: " ← vòng #{N-1}: {YY}/100"}
|
|
328
|
-
Verdict: {APPROVED |
|
|
337
|
+
Verdict: {APPROVED | APPROVED_WITH_SUGGESTIONS | REVISION_REQUIRED | REJECTED} — {n} findings ({blk} BLOCKER · {maj} MAJOR · {min} MINOR · {sug} SUGGESTION)
|
|
329
338
|
File : {qc_artifact_dir}test-cases/REVIEW_SCRIPT_<FEATURE>.md (thêm 1 hàng vào bảng Tổng quan)
|
|
330
339
|
Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
|
|
331
|
-
Next (
|
|
332
|
-
(
|
|
340
|
+
Next (≥ APPROVED_WITH_SUGGESTIONS) : /qc-report {UC-ID} rồi tạo PR
|
|
341
|
+
(REVISION_REQUIRED | REJECTED → sửa script bị gắn cờ, rồi chạy lại lệnh này)
|
|
333
342
|
```
|