@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.
Files changed (104) hide show
  1. package/bin/qc-base-map.json +13 -11
  2. package/bin/self-check.js +49 -4
  3. package/bin/trace-schema.json +3226 -3187
  4. package/core/FRAMEWORK_VERSION +1 -1
  5. package/core/commands/qc-analyze.md +2 -2
  6. package/core/commands/qc-automation-assess.md +3 -3
  7. package/core/commands/qc-design-script.md +60 -30
  8. package/core/commands/qc-design-test.md +79 -7
  9. package/core/commands/qc-plan.md +1 -1
  10. package/core/commands/qc-report.md +85 -76
  11. package/core/commands/qc-review-script.md +25 -16
  12. package/core/commands/qc-review-testcase.md +8 -7
  13. package/core/commands/qc-run-manualtest.md +1 -1
  14. package/core/commands/qc-run-script.md +15 -8
  15. package/core/modules/qc-playwright-ts/module.yaml +13 -0
  16. package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
  17. package/core/modules/qc-wdio-appium/module.yaml +20 -0
  18. package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
  19. package/core/skills/qc/qa-analyst/data-flow.md +1 -1
  20. package/core/skills/qc/qa-automation-assess/matrix.md +6 -3
  21. package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
  22. package/core/skills/qc/qa-designer/functional/api.md +1 -1
  23. package/core/skills/qc/qa-designer/functional/job.md +128 -0
  24. package/core/skills/qc/qa-designer/integration/api.md +1 -1
  25. package/core/skills/qc/qa-designer/integration/db.md +1 -1
  26. package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +20 -4
  27. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
  28. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +17 -0
  29. package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
  30. package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
  31. package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
  32. package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
  33. package/core/skills/qc/qa-reviewer/script/exploratory.md +2 -2
  34. package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
  35. package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
  36. package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
  37. package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
  38. package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
  39. package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
  40. package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
  41. package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
  42. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
  43. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +26 -7
  44. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  45. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  46. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  47. package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
  48. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  49. package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
  50. package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
  51. package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
  52. package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
  53. package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
  54. package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
  55. package/core/skills/qc/qa-script-designer/api/security.md +41 -0
  56. package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
  57. package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
  58. package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
  59. package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
  60. package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
  61. package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
  62. package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
  63. package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
  64. package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
  65. package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
  66. package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
  67. package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
  68. package/core/skills/qc/qa-script-runner/report.md +41 -0
  69. package/core/skills/qc/qa-script-runner/web/run.md +48 -0
  70. package/core/steps/qc-scope.md +43 -0
  71. package/core/steps/report-footer.md +2 -2
  72. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  73. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +10 -10
  74. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +1 -1
  75. package/docs/02-concepts/traceability.md +1 -1
  76. package/docs/03-guides/developer.md +1 -1
  77. package/docs/03-guides/tester-qa.md +40 -12
  78. package/docs/04-reference/commands.md +1 -1
  79. package/docs/04-reference/modules.md +2 -1
  80. package/docs/explain/17-qc-design-test.md +2 -2
  81. package/docs/explain/19-qc-run-test.md +4 -4
  82. package/docs/explain/20-qc-report.md +1 -1
  83. package/docs/explain/23-fix-bug.md +2 -2
  84. package/docs/plans/qc-surgery/01-checklist.md +18 -6
  85. package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
  86. package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
  87. package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
  88. package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
  89. package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
  90. package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
  91. package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
  92. package/package.json +1 -1
  93. package/core/modules/qc-playwright/stack-profile.yaml +0 -66
  94. package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
  95. package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
  96. package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
  97. package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
  98. package/core/skills/qc/qa-runner/e2e.md +0 -49
  99. package/core/skills/qc/qa-runner/functional/api.md +0 -35
  100. package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
  101. package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
  102. package/core/skills/qc/qa-runner/integration.md +0 -47
  103. package/core/skills/qc/qa-runner/non-functional.md +0 -49
  104. package/core/skills/qc/qa-runner/report/report.md +0 -37
