# Chạy Playwright test bằng agent skill trong Claude Code

[TestMu AI (Formerly LambdaTest)](https://homus.dev/speakers/testmu-ai-formerly-lambdatest) · [TestMu AI (Formerly LambdaTest)](https://homus.dev/orgs/testmu-ai-formerly-lambdatest)

> Vì sao agent viết Playwright test thiếu codebase context, cách một Playwright skill sửa điều đó, và demo sinh, chạy test local và trên cloud bằng Claude Code.

Topics: Skills, Coding Agents, Dev Tools

Canonical: https://homus.dev/talks/how-to-run-playwright-tests-with-agent-skills-using-claude-code

## 1. Viết code không khó, thiếu codebase context mới khó

Video mở đầu bằng một nhận xét: các AI coding agent ngày nay có thể sinh ra Playwright test chỉ trong vài giây. Cái khó không nằm ở chỗ sinh code. Cái khó là codebase context, tức ngữ cảnh về chính codebase của bạn.

![Người dẫn của kênh TestMu AI nói trước camera, bên cạnh micro và laptop](https://homus.dev/photos/UgLvBrjP7Ng-0008.jpg)

Người dẫn của kênh TestMu AI ngồi trước micro, giới thiệu vấn đề: agent sinh test rất nhanh, nhưng không biết gì về repo của bạn.

Không có codebase context, agent hoàn toàn không biết các quy ước (convention) trong repo của bạn. Nó không biết team bạn theo locator strategy nào, không biết authentication được implement ra sao, không biết đã có sẵn những shared helper hay fixture nào, và cũng không biết phần Playwright testing của bạn được tổ chức như thế nào.

Kết quả là agent quay về sinh ra những implementation có thể pass hôm nay, nhưng ngày càng khó maintain khi codebase thay đổi theo thời gian. Trên màn hình, câu này hiện thành dòng chữ "Implementations that may pass today", và từng câu hỏi như "Which helpers or fixtures already exist" lần lượt hiện lên.

## 2. Một login test trông đúng, và lỗi đầu tiên: hard-coded timeout

Để minh họa, người dẫn kể đã nhờ agent của Claude Code sinh một Playwright login test. Thoạt nhìn, test này trông hoàn toàn đúng. Nó dùng các Playwright API hợp lệ, cú pháp đúng, và thậm chí có thể pass ngay lần chạy đầu tiên. Nhưng nhìn kỹ hơn một chút thì có ba vấn đề.

![File login.spec.ts do agent sinh ra, dùng page.fill, page.click và waitForTimeout(3000)](https://homus.dev/photos/UgLvBrjP7Ng-0043.jpg)

Slide "At first glance, the generated test looked correct": file `login.spec.ts` điền email, password bằng CSS selector `#email`, `#password`, bấm `button[type=submit]`, rồi gọi `page.waitForTimeout(3000)` trước khi kiểm tra `.dashboard` hiển thị.

Vấn đề thứ nhất là hard-coded timeout. Thay vì chờ ứng dụng đạt tới trạng thái mong đợi, test dừng hẳn 3 giây rồi mới chạy tiếp. Đây là một anti-pattern trong Playwright. Hard-coded timeout làm test phụ thuộc vào thời gian trôi qua, chứ không phụ thuộc vào trạng thái thật của ứng dụng.

Hệ quả có hai chiều. Nếu trang cần lâu hơn dự kiến mới sẵn sàng, test trở nên flaky. Còn nếu trang đã sẵn sàng từ trước, mỗi lần chạy vẫn phải chờ đủ 3 giây, làm tăng thời gian chạy cả ở máy local lẫn trong CI pipeline. Slide lúc này ghi: "Multiplied across your suite, every run pays for it", nghĩa là nhân lên cho cả bộ test thì lần chạy nào cũng phải trả cái giá đó.

## 3. Lỗi thứ hai: CSS locator thay vì user-facing locator

Vấn đề thứ hai là locator strategy. Agent sinh ra một CSS locator. Mà CSS selector là chi tiết implementation. Chúng thường xuyên bị đổi khi refactor UI, khi component thay đổi, hay khi redesign giao diện, dù hành vi của ứng dụng không hề đổi. Khi điều đó xảy ra, locator bị vỡ, trong khi người dùng vẫn tương tác với ứng dụng bình thường.

Đó là lý do tài liệu Playwright khuyên dùng các user-facing locator như `getByRole`, `getByLabel` và `getByPlaceholder` (xem [trang Locators](https://playwright.dev/docs/locators) và [Best Practices](https://playwright.dev/docs/best-practices) của Playwright). Slide "What the docs recommend: User-facing locators" giới thiệu từng locator, bắt đầu với `getByRole` kèm chú thích "role + accessible name".

![Sơ đồ accessibility tree: document, form tên Login, button tên Submit nối tới nút Submit trên trang](https://homus.dev/photos/UgLvBrjP7Ng-0207.jpg)

Slide "Through the accessibility tree": cây gồm `document`, `form` có name "Login" và `button` có name "Submit", nối tới nút Submit trên trang `app.local/login`, kèm dòng "the same way a person finds it".

Các locator này xác định phần tử thông qua accessibility tree thay vì qua chi tiết implementation, tức là tìm phần tử theo cách một người dùng thật tìm thấy nó. Nhờ vậy chúng ổn định hơn đáng kể theo thời gian.

## 4. Lỗi thứ ba: lặp code, và vì sao đây không phải lỗi của Playwright hay model

Vấn đề thứ ba là code duplication. Thay vì dùng lại authentication helper đã có sẵn, agent viết lại toàn bộ authentication flow ngay bên trong test. Giờ cùng một logic xác thực nằm ở nhiều file test khác nhau. Lần tới khi authentication flow thay đổi, từng bản sao phải được sửa riêng lẻ, thay vì chỉ cần maintain một shared helper duy nhất.

![Đoạn generic.spec.ts với locator .submit, waitForTimeout(3000) và ghi chú auth written inline](https://homus.dev/photos/UgLvBrjP7Ng-0322.jpg)

Slide tóm ba lỗi trong một file `generic.spec.ts`: `page.locator('.submit').click()`, `page.waitForTimeout(3000)` và chú thích "auth written inline", tất cả "synthesised from general knowledge", tức được tổng hợp từ kiến thức chung.

Người dẫn nhấn mạnh: không vấn đề nào trong ba vấn đề này là giới hạn của Playwright. Cũng không vấn đề nào là giới hạn của language model. Agent chỉ đơn giản là sinh test mà không có codebase context cần thiết để làm theo convention của team bạn. Slide chốt lại: "The agent was only missing codebase context".

Và đây chính là thứ một Playwright skill mang lại.

## 5. Playwright skill là gì: hai locator, một nút bấm

Một Playwright skill là một file `SKILL.md` mà Claude Code nạp vào context của agent trước khi agent bắt đầu sinh code. Model vốn đã hiểu Playwright API và các automation pattern phổ biến. Điều nó không biết là team bạn áp dụng Playwright như thế nào trong codebase của mình. Skill cung cấp đúng phần ngữ cảnh còn thiếu đó.

Skill ghi lại các convention của codebase, bao gồm: locator strategy được ưu tiên, authentication flow, các assertion pattern, cấu trúc repo, các shared helper, quy ước đặt tên, và các implementation pattern được khuyến nghị. Như vậy, thay vì tổng hợp ra một Playwright test chung chung, agent sinh ra test tuân theo những convention đã được thiết lập sẵn trong repo của bạn.

Người dẫn đưa một ví dụ đơn giản. Hai locator cùng xác định một nút bấm, và cả hai đều có thể pass hôm nay. Khác biệt nằm ở chỗ mỗi locator phụ thuộc vào cái gì.

![Hai locator cùng trỏ vào nút Submit: page.locator('.btn-primary') và page.getByRole('button', { name: 'Submit' })](https://homus.dev/photos/UgLvBrjP7Ng-0343.jpg)

Slide "Two locators, one button": bên trái `page.locator('.btn-primary')` với nhãn "depends on a CSS class", bên phải `page.getByRole('button', { name: 'Submit' })` với nhãn "depends on role + name", cả hai cùng trỏ vào nút Submit trên trang `app.local/checkout`.

Locator thứ nhất phụ thuộc vào một CSS class. CSS class là chi tiết implementation, có thể đổi khi refactor mà hành vi ứng dụng không đổi. Khi chuyện đó xảy ra, locator thất bại dù nút bấm vẫn còn đó và vẫn hoạt động đầy đủ. Locator thứ hai nhắm vào phần tử theo ARIA role và accessible name. Các thuộc tính này mô tả giao diện từ góc nhìn của người dùng chứ không phải từ cách implement, nên locator bền hơn hẳn trước các thay đổi UI.

Đó là mục đích của Playwright skill. Nó không thay đổi model, nó thay đổi codebase context mà agent có trong tay trước khi sinh code. Nhờ vậy test được sinh ra khớp với automation architecture hiện có của bạn, thay vì dựa vào các mặc định chung chung (slide ghi "So the generated test aligns with" kiến trúc sẵn có).

## 6. Bên trong repo agent skills: SKILL.md, reference, scripts, templates

Người dẫn giới thiệu: các nền tảng agentic quality engineering như TestMu AI duy trì một repo mã nguồn mở chứa agent skill cho hơn 45 automation framework và developer tool, gồm Playwright, Selenium, Cypress, Appium và nhiều cái khác (repo [LambdaTest/agent-skills](https://github.com/LambdaTest/agent-skills/tree/main/playwright-skill)). Trong thư mục của một skill, mỗi thư mục con có một mục đích riêng.

![Cây thư mục playwright-skill với SKILL.md, reference, scripts, templates và bản xem trước SKILL.md](https://homus.dev/photos/UgLvBrjP7Ng-0445.jpg)

Slide "01 of 04": thư mục `playwright-skill` gồm `SKILL.md` (đang được chọn, ghi chú "the entry point"), `reference/`, `scripts/`, `templates/`; khung preview cho thấy SKILL.md có tiêu đề "Playwright conventions", mục Locators ghi "Prefer getByRole." và mục Auth.

- **`SKILL.md`** là entry point. Nó chứa các chỉ dẫn mà Claude Code nạp vào context của agent trước khi bắt đầu sinh code. Những chỉ dẫn này định nghĩa các convention của codebase mà test sinh ra phải tuân theo.

- **`reference/`** chứa các implementation pattern được khuyến nghị cho Playwright: locator strategy, authentication pattern, assertion, cloud execution và các hướng dẫn riêng của framework, để agent tham khảo trong lúc sinh test.

- **`scripts/`** chứa các setup script và tiện ích troubleshooting cho những workflow phát triển thường gặp. Thay vì bắt agent tự nghĩ ra shell command từ đầu, nó dùng lại các script đã được kiểm chứng có sẵn trong repo.

- **`templates/`** chứa các file khởi đầu sẵn sàng cho production. Thay vì tổng hợp mọi file từ con số không, agent có thể điều chỉnh các template này, để code sinh ra theo cùng cấu trúc và pattern với phần còn lại của repo.

Gộp lại, các thư mục này cho agent đủ codebase context để sinh Playwright test nhất quán, dễ maintain, và khớp với automation framework hiện có của team.

## 7. Demo bước 1 và 2: cài skill, rồi prompt agent trong Claude Code

Tiếp theo là phần demo cách sinh và chạy Playwright test bằng agent skill với Claude Code. Người dẫn dùng Visual Studio Code làm IDE.

Bước đầu tiên: mở VS Code với project Playwright skill đã được nạp, project này hiện trong mục Recent của màn hình Welcome. Mở terminal tích hợp, gõ lệnh cài đặt rồi nhấn Enter. Lệnh trên màn hình là:

```
npx agentskillsforall add https://github.com/LambdaTest/agent-skills.git --skill playwright-skill
```

Trong lúc cài, sẽ có vài lựa chọn hiện trên màn hình; chọn các tùy chọn phù hợp rồi nhấn Enter để tiếp tục.

![VS Code với terminal vừa chạy lệnh npx agentskillsforall, liệt kê các đường dẫn playwright-skill và dòng Done](https://homus.dev/photos/UgLvBrjP7Ng-0623.jpg)

Bước "Install the skill": terminal PowerShell trong VS Code chạy lệnh `npx agentskillsforall add ... --skill playwright-skill`, liệt kê nhiều đích cài `~\.agents\skills\playwright-skill` và kết thúc bằng "Done! Review skills before use; they run with full agent permissions." Bên phải màn hình Welcome có mục "Get started with Claude Code".

Bước thứ hai: mở panel agent của Claude Code, nhập prompt sau rồi nhấn Enter.

```
Generate a Playwright test that navigates to the TestMu AI Selenium Playground and clicks the Simple Form Demo option.
```

Agent bắt đầu phân tích repo để hiểu Playwright configuration và cách project được thiết lập. Trong quá trình đó, nó đọc các file như `lambdatest-setup` và cấu hình Playwright. Ở bước này người dùng không cần làm gì cả, chỉ chờ agent làm xong.

![Panel Claude Code trong VS Code: agent chạy Glob playwright-skill và Read SKILL.md sau khi nhận prompt](https://homus.dev/photos/UgLvBrjP7Ng-0643.jpg)

Bước "Prompt the agent": sau prompt, agent ghi "I'll check the playwright-skill in your workspace to follow its conventions", chạy `Glob` với pattern `playwright-skill/**/*` (tìm thấy 14 file) rồi `Read` file `SKILL.md`. Explorer bên trái cho thấy thư mục `scripts` có `scaffold-project.sh` và `validate-config.py`.

## 8. Demo bước 3: đọc test vừa sinh và chạy local

Khi agent sinh code xong, một file mới tên `simple-form-demo` tự động mở ra. Người dẫn chuyển sang file đó để đọc lại code được sinh.

![File simple-form-demo.spec.ts trong VS Code, import từ ../lambdatest-setup và chia thành ba test.step](https://homus.dev/photos/UgLvBrjP7Ng-0703.jpg)

Bước "Review the generated test": file `tests/simple-form-demo.spec.ts` import từ `../lambdatest-setup`, chia thành ba `test.step` và dùng `getByRole` cho heading và link. Panel agent ghi rằng đã có sẵn các file liên quan và nó đọc chúng để khớp convention.

Có mấy điểm đáng chú ý: test import từ `lambdatest-setup` thay vì trực tiếp từ `@playwright/test`, tổ chức workflow bằng các khối `test.step`, và điều hướng trong ứng dụng bằng `page.goto`. Đó đều là các phần của Playwright test vừa được sinh. Nội dung file trên màn hình:

```
import { test, expect } from '../lambdatest-setup';

test('navigate to Selenium Playground and open Simple Form Demo', async ({ page }) => {
await test.step('Open the TestMu AI Selenium Playground', async () => {
await page.goto('https://www.testmuai.com/selenium-playground');
await expect(page.getByRole('heading', { name: 'Selenium Playground' })).toBeVisible();
});

await test.step('Click the Simple Form Demo option', async () => {
await page.getByRole('link', { name: 'Simple Form Demo' }).click();
});

await test.step('Verify the Simple Form Demo page loaded', async () => {
await expect(page).toHaveURL(/simple-form-demo/);
await expect(page.getByRole('heading', { name: 'Simple Form Demo' })).toBeVisible();
});
});
```

Bước thứ ba là chạy test. Bấm vào trong terminal, chạy lệnh sau và nhấn Enter:

```
npx playwright test simple-form-demo
```

Playwright test runner bắt đầu chạy bộ test. Người dẫn bảo hãy xác nhận terminal hiển thị dòng "Running 4 tests using 4 workers", rồi chờ chạy xong. Khi kết thúc, kiểm tra phần tóm tắt báo 4 passed, xác nhận mọi test đều hoàn thành thành công.

![Terminal báo 4 passed và panel agent gợi ý hai lệnh chạy local và chạy cloud](https://homus.dev/photos/UgLvBrjP7Ng-0743.jpg)

Kết quả chạy local: terminal báo "4 passed (30.2s)", trong đó có dòng chạy trên `[chromium]` và dòng chạy trên `[@lambdatest]`. Phía trên, agent giải thích test làm gì (Navigates, Clicks, Verifies) và gợi ý sẵn hai lệnh chạy, một cho local browsers và một cho cloud.

## 9. Chạy cùng test trên cloud và xem lại phiên chạy

Bây giờ chạy chính test đó trên automation cloud của TestMu AI. Trước khi bắt đầu, cần có tài khoản TestMu AI và đã cấu hình thông tin xác thực bằng cách đặt username và access key. Câu trả lời của agent trên màn hình ghi rõ lệnh cloud cần `LT_USERNAME` / `LT_ACCESS_KEY`.

Vẫn dùng terminal cũ. Người dẫn chỉ ra rằng agent của Claude Code đã sinh sẵn lệnh cần thiết để chạy test trên cloud grid của TestMu AI. Chạy lệnh sau và nhấn Enter:

```
npx playwright test --project="chrome:latest:Windows 11@lambdatest"
```

Playwright test runner kết nối tới cloud grid của TestMu AI và bắt đầu chạy. Xác nhận terminal hiển thị "Running 1 test using 1 worker", rồi chờ chạy xong.

![Terminal chạy lệnh npx playwright test với project chrome latest Windows 11 trên lambdatest, báo Running 1 test using 1 worker](https://homus.dev/photos/UgLvBrjP7Ng-0803.jpg)

Bước "Run it on the cloud": sau lần chạy local, terminal chạy lệnh có `--project="chrome:latest:Windows 11@lambdatest"` và báo "Running 1 test using 1 worker", test đang chạy trên cấu hình Windows 11.

Tiếp theo, chuyển sang trình duyệt và mở web automation dashboard của TestMu AI. Trang Builds liệt kê các build theo ngày; bấm vào build vừa chạy.

Ở trang chi tiết test có video replay của lần chạy. Bấm play để xem lại toàn bộ phiên trình duyệt từ đầu tới cuối. Có thể mở rộng panel commands: panel này hiển thị toàn bộ execution timeline của test, tức bảng phân tích từng bước cho mọi thao tác đã thực hiện trong lúc chạy test trên TestMu AI Cloud.

![Trang chi tiết test trên dashboard TestMu AI: trạng thái Passed, danh sách 13 commands và khung video](https://homus.dev/photos/UgLvBrjP7Ng-0823.jpg)

Bước "Review the run": test "navigate to Selenium Playground and open Simple Form Demo" ở trạng thái Passed, mất 6s trên Chrome 149.0, Windows 11, 1920x1080. Cột "All Commands" liệt kê 13 lệnh (Browser Session Started, New Page, Navigate to URL, expect, Click, Page closed...), bên phải là khung Video để xem lại.

Video kết lại: đó là cách sinh và chạy Playwright test bằng agent skill. Bằng cách đưa trước cho agent các convention của codebase, bạn có thể sinh ra test khớp với automation framework hiện có, rồi chạy chúng ở local hoặc trên TestMu AI Cloud với rất ít thao tác thủ công. Phần mô tả video có một lời mời đăng ký dùng thử TestMu AI.

## Nguồn và liên kết

- Tên gốc: How to Run Playwright Tests with Agent Skills Using Claude Code
- Sự kiện: [YouTube](https://homus.dev/events/youtube)
- Video gốc: [https://www.youtube.com/watch?v=UgLvBrjP7Ng](https://www.youtube.com/watch?v=UgLvBrjP7Ng)

- Kênh YouTube TestMu AI (Formerly LambdaTest) (TestMu AI): [youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw](https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw)

- Playwright skill trong repo agent skills mã nguồn mở của TestMu AI (README của repo có lệnh `npx agentskillsforall add ... --skill playwright-skill`): [github.com/LambdaTest/agent-skills/tree/main/playwright-skill](https://github.com/LambdaTest/agent-skills/tree/main/playwright-skill)

- Tài liệu TestMu AI về chạy Playwright test bằng agent skill: [testmuai.com/support/docs/playwright-agent-skills](https://www.testmuai.com/support/docs/playwright-agent-skills/)

- Playwright, trang Locators (getByRole, getByLabel, getByPlaceholder): [playwright.dev/docs/locators](https://playwright.dev/docs/locators)

- Playwright, Best Practices: [playwright.dev/docs/best-practices](https://playwright.dev/docs/best-practices)

- Tài liệu Claude Code về skill và file SKILL.md: [code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills)

Nguồn: https://homus.dev/talks/how-to-run-playwright-tests-with-agent-skills-using-claude-code · cập nhật 2026-10-16
