mcpField
P
playwright-e2e-testing

playwright-e2e-testing

github.com/fugazi测试与质量256617 次安装3 天前更新
代码仓库

关于 playwright-e2e-testing

playwright-e2e-testing 是用于编写和维护 Playwright 网页端到端测试的 TypeScript 技能,涵盖 UI 流程、API 辅助设置、响应式验证、模拟和调试。

主要功能

  1. 01编写 TypeScript 端到端测试
  2. 02测试表单、导航和身份验证
  3. 03模拟并拦截 API 请求
  4. 04检查响应式布局和视觉变化
  5. 05使用追踪、截图和视频调试

适用场景

  1. 01验证登录或结账流程
  2. 02使用模拟 API 响应测试 UI
  3. 03检查移动端和桌面端布局
  4. 04排查不稳定的浏览器测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fugazi/test-automation-skills-agents --skill playwright-e2e-testing

安装后在 Claude Code 中输入/playwright-e2e-testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.txt
references/
debugging-errors-network.md
debugging-flaky-locators.md
debugging-tools-ui.md
debugging-tracing-logging.md
file-map-template.md
locator-strategies-anti-debug.md
locator-strategies-filtering.md
locator-strategies-priority.md
locator-strategies-text.md
page-object-model-basics.md
page-object-model-components.md
page-object-model-fixtures.md
page-object-model-practices.md
snippets-assertions-debugging.md
snippets-interactions.md
snippets-setup.md
snippets-viewports-auth.md

详细介绍

Playwright E2E 测试(TypeScript)

使用 Playwright 和 TypeScript 对 Web 应用进行端到端测试的综合工具包。遵循最佳实践,支持可靠的 UI 测试、依赖 UI 的 API 设置以及响应式设计验证。

激活条件: 在编写或维护版本化的 Playwright UI 规范及其测试基础设施时触发此技能。

适用场景

  • 编写 E2E 测试,覆盖用户流程、表单、导航和身份验证
  • 通过 request fixture 或网络拦截进行依赖 UI 的 API 设置
  • 响应式测试,覆盖移动设备、平板和桌面视口
  • 使用跟踪记录、屏幕截图、视频和 Playwright Inspector 调试不稳定的测试
  • 使用 Page Object Model 和 fixture 设置测试基础设施
  • 模拟/拦截 API,进行隔离且确定性的测试
  • 使用屏幕截图对比进行视觉回归测试
不适用场景
  • 不涉及浏览器的独立 API/契约测试(使用 api-testing)。
  • 以交互方式驱动真实浏览器进行探索或调试(使用 playwright-cli)。
  • 管理大型回归测试套件、测试分层或 CI 分片策略(使用 playwright-regression-testing)。
  • Selenium/Java 浏览器自动化(使用 webapp-selenium-testing)。

前提条件

要求详情
Node.js建议使用 v18+
包管理器npm、yarn 或 pnpm
Playwright@playwright/test 包
TypeScripttypescript + ts-node(可选,但建议使用)
浏览器通过 npx playwright install 安装
快速设置
# Initialize new project
npm init playwright@latest

# Or add to existing project
npm install -D @playwright/test
npx playwright install

首先要确认的问题

编写测试之前,请先确认:

  1. 应用 URL:本地开发服务的启动命令和端口,还是预发布环境 URL?
  2. 关键流程:必须覆盖哪些用户旅程(正常流程和错误状态)?
  3. 浏览器/设备:Chrome、Firefox、Safari?移动端视口?
  4. API 策略:真实后端、模拟响应,还是混合方式?
  5. 测试数据:是否有种子数据?如何重置/清理?

核心原则

1. 测试运行器和 TypeScript

始终使用 @playwright/test 和 TypeScript,以确保类型安全并获得更好的 IDE 支持。

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

test("user can login", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("Email").fill("[email protected]");
  await page.getByLabel("Password").fill("password123");
  await page.getByRole("button", { name: "Sign in" }).click();
  await expect(page).toHaveURL(/.*dashboard/);
});
2. 定位器策略(优先级顺序)

优先使用基于角色且带有可访问名称的定位器(getByRole),然后依次使用 label → placeholder → text → test ID → CSS(最后手段)。绝不使用 XPath。

➡️ 完整的优先级层级、角色参考和示例: 定位器策略:优先级 — 唯一可信来源。

3. 自动等待和 Web 优先断言

Playwright 会自动等待元素。绝不要使用 sleep() 或任意超时。

// [ok] Web-first assertions (auto-retry)
await expect(page.getByRole("alert")).toBeVisible();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByTestId("status")).toHaveText("Success!");

// [no] Avoid manual waits
await page.waitForTimeout(2000); // Bad practice
4. 使用步骤组织测试

使用 test.step() 生成易读的报告,并便于定位失败原因:

test("checkout flow", async ({ page }) => {
  await test.step("Add item to cart", async () => {
    await page.goto("/products/1");
    await page.getByRole("button", { name: "Add to Cart" }).click();
  });

  await test.step("Complete checkout", async () => {
    await page.goto("/checkout");
    await page.getByRole("button", { name: "Pay Now" }).click();
  });

  await test.step("Verify confirmation", async () => {
    await expect(page.getByRole("heading")).toContainText("Order Confirmed");
  });
});

关键工作流

表单和导航
// Form submit and wait for navigation (auto-waiting)
await page.getByRole("button", { name: "Login" }).click();
await expect(page).toHaveURL(/.*dashboard/);

