Skip to content

Webapp Testing Skill 详解

使用 Playwright 测试本地 Web 应用

基本信息

属性
名称webapp-testing
类别开发工具
输出格式测试结果 / 截图
许可证Apache 2.0
yaml
name: webapp-testing
description: Toolkit for interacting with and testing local web applications
using Playwright. Supports verifying frontend functionality, debugging UI
behavior, capturing browser screenshots, and viewing browser logs.

1. 核心概念

1.1 Playwright 简介

通俗比喻:Playwright 就像一个"机器人浏览器操作员"——它可以自动化打开网页、点击按钮、填写表单、截图等操作,就像真人在操作浏览器一样。

1.2 辅助脚本

markdown
**可用脚本**
- `scripts/with_server.py` - 管理服务器生命周期(支持多服务器)

**重要**:始终先运行脚本的 --help 查看用法
不要先读取源码——这些脚本是作为黑盒工具使用的

2. 决策树

mermaid
graph TD
    A[用户任务] --> B{是静态 HTML?}
    B -->|是| C[直接读取 HTML 识别选择器]
    B -->|否| D{服务器已运行?}

    C --> C1[成功] --> C2[使用选择器编写 Playwright 脚本]
    C --> C3[失败/不完整] --> D

    D -->|否| E[运行 with_server.py --help]
    D -->|是| F[侦察后操作模式]

    E --> E1[使用辅助脚本 + 简化 Playwright 脚本]
    F --> F1[导航并等待 networkidle]
    F1 --> F2[截图或检查 DOM]
    F2 --> F3[从渲染状态识别选择器]
    F3 --> F4[使用发现的选择器执行操作]

3. 使用 with_server.py

3.1 查看帮助

bash
python scripts/with_server.py --help

3.2 单服务器

bash
python scripts/with_server.py \
  --server "npm run dev" \
  --port 5173 \
  -- python your_automation.py

3.3 多服务器(后端 + 前端)

bash
python scripts/with_server.py \
  --server "cd backend && python server.py" --port 3000 \
  --server "cd frontend && npm run dev" --port 5173 \
  -- python your_automation.py

4. Playwright 脚本编写

4.1 基本模板

python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)  # 始终使用 headless 模式
    page = browser.new_page()
    page.goto('http://localhost:5173')
    page.wait_for_load_state('networkidle')  # 关键:等待 JS 执行完成

    # ... 你的自动化逻辑

    browser.close()

4.2 关键注意事项

markdown
**常见陷阱**

❌ 不要在动态应用上等待 networkidle 之前检查 DOM
✅ 始终先等待 page.wait_for_load_state('networkidle')

5. 侦察后操作模式

5.1 步骤1:检查渲染的 DOM

python
# 截图
page.screenshot(path='/tmp/inspect.png', full_page=True)

# 获取页面内容
content = page.content()

# 查找所有按钮
buttons = page.locator('button').all()

5.2 步骤2:从检查结果识别选择器

分析截图或 DOM 内容,确定正确的选择器。

5.3 步骤3:使用发现的选择器执行操作

python
# 使用识别的选择器执行操作
page.locator('button:has-text("Submit")').click()
page.locator('#email').fill('test@example.com')

6. 常用操作

6.1 元素交互

python
# 点击
page.locator('button').click()
page.locator('text=Submit').click()

# 填写表单
page.locator('#username').fill('user123')
page.locator('input[type="password"]').fill('secret')

# 选择下拉选项
page.locator('select#country').select_option('china')

# 复选框
page.locator('input[type="checkbox"]').check()
page.locator('input[type="checkbox"]').uncheck()

6.2 等待操作

python
# 等待特定元素
page.wait_for_selector('.loading-complete')

# 等待固定时间(不推荐,仅用于调试)
page.wait_for_timeout(1000)  # 1 秒

# 等待页面状态
page.wait_for_load_state('networkidle')
page.wait_for_load_state('domcontentloaded')

6.3 截图和调试

python
# 截图
page.screenshot(path='screenshot.png')
page.screenshot(path='full.png', full_page=True)

# 获取元素截图
page.locator('.header').screenshot(path='header.png')

7. 选择器类型

7.1 推荐的选择器

python
# 文本内容
page.locator('text=Click me')
page.locator(':has-text("Welcome")')

# 角色
page.locator('role=button')
page.locator('role=textbox')

# CSS 选择器
page.locator('.class-name')
page.locator('#element-id')
page.locator('button.primary')

# 组合选择器
page.locator('form >> input[type="email"]')

7.2 最佳实践

markdown
- 使用描述性选择器:`text=`, `role=`, CSS 选择器, 或 ID
- 添加适当的等待:`page.wait_for_selector()` 或超时

8. 示例脚本

8.1 元素发现

python
# examples/element_discovery.py
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto('http://localhost:5173')
    page.wait_for_load_state('networkidle')

    # 发现按钮
    buttons = page.locator('button').all()
    for btn in buttons:
        print(f"Button: {btn.text_content()}")

    # 发现链接
    links = page.locator('a').all()
    for link in links:
        print(f"Link: {link.get_attribute('href')}")

    # 发现输入框
    inputs = page.locator('input').all()
    for inp in inputs:
        print(f"Input: {inp.get_attribute('name')}")

    browser.close()

8.2 静态 HTML 自动化

python
# examples/static_html_automation.py
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # 使用 file:// URL 加载本地 HTML
    page.goto('file:///path/to/local/index.html')

    # 执行操作
    page.locator('button#submit').click()

    browser.close()

8.3 控制台日志捕获

python
# examples/console_logging.py
from playwright.sync_api import sync_playwright

def handle_console(msg):
    print(f"Console {msg.type}: {msg.text}")

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # 监听控制台消息
    page.on('console', handle_console)

    page.goto('http://localhost:5173')
    page.wait_for_load_state('networkidle')

    # 执行可能产生日志的操作
    page.locator('button').click()

    browser.close()

9. 最佳实践

9.1 使用打包脚本作为黑盒

markdown
**重要**
- 考虑 scripts/ 中的脚本是否能完成任务
- 使用 --help 查看用法
- 直接调用,而非读取源码到上下文
- 这些脚本处理常见的复杂工作流

9.2 脚本编写规范

markdown
- 使用 sync_playwright() 进行同步脚本
- 始终关闭浏览器
- 使用描述性选择器
- 添加适当的等待

10. 使用示例

10.1 触发方式

"帮我测试这个 Web 应用的登录功能"
"截取这个页面的截图"
"test the form submission on localhost:3000"
"debug why the button click doesn't work"

10.2 典型场景

场景方法
测试静态 HTML直接读取 HTML,编写选择器
测试运行中的服务器侦察后操作模式
测试需要启动的服务器with_server.py + 自动化脚本
调试 UI 行为截图 + 控制台日志捕获

11. 本节小结

要点说明
核心工具Playwright + with_server.py
关键等待始终等待 networkidle
侦察模式先检查 DOM,再执行操作
选择器使用 text=, role=, CSS, ID
最佳实践脚本作为黑盒使用

返回:Skills 目录

基于 MIT 许可证发布。内容版权归作者所有。