還在手動測試?Playwright Skill 讓你解放雙手
整理版優先睇
想用AI幫手寫Playwright測試?先分清Skill類型、先偵察再斷言,先等服務就緒先落selector,呢啲順序比乜都重要。
呢篇文章係一位熟悉Playwright同AI工具嘅技術人寫嘅,佢發現好多人用Agent寫Playwright測試嗰陣成日撞板:測例一跑全紅、selector寫死喺未加載完嘅DOM上、本地偶爾綠但CI常紅。作者想解決嘅問題係:點樣用Playwright相關Skill少踩坑,將測試寫得穩定同可靠。佢嘅結論係:與其堆「幫我認真測」呢類空泛prompt,不如喺prompt裏面指明用邊條Skill、要乜產物、同埋操作順序——服務就緒→頁面穩定→睇清DOM→先斷言→跑綠先交差。
文章分享咗五個真實痛點:冇等服務就跑斷言、服務未起或端口錯、Agent過早生成測例代碼、Selector太脆、同埋將巨大腳本讀入上下文。每個痛點都畀咗具體解法同話術範例,例如對SPA要用networkidle、用with_server.py管服務生命週期、先MCP逐步操作再生成TypeScript測例、優先role/accessible name做selector。最後仲提供咗12條實用技巧同四類話術模板,涵蓋本地冒煙、沉澱CI測例、調試紅燈同糾偏對話。
- 分清楚webapp-testing同playwright-generate-test兩條Skill:前者出Python腳本做本地冒煙,後者出TypeScript測例入CI。
- 對SPA動態頁面一定要先wait_for_load_state('networkidle')再截圖睇DOM,唔好一goto就寫selector。
- 用with_server.py管服務生命週期,唔好假設用戶已經起咗dev server;端口要喺prompt寫死。
- 用playwright-generate-test時要先MCP逐步操作瀏覽器,唔好跳過步驟直接生成spec文件。
- Selector優先級:get_by_role / get_by_label > get_by_test_id > CSS / nth-child,禁止nth-child鏈。
webapp-testing(Anthropic Skills)
Playwright相關Skill嘅GitHub倉庫,包含with_server.py等工具
Playwright官方文檔
包含locator、trace、CI配置等完整說明
安裝命令
npx skills add anthropics/skills@webapp-testing -y -g
先分清用邊條Skill
生態裏同Playwright相關嘅入口最少有兩條,唔好用錯。Skill文檔寫得好清楚,但好多人撈亂咗。
如果你想要<span class="highlight_inline">.spec.ts</span>入倉庫,唔好講「幫我測一下登錄頁」——Agent可能會寫段Python腳本跑完就掉。正確講法係:用playwright-generate-test,先通過Playwright MCP逐步行完場景,再生成tests/下面嘅TypeScript測例並跑到通過。用webapp-testing嘅話,就寫Python腳本驗證localhost某流程,需要時起dev server。
- webapp-testing: Python腳本,一次性自動化,配合with_server.py
- playwright-generate-test: TypeScript測例,需MCP逐步操作,適合CI
重點:一開頭就要講清楚用邊條Skill,唔好畀Agent自己估。
先偵察再斷言:等服務就緒先落selector
SPA(Vue/React)首屏大量靠JS渲染,如果一goto就寫locator,好易揀到仲未存在嘅元素。Skill文檔寫得好直白:動態頁面先networkidle,再睇DOM。
你可以同Agent講:「呢個係Vite SPA,goto之後必須wait_for_load_state('networkidle'),先截圖確認元素再寫click,唔好亂估id。」靜態HTML可以直接讀文件揀selector;一碰路由、接口、懶加載,就當動態站處理。
- 1 page.goto('http://localhost:5173')
- 2 page.wait_for_load_state('networkidle')
- 3 page.screenshot(path='/tmp/recon.png', full_page=True)
- 4 page.get_by_role('button', name='登錄').click()
仲有一個常見錯:唔等服務就斷言。一定要先確保服務起咗、頁面加載完。
服務管理:唔好假設用戶已經起咗dev server
webapp-testing提供with_server.py管生命週期。你唔可以假設「用戶已經npm run dev咗」,除非喺prompt裏面寫明。
python scripts/with_server.py --help
python scripts/with_server.py \
--server "npm run dev" --port 5173 \
-- python your_check.py
# 前後端分離
python scripts/with_server.py \
--server "cd api && python app.py" --port 3000 \
--server "cd web && npm run dev" --port 5173 \
-- python your_check.py
你可以同Agent講:「前端未起。用webapp-testing嘅with_server.py喺5173起npm run dev,腳本裏面只寫Playwright邏輯,端口寫死5173。」
記住:with_server.py可能好大,唔好read源碼,直接--help黑盒調用就得。
生成測例嘅正確流程:先MCP逐步行,唔好跳步
playwright-generate-test明確要求:唔好得個場景就寫代碼;先用MCP一步一步操作瀏覽器,最後再根據操作歷史生成TypeScript。
- 1 你描述場景,例如「已登錄用戶進入設置頁改暱稱」
- 2 Agent用MCP逐步行:navigate / fill / click
- 3 每步確認頁面狀態(截圖或snapshot)
- 4 生成tests/xxx.spec.ts
- 5 執行測例,失敗就改到通過
你可以同Agent講:「唔好先貼一版spec。按playwright-generate-test:先用MCP行完整條路徑,再生成測試文件,保存到tests/,行npx playwright test直到通過。」呢個係專治「睇落似對、一跑就死」嘅最有效約束。
如果Agent一嚟就寫代碼,你要立即叫停:「停。未用MCP操作瀏覽器。按playwright-generate-test先逐步執行場景,禁止先輸出spec文件。」
Selector優先級同實用技巧
Agent好中意寫#root > div:nth-child(3) > button呢類selector,本地DOM變少少就死。所以要喺prompt裏面定好優先級。
你可以同Agent講:「優先role同accessible name,禁止nth-child鏈。對動態列表用get_by_role('row').filter(has_text='xxx')。」
- 點名Skill + 產物:要.spec.ts就講playwright-generate-test;要臨時腳本就講webapp-testing
- 聲明棧:Vite/Next/純靜態HTML,決定使唔使networkidle
- 聲明端口同環境變量:BASE_URL=http://localhost:5173
- 先偵察再斷言:要求先screenshot或page.content()再寫locator
- 登錄態寫清楚:用storageState、fixture定係每測例UI登錄
- 一條測例一個意圖:拆file或拆test(),唔好塞80行巨測
- 要求跑通先交貨:npx playwright test path/to.spec.ts綠咗先算
- CI參數分開講:headless、workers=1、retries
呢12條技巧可以直接複製入prompt,特別係「一條測例一個意圖」同「用storageState處理登錄態」。
Playwright Skill 使用技巧:少寫廢測,先把頁面摸清楚

