·

Playwright MCP với Claude Code CLI and VS Code

Cài đặt Playwright MCP trong Claude Code CLI and VS Code để AI agent có thể điều khiển trình duyệt thật để kiểm thử và kiểm tra trang web ngay trong trình soạn thảo.

Claude Code là một trong những AI coding agent có hỗ trợ MCP (Model Context Protocol) mượt nhất hiện nay, và khi kết hợp với Playwright MCP, bạn có một "junior QA engineer AI" thực sự có thể mở trình duyệt, thao tác, và viết ra test E2E (end-to-end) hoàn chỉnh. Bài này hướng dẫn chi tiết cách cài đặt Playwright MCP cho Claude Code — cả ở dạng CLI thuần và trong VS Code extension — cùng các best practice để bộ test do AI sinh ra thực sự đáng tin cậy trong CI, không chỉ "chạy được một lần rồi thôi".

Cài Đặt Và Kết Nối Playwright MCP Với Claude Code

Claude Code hỗ trợ đăng ký MCP server qua CLI hoặc qua file cấu hình project. Cách nhanh nhất là dùng lệnh claude mcp add:

claude mcp add playwright -- npx @playwright/mcp@latest

Lệnh này thêm một MCP server tên playwright, chạy qua npx, vào scope hiện tại (mặc định là project). Bạn có thể kiểm tra lại danh sách server đã đăng ký:

claude mcp list

Nếu muốn cấu hình chia sẻ cùng team qua git, hãy tạo file .mcp.json ở root project:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Commit file này vào repo — mọi thành viên team clone về và mở Claude Code sẽ tự động có sẵn Playwright MCP, không cần cài riêng lẻ. Sau khi khởi động lại session Claude Code, gõ /mcp để xác nhận server playwright đã ở trạng thái "connected".

Một điểm hay bị bỏ sót: nếu project của bạn cần trình duyệt cụ thể đã cài sẵn (ví dụ Chromium bundled của Playwright), hãy chạy trước:

npx playwright install chromium

để tránh lỗi "browser not found" khi agent lần đầu gọi browser_navigate.

Mẹo: Đặt file .mcp.json vào repo và thêm vào README một dòng hướng dẫn claude mcp list để kiểm tra — nhiều bạn junior trong team quên rằng MCP server cần Node.js/npx sẵn trên máy, dẫn đến lỗi "command not found" khi mở Claude Code lần đầu trên máy mới.

Sinh Và Chạy Test E2E Từ Mô Tả Bằng Ngôn Ngữ Tự Nhiên

Sau khi kết nối xong, workflow thực chiến với Claude Code thường theo 3 bước: mô tả luồng, để agent thực thi thử qua browser thật, rồi yêu cầu chuyển thành file test chính thức.

Ví dụ prompt mở đầu:

Ứng dụng đang chạy tại http://localhost:3000. Hãy mở trang /login, đăng nhập với
email "test@test.com" và password "12345678", sau đó vào trang /profile và đổi
tên hiển thị thành "QA Bot". Xác nhận là tên mới hiển thị đúng sau khi lưu.

Claude Code sẽ tự gọi các tool của Playwright MCP: browser_navigatebrowser_snapshot để đọc accessibility tree (cây truy cập, tức cấu trúc trang theo role của phần tử) → browser_type/browser_click để điền form và bấm nút → browser_wait_for để chờ trang chuyển → snapshot lại để xác nhận. Bạn sẽ thấy toàn bộ log tool call ngay trong terminal, kèm tóm tắt bằng lời mỗi bước agent vừa làm.

Sau khi xác nhận luồng đúng, prompt tiếp theo để sinh test chính thức:

Luồng trên đã đúng. Viết lại thành file tests/e2e/update-profile.spec.ts theo
chuẩn @playwright/test. Dùng getByRole/getByLabel thay vì CSS selector, mỗi
bước quan trọng đều có expect() tương ứng, và đặt beforeEach để login trước
mỗi test case trong file.

Kết quả tham khảo:

import { test, expect } from '@playwright/test';

test.describe('Update profile', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/login');
    await page.getByLabel('Email').fill('test@test.com');
    await page.getByLabel('Password').fill('12345678');
    await page.getByRole('button', { name: 'Log in' }).click();
    await expect(page).toHaveURL(/.*dashboard/);
  });

  test('user can update display name', async ({ page }) => {
    await page.goto('/profile');
    await page.getByLabel('Display name').fill('QA Bot');
    await page.getByRole('button', { name: 'Save' }).click();
    await expect(page.getByText('QA Bot')).toBeVisible();
  });
});

Chạy thử ngay để đảm bảo file độc lập, không phụ thuộc trạng thái phiên agent vừa thao tác:

npx playwright test tests/e2e/update-profile.spec.ts

Mẹo: Luôn yêu cầu Claude Code thêm test.beforeEach cho các bước setup lặp lại (login, seed data) ngay từ lần sinh code đầu tiên — nếu không, agent thường viết mỗi test case độc lập với đoạn login lặp đi lặp lại, vừa dài dòng vừa khó maintain khi luồng login đổi.

Playwright MCP Trong VS Code Extension Của Claude Code Cho Workflow Kiểm Thử

Claude Code extension trong VS Code mang lại một số lợi thế so với dùng CLI thuần khi làm việc với Playwright MCP:

Xem diff trực quan trước khi ghi file

Khi agent đề xuất tạo/sửa file test, VS Code extension hiển thị diff ngay trong editor (giống review pull request), cho phép bạn approve/reject từng đoạn thay đổi thay vì phải đọc raw text trong terminal. Điều này đặc biệt hữu ích khi agent sinh ra file test dài hàng trăm dòng — bạn dễ dàng thấy chính xác phần nào là mới thêm.