@@ -0,0 +1,32 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Mobile Functional Feature (đa màn hình, Flutter)
7
+
8
+ **Đọc `_shared/mobile-conventions.md` trước.**
9
+
10
+ ## Khi nào trigger
11
+ - Convert TC feature đa-màn (output `qa-designer/functional/gui-feature.md`, platform `app`),
12
+ TC Automatable=Y.
13
+
14
+ ## Khi KHÔNG trigger
15
+ - Gọn 1 màn → `functional/screen.md` · đầu-cuối xuyên hệ thống ngoài → `e2e.md`
16
+
17
+ ## Phase 1 — Clarify
18
+ Liệt kê các màn/Page Object cần; state truyền giữa màn (đặc biệt qua navigation Flutter —
19
+ argument truyền route, không phải chỉ URL như web).
20
+
21
+ ## Phase 2 — Generate
22
+ Điều hướng giữa Page Object: test tự import Page Object màn kế tiếp sau action điều hướng
23
+ (singleton pattern WDIO — khác Playwright là PO theo instance `page`). Phủ đúng TC
24
+ Automatable=Y. Assert sau mỗi chặng có side-effect, không dồn về cuối.
25
+
26
+ ## Phase 3 — Self-Verify
27
+ ```bash
28
+ npx tsc --noEmit
29
+ ```
30
+
31
+ ## Output
32
+ Script + nhiều Page Object (mỗi màn) trong `mobile-automation/pageobjects/{TICKET-ID}/...`.
@@ -0,0 +1,42 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Mobile Functional Screen (1 màn hình, Flutter)
7
+
8
+ **Đọc `_shared/mobile-conventions.md` trước** (Locator Strategy — vì sao cần
9
+ `FlutterIntegration`, Page Object, Wait/Assertion, Common Pitfalls).
10
+
11
+ ## Khi nào trigger
12
+ - Convert TC functional 1 màn (output `qa-designer/functional/gui-screen.md`, platform `app`),
13
+ TC Automatable=Y, `TC_<FEATURE>.md` đã approve.
14
+
15
+ ## Khi KHÔNG trigger
16
+ - Feature đa-màn → `functional/feature.md` · web → dùng bộ `qa-script-designer/web/*`
17
+
18
+ ## Phase 1 — Clarify
19
+ Đọc `TC_<FEATURE>.md` + `TEST_DATA_PLAN.md`. Page Object cho màn này đã có chưa. Đọc contract
20
+ `ValueKey` §4.5.6 tech-doc gộp cho màn này (xem `_shared/mobile-conventions.md` §1.1).
21
+ **§4.5.6 không đủ/không có** → probe widget tree thật bằng Appium Inspector/Flutter DevTools
22
+ trước khi viết locator (xem `_shared/mobile-conventions.md` §1.2) — không đoán `ValueKey` từ
23
+ ảnh chụp màn hình.
24
+
25
+ ## Phase 2 — Generate
26
+ Phủ đúng TC Automatable=Y của màn này (đếm khớp `AUTOMATION_ASSESSMENT.md`). Rào cản kỹ
27
+ thuật (thiếu `ValueKey`, permission dialog chặn) → viết test tốt nhất có thể + đánh dấu
28
+ `it.skip` có lý do + ghi `IMPROVE-xxx`, không bỏ sót TC.
29
+
30
+ Nhóm `describe`: GUI (hiển thị/enable-disable) → Functional (input/validation/action). Data từ
31
+ `TEST_DATA_PLAN.md`.
32
+
33
+ ## Phase 3 — Self-Verify
34
+ ```bash
35
+ npx tsc --noEmit
36
+ ```
37
+ Đối chiếu thủ công số `it(...)` sinh ra = số TC Automatable=Y của màn này.
38
+
39
+ ## Output
40
+ `mobile-automation/test/specs/{TICKET-ID}/<screen-slug>.spec.ts` +
41
+ `mobile-automation/pageobjects/{TICKET-ID}/<screen-slug>.page.ts`
42
+ (xem quy tắc slug/kiểm tra tồn tại trước khi tạo ở `_shared/file-naming-and-folders.md`).
@@ -0,0 +1,39 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Mobile Integration (App↔Backend)
7
+
8
+ **Đọc `_shared/mobile-conventions.md` trước.** Phần backend (DB/Kafka/API thuần) dùng lại
9
+ đúng client/fixture của `qa-script-designer/web/integration.md` — chỉ khác **phía trigger**
10
+ là thao tác trên app qua WebdriverIO thay vì Playwright.
11
+
12
+ ## Khi nào trigger
13
+ - TC integration app↔backend (output `qa-designer/integration/gui.md` cho platform `app`),
14
+ TC Automatable=Y.
15
+
16
+ ## Quy ước riêng — không mock
17
+ Giống nguyên tắc web: gọi API/DB thật trên môi trường test, không mock response. Khác biệt
18
+ mobile: capture network request từ app khó hơn web (không có `page.waitForResponse()`) —
19
+ dùng 1 trong 2 cách:
20
+ - **Proxy chặn network của thiết bị/emulator** (mitmproxy hoặc tương đương) để verify request
21
+ thật gửi đi — cần setup riêng trong `wdio.conf.ts`.
22
+ - **Verify gián tiếp qua backend**: sau action trên app, query API/DB để xác nhận state đã
23
+ đổi đúng — đơn giản hơn, đủ dùng cho phần lớn TC integration.
24
+
25
+ ## Phase 1 — Clarify
26
+ Chuỗi tích hợp & chặng cần verify; client/fixture backend đã có chưa (tái dùng từ web nếu đã
27
+ tồn tại trong cùng project).
28
+
29
+ ## Phase 2 — Generate
30
+ Mỗi TC → 1 test: action trên app → verify chặng backend (API/DB). Nhóm happy → contract-negative
31
+ → concurrency (nếu áp dụng).
32
+
33
+ ## Phase 3 — Self-Verify
34
+ ```bash
35
+ npx tsc --noEmit
36
+ ```
37
+
38
+ ## Output
39
+ Script trong `mobile-automation/test/specs/{TICKET-ID}/integration/` + client/fixture backend tái dùng.
@@ -0,0 +1,39 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Mobile Non-Functional (Performance/Security/Compatibility)
7
+
8
+ **Đọc `_shared/mobile-conventions.md` trước.**
9
+
10
+ ## Công cụ theo loại
11
+
12
+ | Loại | Công cụ | Assert |
13
+ |---|---|---|
14
+ | **Performance** | Thời gian cold start (`driver.startActivity`/launch time), thời gian render màn hình đo qua timestamp trước/sau `waitForDisplayed` | Ngưỡng cụ thể (vd cold start < 3s) |
15
+ | **Security** | Test lưu trữ local không mã hoá (kiểm tra file app data qua ADB/`driver.execute('mobile: shell', ...)`), test deep-link injection | Assert dữ liệu nhạy cảm không tồn tại dạng plaintext |
16
+ | **Compatibility** | `capabilities` parametrize theo OS version/device profile trong `wdio.conf.ts`; dùng Device Farm (BrowserStack/Sauce Labs/Firebase Test Lab, xem `_shared/mobile-conventions.md` §5.2) khi cần phủ device thật ngoài máy sẵn có | Mỗi profile = 1 target trong TC |
17
+
18
+ Mobile **không có** hạng mục accessibility qua axe-core (đó là công cụ web); nếu TC yêu cầu
19
+ accessibility mobile, dùng công cụ nền tảng riêng (Android Accessibility Scanner API/iOS
20
+ Accessibility Inspector) — thường vẫn cần một phần thao tác thủ công, đánh dấu rõ trong TC
21
+ gốc thay vì cố automate 100%.
22
+
23
+ ## Quy ước riêng
24
+ - Ngưỡng cụ thể khớp TC gốc; đo elapsed không gồm thời gian setup fixture/app install.
25
+ - Test cần thiết bị/profile đặc biệt → `it.skip(!deviceReady, 'lý do')`.
26
+
27
+ ## Phase 1 — Clarify
28
+ Loại + ngưỡng + công cụ; profile thiết bị cần test.
29
+
30
+ ## Phase 2 — Generate
31
+ Mỗi TC → 1 test đo + assert ngưỡng.
32
+
33
+ ## Phase 3 — Self-Verify
34
+ ```bash
35
+ npx tsc --noEmit
36
+ ```
37
+
38
+ ## Output
39
+ `mobile-automation/test/specs/{TICKET-ID}/non-functional/<feature>-<scenario>.spec.ts` + helper đo (`utils/measure.ts`).
@@ -0,0 +1,36 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Web E2E Journey
7
+
8
+ **Đọc `_shared/web-conventions.md` trước.**
9
+
10
+ ## Khi nào trigger
11
+ - Convert TC E2E journey (output `qa-designer/e2e/journey.md`), TC Automatable=Y.
12
+
13
+ ## Khi KHÔNG trigger
14
+ - Test 1 màn/field → `functional/*` · 1 điểm tích hợp → `integration.md`
15
+
16
+ ## Quy ước riêng
17
+ - Chuỗi Page Object xuyên các màn; verify points (V1…Vn của journey) thành `expect()` rõ ràng
18
+ **sau mỗi chặng**, không dồn hết về cuối (Common Pitfall #4).
19
+ - Tiền điều kiện phức tạp (tài khoản role, dữ liệu buổi/lớp) qua fixture Playwright riêng,
20
+ không inline trong test; cleanup sau journey.
21
+ - Cần verify hệ thống ngoài (DB/CRM) → client/fixture riêng, giống `integration.md`.
22
+
23
+ ## Phase 1 — Clarify
24
+ Các màn/PO + hệ thống verify; tài khoản/data cần dựng; điểm cleanup.
25
+
26
+ ## Phase 2 — Generate
27
+ Mỗi journey → 1 test; verify đủ V1…Vn. Journey phụ thuộc gap → `test.fixme('...GAP-xx')`.
28
+
29
+ ## Phase 3 — Self-Verify
30
+ ```bash
31
+ npx tsc --noEmit
32
+ npx playwright test automation/tests/{TICKET-ID}/e2e/<feature>-<scenario>.spec.ts --list
33
+ ```
34
+
35
+ ## Output
36
+ `automation/tests/{TICKET-ID}/e2e/<feature>-<scenario>.spec.ts` + Page Object/client tái dùng.
@@ -0,0 +1,39 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — API (dùng chung mọi platform)
7
+
8
+ Skill sinh script test API thuần (không qua UI), dùng `@playwright/test` `APIRequestContext`.
9
+ Test API **không phân biệt platform gọi nó là web hay mobile** — backend là một, nên file này
10
+ dùng chung cho cả pipeline web và mobile (không có bản mobile riêng).
11
+
12
+ ## Khi nào trigger
13
+ - Convert TC API (output `qa-designer/functional/api.md`), TC Automatable=Y, `TC_<FEATURE>.md` đã approve.
14
+
15
+ ## Khi KHÔNG trigger
16
+ - Test qua UI → `functional/gui-screen.md`/mobile tương ứng · tích hợp đa thành phần → `integration.md`
17
+
18
+ ## Quy ước riêng (ngoài Locator/Wait/Assertion chung — API không có locator)
19
+ - Client API gói trong fixture Playwright (`test.extend`) — base URL + auth header từ
20
+ `process.env.*`, KHÔNG rải request rời rạc trong test.
21
+ - Assertion: status code **và** field response (JSON path) — không chỉ status code.
22
+ - Test độc lập: tạo data qua API → dùng → cleanup qua API (`test.afterEach`), không phụ thuộc
23
+ thứ tự chạy.
24
+
25
+ ## Phase 1 — Clarify
26
+ Base URL/auth/role theo `TEST_DATA_PLAN.md`; client fixture đã có chưa.
27
+
28
+ ## Phase 2 — Generate
29
+ Mỗi TC Automatable=Y → 1 test gọi endpoint với request từ `TEST_DATA_PLAN.md`; assert status +
30
+ field. Nhóm `test.describe`: happy → validation → auth → not-found → edge.
31
+
32
+ ## Phase 3 — Self-Verify
33
+ ```bash
34
+ npx tsc --noEmit
35
+ npx playwright test automation/tests/{TICKET-ID}/functional/api/<feature>-<scenario>.spec.ts --list
36
+ ```
37
+
38
+ ## Output
39
+ `automation/tests/{TICKET-ID}/functional/api/<feature>-<scenario>.spec.ts` + client fixture (`fixtures/api-client.ts`) nếu mới.
@@ -0,0 +1,34 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Web Functional GUI Feature (đa màn hình)
7
+
8
+ Skill sinh script cho feature span ≥2 màn. **Đọc `_shared/web-conventions.md` trước.**
9
+
10
+ ## Khi nào trigger
11
+ - Convert TC feature đa-màn (output `qa-designer/functional/gui-feature.md`), TC Automatable=Y,
12
+ `TC_<FEATURE>.md` đã approve.
13
+
14
+ ## Khi KHÔNG trigger
15
+ - Gọn 1 màn → `functional/gui-screen.md` · đầu-cuối xuyên hệ thống ngoài → `e2e.md`
16
+
17
+ ## Phase 1 — Clarify
18
+ Liệt kê các màn/Page Object cần; state truyền giữa màn (giá trị nhập màn A hiển thị đúng ở
19
+ màn B); data từ `TEST_DATA_PLAN.md`.
20
+
21
+ ## Phase 2 — Generate
22
+ Mỗi Page Object action điều hướng **trả về PO màn kế tiếp** (`return new NextPage(this.page)`)
23
+ — test chuỗi `const p2 = await p1.doAction()`. Phủ đúng TC Automatable=Y (đếm khớp
24
+ `AUTOMATION_ASSESSMENT.md`). Assert **sau mỗi chặng có side-effect**, không chỉ ở bước cuối
25
+ (xem Common Pitfall #4 trong `_shared/web-conventions.md`).
26
+
27
+ ## Phase 3 — Self-Verify
28
+ ```bash
29
+ npx tsc --noEmit
30
+ npx playwright test automation/tests/{TICKET-ID}/<feature>-<scenario>.spec.ts --list
31
+ ```
32
+
33
+ ## Output
34
+ Script + nhiều Page Object (mỗi màn) trong `automation/pages/{TICKET-ID}/...`.
@@ -0,0 +1,42 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Web Functional GUI Screen (1 màn hình)
7
+
8
+ Skill sinh script cho 1 màn hình đơn. **Đọc `_shared/web-conventions.md` trước** (Locator
9
+ Strategy, Page Object, Wait/Assertion, Common Pitfalls) — file này chỉ có phần sinh-script
10
+ riêng của layer.
11
+
12
+ ## Khi nào trigger
13
+ - Convert TC functional 1 màn (output `qa-designer/functional/gui-screen.md`), TC đã
14
+ `Automatable: Y` (từ `AUTOMATION_ASSESSMENT.md`) và `TC_<FEATURE>.md` đã approve.
15
+
16
+ ## Khi KHÔNG trigger
17
+ - Feature đa-màn → `functional/gui-feature.md` · API thuần → `functional/api.md`
18
+
19
+ ## Phase 1 — Clarify
20
+ Đọc `TC_<FEATURE>.md` (chỉ TC Automatable=Y) + `TEST_DATA_PLAN.md`. Page Object cho màn này đã có
21
+ chưa → tạo mới nếu chưa. Đọc bảng test-id §4.5.6 tech-doc gộp cho màn này.
22
+
23
+ ## Phase 2 — Generate
24
+ **Phủ đúng các TC Automatable=Y** — đếm TC trong `AUTOMATION_ASSESSMENT.md` có `Y` cho màn
25
+ này = số `test(...)` phải sinh (không hơn, không kém). TC Automatable=Y nhưng phát hiện rào
26
+ cản kỹ thuật lúc viết → `test.fixme('TC_xxx — {lý do}')` + ghi `IMPROVE-xxx` (xem command
27
+ `/qc-design-script` §Testability Improvement List), không âm thầm bỏ qua.
28
+
29
+ Nhóm theo `test.describe`: GUI (hiển thị/enable-disable) → Functional (input/validation/action).
30
+ Data lấy từ `TEST_DATA_PLAN.md` (theo `TD-xxx` map ở cột "Dùng bởi").
31
+
32
+ ## Phase 3 — Self-Verify (trước khi báo Human approve)
33
+ ```bash
34
+ npx tsc --noEmit
35
+ npx playwright test automation/tests/{TICKET-ID}/<screen>.spec.ts --list
36
+ ```
37
+ Số test liệt kê = số TC Automatable=Y của màn này. Thiếu → quay lại Phase 2.
38
+
39
+ ## Output
40
+ `automation/tests/{TICKET-ID}/<screen-slug>.spec.ts` +
41
+ `automation/pages/{TICKET-ID}/<screen-slug>.page.ts` (mới nếu cần —
42
+ xem quy tắc slug/kiểm tra tồn tại trước khi tạo ở `_shared/file-naming-and-folders.md`).
@@ -0,0 +1,43 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Web Integration (API↔DB↔service↔queue↔UI)
7
+
8
+ **Đọc `_shared/web-conventions.md` trước.**
9
+
10
+ ## Khi nào trigger
11
+ - Convert TC integration (output `qa-designer/integration/*`), TC Automatable=Y.
12
+
13
+ ## Khi KHÔNG trigger
14
+ - Chỉ 1 endpoint/UI đơn → `functional/*` · hành trình đầu-cuối → `e2e.md`
15
+
16
+ ## Quy ước riêng — không mock (nguyên tắc quan trọng nhất của integration test)
17
+ Mock API/DB trong integration test biến nó thành **unit test trá hình** — không còn verify
18
+ được tích hợp thật. Luôn gọi network/DB thật trên môi trường test:
19
+ - **GUI↔Backend**: `page.waitForResponse(url)` để capture request/response thật khi thao tác UI.
20
+ - **DB**: client DB thật (qua fixture, connection string từ `process.env.*`), verify trực tiếp
21
+ bảng/cột — không chỉ verify qua UI hiển thị đúng (UI có thể cache sai mà DB đã đúng, hoặc
22
+ ngược lại).
23
+ - **Kafka/queue**: producer/consumer thật trong fixture, verify payload nhận được, không
24
+ giả lập message.
25
+
26
+ ## Phase 1 — Clarify
27
+ Chuỗi tích hợp & chặng cần verify; client/fixture (API/DB/Kafka) đã có chưa; data từ
28
+ `TEST_DATA_PLAN.md`.
29
+
30
+ ## Phase 2 — Generate
31
+ Mỗi TC → 1 test theo data flow: action → verify từng chặng (response → DB → event → UI).
32
+ Nhóm: happy → contract-negative (4xx/5xx + UI hiển thị đúng message) → concurrency (mô tả rõ
33
+ số request đồng thời, assert không race condition — vd unique constraint giữ nguyên).
34
+
35
+ ## Phase 3 — Self-Verify
36
+ ```bash
37
+ npx tsc --noEmit
38
+ npx playwright test automation/tests/{TICKET-ID}/integration/<feature>-<scenario>.spec.ts --list
39
+ ```
40
+ (Cần môi trường staging/DB/Kafka test khả dụng để chạy thật sau khi generate.)
41
+
42
+ ## Output
43
+ Script + client/fixture (DB/Kafka/API) trong `automation/tests/{TICKET-ID}/integration/` + `fixtures/`.
@@ -0,0 +1,42 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ ---
5
+
6
+ # Gen Script — Web Non-Functional (Performance/Security/Accessibility/Compatibility)
7
+
8
+ **Đọc `_shared/web-conventions.md` trước** (locator/wait/assertion nền tảng vẫn áp dụng).
9
+
10
+ ## Khi nào trigger
11
+ - Convert TC non-functional (output `qa-designer/non-functional.md`), TC Automatable=Y, có
12
+ **ngưỡng đo cụ thể** trong `TC_<FEATURE>.md`.
13
+
14
+ ## Công cụ theo loại
15
+
16
+ | Loại | Công cụ | Assert |
17
+ |---|---|---|
18
+ | **Performance** | `performance.timing`/`page.evaluate` đo, hoặc tích hợp k6/Artillery cho load thật | Ngưỡng cụ thể (`expect(elapsed).toBeLessThan(2000)`), không assert mơ hồ |
19
+ | **Security** | Payload injection trong constant/fixture; test trên môi trường test, KHÔNG production | Status 4xx + không tạo được record + response không lộ PII |
20
+ | **Accessibility** | `@axe-core/playwright` (`AxeBuilder`) | `expect(results.violations).toHaveLength(0)` hoặc filter đúng WCAG level (`wcag2a`/`wcag2aa`) |
21
+ | **Compatibility** | Playwright `projects` trong config (chromium/firefox/webkit), hoặc device emulation | Mỗi project = 1 target trong TC; không hardcode 1 browser |
22
+
23
+ ## Quy ước riêng
24
+ - Assertion **luôn có ngưỡng cụ thể khớp TC gốc** — không tự đặt ngưỡng khác, không
25
+ `expect(response).toBeTruthy()` mơ hồ.
26
+ - Đo elapsed time: bắt đầu/kết thúc rõ ràng, **không** bao gồm thời gian fixture setup.
27
+ - Test cần môi trường đặc biệt (load server, scanner) → `test.skip(!envReady, 'lý do')`.
28
+
29
+ ## Phase 1 — Clarify
30
+ Loại + ngưỡng + công cụ; môi trường/tải mẫu; data đặc biệt từ `TEST_DATA_PLAN.md`.
31
+
32
+ ## Phase 2 — Generate
33
+ Mỗi TC → 1 test đo + assert ngưỡng; đánh dấu test cần môi trường riêng bằng tag `@slow`.
34
+
35
+ ## Phase 3 — Self-Verify
36
+ ```bash
37
+ npx tsc --noEmit
38
+ npx playwright test automation/tests/{TICKET-ID}/non-functional/<feature>-<scenario>.spec.ts --list
39
+ ```
40
+
41
+ ## Output
42
+ `automation/tests/{TICKET-ID}/non-functional/<feature>-<scenario>.spec.ts` + helper đo/scan (`utils/measure.ts`).
@@ -0,0 +1,38 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ new_in: QC-Workflow-Proposal (8-phase)
5
+ ---
6
+
7
+ # Run — Mobile (WebdriverIO + Appium)
8
+
9
+ Skill **tự chứa** cho `/qc-run-script` khi `active_platform = app`.
10
+
11
+ ## Lệnh chạy
12
+
13
+ ```bash
14
+ npx wdio run wdio.conf.ts --spec mobile-automation/test/specs/{TICKET-ID}/...
15
+ ```
16
+
17
+ Video/screenshot on-fail cấu hình qua `afterTest` hook trong `wdio.conf.ts` (chụp screenshot
18
+ khi `passed === false`; ghi video nếu dùng service `wdio-video-reporter` hoặc quay màn hình
19
+ qua `driver.saveRecordingScreen`/tương đương simulator/emulator).
20
+
21
+ ## Đọc kết quả trước khi đề xuất phân loại Fail
22
+
23
+ Với mỗi FAIL, xem screenshot/video tại thời điểm fail + log Appium server (`appium.log`)
24
+ trước khi đoán:
25
+
26
+ | Dấu hiệu | Khả năng cao là |
27
+ |---|---|
28
+ | Element "not found" nhưng screenshot cho thấy nó **hiển thị rõ trên màn hình** | **script-bug** — sai `ValueKey`/locator, hoặc app chưa bật `Semantics` đúng cho driver `FlutterIntegration` đọc |
29
+ | Log Appium báo `automationName` không khớp app (vd dùng `UiAutomator2` cho app Flutter không bật accessibility) | **script-bug** — sai cấu hình driver, xem `_shared/mobile-conventions.md` §0 |
30
+ | Hành động đúng (tap đúng nút, đúng data) nhưng app **không phản hồi đúng spec** (không điều hướng, không lưu data) | **product-gap** |
31
+ | Permission dialog native chặn action, test không xử lý | **script-bug** — thiếu xử lý dialog, không phải bug sản phẩm |
32
+ | Fail chỉ xảy ra trên 1 device/OS version cụ thể | Có thể **product-gap** riêng cho compatibility đó — không quy chung là flaky |
33
+
34
+ ## Retry trước khi kết luận (bắt buộc — bước 0 của gate phân loại Fail)
35
+ Mobile vốn có độ trễ/nhiễu cao hơn web (cold start, animation, tốc độ máy) — trước khi đề xuất
36
+ phân loại bất kỳ Fail nào, chạy lại riêng test đó tối đa 2 lần trên cùng device/emulator. Kết
37
+ quả không nhất quán → đề xuất `flaky` (xem `/qc-run-script` §Phân loại mỗi Fail), không phải
38
+ script-bug/product-gap ngay.
@@ -0,0 +1,41 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ source: upstream/qc-base-new/Automation-Standards.md §1 + OQ-01 · Mobile-Automation-Standards.md §1 (Approved)
5
+ ---
6
+
7
+ # Report skill — TypeScript stack (Playwright HTML Report / WDIO Allure Report)
8
+
9
+ Skill **tự chứa** cho `/qc-report`. Báo cáo do **công cụ sinh** — Playwright HTML Report (web·system) hoặc Allure v2.x (app) — **không** dashboard tự viết.
10
+
11
+ ## Web — Playwright HTML Report + Trace Viewer
12
+
13
+ ```bash
14
+ npx playwright test automation/tests/{TICKET-ID}/... --reporter=html
15
+ npx playwright show-report # mở report HTML tương tác
16
+ npx playwright show-trace test-results/<nodeid>/trace.zip # debug 1 test cụ thể
17
+ ```
18
+
19
+ - Report HTML mặc định ở `playwright-report/` (self-contained, mở trực tiếp trong browser).
20
+ - Mỗi test fail có sẵn trace + screenshot đính kèm (cấu hình qua
21
+ `use: { trace: 'on-first-retry', screenshot: 'only-on-failure' }` trong `playwright.config.ts`).
22
+
23
+ ## Mobile — WebdriverIO Allure Report
24
+
25
+ ```bash
26
+ npx wdio run wdio.conf.ts --spec ...
27
+ npx allure generate ./allure-results --clean -o ./allure-report
28
+ npx allure open ./allure-report
29
+ ```
30
+
31
+ - Cần reporter `@wdio/allure-reporter` khai trong `wdio.conf.ts` (`reporters: ['allure']`).
32
+ - Screenshot/video on-fail đính kèm tự động vào report qua `afterTest` hook (xem
33
+ `qa-script-runner/mobile/run.md`).
34
+
35
+ ## Nguyên tắc chung (cả hai platform)
36
+ - Evidence trung thực: report phản ánh đúng lần chạy gần nhất, không chỉnh sửa số liệu.
37
+ - FAIL giữ nguyên trạng thái thật cho tới khi fix + chạy lại — **không fake-pass**.
38
+ - `playwright-report/`, `test-results/`, `allure-results/`, `allure-report/` đã gitignore
39
+ (artifact nặng) — không commit vào repo.
40
+ - Tóm tắt bắt buộc: **TOTAL / PASS / FAIL / SKIP / FLAKY** + duration, và với mỗi FAIL: phân
41
+ loại đã xác nhận (script-bug/product-gap/flaky) từ `/qc-run-script`, kèm `BUG-{id}` nếu đã file.
@@ -0,0 +1,48 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-09
4
+ new_in: QC-Workflow-Proposal (8-phase)
5
+ ---
6
+
7
+ # Run — Web (Playwright Test)
8
+
9
+ Skill **tự chứa** cho `/qc-run-script` khi `active_platform = web`.
10
+
11
+ ## Lệnh chạy
12
+
13
+ ```bash
14
+ npx playwright test automation/tests/{TICKET-ID}/... --reporter=html,list
15
+ ```
16
+
17
+ Trace tự động bật qua `playwright.config.ts` (`use: { trace: 'on-first-retry' }` hoặc `'on'`
18
+ nếu muốn trace mọi lần) → mỗi test có `test-results/<nodeid>/trace.zip` khi fail.
19
+
20
+ ## Đọc kết quả trước khi đề xuất phân loại Fail
21
+
22
+ Với mỗi FAIL, **mở trace trước khi đoán**:
23
+
24
+ ```bash
25
+ npx playwright show-trace test-results/<nodeid>/trace.zip
26
+ ```
27
+
28
+ Trace viewer cho: timeline hành động, DOM snapshot tại từng bước, network request/response,
29
+ console log. Dấu hiệu phân biệt:
30
+
31
+ | Dấu hiệu trong trace | Khả năng cao là |
32
+ |---|---|
33
+ | Locator "not found" nhưng DOM snapshot cho thấy element **có tồn tại** với selector khác | **script-bug** — selector sai/lỗi thời do UI đổi cấu trúc, không phải bug sản phẩm |
34
+ | Element thực sự **không xuất hiện** sau hành động đúng spec (nút bấm không có phản hồi, API trả lỗi mà spec nói phải thành công) | **product-gap** — hành vi thực tế ≠ spec |
35
+ | Timeout chờ network response, response **không bao giờ tới** | **product-gap** nếu spec yêu cầu response — hoặc **script-bug** nếu URL/endpoint chờ sai |
36
+ | Assertion so giá trị: actual đúng theo spec nhưng expected trong test viết sai | **script-bug** |
37
+ | Flaky ngẫu nhiên (pass khi chạy lẻ, fail khi chạy song song) | **script-bug** — thiếu cách ly data/test independence, xem `_shared/web-conventions.md` §Common Pitfalls #5-6 |
38
+
39
+ Không kết luận nếu bằng chứng không đủ rõ — báo "không chắc, cần điều tra thêm" thay vì đoán.
40
+
41
+ ## Retry trước khi kết luận (bắt buộc — bước 0 của gate phân loại Fail)
42
+ Trước khi đề xuất phân loại bất kỳ Fail nào, chạy lại riêng test đó tối đa 2 lần:
43
+ ```bash
44
+ npx playwright test <file> -g "<title>" --repeat-each=1
45
+ ```
46
+ Kết quả không nhất quán (fail→pass hoặc ngược lại) → đề xuất `flaky`, không phải
47
+ script-bug/product-gap (xem `/qc-run-script` §Phân loại mỗi Fail). Chỉ khi fail **nhất quán**
48
+ qua các lần retry mới tiếp tục điều tra để phân biệt script-bug/product-gap.
@@ -58,6 +58,49 @@ Theo thứ tự, dừng ở cái đầu tiên khớp:
58
58
  Lưu `active_platform`. Từ đây, **mọi** phép đọc `.feature` chỉ đọc thư mục
59
59
  `bdd/{active_platform}/` — không trộn SC chéo nền.
60
60
 
61
+ > **Nền `system` còn MỘT câu hỏi nữa, và nó ở trạm 3.** `system` không đồng nghĩa với API — nó
62
+ > còn chứa **job tự chạy** và **consumer hàng đợi**, hai thứ không có endpoint nào. Khi không suy
63
+ > được, `/qc-design-test` hỏi QC rồi ghi câu trả lời vào `Tags` của TC. Xem
64
+ > `/qc-design-test` §Nền `system`. Ghi ở đây để người đọc luật nền biết **còn một câu chưa xong**,
65
+ > chứ không phải phân giải xong nền là hết.
66
+
67
+ ### 2b — Nền → module QC → lane skill *(bảng DUY NHẤT, đừng chép lại ở lệnh)*
68
+
69
+ | `active_platform` | module QC | `layout` | lane skill |
70
+ |---|---|---|---|
71
+ | `web` · `webview` | `qc-playwright-ts` | `layout.web` — `automation/` | `qa-script-designer/web/*` |
72
+ | `app` · `app-ios` · `app-android` | `qc-wdio-appium` | `layout.mobile` — `mobile-automation/` | `qa-script-designer/mobile/*` |
73
+ | `system` + lane `api` | `qc-playwright-ts` | `layout.api` — `api-automation/` | `qa-script-designer/api/*` |
74
+ | `system` + lane `job` · `queue` | `qc-playwright-ts` | `layout.api` — `api-automation/` | ⚠️ **chưa có lane script** — xem dưới |
75
+
76
+ > **Vì sao bảng này ở đây chứ không ở lệnh.** Cùng lý do mục §2 tồn tại: luật phân giải nền
77
+ > từng được copy-paste ở 5 lệnh rồi câu chữ lệch nhau. Ba lệnh script trỏ vào đây, **không
78
+ > chép lại**.
79
+ >
80
+ > **Vì sao KHÔNG có key cấu hình riêng.** Từng có một lời hứa `tech_stack.qc_module` trong
81
+ > comment của module cũ, nhưng nó **chưa bao giờ được cài** — và không nên cài: `active_platform`
82
+ > đã trả lời xong câu này ở §2 và đã **khoá cho cả pass QC**. Một field thứ hai là hai đáp án
83
+ > cho một câu hỏi, và khi chúng lệch nhau thì artifact ghi vào thư mục của nền này trong khi
84
+ > script sinh theo layout của nền kia — hỏng **im lặng**.
85
+ >
86
+ > 🔴 **`system` KHÔNG đồng nghĩa với API — sửa 2026-09-17 sau ca thật LESS-22.** Quyết định
87
+ > `S-API` ánh xạ `system → lane api` vô điều kiện, và nó **sai**: `system` còn chứa **job tự
88
+ > chạy** *(không ai gọi)* và **consumer hàng đợi** *(nằm chờ message)*. Cả ba tài liệu chuẩn dùng
89
+ > để chốt `S-API` đều **chỉ nói về API**, nên không ai thấy hai hình dạng kia.
90
+ >
91
+ > **Tầng thiết kế TC đã có đủ ba** *(trạm 3 hỏi QC rồi ghi lane — xem `/qc-design-test` §Nền
92
+ > `system`)*: `functional/api` · `functional/job` · `integration/queue`.
93
+ >
94
+ > **Tầng sinh script mới có một** — `qa-script-designer/api/*`. Lane `job` và `queue` chạy tới
95
+ > trạm 6 thì **chưa có skill**. Đây là **lỗ đã biết, ghi ra thay vì để trạm 6 lặng lẽ dùng lane
96
+ > `api`**: gặp TC lane `job`/`queue`, trạm 6 phải **DỪNG** và nói rõ chưa hỗ trợ, không được
97
+ > sinh API Object cho một thứ không có endpoint.
98
+
99
+ > **`web` và `system` dùng chung module, khác `layout`.** Đó là chủ ý: cùng Playwright + TS
100
+ > *(AD-API-001 — "tái dùng infrastructure với Web testing")*, nên tách làm hai module là khai
101
+ > dãy phiên bản hai lần. Nhưng **API Object ≠ Page Object** và `api-automation/` là thư mục
102
+ > gốc riêng, nên `layout` và lane skill phải tách.
103
+
61
104
  ---
62
105
 
63
106
  ## 3 — `qc_artifact_dir`
@@ -99,9 +99,9 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
99
99
  | /qc-plan | `/qc-design-test {UC-ID}` |
100
100
  | /qc-design-test | `/qc-review-testcase {UC-ID}` |
101
101
  | /qc-automation-assess | `/qc-design-script {TICKET-ID}` (Automatable: Y) · `/qc-run-manualtest {UC-ID}` (N) |
102
- | /qc-review-testcase | `/qc-automation-assess {TICKET-ID}` nếu APPROVED; sửa TC bằng `/qc-design-test` nếu NEEDS_FIX |
102
+ | /qc-review-testcase | `/qc-automation-assess {TICKET-ID}` nếu `APPROVED` hoặc `APPROVED_WITH_SUGGESTIONS`; sửa TC bằng `/qc-design-test` nếu `REVISION_REQUIRED` · `REJECTED` |
103
103
  | /qc-run-script | `/qc-run-manualtest {UC-ID}` (TC Automatable: N) rồi `/qc-report {UC-ID}` |
104
- | /qc-review-script | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED; sửa script nếu NEEDS_FIX |
104
+ | /qc-review-script | `/qc-report {UC-ID}` rồi tạo PR nếu `APPROVED` hoặc `APPROVED_WITH_SUGGESTIONS`; sửa script nếu `REVISION_REQUIRED` · `REJECTED` |
105
105
  | /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
106
106
  | /generate-tech-docs | `/map-testids {UC-ID}` — chốt hợp đồng test-id §4.5.6 **trước** khi review |
107
107
  | /map-testids | `/review-tech-docs {tech-design-file}` (review CẢ hợp đồng vừa ghi) |
@@ -25,7 +25,7 @@ Trước khi đẩy sang QC chính thức, Dev cần một vòng **kiểm nhanh
25
25
 
26
26
  > **`dev_selftest` ≠ `qc_status`.** Hai trục **độc lập**: dev smoke (nhanh, tự kiểm) vs QC chính thức (Playwright, evidence). Không lấn quyền nhau.
27
27
  >
28
- > ⚠️ **Nhưng "độc lập" chỉ đúng với `status` về KẾT QUẢ CHẠY, không đúng về QUYỀN KHẲNG ĐỊNH** *(GAPS-v4 G55)*. `pass` mang nghĩa *"scenario này đã được nghiệm thu theo spec **hiện tại**"* — nên trên row `DRIFT`/`ORPHANED`, `/dev-run-test` và `/qc-design-script` `/qc-run-script` **không được** ghi `pass`; chúng hạ về `not_run`. `fail`/`skip` thì ghi bình thường. `lint-trace` **T12** bắt trạng thái `DRIFT + pass` ở sổ thật, bất kể ai ghi ra.
28
+ > ⚠️ **Nhưng "độc lập" chỉ đúng với `status` về KẾT QUẢ CHẠY, không đúng về QUYỀN KHẲNG ĐỊNH** *(GAPS-v4 G55)*. `pass` mang nghĩa *"scenario này đã được nghiệm thu theo spec **hiện tại**"* — nên trên row `DRIFT`/`ORPHANED`, `/dev-run-test` và `/qc-run-script` `/qc-run-manualtest` **không được** ghi `pass`; chúng hạ về `not_run`. `fail`/`skip` thì ghi bình thường. `lint-trace` **T12** bắt trạng thái `DRIFT + pass` ở sổ thật, bất kể ai ghi ra.
29
29
 
30
30
  ---
31
31