@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
|
@@ -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.
|
package/core/steps/qc-scope.md
CHANGED
|
@@ -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
|
|
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
|
|
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-
|
|
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` và `/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
|
|