Terminal tích hợp để chạy test ngay

Sau khi accept file test, bạn có thể yêu cầu agent chạy npx playwright test ngay trong terminal tích hợp của VS Code, và agent sẽ đọc kết quả (pass/fail, stack trace) trực tiếp từ output đó để tự sửa nếu cần — không cần bạn copy-paste log qua lại.

Theo dõi trạng thái MCP server trực quan

Panel MCP trong sidebar của extension hiển thị trạng thái kết nối (connected/error) của playwright server theo thời gian thực, giúp phát hiện sớm khi npx bị lỗi version hoặc trình duyệt chưa cài, thay vì phải chờ agent báo lỗi giữa luồng thực thi.

Workflow gợi ý trong VS Code

  1. Mở Claude Code panel, gõ prompt mô tả luồng cần test.
  2. Quan sát agent thực thi qua browser (nếu chạy headed, một cửa sổ Chromium sẽ mở lên cho bạn xem trực tiếp).
  3. Yêu cầu sinh file .spec.ts, review diff trong editor.
  4. Accept, sau đó yêu cầu agent chạy test ngay trong terminal tích hợp.
  5. Nếu fail, để agent tự đọc log lỗi và đề xuất fix — bạn review lại diff lần hai trước khi accept.

Mẹo: Bật chế độ headed (--headed hoặc để trình duyệt hiển thị mặc định) khi làm việc trong VS Code — vì bạn đang có màn hình sẵn, việc quan sát trực tiếp Chromium mở lên giúp bạn bắt lỗi selector/label sai ngay lập tức, nhanh hơn nhiều so với đọc log text.

Best Practice Cho Test Suite Playwright Do AI Sinh Ra

Test do AI sinh ra rất nhanh có, nhưng nếu không kiểm soát chất lượng, bạn sẽ có một test suite đẹp trên bề mặt nhưng flaky (không ổn định, đôi lúc pass đôi lúc fail) khi chạy trong CI. Vài nguyên tắc nên áp dụng ngay từ đầu:

Ưu tiên locator theo role/text, tránh CSS selector do agent tự đoán

Luôn chỉ định rõ trong system prompt hoặc file hướng dẫn dự án (ví dụ CLAUDE.md): "chỉ dùng getByRole, getByLabel, getByText, tránh page.locator('.class-name') trừ khi không còn cách khác". CSS class tự sinh (đặc biệt với Tailwind/CSS Modules có hash) là nguồn flaky test hàng đầu.

Bắt buộc assertion rõ ràng, tránh test "chạy hết không lỗi là pass"

Một lỗi thường gặp: agent viết test chỉ có các hành động (click, fill) mà không có expect() nào — test này "pass" ngay cả khi tính năng đã hỏng, vì không có gì để fail. Luôn review và yêu cầu agent thêm assertion cho từng outcome quan trọng.

Kiểm soát dữ liệu test (test data) tường minh

Đừng để agent "tự bịa" dữ liệu test ngẫu nhiên mỗi lần chạy — điều này khiến test không reproducible. Chỉ định rõ dùng fixture cố định hoặc factory function (ví dụ createTestUser()) có sẵn trong codebase.

Review test AI sinh như review code thật

Đưa file .spec.ts do AI sinh vào pull request bình thường, yêu cầu reviewer khác đọc qua — không có ngoại lệ "vì AI viết nên chắc đúng". Kinh nghiệm thực tế cho thấy AI rất hay viết waitForTimeout(2000) (chờ cứng theo thời gian) để "cho chắc" — đây là anti-pattern gây flaky và làm chậm CI, cần thay bằng expect(...).toBeVisible() hoặc browser_wait_for dựa trên điều kiện thực.

Tích hợp vào CI ngay khi test ổn định

Sau khi một test đã chạy pass ổn định vài lần liên tiếp (không chỉ một lần), thêm vào pipeline CI (ví dụ GitHub Actions) để chạy trên mọi pull request, tránh regression (lỗi tái phát) về sau.

Mẹo: Thêm một rule vào file cấu hình hướng dẫn của Claude Code (ví dụ CLAUDE.md ở root project): "Không dùng waitForTimeout. Luôn dùng expect với auto-retry hoặc browser_wait_for theo điều kiện cụ thể." Rule này giúp giảm đáng kể tỉ lệ flaky test do AI sinh ra theo thói quen "chờ cho chắc".

Mẹo Tổng Hợp Khi Dùng Playwright MCP Với Claude Code

Một vài lưu ý gom lại từ thực tế triển khai: luôn chạy npx playwright install trước buổi làm việc đầu tiên trên máy mới để tránh lỗi thiếu browser binary; giữ file .mcp.json trong repo (không phải chỉ cấu hình local) để cả team dùng chung; và tách rõ hai loại session — session để agent "khám phá" luồng (có thể chạy headed, tương tác nhiều) và session để "sinh test cuối cùng" (chỉ cần đọc lại kết quả khám phá và viết code, không cần mở browser lại).

Mẹo: Nếu bạn làm việc trên một luồng phức tạp nhiều bước (ví dụ checkout có 5-6 màn hình), hãy chia nhỏ thành nhiều prompt tuần tự thay vì một prompt dài mô tả toàn bộ luồng — agent xử lý từng đoạn ngắn chính xác hơn nhiều so với việc phải giữ toàn bộ ngữ cảnh (context) của một luồng dài trong một lượt gọi.