用 Agent 寫 Playwright 測試,常見結果不是「一次通過」,而是:測例生成了,一跑全紅;或者 selector 寫死在還沒加載完的 DOM 上,本地偶爾綠、CI 常紅。
這篇只談怎麼用 Playwright 相關 Skill 少踩坑。不吹「AI 一鍵全覆蓋」,只說真實場景裏管用的說法和順序。
一、先分清你在用哪條 Skill
生態裏和 Playwright 相關的入口至少兩條,別混用預期:
| webapp-testing | sync_playwright,配合 with_server.py 起服務 | |
| playwright-generate-test | @playwright/test,需先走 MCP 逐步操作 |
痛點: 想要 .spec.ts 進倉庫,卻只說「幫我測一下登錄頁」——Agent 可能寫一段 Python 腳本跑完就扔,並不落盤測例。
說法:
用 playwright-generate-test:
先通過 Playwright MCP 逐步走完場景,再生成 tests/ 下的 TypeScript 測例並跑到通過。
用 webapp-testing:
寫 Python 腳本驗證 http://localhost:5173 某流程,需要時起 dev server。
二、真實痛點 1:沒等服務就跑斷言
SPA(Vue / React)首屏大量靠 JS 渲染。Skill 文檔裏寫得很直白:動態頁面先 networkidle,再查 DOM。
錯誤順序
page.goto(url)
button = page.locator('#submit') # 可能還不存在
button.click()
推薦順序(偵察 → 再動手)
page.goto('http://localhost:5173')
page.wait_for_load_state('networkidle')
page.screenshot(path='/tmp/recon.png', full_page=True)
# 看過再寫 locator
page.get_by_role('button', name='登錄').click()
你對 Agent 說:
這是 Vite SPA,goto 之後必須 wait_for_load_state('networkidle'),
先截圖確認元素再寫 click,不要猜 id。
靜態 HTML 可以直接讀文件找 selector;一碰路由、接口、懶加載,就當動態站處理。
三、真實痛點 2:服務沒起或端口錯了
webapp-testing 提供 with_server.py 管生命週期。別假設「用戶已經 npm run dev 了」,除非你在 prompt 裏寫明。
起服務 + 跑腳本(先 --help):
python scripts/with_server.py --help
python scripts/with_server.py \
--server "npm run dev" --port 5173 \
-- python your_check.py
前後端分離要兩個 --server:
python scripts/with_server.py \
--server "cd api && python app.py" --port 3000 \
--server "cd web && npm run dev" --port 5173 \
-- python your_check.py
你對 Agent 說:
前端還沒啓動。用 webapp-testing 的 with_server.py 在 5173 起 npm run dev,
腳本里只寫 Playwright 邏輯,端口寫死 5173。
四、真實痛點 3:Agent 過早生成測例代碼
playwright-generate-test 明確要求:不要只有場景就寫代碼;先用 MCP 一步一步操作瀏覽器,最後再根據操作歷史生成 TypeScript。
推薦流程
你描述場景(例如:「已登錄用戶進入設置頁改暱稱」) Agent 用 MCP 逐步 navigate / fill / click 每步確認頁面狀態(截圖或 snapshot) 生成 tests/xxx.spec.ts執行測例,失敗就改到綠為止
你對 Agent 說:
不要先貼一版 spec。按 playwright-generate-test:
先用 MCP 走完完整路徑,再生成測試文件,保存到 tests/,運行 npx playwright test 直到通過。
這是專治「看起來對、一跑就掛」的最有效約束。
五、真實痛點 4:Selector 脆、CI 才炸
Agent 愛寫 #root > div:nth-child(3) > button。本地 DOM 變一點就掛。
優先級(寫進 prompt)
get_by_role('button', name='保存')get_by_label('郵箱')get_by_test_id('save-profile')(需項目有 data-testid)CSS / nth-child — 僅作最後手段
你對 Agent 說:
優先 role 和 accessible name,禁止 nth-child 鏈。
對動態列表用 get_by_role('row').filter(has_text='xxx')。
六、真實痛點 5:把巨大腳本讀進上下文
webapp-testing 的 with_server.py 可能很大。Skill 原話:先 --help 黑盒調用,非必要不讀源碼,否則污染上下文、還容易改壞。
你對 Agent 說:
運行 scripts/with_server.py --help 按說明調用,不要 read 整個腳本內容。
七、12 條實用技巧(可直接複製)
點名 Skill + 產出物:要 .spec.ts就說playwright-generate-test;要臨時腳本就說webapp-testing。聲明棧:Vite / Next / 純靜態 HTML,決定要不要 networkidle。聲明端口和環境變量: BASE_URL=http://localhost:5173,避免寫死錯端口。先偵察再斷言:要求先 screenshot或page.content()再寫 locator。登錄態寫清楚:用 storageState、fixture,還是每測例 UI 登錄——別留給 Agent 猜。 一條測例一個意圖:「登錄成功」和「修改資料」拆文件或拆 test(),別塞一個 80 行巨測。要求跑通再交付: npx playwright test path/to.spec.ts綠了才算完。CI 參數單獨說:headless、workers=1、retries——本地和 CI 不一致是常見紅線來源。 **等穩定元素,別 wait_for_timeout(3000)**:優先wait_for_selector/expect(locator).toBeVisible()。失敗保留證據: trace: 'on-first-retry'、失敗截圖路徑寫進 Skill 約束。別測第三方:支付、驗證碼、外網 CDN——mock 或跳過,寫在場景裏。 測例和數據隔離:用隨機郵箱前綴,避免並行跑時撞庫。
八、四類話術模板
A. 本地冒煙(Python)
用 webapp-testing:
- with_server.py 起 npm run dev,端口 5173
- 打開首頁,networkidle 後確認標題含「控制枱」
- 截圖為 /tmp/home.png
- 不要生成 TypeScript 測例
B. 沉澱 CI 測例(TypeScript)
用 playwright-generate-test:
場景:未登錄訪問 /settings 應跳轉登錄頁
MCP 逐步操作 → 生成 tests/settings-guard.spec.ts → 跑到通過
C. 調試已有紅燈
tests/login.spec.ts 在 CI 失敗,本地通過。
先 trace 分析,懷疑 race condition。
加強等待:expect(loginButton).toBeEnabled() 後再 click,不要加固定 sleep。
D. 糾偏(Agent 一上來就寫代碼)
停。還沒用 MCP 操作瀏覽器。按 playwright-generate-test 先逐步執行場景,禁止先輸出 spec 文件。
九、使用中的踩坑
十、三個短示例
示例 1:註冊表單
webapp-testing,5173 起 dev。
打開 /register,networkidle 後填寫郵箱和密碼,點註冊,
expect 頁面出現「驗證郵件已發送」。截圖留存。
示例 2:管理後台權限
playwright-generate-test:
普通用戶訪問 /admin 應 403 或跳轉。
MCP 走一遍 → tests/admin-guard.spec.ts → playwright test 通過。
示例 3:接口 + 頁面對照
webapp-testing,雙 server:api:3000 + web:5173。
頁面點「刷新列表」後,expect 表格第一行包含 mock 數據裏的訂單號 ORD-001。
寫在最後
Playwright Skill 的價值不是「少寫代碼」,而是 逼 Agent 按正確順序幹活:服務就緒 → 頁面穩定 → 看清 DOM → 再斷言 → 跑綠再交差。
你只要在 prompt 裏把 用哪個 Skill、要什麼產物、要不要先 MCP 說清楚,比堆「幫我認真測」有效得多。
覺得有用可以收藏;你遇到過最煩的 flaky 場景是什麼,留言區說說。
附錄
# 安裝(示例座標以 npx skills find 為準)
npx skills find playwright
npx skills add anthropics/skills@webapp-testing -y -g
# 本地跑生成的 TS 測例
npx playwright test tests/xxx.spec.ts
npx playwright test --ui # 調試
參考
ebapp-testing(Anthropic Skills)
https://github.com/anthropics/skills/tree/main/skills/webapp-testing
Playwright 官方文檔 — locator、trace、CI 配置
https://playwright.dev/docs/intro