mcpField
E
e2e-playwright-testing

e2e-playwright-testing

github.com/asyrafhussin测试与质量95814 次安装9 周前更新
代码仓库

关于 e2e-playwright-testing

面向 Web 开发者和编码 Agent 的 Playwright 端到端测试技能,按项目技术栈提供浏览器测试规范,涵盖定位器、认证复用及 CI 配置。

主要功能

  1. 01检测项目技术栈与认证方式
  2. 02提供无障碍定位器建议
  3. 03复用认证状态
  4. 04指导表单与断言模式
  5. 05规范测试组织和可靠性
  6. 06提供 CI 配置指南

适用场景

  1. 01编写或审查 Playwright 端到端测试
  2. 02排查不稳定的浏览器测试
  3. 03测试表单与认证流程
  4. 04配置 Playwright CI

安装

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

$npx skills add https://github.com/asyrafhussin/agent-skills --skill e2e-playwright-testing

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

包含的文件

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

AGENTS.md
metadata.json
README.md
rules/
_sections.md
_template.md
assert-web-first.md
auth-storage-state.md
form-custom-checkboxes.md
form-react-date-inputs.md
loc-prefer-role-locators.md
loc-strict-mode.md
org-mirror-routes.md
rel-no-wait-for-timeout.md

详细介绍

E2E Playwright 测试

使用 Playwright 进行可靠的端到端浏览器测试的模式与约定。

Web 应用的综合 E2E 测试指南。包含 8 条规则,分为 6 个类别,涵盖定位器策略、身份验证复用、表单测试(包括 React/SPA 特有的问题)、断言、测试组织、可靠性以及 CI/CD 配置。

技术栈检测

编写或审查 E2E 测试之前,请先检测项目的技术栈:

步骤 1 — 检查是否使用 Playwright
# Look in package.json devDependencies:
# "@playwright/test" → Playwright is installed
# Check for playwright.config.js or playwright.config.ts
  • 如果存在 @playwright/test → 使用此技能中的 Playwright 模式
  • 如果存在 cypress → 此技能不适用
步骤 2 — 检测前端框架
# Check package.json dependencies:
# "react" + "@inertiajs/react" → React + Inertia.js (SPA with server routing)
# "react" + "react-router" → React SPA
# "vue" → Vue.js
# "next" → Next.js

这很重要的原因:

  • React + Inertia.js:使用 waitForURL,而不是 waitForLoadState('networkidle')——Inertia 使用 history.pushState
  • React 受控输入框:文本输入可使用 fill();日期/时间输入需要使用 keyboard.type()
  • SPA 导航:页面不会完整重新加载——断言应等待内容,而不是等待网络空闲
步骤 3 — 检测身份验证模式
# Check for session-based (Laravel Sanctum) or token-based (JWT) auth
# Session: storageState saves cookies
# Token: may need to save tokens to localStorage
步骤 4 — 检测速率限制
# Check routes for throttle middleware
# If present in dev, tests will hit 429 after ~5 login attempts
# Solution: production-only throttle or increase limits in test env

元数据

  • 版本: 1.0.0
  • 规则数量: 6 个类别中的 8 条规则
  • 许可证: MIT

适用场景

  • 编写或审查 Playwright E2E 测试
  • 为新项目设置 E2E 测试
  • 调试不稳定的浏览器测试
  • 测试表单提交、身份验证流程或用户交互
  • 为元素选择定位器策略
  • 配置 Playwright 以用于 CI/CD

按优先级划分的规则类别

优先级类别影响前缀
1定位器严重loc
2身份验证严重auth
3断言高assert
4表单与输入框高form
5测试组织中org
6可靠性中rel

快速参考

1. 定位器(严重)
  • loc-prefer-role-locators - 优先使用 getByRole/getByLabel,而不是 CSS 选择器
  • loc-strict-mode - 使用 exact/first/限定范围的定位器处理严格模式违规
2. 身份验证(严重)
  • auth-storage-state - 使用设置项目模式复用登录状态
3. 断言(高)
  • assert-web-first - 使用会自动重试的 expect(locator) 断言
4. 表单与输入框(高)
  • form-react-date-inputs - 在 React 应用中输入日期/时间时使用 keyboard.type()
  • form-custom-checkboxes - 处理 sr-only 复选框组件
5. 测试组织(中)
  • org-mirror-routes - 目录结构与路由组保持一致
6. 可靠性(中)
  • rel-no-wait-for-timeout - 切勿使用任意的 waitForTimeout

核心模式

定位器优先级
// 1st: Role (best — mirrors accessibility)
page.getByRole('button', { name: 'Submit' })
page.getByRole('tab', { name: 'Network' })
page.getByRole('heading', { name: 'Dashboard' })

// 2nd: Label (for form fields)
page.getByLabel('Email')

// 3rd: Text (for static content, use exact when ambiguous)
page.getByText('Welcome', { exact: true })

// 4th: ID (for inputs without proper labels)
page.locator('#password')

// Last resort: CSS selector
page.locator('button.submit-btn')
身份验证设置模式
// Setup project logs in once per role, all tests reuse the state
// 3 logins for 90+ tests (not 90 logins)

// In test files:
test.use({ role: 'customer' });
test('shows dashboard', async ({ authedPage: page }) => {
    await page.goto('/dashboard');
    await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
});
React 日期输入问题
// fill() doesn't trigger React onChange for date/time inputs
// Use keyboard.type() instead:
await dateInput.click();
await page.keyboard.type('16042026');  // DDMMYYYY

await timeInput.click();
await page.keyboard.type('1000AM');    // 10:00 AM
严格模式修复
// Bad: matches "Verified" AND "Unverified"
page.getByRole('button', { name: 'Verified' })

// Good: exact match
page.getByRole('button', { name: 'Verified', exact: true })

// Bad: matches heading AND breadcrumb
page.getByText('POS Demo')

// Good: use role to disambiguate
page.getByRole('heading', { name: 'POS Demo' })
并行运行决策
// Default Playwright: fullyParallel: true
// Use this when: tests are independent, each test creates its own data

// Override to sequential: workers: 1
// Use this when: tests share a seeded database with mutable state
// Without this, one test's buy transaction changes the balance another test expects

配置模板

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

export default defineConfig({
    testDir: './specs',
    fullyParallel: false,              // true if tests are independent
    workers: 1,                        // increase if no shared mutable state
    forbidOnly: !!process.env.CI,
    retries: process.env.CI ? 2 : 0,
    reporter: [['html', { open: 'never' }], ['list']],
    use: {
        baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:8000',
        trace: 'on-first-retry',
        screenshot: 'only-on-failure',
        video: 'retain-on-failure',
    },
    projects: [
        { name: 'auth-setup', testMatch: /auth\.setup\.js$/, testDir: './auth' },
        { name: 'chrome', use: { ...devices['Desktop Chrome'] }, dependencies: ['auth-setup'] },
        { name: 'mobile', use: { ...devices['iPhone 14'] }, dependencies: ['auth-setup'], testMatch: /responsive/ },
    ],
});

参考资料

完整编译文档

如需查看包含所有展开规则的完整指南:AGENTS.md

评论

支持 Markdown