831 lines
20 KiB
Markdown
831 lines
20 KiB
Markdown
# 冒烟测试失败修复实施计划
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**目标:** 修复 233 个冒烟测试失败,将测试通过率从 78.5% 提升至 95% 以上
|
|
|
|
**架构:** 采用分层修复策略,优先修复关键路径(导航、联系页面、表单),然后处理次要问题(滚动、可见性),最后优化测试稳定性
|
|
|
|
**技术栈:** Next.js 16.1.6, React 19.2.3, TypeScript 5, Playwright, Tailwind CSS 4
|
|
|
|
---
|
|
|
|
## 优先级分类
|
|
|
|
### P0 - 关键问题 (立即修复)
|
|
- 导航菜单不可见
|
|
- 联系页面加载失败
|
|
- 表单输入功能失败
|
|
- 提交按钮不可见
|
|
|
|
### P1 - 高优先级 (尽快修复)
|
|
- 区块可见性问题
|
|
- 滚动功能问题
|
|
- 联系信息显示问题
|
|
|
|
### P2 - 中优先级 (稍后修复)
|
|
- 页脚可见性
|
|
- 页面描述和徽章
|
|
- 必填字段标记
|
|
|
|
### P3 - 低优先级 (可选优化)
|
|
- 字段占位符
|
|
- 测试稳定性优化
|
|
|
|
---
|
|
|
|
## Task 1: 修复导航菜单选择器
|
|
|
|
**问题:** 导航元素选择器不正确,导致移动端和部分设备上导航测试失败
|
|
|
|
**文件:**
|
|
- 修改: `src/components/layout/header.tsx:242-248`
|
|
- 测试: `e2e/src/tests/smoke/home-page.smoke.spec.ts:25-29`
|
|
|
|
**Step 1: 添加导航语义化属性**
|
|
|
|
在 `src/components/layout/header.tsx` 第 242 行附近,为桌面导航添加 `role="navigation"`:
|
|
|
|
```tsx
|
|
// 修改前 (第 242 行)
|
|
<nav className="hidden md:flex items-center gap-1">
|
|
|
|
// 修改后
|
|
<nav className="hidden md:flex items-center gap-1" role="navigation" aria-label="主导航">
|
|
```
|
|
|
|
**Step 2: 验证导航选择器**
|
|
|
|
运行测试验证导航可见性:
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "应该显示主导航菜单"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 3: 添加移动端导航测试**
|
|
|
|
在 `e2e/src/tests/smoke/home-page.smoke.spec.ts` 第 25 行后添加移动端导航测试:
|
|
|
|
```typescript
|
|
test('移动端应该显示导航菜单按钮', async ({ homePage, page }) => {
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await expect(homePage.mobileMenuButton).toBeVisible();
|
|
});
|
|
```
|
|
|
|
**Step 4: 运行移动端测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "移动端应该显示导航菜单按钮"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 5: 提交修改**
|
|
|
|
```bash
|
|
git add src/components/layout/header.tsx e2e/src/tests/smoke/home-page.smoke.spec.ts
|
|
git commit -m "fix: add navigation role attribute for better test selector"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 2: 修复联系页面元素选择器
|
|
|
|
**问题:** 联系页面多个元素选择器不正确,导致大量测试失败
|
|
|
|
**文件:**
|
|
- 修改: `e2e/src/pages/ContactPage.ts:16-51`
|
|
- 修改: `src/app/(marketing)/contact/page.tsx:152-165`
|
|
- 测试: `e2e/src/tests/smoke/contact-page.smoke.spec.ts`
|
|
|
|
**Step 1: 为联系页面元素添加 data-testid**
|
|
|
|
在 `src/app/(marketing)/contact/page.tsx` 第 152 行附近,为联系信息卡片添加测试标识:
|
|
|
|
```tsx
|
|
// 修改前 (第 152 行附近)
|
|
<div className="space-y-4">
|
|
<div className="flex items-start gap-4 group">
|
|
<div className="w-10 h-10 bg-[#C41E3A] rounded-md flex items-center justify-center flex-shrink-0 transition-transform duration-200 group-hover:scale-105">
|
|
<Mail className="w-5 h-5 text-white" />
|
|
</div>
|
|
<div>
|
|
<p className="text-sm text-[#5C5C5C] mb-1">邮箱</p>
|
|
<a href={`mailto:${COMPANY_INFO.email}`} className="text-[#1C1C1C] hover:text-[#C41E3A] transition-colors duration-200">
|
|
{COMPANY_INFO.email}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
// 修改后
|
|
<div className="space-y-4" data-testid="contact-info">
|
|
<div className="flex items-start gap-4 group" data-testid="email-info">
|
|
<div className="w-10 h-10 bg-[#C41E3A] rounded-md flex items-center justify-center flex-shrink-0 transition-transform duration-200 group-hover:scale-105">
|
|
<Mail className="w-5 h-5 text-white" />
|
|
</div>
|
|
<div>
|
|
<p className="text-sm text-[#5C5C5C] mb-1">邮箱</p>
|
|
<a href={`mailto:${COMPANY_INFO.email}`} className="text-[#1C1C1C] hover:text-[#C41E3A] transition-colors duration-200" data-testid="email-link">
|
|
{COMPANY_INFO.email}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
**Step 2: 为工作时间卡片添加测试标识**
|
|
|
|
在第 181 行附近:
|
|
|
|
```tsx
|
|
// 修改前
|
|
<div className="bg-[#FFFBF5] p-5 rounded-lg border border-[#E5E5E5]">
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<Clock className="w-4 h-4 text-[#C41E3A]" />
|
|
<h4 className="text-sm font-medium text-[#1C1C1C]">工作时间</h4>
|
|
</div>
|
|
|
|
// 修改后
|
|
<div className="bg-[#FFFBF5] p-5 rounded-lg border border-[#E5E5E5]" data-testid="work-hours-card">
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<Clock className="w-4 h-4 text-[#C41E3A]" />
|
|
<h4 className="text-sm font-medium text-[#1C1C1C]">工作时间</h4>
|
|
</div>
|
|
```
|
|
|
|
**Step 3: 更新 ContactPage 测试选择器**
|
|
|
|
在 `e2e/src/pages/ContactPage.ts` 第 16 行附近更新选择器:
|
|
|
|
```typescript
|
|
// 修改前
|
|
this.contactInfoCard = page.locator('[data-slot="card"]').filter({ hasText: '联系方式' }).first();
|
|
this.workHoursCard = page.locator('[data-slot="card"]').filter({ hasText: '工作时间' }).first();
|
|
|
|
// 修改后
|
|
this.contactInfoCard = page.locator('[data-testid="contact-info"]');
|
|
this.workHoursCard = page.locator('[data-testid="work-hours-card"]');
|
|
this.emailInfo = page.locator('[data-testid="email-info"]');
|
|
this.emailLink = page.locator('[data-testid="email-link"]');
|
|
```
|
|
|
|
**Step 4: 运行联系页面测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- contact-page.smoke.spec.ts
|
|
```
|
|
|
|
预期: 大部分测试通过
|
|
|
|
**Step 5: 提交修改**
|
|
|
|
```bash
|
|
git add src/app/\(marketing\)/contact/page.tsx e2e/src/pages/ContactPage.ts
|
|
git commit -m "fix: add data-testid attributes for contact page elements"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 3: 修复表单输入字段选择器
|
|
|
|
**问题:** 表单输入字段选择器不正确,导致输入测试失败
|
|
|
|
**文件:**
|
|
- 修改: `src/app/(marketing)/contact/page.tsx:250-290`
|
|
- 修改: `e2e/src/pages/ContactPage.ts:12-17`
|
|
- 测试: `e2e/src/tests/smoke/contact-page.smoke.spec.ts:36-40`
|
|
|
|
**Step 1: 为表单字段添加 name 属性和 data-testid**
|
|
|
|
在 `src/app/(marketing)/contact/page.tsx` 第 250 行附近的表单部分:
|
|
|
|
```tsx
|
|
// 修改前
|
|
<Input
|
|
type="text"
|
|
placeholder="请输入您的姓名"
|
|
value={formData.name}
|
|
onChange={(e) => handleChange('name', e.target.value)}
|
|
onBlur={(e) => handleBlur('name', e.target.value)}
|
|
className={errors.name ? 'border-red-500' : ''}
|
|
/>
|
|
|
|
// 修改后
|
|
<Input
|
|
type="text"
|
|
name="name"
|
|
data-testid="name-input"
|
|
placeholder="请输入您的姓名"
|
|
value={formData.name}
|
|
onChange={(e) => handleChange('name', e.target.value)}
|
|
onBlur={(e) => handleBlur('name', e.target.value)}
|
|
className={errors.name ? 'border-red-500' : ''}
|
|
required
|
|
/>
|
|
```
|
|
|
|
对其他字段重复此操作:
|
|
- email (第 260 行附近)
|
|
- phone (第 270 行附近)
|
|
- subject (第 280 行附近)
|
|
- message (第 290 行附近)
|
|
|
|
**Step 2: 为提交按钮添加测试标识**
|
|
|
|
```tsx
|
|
// 修改前
|
|
<Button type="submit" disabled={isSubmitting}>
|
|
{isSubmitting ? (
|
|
<>
|
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
|
发送中...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Send className="w-4 h-4 mr-2" />
|
|
发送消息
|
|
</>
|
|
)}
|
|
</Button>
|
|
|
|
// 修改后
|
|
<Button type="submit" disabled={isSubmitting} data-testid="submit-button">
|
|
{isSubmitting ? (
|
|
<>
|
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
|
发送中...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Send className="w-4 h-4 mr-2" />
|
|
发送消息
|
|
</>
|
|
)}
|
|
</Button>
|
|
```
|
|
|
|
**Step 3: 更新 ContactPage 选择器**
|
|
|
|
在 `e2e/src/pages/ContactPage.ts` 第 12 行:
|
|
|
|
```typescript
|
|
// 修改前
|
|
this.nameInput = page.locator('input[name="name"]');
|
|
this.phoneInput = page.locator('input[name="phone"]');
|
|
this.emailInput = page.locator('input[name="email"]');
|
|
this.subjectInput = page.locator('input[name="subject"]');
|
|
this.messageInput = page.locator('textarea[name="message"]');
|
|
this.submitButton = page.locator('button[type="submit"]');
|
|
|
|
// 修改后
|
|
this.nameInput = page.locator('[data-testid="name-input"]');
|
|
this.phoneInput = page.locator('[data-testid="phone-input"]');
|
|
this.emailInput = page.locator('[data-testid="email-input"]');
|
|
this.subjectInput = page.locator('[data-testid="subject-input"]');
|
|
this.messageInput = page.locator('[data-testid="message-input"]');
|
|
this.submitButton = page.locator('[data-testid="submit-button"]');
|
|
```
|
|
|
|
**Step 4: 运行表单输入测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- contact-page.smoke.spec.ts -g "应该能够输入"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 5: 提交修改**
|
|
|
|
```bash
|
|
git add src/app/\(marketing\)/contact/page.tsx e2e/src/pages/ContactPage.ts
|
|
git commit -m "fix: add name and data-testid attributes for form inputs"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 4: 修复滚动到顶部功能
|
|
|
|
**问题:** `scrollToTop()` 函数实现有问题,滚动位置未归零
|
|
|
|
**文件:**
|
|
- 修改: `e2e/src/pages/BasePage.ts:40-50`
|
|
- 测试: `e2e/src/tests/smoke/home-page.smoke.spec.ts:55-59`
|
|
|
|
**Step 1: 检查 BasePage 滚动实现**
|
|
|
|
读取 `e2e/src/pages/BasePage.ts`:
|
|
|
|
```bash
|
|
cat e2e/src/pages/BasePage.ts
|
|
```
|
|
|
|
**Step 2: 修复 scrollToTop 方法**
|
|
|
|
在 `e2e/src/pages/BasePage.ts` 中:
|
|
|
|
```typescript
|
|
// 修改前
|
|
async scrollToTop(): Promise<void> {
|
|
await this.page.evaluate(() => window.scrollTo(0, 0));
|
|
}
|
|
|
|
// 修改后
|
|
async scrollToTop(): Promise<void> {
|
|
await this.page.evaluate(() => {
|
|
window.scrollTo({ top: 0, behavior: 'instant' });
|
|
});
|
|
await this.page.waitForLoadState('domcontentloaded');
|
|
await this.page.waitForTimeout(500);
|
|
}
|
|
```
|
|
|
|
**Step 3: 运行滚动测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "应该能够滚动到页面顶部"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 4: 提交修改**
|
|
|
|
```bash
|
|
git add e2e/src/pages/BasePage.ts
|
|
git commit -m "fix: improve scrollToTop implementation with instant behavior"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 5: 修复区块滚动和可见性问题
|
|
|
|
**问题:** 区块滚动和可见性检测存在时序问题
|
|
|
|
**文件:**
|
|
- 修改: `e2e/src/pages/HomePage.ts:73-80`
|
|
- 测试: `e2e/src/tests/smoke/home-page.smoke.spec.ts:31-45`
|
|
|
|
**Step 1: 优化 scrollToSection 方法**
|
|
|
|
在 `e2e/src/pages/HomePage.ts` 第 73 行:
|
|
|
|
```typescript
|
|
// 修改前
|
|
async scrollToSection(sectionId: string): Promise<void> {
|
|
const section = this.page.locator(`#${sectionId}`);
|
|
await section.waitFor({ state: 'attached', timeout: 10000 });
|
|
await section.scrollIntoViewIfNeeded();
|
|
await this.page.waitForLoadState('networkidle');
|
|
await this.page.waitForTimeout(1000);
|
|
}
|
|
|
|
// 修改后
|
|
async scrollToSection(sectionId: string): Promise<void> {
|
|
const section = this.page.locator(`#${sectionId}`);
|
|
await section.waitFor({ state: 'attached', timeout: 15000 });
|
|
await section.scrollIntoViewIfNeeded();
|
|
await this.page.waitForLoadState('networkidle');
|
|
await this.page.waitForTimeout(1500);
|
|
await section.waitFor({ state: 'visible', timeout: 5000 });
|
|
}
|
|
```
|
|
|
|
**Step 2: 为区块添加 ID 属性**
|
|
|
|
检查并确保所有区块都有正确的 ID:
|
|
- `src/components/sections/hero-section.tsx` - `id="home"`
|
|
- `src/components/sections/services-section.tsx` - `id="services"`
|
|
- `src/components/sections/products-section.tsx` - `id="products"`
|
|
- `src/components/sections/cases-section.tsx` - `id="cases"`
|
|
- `src/components/sections/about-section.tsx` - `id="about"`
|
|
- `src/components/sections/news-section.tsx` - `id="news"`
|
|
|
|
**Step 3: 运行区块可见性测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "应该显示.*区块标题"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 4: 提交修改**
|
|
|
|
```bash
|
|
git add e2e/src/pages/HomePage.ts
|
|
git commit -m "fix: improve scrollToSection with better wait conditions"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 6: 添加页面徽章和描述元素
|
|
|
|
**问题:** 页面徽章和描述元素缺失或选择器不正确
|
|
|
|
**文件:**
|
|
- 修改: `src/app/(marketing)/contact/page.tsx:138-145`
|
|
- 修改: `e2e/src/pages/ContactPage.ts:60-70`
|
|
|
|
**Step 1: 为联系页面添加徽章元素**
|
|
|
|
在 `src/app/(marketing)/contact/page.tsx` 第 138 行附近:
|
|
|
|
```tsx
|
|
// 修改前
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="w-8 h-px bg-gradient-to-r from-[#1C1C1C] to-[#C41E3A]" />
|
|
<span className="text-sm text-[#5C5C5C] tracking-wide">联系我们</span>
|
|
</div>
|
|
|
|
// 修改后
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="w-8 h-px bg-gradient-to-r from-[#1C1C1C] to-[#C41E3A]" />
|
|
<span className="text-sm text-[#5C5C5C] tracking-wide" data-testid="page-badge">联系我们</span>
|
|
</div>
|
|
```
|
|
|
|
**Step 2: 添加页面描述元素**
|
|
|
|
```tsx
|
|
// 修改前
|
|
<p className="mt-4 text-[#5C5C5C] max-w-2xl">
|
|
无论您有任何问题或合作意向,我们都很乐意与您交流
|
|
</p>
|
|
|
|
// 修改后
|
|
<p className="mt-4 text-[#5C5C5C] max-w-2xl" data-testid="page-description">
|
|
无论您有任何问题或合作意向,我们都很乐意与您交流
|
|
</p>
|
|
```
|
|
|
|
**Step 3: 更新 ContactPage 选择器**
|
|
|
|
在 `e2e/src/pages/ContactPage.ts` 第 60 行附近添加:
|
|
|
|
```typescript
|
|
// 添加新属性
|
|
readonly pageBadge: Locator;
|
|
readonly pageDescription: Locator;
|
|
|
|
// 在构造函数中初始化
|
|
this.pageBadge = page.locator('[data-testid="page-badge"]');
|
|
this.pageDescription = page.locator('[data-testid="page-description"]');
|
|
```
|
|
|
|
**Step 4: 添加获取方法**
|
|
|
|
```typescript
|
|
async getBadgeText(): Promise<string> {
|
|
return await this.pageBadge.textContent() || '';
|
|
}
|
|
|
|
async getPageDescription(): Promise<string> {
|
|
return await this.pageDescription.textContent() || '';
|
|
}
|
|
```
|
|
|
|
**Step 5: 运行测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- contact-page.smoke.spec.ts -g "应该显示页面"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 6: 提交修改**
|
|
|
|
```bash
|
|
git add src/app/\(marketing\)/contact/page.tsx e2e/src/pages/ContactPage.ts
|
|
git commit -m "fix: add data-testid for page badge and description"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 7: 修复页脚可见性问题
|
|
|
|
**问题:** 部分移动设备上页脚不可见
|
|
|
|
**文件:**
|
|
- 修改: `src/components/layout/footer.tsx:1-50`
|
|
- 修改: `e2e/src/pages/HomePage.ts:22`
|
|
- 测试: `e2e/src/tests/smoke/home-page.smoke.spec.ts:47-51`
|
|
|
|
**Step 1: 检查 Footer 组件**
|
|
|
|
```bash
|
|
cat src/components/layout/footer.tsx | head -50
|
|
```
|
|
|
|
**Step 2: 为 Footer 添加测试标识**
|
|
|
|
在 `src/components/layout/footer.tsx`:
|
|
|
|
```tsx
|
|
// 修改前
|
|
<footer className="bg-[#1C1C1C] text-white">
|
|
|
|
// 修改后
|
|
<footer className="bg-[#1C1C1C] text-white" data-testid="footer" role="contentinfo">
|
|
```
|
|
|
|
**Step 3: 更新 HomePage 选择器**
|
|
|
|
在 `e2e/src/pages/HomePage.ts` 第 22 行:
|
|
|
|
```typescript
|
|
// 修改前
|
|
this.footer = page.locator('footer');
|
|
|
|
// 修改后
|
|
this.footer = page.locator('[data-testid="footer"]');
|
|
```
|
|
|
|
**Step 4: 改进页脚等待逻辑**
|
|
|
|
```typescript
|
|
async waitForFooter(): Promise<void> {
|
|
await this.scrollToBottom();
|
|
await this.page.waitForLoadState('networkidle');
|
|
await this.footer.waitFor({ state: 'visible', timeout: 10000 });
|
|
}
|
|
```
|
|
|
|
**Step 5: 运行页脚测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "应该显示页脚"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 6: 提交修改**
|
|
|
|
```bash
|
|
git add src/components/layout/footer.tsx e2e/src/pages/HomePage.ts
|
|
git commit -m "fix: add data-testid and role for footer element"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 8: 修复立即咨询按钮可见性
|
|
|
|
**问题:** 移动端立即咨询按钮不可见
|
|
|
|
**文件:**
|
|
- 修改: `src/components/layout/header.tsx:200-205`
|
|
- 测试: `e2e/src/tests/smoke/home-page.smoke.spec.ts`
|
|
|
|
**Step 1: 为咨询按钮添加测试标识**
|
|
|
|
在 `src/components/layout/header.tsx` 第 200 行:
|
|
|
|
```tsx
|
|
// 修改前
|
|
<Button
|
|
size="sm"
|
|
asChild
|
|
>
|
|
<Link href="/contact">立即咨询</Link>
|
|
</Button>
|
|
|
|
// 修改后
|
|
<Button
|
|
size="sm"
|
|
asChild
|
|
data-testid="consult-button"
|
|
>
|
|
<Link href="/contact">立即咨询</Link>
|
|
</Button>
|
|
```
|
|
|
|
**Step 2: 添加测试用例**
|
|
|
|
在 `e2e/src/tests/smoke/home-page.smoke.spec.ts`:
|
|
|
|
```typescript
|
|
test('应该显示立即咨询按钮', async ({ homePage }) => {
|
|
const consultButton = homePage.page.locator('[data-testid="consult-button"]');
|
|
await expect(consultButton).toBeVisible();
|
|
});
|
|
```
|
|
|
|
**Step 3: 运行测试**
|
|
|
|
```bash
|
|
cd e2e && npm test -- home-page.smoke.spec.ts -g "应该显示立即咨询按钮"
|
|
```
|
|
|
|
预期: PASS
|
|
|
|
**Step 4: 提交修改**
|
|
|
|
```bash
|
|
git add src/components/layout/header.tsx e2e/src/tests/smoke/home-page.smoke.spec.ts
|
|
git commit -m "fix: add data-testid for consult button"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 9: 优化测试等待和超时设置
|
|
|
|
**问题:** 测试因时序问题导致不稳定
|
|
|
|
**文件:**
|
|
- 修改: `e2e/playwright.config.ts:30-40`
|
|
- 修改: `e2e/src/fixtures/base.fixture.ts`
|
|
|
|
**Step 1: 增加全局超时时间**
|
|
|
|
在 `e2e/playwright.config.ts`:
|
|
|
|
```typescript
|
|
// 修改前
|
|
timeout: 60000,
|
|
expect: {
|
|
timeout: 30000,
|
|
},
|
|
|
|
// 修改后
|
|
timeout: 90000,
|
|
expect: {
|
|
timeout: 45000,
|
|
toHaveScreenshot: { timeout: 60000 },
|
|
},
|
|
```
|
|
|
|
**Step 2: 添加测试夹具超时配置**
|
|
|
|
在 `e2e/src/fixtures/base.fixture.ts`:
|
|
|
|
```typescript
|
|
import { test as base } from '@playwright/test';
|
|
|
|
export const test = base.extend({
|
|
page: async ({ page }, use) => {
|
|
page.setDefaultTimeout(45000);
|
|
page.setDefaultNavigationTimeout(90000);
|
|
await use(page);
|
|
},
|
|
});
|
|
```
|
|
|
|
**Step 3: 运行完整测试套件**
|
|
|
|
```bash
|
|
cd e2e && npm test -- --retries=2
|
|
```
|
|
|
|
**Step 4: 提交修改**
|
|
|
|
```bash
|
|
git add e2e/playwright.config.ts e2e/src/fixtures/base.fixture.ts
|
|
git commit -m "perf: increase test timeouts for better stability"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 10: 运行完整冒烟测试并验证修复
|
|
|
|
**目标:** 验证所有修复,确保测试通过率达到 95% 以上
|
|
|
|
**Step 1: 运行完整冒烟测试套件**
|
|
|
|
```bash
|
|
cd e2e && npm test -- --grep "@smoke" --reporter=html
|
|
```
|
|
|
|
**Step 2: 生成测试报告**
|
|
|
|
```bash
|
|
cd e2e && npm run test:report
|
|
```
|
|
|
|
**Step 3: 分析剩余失败**
|
|
|
|
检查 HTML 报告,识别剩余的失败测试:
|
|
|
|
```bash
|
|
open e2e/playwright-report/index.html
|
|
```
|
|
|
|
**Step 4: 创建修复总结文档**
|
|
|
|
创建 `docs/test-fix-summary.md`:
|
|
|
|
```markdown
|
|
# 冒烟测试修复总结
|
|
|
|
## 修复前统计
|
|
- 总测试数: 1083
|
|
- 通过: ~850 (78.5%)
|
|
- 失败: ~233 (21.5%)
|
|
|
|
## 修复后统计
|
|
- 总测试数: 1083
|
|
- 通过: [填写实际数字]
|
|
- 失败: [填写实际数字]
|
|
- 通过率: [填写实际百分比]
|
|
|
|
## 已修复问题
|
|
1. ✅ 导航菜单选择器
|
|
2. ✅ 联系页面元素选择器
|
|
3. ✅ 表单输入字段选择器
|
|
4. ✅ 滚动到顶部功能
|
|
5. ✅ 区块滚动和可见性
|
|
6. ✅ 页面徽章和描述
|
|
7. ✅ 页脚可见性
|
|
8. ✅ 立即咨询按钮
|
|
9. ✅ 测试超时设置
|
|
|
|
## 剩余问题
|
|
[列出剩余的失败测试]
|
|
|
|
## 下一步计划
|
|
[列出后续优化建议]
|
|
```
|
|
|
|
**Step 5: 提交最终修改**
|
|
|
|
```bash
|
|
git add docs/test-fix-summary.md
|
|
git commit -m "docs: add smoke test fix summary"
|
|
```
|
|
|
|
---
|
|
|
|
## 验收标准
|
|
|
|
### 功能验收
|
|
- [ ] 所有 P0 关键问题已修复
|
|
- [ ] 所有 P1 高优先级问题已修复
|
|
- [ ] 至少 80% 的 P2 中优先级问题已修复
|
|
- [ ] 测试通过率 ≥ 95%
|
|
|
|
### 代码质量验收
|
|
- [ ] 所有修改都有对应的测试
|
|
- [ ] 代码符合 ESLint 规则
|
|
- [ ] TypeScript 类型检查通过
|
|
- [ ] 无 console.log 或调试代码
|
|
|
|
### 文档验收
|
|
- [ ] 修复总结文档完整
|
|
- [ ] 所有修改都有清晰的 commit message
|
|
- [ ] 测试报告已生成
|
|
|
|
---
|
|
|
|
## 风险与缓解
|
|
|
|
### 风险 1: 选择器变更影响生产代码
|
|
**缓解:** 使用 `data-testid` 属性,不影响样式和功能
|
|
|
|
### 风险 2: 超时时间增加影响 CI 速度
|
|
**缓解:** 仅在必要时增加超时,优先优化等待逻辑
|
|
|
|
### 风险 3: 移动端测试不稳定
|
|
**缓解:** 增加重试次数,优化移动端特定选择器
|
|
|
|
---
|
|
|
|
## 执行建议
|
|
|
|
### 推荐执行方式
|
|
使用 **Subagent-Driven Development** 模式:
|
|
- 每个任务由独立的 subagent 执行
|
|
- 任务间进行代码审查
|
|
- 快速迭代,及时调整
|
|
|
|
### 执行顺序
|
|
1. Task 1-3: 关键路径修复 (导航、联系页面、表单)
|
|
2. Task 4-5: 功能修复 (滚动、区块)
|
|
3. Task 6-8: 可见性修复 (徽章、页脚、按钮)
|
|
4. Task 9: 稳定性优化
|
|
5. Task 10: 验证和总结
|
|
|
|
### 预计时间
|
|
- Task 1-3: 2-3 小时
|
|
- Task 4-8: 2-3 小时
|
|
- Task 9-10: 1-2 小时
|
|
- **总计: 5-8 小时**
|
|
|
|
---
|
|
|
|
## 后续优化建议
|
|
|
|
### 短期 (1-2 周)
|
|
1. 为所有关键元素添加 `data-testid` 属性
|
|
2. 优化移动端测试配置
|
|
3. 增加视觉回归测试
|
|
|
|
### 中期 (1 个月)
|
|
1. 建立 E2E 测试最佳实践文档
|
|
2. 实施测试覆盖率监控
|
|
3. 集成到 CI/CD 流程
|
|
|
|
### 长期 (3 个月)
|
|
1. 建立测试性能基准
|
|
2. 实施自动化测试报告
|
|
3. 优化测试执行时间
|