From fb6b8a6aecdc110fd700953f42396846165f93f1 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Thu, 09 Apr 2026 18:07:58 +0800
Subject: [PATCH] chore: 移除 Playwright MCP 并添加 e2e 测试技能
---
.claude/skills/tevin-write-e2etest/SKILL.md | 93 +++++++++++++++++++++++++++++++
package.json | 1
pnpm-lock.yaml | 31 ----------
3 files changed, 93 insertions(+), 32 deletions(-)
diff --git a/.claude/skills/tevin-write-e2etest/SKILL.md b/.claude/skills/tevin-write-e2etest/SKILL.md
new file mode 100644
index 0000000..9dc9241
--- /dev/null
+++ b/.claude/skills/tevin-write-e2etest/SKILL.md
@@ -0,0 +1,93 @@
+---
+name: tevin-write-e2etest
+description: 为项目编写 Playwright E2E 测试脚本的技能。适用于实现组件或功能的端到端测试,避免使用 MCP,改用传统的测试脚本方式。
+license: MIT
+compatibility: 项目使用 @playwright/test、React、Vite、TypeScript
+metadata:
+ author: tevin
+ version: "1.0"
+---
+
+使用 `@playwright/test` 编写 E2E 测试,不使用 MCP。
+
+## 项目测试规范
+
+**测试目录**: `test/e2e/`
+**路由模式**: hash 路由,`#/preview/pages/<path>`
+**开发服务器**: `pnpm dev` (http://localhost:5173)
+
+## 测试文件结构
+
+```typescript
+import { test, expect } from '@playwright/test';
+
+test.describe('功能名称', () => {
+ test.beforeEach(async ({ page }) => {
+ // 访问包含该功能的页面
+ await page.goto('http://localhost:5173/#/preview/pages/xxx/Page.tsx');
+ });
+
+ test('测试场景描述', async ({ page }) => {
+ // 使用 page.waitForSelector 或 expect 等待元素
+ await expect(page.locator('text=预期文本')).toBeVisible();
+ });
+
+ test('交互功能测试', async ({ page }) => {
+ // 点击操作
+ await page.click('text=可点击文本');
+ // 验证结果
+ await expect(page.locator('text=结果文本')).toBeVisible();
+ });
+});
+```
+
+## 编写步骤
+
+1. **确认测试页面路径**
+ - 组件示例页面: `http://localhost:5173/#/preview/pages/<component>/<Page>.tsx`
+ - 如果不确定,先运行 `pnpm dev` 访问确认
+
+2. **分析页面功能**
+ - 识别页面的主要元素(菜单、表单、按钮等)
+ - 确定需要测试的用户交互流程
+
+3. **编写测试用例**
+ - 每个 `test` 块描述一个独立场景
+ - 使用 `test.beforeEach` 统一初始化
+ - 用 `expect` 断言而非 `console.log` 验证
+
+4. **运行测试**
+ - 确保开发服务器已启动: `pnpm dev`
+ - 运行测试: `pnpm exec playwright test test/e2e/<spec>.ts`
+
+## 最佳实践
+
+- **使用稳定选择器**: 优先使用 `text=` 定位文本,避免脆弱的 CSS 选择器
+- **显式等待**: 使用 `expect(locator).toBeVisible()` 而非 `page.waitForTimeout()`
+- **独立测试**: 每个测试应能独立运行,不依赖其他测试的状态
+- **清晰命名**: 测试名称应描述预期行为,如 `should display menu items`
+
+## 常见模式
+
+**菜单导航测试**:
+```typescript
+test('菜单点击跳转', async ({ page }) => {
+ await page.click('text=菜单项');
+ await expect(page.locator('text=目标页面内容')).toBeVisible();
+});
+```
+
+**表单输入测试**:
+```typescript
+test('表单提交', async ({ page }) => {
+ await page.fill('input[placeholder="输入框"]', '测试值');
+ await page.click('button:has-text("提交")');
+ await expect(page.locator('text=成功消息')).toBeVisible();
+});
+```
+
+## 注意事项
+
+- 不要使用 Playwright MCP (`@playwright/mcp` 已从项目移除)
+- 测试文件后缀为 `.spec.ts`
+- 首次运行需要安装浏览器: `pnpm exec playwright install`
diff --git a/package.json b/package.json
index f7f3a75..a01eafd 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,6 @@
},
"devDependencies": {
"@eslint/js": "^9.39.4",
- "@playwright/mcp": "^0.0.70",
"@playwright/test": "^1.59.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2a2bb56..387162f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -24,9 +24,6 @@
'@eslint/js':
specifier: ^9.39.4
version: 9.39.4
- '@playwright/mcp':
- specifier: ^0.0.70
- version: 0.0.70
'@playwright/test':
specifier: ^1.59.1
version: 1.59.1
@@ -478,11 +475,6 @@
'@parcel/watcher@2.5.6':
resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
engines: {node: '>= 10.0.0'}
-
- '@playwright/mcp@0.0.70':
- resolution: {integrity: sha512-Kl0a6l9VL8rvT1oBou3hS5yArjwWV9UlwAkq+0skfK1YVg8XfmmNaAmwZhMeNx/ZhGiWXfCllo6rD/jvZz+WuA==}
- engines: {node: '>=18'}
- hasBin: true
'@playwright/test@1.59.1':
resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==}
@@ -1621,18 +1613,8 @@
engines: {node: '>=18'}
hasBin: true
- playwright-core@1.60.0-alpha-1774999321000:
- resolution: {integrity: sha512-ams3Zo4VXxeOg5ZTTh16GkE8g48Bmxo/9pg9gXl9SVKlVohCU7Jaog7XntY8yFuzENA6dJc1Fz7Z/NNTm9nGEw==}
- engines: {node: '>=18'}
- hasBin: true
-
playwright@1.59.1:
resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==}
- engines: {node: '>=18'}
- hasBin: true
-
- playwright@1.60.0-alpha-1774999321000:
- resolution: {integrity: sha512-Bd5DkzYKG+2g1jLO6NeTXmGLbBYSFffJIOsR4l4hUBkJvzvGGdLZ7jZb2tOtb0WIoWXQKdQj3Ap6WthV4DBS8w==}
engines: {node: '>=18'}
hasBin: true
@@ -2528,11 +2510,6 @@
'@parcel/watcher-win32-ia32': 2.5.6
'@parcel/watcher-win32-x64': 2.5.6
optional: true
-
- '@playwright/mcp@0.0.70':
- dependencies:
- playwright: 1.60.0-alpha-1774999321000
- playwright-core: 1.60.0-alpha-1774999321000
'@playwright/test@1.59.1':
dependencies:
@@ -3729,17 +3706,9 @@
playwright-core@1.59.1: {}
- playwright-core@1.60.0-alpha-1774999321000: {}
-
playwright@1.59.1:
dependencies:
playwright-core: 1.59.1
- optionalDependencies:
- fsevents: 2.3.2
-
- playwright@1.60.0-alpha-1774999321000:
- dependencies:
- playwright-core: 1.60.0-alpha-1774999321000
optionalDependencies:
fsevents: 2.3.2
--
Gitblit v1.9.1