// Form with API response validation
const responsePromise = page.waitForResponse(
  (r) => r.url().includes("/api/login") && r.status() === 200,
);
await page.getByRole("button", { name: "Login" }).click();
const response = await responsePromise;
API 测试(Request Fixture)
test("API health check", async ({ request }) => {
  const response = await request.get("/api/health");
  expect(response.ok()).toBeTruthy();
  expect(await response.json()).toMatchObject({ status: "ok" });
});
API 模拟和拦截
test("handles API error", async ({ page }) => {
  await page.route("**/api/users", (route) =>
    route.fulfill({
      status: 500,
      body: JSON.stringify({ error: "Server error" }),
    }),
  );
  await page.goto("/users");
  await expect(page.getByRole("alert")).toContainText("Something went wrong");
});
响应式测试
const viewports = [
  { width: 375, height: 667, name: "mobile" },
  { width: 768, height: 1024, name: "tablet" },
  { width: 1280, height: 720, name: "desktop" },
];

for (const vp of viewports) {
  test(`navigation works on ${vp.name}`, async ({ page }) => {
    await page.setViewportSize(vp);
    await page.goto("/");
    // Mobile: hamburger menu
    if (vp.width < 768) {
      await page.getByRole("button", { name: /menu/i }).click();
    }
    await page.getByRole("link", { name: "About" }).click();
    await expect(page).toHaveURL(/about/);
  });
}

配置

使用 playwright.config.ts 设置项目范围的配置:

import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./tests",
  retries: process.env.CI ? 2 : 0,
  reporter: [["html"], ["junit", { outputFile: "results.xml" }]],
  use: {
    baseURL: "http://localhost:3000",
    trace: "on-first-retry",
    screenshot: "only-on-failure",
    video: "retain-on-failure",
  },
  projects: [
    { name: "chromium", use: devices["Desktop Chrome"] },
    { name: "mobile", use: devices["Pixel 5"] },
  ],
  webServer: {
    command: "npm run dev",
    url: "http://localhost:3000",
    reuseExistingServer: !process.env.CI,
  },
});

故障排查

问题原因解决方案
找不到元素定位器错误或元素尚未渲染使用 PWDEBUG=1 检查,并通过 getByRole 验证
等待超时元素隐藏或加载缓慢检查是否存在遮罩层,延长超时时间,使用 waitFor()
测试不稳定竞态条件、动画添加 test.step(),使用适当的等待方式,禁用动画
严格模式违规匹配到多个元素使用 .first()、.filter() 或更具体的定位器
截图不一致动态内容遮盖动态区域,使用确定性数据
CI 中失败,本地通过环境差异检查 baseURL、超时时间和 webServer 配置
API 模拟无效路由模式不匹配使用 **/api/... glob 模式,并通过 page.on('request') 验证

CLI 快速参考

命令说明
npx playwright test无头模式运行所有测试
npx playwright test --ui打开 UI 模式(交互式)
npx playwright test --headed在可见浏览器中运行
npx playwright test --debug运行 Playwright Inspector
npx playwright test -g "login"运行匹配模式的测试
npx playwright test --project=chromium运行指定项目
npx playwright show-report打开 HTML 报告
npx playwright codegen通过录制生成测试
PWDEBUG=1 npx playwright test使用 Inspector 调试
DEBUG=pw:api npx playwright test输出详细的 API 日志

危险信号

  • 有 role、label 或 testId 可用时仍使用 CSS/XPath 定位器——这类定位器很脆弱,重构时容易失效。
  • 使用 waitForTimeout / 手动休眠,而不是采用 Web 优先、可自动重试的断言。
  • 测试共享状态并依赖执行顺序——容易不稳定,且与执行顺序耦合。
  • 断言只检查状态码或 URL,不验证可见状态——会掩盖渲染回归问题。
  • 在多个测试中重复内联页面设置,而不使用 fixture——会造成重复和偏差。

参考资料

文档内容
代码片段:设置配置、身份验证设置、自定义夹具和日志记录
代码片段:交互表单交互、API 测试和网络拦截
代码片段:视口和身份验证响应式视口和身份验证模式
代码片段:断言和调试断言、调试命令和实用辅助函数
定位器策略:优先级定位器优先级层次结构和基于角色的定位器
定位器策略:文本标签、文本、占位符、替代文本和测试 ID 定位器
定位器策略:筛选筛选、链式调用和复杂定位器模式
定位器策略:反模式和调试反模式、最后手段 CSS、调试和快速参考
POM:基础知识POM 概念、目录结构、基础页面和流式 API
POM:组件页面对象和可复用组件对象的实现
POM:夹具自定义和经过身份验证的页面对象夹具
POM:实践最佳实践、反模式和完整示例
调试:工具和 UI调试工具、UI 模式、Inspector 和有头模式
调试:跟踪和日志跟踪查看器、详细日志、屏幕截图和视频
调试:错误和网络控制台/页面错误和网络调试
调试:不稳定测试和定位器不稳定测试修复、定位器调试和快速命令

验证

  • 使用自定义夹具注入 — 规范文件中没有 new PageObject() 调用;所有 POM 均通过夹具注入
  • 定位器使用推荐策略 — 所有定位器均使用 getByRole()、getByTestId() 或 getByText();交互元素不使用 CSS 选择器
  • 测试彼此独立 — 每个测试都会自行设置和清理状态;不使用共享可变状态的 beforeAll
  • 覆盖错误状态 — 至少有一个测试会在正常流程之外验证错误、空状态或加载状态

评论

支持 Markdown