Đây là workflow multi-MCP phức tạp nhất trong module này vì nó nối ba server thay vì hai: Playwright (nguồn sự thật về hành vi UI thực tế trong CI), GitHub (nguồn code và PR), và Jira (nguồn quản lý công việc). Khi một test E2E fail trong CI, câu hỏi đầu tiên luôn là "bug thật hay flaky test?" — và trả lời đúng câu hỏi này quyết định toàn bộ hướng đi của workflow. Bài này đi qua toàn bộ chuỗi: từ đọc kỹ báo cáo test failure, phân biệt bug thật với nhiễu, tạo ticket Jira có bối cảnh đầy đủ, đến sửa code, update test, và khép vòng bằng cách đóng ticket khi merge.
Tổng Quan Workflow: Từ CI Test Failure Đến Jira Bug Ticket Đến Fix Được Merge
Điểm khác biệt cốt lõi so với hai cặp MCP trước: ở đây có một quyết định rẽ nhánh quan trọng ngay từ đầu — agent phải xác định test failure là bug thật trong sản phẩm hay chỉ là flaky test (test không ổn định do timing, race condition trong chính test, môi trường CI...) trước khi quyết định có nên tạo Jira ticket không. Tạo ticket cho mọi lần fail, kể cả flaky, sẽ làm board Jira ngập rác và giảm độ tin cậy của quy trình tự động hoá này.
Playwright MCP server GitHub MCP server Jira MCP server
────────────────────── ────────────────── ──────────────
CI test failure report ──read──►
test: "checkout flow completes"
error: "Expected button to be
visible, timeout 5000ms"
trace file + screenshot
agent replay lại bước fail
bằng browser thật (không CI)
để xác nhận có tái hiện được
không, và ở local có fail
giống hệt không
Nếu tái hiện được (bug thật) ──────────► agent đọc code liên quan
tới hành vi bị fail
──► agent tạo bug ticket
kèm trace, screenshot,
bước tái hiện
agent sửa code fix bug
◄─write──
agent update test
(nếu cần) + mở PR
◄─write──
PR merged ──► ticket → Done
Trong workflow này, Playwright MCP server không chỉ dùng để đọc kết quả test cũ — nó còn dùng để replay tương tác thật (click, type, chờ element) trên một trình duyệt thật do agent điều khiển, nhằm xác nhận độc lập rằng lỗi có thật, không phải chỉ dựa vào 1 lần fail ngẫu nhiên trong CI. Đây là bước "verify trước khi báo cáo" — kỹ năng quan trọng nhất của workflow này, và cũng là bước hay bị bỏ qua nhất khi mới tự động hoá.
Mẹo: Không bao giờ để agent tạo Jira ticket ngay khi thấy 1 lần test fail trong CI report. Luôn bắt agent tự replay lại bước tương tác bằng Playwright MCP (không chỉ đọc report cũ) tối thiểu 1-2 lần trước khi kết luận đây là bug thật — chi phí replay này rẻ hơn rất nhiều so với chi phí một ticket "false alarm" làm mất thời gian của cả team.
Bước 1: Phân Tích Playwright Test Failure Và Xác Định Root Cause
Bắt đầu bằng đọc đầy đủ báo cáo lỗi từ CI — không chỉ error message, mà cả trace file (ghi lại toàn bộ hành động, network request, console log trong lúc test chạy) và screenshot tại thời điểm fail:
Đọc kết quả test failure của "checkout flow completes successfully"
trong CI run #4821 (repo acme/checkout-web).
Lấy đầy đủ: error message, trace.zip, screenshot lúc fail, và
console log của trang trong lúc test chạy.
Error message thường ngắn và dễ gây hiểu nhầm: "Expected button to be visible, timeout 5000ms" — nghe như UI chậm hoặc selector sai, nhưng nguyên nhân thật có thể hoàn toàn khác (ví dụ một API call bị lỗi 500 phía sau khiến nút "Đặt hàng" không render). Đây là lý do trace file quan trọng hơn error message — nó cho thấy toàn bộ network activity, không chỉ trạng thái DOM cuối cùng.
Sau khi đọc trace, bước quan trọng nhất: tự replay lại bằng Playwright MCP thay vì chỉ tin vào report:
Dùng Playwright MCP, mở browser và replay chính xác các bước của
test "checkout flow completes successfully":
1. Điều hướng tới /cart với 2 item có sẵn trong session test
2. Click "Proceed to checkout"
3. Chờ nút "Đặt hàng" xuất hiện, chụp snapshot accessibility tree
nếu không thấy nút trong 5 giây
Nếu tái hiện được lỗi giống báo cáo CI, ghi lại chính xác trạng thái
trang lúc đó (snapshot + network log). Nếu KHÔNG tái hiện được sau
3 lần thử, đây có khả năng cao là flaky test — không tạo bug ticket,
chỉ ghi chú vào PR/issue theo dõi flaky test hiện có.
Việc yêu cầu thử "3 lần" (không chỉ 1 lần) là chi tiết quan trọng — flaky test theo định nghĩa là không ổn định, một lần replay thành công không đủ để loại trừ khả năng bug thật (có thể chỉ xảy ra trong điều kiện race condition hiếm), và một lần replay fail không đủ để khẳng định là bug thật (có thể môi trường local lúc đó cũng đang chậm). Ba lần với kết quả nhất quán mới là dấu hiệu đáng tin.
Nếu tái hiện được, dùng chính snapshot accessibility tree tại thời điểm fail để xác định chính xác cái gì đang xảy ra trên trang thay vì đoán:
{
"url": "/checkout",
"visibleElements": ["cart-summary", "shipping-form"],
"missingElement": "submit-order-button",
"consoleErrors": [
"POST /api/orders/validate 500 (Internal Server Error)"
]
}
Console error POST /api/orders/validate 500 chính là root cause thật — nút "Đặt hàng" không render vì component chờ kết quả validate order trước khi hiện nút, và API validate đang lỗi 500. Đây là ví dụ điển hình cho thấy error message của Playwright ("timeout waiting for button") chỉ là triệu chứng bề mặt, root cause nằm ở một lớp hoàn toàn khác (backend API).
Mẹo: Luôn đọc console log và network log trong trace, không chỉ nhìn error message của test framework. Playwright báo "timeout chờ element" là mô tả hành vi quan sát được, không phải nguyên nhân — nguyên nhân thật thường ẩn trong network request hoặc console error xảy ra ngay trước đó.
Bước 2: Tự Động Tạo Jira Bug Ticket Từ Test Report
Sau khi xác nhận đây là bug thật (đã replay tái hiện được, không phải flaky), tạo Jira ticket với đầy đủ bối cảnh để bất kỳ ai xử lý sau cũng không cần đọc lại toàn bộ CI log:
Tạo Jira bug ticket trong project CHECKOUT với:
Title: "Nút 'Đặt hàng' không hiện khi API validate order trả lỗi 500"
Description:
## Mô tả
Test E2E "checkout flow completes successfully" fail trong CI run
#4821. Đã replay và xác nhận tái hiện được 3/3 lần ở local.
## Root cause (sơ bộ)
POST /api/orders/validate trả 500, khiến component chờ kết quả
validate không bao giờ hiện nút "Đặt hàng" (không có fallback UI
cho trường hợp API lỗi).
## Bước tái hiện
1. Vào /cart với ít nhất 1 item
2. Click "Proceed to checkout"
3. Quan sát: nút "Đặt hàng" không xuất hiện, console có lỗi 500
từ /api/orders/validate
## Đính kèm
- Trace file: [link tới CI artifact run #4821]
- Screenshot lúc fail: [đính kèm]
- Console log: [đính kèm]
Priority: High (block toàn bộ luồng checkout)
Labels: bug, e2e-detected, checkout
Gắn label e2e-detected (hoặc tương đương) là thực hành tốt để phân biệt rõ ticket này được phát hiện bởi automation test, không phải do user report hoặc QA thủ công — giúp team sau này thống kê được tỷ lệ bug do E2E test bắt được, một chỉ số hữu ích để đánh giá độ hiệu quả của test suite.
Việc đính kèm trace file, screenshot, console log trực tiếp vào ticket (không chỉ link tới CI run, vì CI artifact thường có thời hạn lưu trữ giới hạn, ví dụ GitHub Actions xoá artifact sau 90 ngày mặc định) đảm bảo ticket vẫn đầy đủ thông tin để debug dù có xử lý muộn vài tháng sau.
Mẹo: Luôn đính kèm trực tiếp trace/screenshot vào ticket, không chỉ dán link tới CI run. Artifact CI có thời hạn lưu trữ giới hạn (thường 14-90 ngày tùy cấu hình) — nếu ticket bị để tồn đọng lâu hơn thời hạn đó, link sẽ chết và người xử lý sau mất hoàn toàn bối cảnh gốc.
Bước 3: Fix Code, Cập Nhật Test Và Đóng Jira Ticket
Với root cause đã rõ (thiếu fallback UI khi API validate lỗi), sửa code qua GitHub MCP server theo đúng flow đã quen ở các bài trước, nhưng có một điểm khác biệt quan trọng ở bước này: cần cân nhắc sửa cả 2 lớp — UI fallback (để user không bị kẹt khi API lỗi) và test (để test bắt được đúng case này rõ ràng hơn, không chỉ timeout mơ hồ):
Tạo branch fix/checkout-validate-500-fallback từ main trong repo
acme/checkout-web.
Sửa component CheckoutSummary: khi API validate order trả lỗi
(bất kỳ status >= 500), hiện thông báo lỗi rõ ràng "Không thể xác
nhận đơn hàng, vui lòng thử lại" kèm nút "Thử lại", thay vì để
nút "Đặt hàng" không bao giờ xuất hiện.
Cập nhật test "checkout flow completes successfully": thêm 1 test
case mới riêng cho trường hợp API validate lỗi 500, assert hiện
đúng thông báo lỗi và nút "Thử lại" — không chỉ dựa vào timeout
5000ms để phát hiện lỗi như hiện tại.
Commit, push, mở PR vào main với description có root cause (như
trong ticket), link Jira CHECKOUT-89, và giải thích rõ đã thêm
test case mới cho case lỗi 500 (không chỉ sửa case happy path).
Chi tiết quan trọng: test case mới assert rõ hành vi mong đợi khi lỗi (hiện thông báo + nút thử lại), thay vì test cũ chỉ ngầm định "nếu không thấy nút trong 5s thì coi như fail". Cách viết test cũ có nhược điểm là không phân biệt được "app thật sự lỗi" với "app chậm hơn 5s vì mạng yếu" — cả hai đều timeout giống nhau. Test mới rõ ràng hơn: giả lập response 500 (mock), rồi assert chính xác UI hiển thị đúng thông báo lỗi, loại bỏ hoàn toàn yếu tố timing.
Sau khi PR merge, đóng vòng bằng cách cập nhật Jira ticket, tương tự pattern đã dùng ở workflow GitHub + Jira:
Kiểm tra PR #612 (acme/checkout-web) đã merged.
Nếu đã merge: chuyển Jira ticket CHECKOUT-89 sang "Done", thêm
comment: "Fixed trong PR #612. Đã thêm fallback UI khi API validate
lỗi 500 và test case riêng cho trường hợp này. Root cause: thiếu
error handling cho response lỗi từ /api/orders/validate."
Mẹo: Khi sửa bug được phát hiện qua E2E test timeout, luôn cân nhắc viết thêm 1 test case rõ ràng cho đúng nguyên nhân gốc (ví dụ mock API trả lỗi, assert UI fallback), thay vì chỉ sửa code và giữ nguyên test cũ dựa vào timeout. Test dựa vào timeout để phát hiện lỗi thường tiếp tục flaky hoặc che giấu regression tương tự trong tương lai — test assert rõ hành vi mới là cách thật sự "đóng" được lỗi này về lâu dài.
Vài Lưu Ý Thêm
- Luôn replay lại (tối thiểu 2-3 lần) trước khi kết luận test failure là bug thật, tránh tạo Jira ticket cho flaky test làm loãng board.
- Đọc console log và network log trong trace, đừng chỉ tin vào error message bề mặt của test framework — root cause thường ở một lớp khác (backend, network) so với nơi lỗi biểu hiện (UI).
- Đính kèm trực tiếp trace/screenshot vào ticket, không chỉ link tới CI artifact có thời hạn lưu trữ giới hạn.
- Gắn label riêng cho bug phát hiện qua automation (ví dụ
e2e-detected) để đo hiệu quả test suite theo thời gian. - Khi sửa bug phát hiện qua timeout, ưu tiên viết test case mới assert rõ hành vi mong đợi, thay vì giữ nguyên cách test dựa vào timeout.
Mẹo: Xây một quy tắc rõ ràng ngay từ đầu cho agent: "chỉ tạo Jira ticket khi đã replay tái hiện được lỗi tối thiểu 2/3 lần thử — nếu không, gắn nhãn flaky và báo cáo riêng, không tạo ticket." Quy tắc cứng này quan trọng hơn việc agent "thông minh" tới đâu, vì nó loại bỏ hoàn toàn rủi ro spam ticket khi CI chạy trên môi trường không ổn định.