-```
-
-**Step 2: 验证修改**
-
-Run: `npm run lint`
-
-Expected: 无 lint 错误
-
-**Step 3: Commit**
-
-```bash
-git add src/app/\(marketing\)/cases/\[id\]/client.tsx
-git commit -m "style: unify color scheme to brand red in case detail page"
-```
-
----
-
-### Task 4.2: 更新 Solutions 页面配色
-
-**Files:**
-- Modify: `src/app/(marketing)/solutions/page.tsx`
-
-**Step 1: 将紫色替换为品牌红**
-
-Read: `src/app/(marketing)/solutions/page.tsx`
-
-Replace all occurrences of:
-- `#4F46E5` → `#C41E3A`
-- `rgba(79,70,229,` → `rgba(196,30,58,`
-
-**Step 2: 验证修改**
-
-Run: `npm run lint`
-
-Expected: 无 lint 错误
-
-**Step 3: Commit**
-
-```bash
-git add src/app/\(marketing\)/solutions/page.tsx
-git commit -m "style: unify color scheme to brand red in solutions page"
-```
-
----
-
-### Task 4.3: 更新 Products Section 配色
-
-**Files:**
-- Modify: `src/components/sections/products-section.tsx`
-
-**Step 1: 将紫色替换为品牌红**
-
-Read: `src/components/sections/products-section.tsx`
-
-Replace all occurrences of:
-- `#4F46E5` → `#C41E3A`
-- `rgba(79,70,229,` → `rgba(196,30,58,`
-
-**Step 2: 验证修改**
-
-Run: `npm run lint`
-
-Expected: 无 lint 错误
-
-**Step 3: Commit**
-
-```bash
-git add src/components/sections/products-section.tsx
-git commit -m "style: unify color scheme to brand red in products section"
-```
-
----
-
-## 阶段 5: 清理与验证
-
-### Task 5.1: 删除旧的 Solutions 页面(可选)
-
-**Files:**
-- Delete: `src/app/(marketing)/solutions/` (如果与 services 重复)
-
-**Step 1: 检查是否需要删除**
-
-Run: `ls -la src/app/\(marketing\)/solutions/`
-
-如果 solutions 页面与 services 功能重复,考虑重定向或删除。
-
-**Step 2: 如果决定保留,更新导航**
-
-确保导航指向正确的页面。
-
----
-
-### Task 5.2: 运行完整测试
-
-**Step 1: 运行 lint 检查**
-
-Run: `npm run lint`
-
-Expected: 无错误
-
-**Step 2: 运行类型检查**
-
-Run: `npm run typecheck || npx tsc --noEmit`
-
-Expected: 无类型错误
-
-**Step 3: 运行构建**
-
-Run: `npm run build`
-
-Expected: 构建成功
-
-**Step 4: 本地测试**
-
-Run: `npm run dev`
-
-手动测试以下页面:
-- `/` - 首页
-- `/services` - 服务列表
-- `/services/[id]` - 服务详情
-- `/products` - 产品列表
-- `/products/[id]` - 产品详情
-- `/cases` - 案例列表
-- `/cases/[id]` - 案例详情
-- `/about` - 关于我们
-- `/news` - 新闻列表
-- `/contact` - 联系我们
-
----
-
-### Task 5.3: 最终提交
-
-**Step 1: 检查所有更改**
-
-Run: `git status`
-
-**Step 2: 提交所有更改**
-
-```bash
-git add -A
-git commit -m "refactor: complete website optimization - unified navigation, colors, and structure"
-```
-
----
-
-## 实施完成检查清单
-
-- [ ] 服务详情页创建完成
-- [ ] 服务列表页创建完成
-- [ ] 服务模态框已删除
-- [ ] 首页 About Section 已精简
-- [ ] 首页 Cases Section 已添加
-- [ ] 导航链接已统一
-- [ ] 产品列表页已创建
-- [ ] Footer 链接已更新
-- [ ] 配色方案已统一
-- [ ] Lint 检查通过
-- [ ] 类型检查通过
-- [ ] 构建成功
-- [ ] 手动测试通过
diff --git a/docs/plans/2026-02-27-e2e-driven-system-optimization.md b/docs/plans/2026-02-27-e2e-driven-system-optimization.md
deleted file mode 100644
index 00791ac..0000000
--- a/docs/plans/2026-02-27-e2e-driven-system-optimization.md
+++ /dev/null
@@ -1,885 +0,0 @@
-# E2E测试结果驱动的系统优化实施计划
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**目标:** 基于E2E测试结果,通过TDD方法系统性地修复测试失败问题,提升系统质量
-
-**架构:** 采用测试驱动开发(TDD)方法,按照优先级逐步修复问题:优先级1(关键功能)→ 优先级2(性能优化)→ 优先级3(响应式改进)
-
-**技术栈:** Next.js 15, React, TypeScript, Playwright E2E测试, Tailwind CSS
-
----
-
-## 阶段1: 优先级1 - 关键功能修复
-
-### Task 1: 完善联系表单提交功能
-
-**背景:** 回归测试显示联系表单提交功能未完全实现,导致测试失败
-
-**Files:**
-- Create: `src/app/contact/actions.ts`
-- Modify: `src/app/contact/page.tsx`
-- Test: `e2e/src/tests/regression/contact-form.regression.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/regression/contact-form.regression.spec.ts
-test('应该能够提交完整的表单', async ({ contactPage }) => {
- await contactPage.fillContactForm({
- name: '测试用户',
- email: 'test@example.com',
- phone: '13800138000',
- message: '这是一条测试消息'
- });
-
- await contactPage.submitForm();
-
- await contactPage.page.waitForTimeout(2000);
-
- const successMessage = await contactPage.page.locator('text=提交成功').isVisible();
- expect(successMessage).toBeTruthy();
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够提交完整的表单"`
-
-Expected: FAIL - 表单提交功能未实现
-
-**Step 3: 创建表单提交Action**
-
-```typescript
-// src/app/contact/actions.ts
-'use server';
-
-export async function submitContactForm(formData: FormData) {
- const name = formData.get('name') as string;
- const email = formData.get('email') as string;
- const phone = formData.get('phone') as string;
- const message = formData.get('message') as string;
-
- if (!name || !email || !message) {
- return { success: false, error: '请填写必填字段' };
- }
-
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- if (!emailRegex.test(email)) {
- return { success: false, error: '请输入有效的邮箱地址' };
- }
-
- return { success: true, message: '提交成功' };
-}
-```
-
-**Step 4: 更新联系页面集成表单提交**
-
-```typescript
-// src/app/contact/page.tsx
-'use client';
-
-import { useState } from 'react';
-import { submitContactForm } from './actions';
-
-export default function ContactPage() {
- const [formData, setFormData] = useState({
- name: '',
- email: '',
- phone: '',
- message: ''
- });
- const [submitResult, setSubmitResult] = useState<{ success: boolean; message?: string } | null>(null);
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- const formDataObj = new FormData();
- Object.entries(formData).forEach(([key, value]) => {
- formDataObj.append(key, value);
- });
-
- const result = await submitContactForm(formDataObj);
- setSubmitResult(result);
- };
-
- return (
-
- );
-}
-```
-
-**Step 5: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够提交完整的表单"`
-
-Expected: PASS
-
-**Step 6: 提交**
-
-```bash
-git add src/app/contact/actions.ts src/app/contact/page.tsx
-git commit -m "feat: implement contact form submission with validation"
-```
-
----
-
-### Task 2: 优化移动端菜单交互
-
-**背景:** 回归测试显示移动端菜单交互需要完善
-
-**Files:**
-- Modify: `src/components/Header.tsx`
-- Test: `e2e/src/tests/regression/navigation.regression.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/regression/navigation.regression.spec.ts
-test('应该能够打开和关闭移动端菜单', async ({ homePage }) => {
- await homePage.page.setViewportSize({ width: 375, height: 667 });
-
- await homePage.openMobileMenu();
- const isMenuOpen = await homePage.isMobileMenuOpen();
- expect(isMenuOpen).toBeTruthy();
-
- await homePage.closeMobileMenu();
- const isMenuClosed = await !(await homePage.isMobileMenuOpen());
- expect(isMenuClosed).toBeTruthy();
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够打开和关闭移动端菜单"`
-
-Expected: FAIL - 移动端菜单交互未实现
-
-**Step 3: 实现移动端菜单状态管理**
-
-```typescript
-// src/components/Header.tsx
-'use client';
-
-import { useState } from 'react';
-
-export default function Header() {
- const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
-
- const toggleMobileMenu = () => {
- setIsMobileMenuOpen(!isMobileMenuOpen);
- };
-
- return (
-
- );
-}
-```
-
-**Step 4: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够打开和关闭移动端菜单"`
-
-Expected: PASS
-
-**Step 5: 提交**
-
-```bash
-git add src/components/Header.tsx
-git commit -m "feat: implement mobile menu toggle functionality"
-```
-
----
-
-### Task 3: 修复页面滚动问题
-
-**背景:** 回归测试显示页面滚动事件处理需要优化
-
-**Files:**
-- Create: `src/hooks/useSmoothScroll.ts`
-- Modify: `src/components/Header.tsx`, `src/app/contact/page.tsx`
-- Test: `e2e/src/tests/regression/navigation.regression.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/regression/navigation.regression.spec.ts
-test('应该能够平滑滚动到锚点', async ({ homePage }) => {
- await homePage.navigateTo('/');
-
- await homePage.scrollToSection('services');
- const servicesSection = homePage.page.locator('#services');
- const isVisible = await servicesSection.isVisible();
- expect(isVisible).toBeTruthy();
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够平滑滚动到锚点"`
-
-Expected: FAIL - 平滑滚动未实现
-
-**Step 3: 创建平滑滚动Hook**
-
-```typescript
-// src/hooks/useSmoothScroll.ts
-import { useEffect } from 'react';
-
-export function useSmoothScroll() {
- useEffect(() => {
- const handleAnchorClick = (e: MouseEvent) => {
- const target = e.target as HTMLAnchorElement;
- if (target.tagName === 'A' && target.hash) {
- e.preventDefault();
- const element = document.querySelector(target.hash);
- if (element) {
- element.scrollIntoView({ behavior: 'smooth' });
- }
- }
- };
-
- document.addEventListener('click', handleAnchorClick);
- return () => document.removeEventListener('click', handleAnchorClick);
- }, []);
-}
-```
-
-**Step 4: 集成平滑滚动到页面**
-
-```typescript
-// src/app/contact/page.tsx
-import { useSmoothScroll } from '@/hooks/useSmoothScroll';
-
-export default function ContactPage() {
- useSmoothScroll();
-
- return (
-
- );
-}
-```
-
-**Step 5: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:regression -- --grep "应该能够平滑滚动到锚点"`
-
-Expected: PASS
-
-**Step 6: 提交**
-
-```bash
-git add src/hooks/useSmoothScroll.ts src/app/contact/page.tsx
-git commit -m "feat: implement smooth scrolling for anchor links"
-```
-
----
-
-## 阶段2: 优先级2 - 性能优化
-
-### Task 4: 优化页面加载时间
-
-**背景:** 性能测试显示页面加载时间超出阈值
-
-**Files:**
-- Modify: `next.config.mjs`
-- Create: `src/app/loading.tsx`
-- Test: `e2e/src/tests/performance/performance.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/performance/performance.spec.ts
-test('首页应该在2秒内完成加载', async ({ page }) => {
- const startTime = Date.now();
- await page.goto('/');
- await page.waitForLoadState('networkidle');
- const loadTime = Date.now() - startTime;
-
- expect(loadTime).toBeLessThan(2000);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:performance -- --grep "首页应该在2秒内完成加载"`
-
-Expected: FAIL - 页面加载时间超过2秒
-
-**Step 3: 配置代码分割和优化**
-
-```javascript
-// next.config.mjs
-/** @type {import('next').NextConfig} */
-const nextConfig = {
- reactStrictMode: true,
- swcMinify: true,
- compress: true,
- images: {
- formats: ['image/avif', 'image/webp'],
- deviceSizes: [640, 750, 828, 1080, 1200, 1920],
- imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
- },
- experimental: {
- optimizeCss: true,
- },
-};
-
-export default nextConfig;
-```
-
-**Step 4: 创建加载状态组件**
-
-```typescript
-// src/app/loading.tsx
-export default function Loading() {
- return (
-
- );
-}
-```
-
-**Step 5: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:performance -- --grep "首页应该在2秒内完成加载"`
-
-Expected: PASS
-
-**Step 6: 提交**
-
-```bash
-git add next.config.mjs src/app/loading.tsx
-git commit -m "perf: optimize page load time with code splitting and image optimization"
-```
-
----
-
-### Task 5: 改善交互响应时间
-
-**背景:** 性能测试显示交互响应时间需要优化
-
-**Files:**
-- Modify: `src/components/Header.tsx`, `src/components/Button.tsx`
-- Test: `e2e/src/tests/performance/performance.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/performance/performance.spec.ts
-test('按钮点击应该在100ms内响应', async ({ page }) => {
- await page.goto('/');
- const button = page.locator('button:has-text("立即咨询")').first();
-
- const startTime = Date.now();
- await button.click();
- const responseTime = Date.now() - startTime;
-
- expect(responseTime).toBeLessThan(100);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:performance -- --grep "按钮点击应该在100ms内响应"`
-
-Expected: FAIL - 按钮响应时间超过100ms
-
-**Step 3: 优化按钮组件**
-
-```typescript
-// src/components/Button.tsx
-'use client';
-
-import { forwardRef } from 'react';
-
-export const Button = forwardRef
>(
- ({ children, onClick, ...props }, ref) => {
- const handleClick = (e: React.MouseEvent) => {
- requestAnimationFrame(() => {
- onClick?.(e);
- });
- };
-
- return (
-
- );
- }
-);
-
-Button.displayName = 'Button';
-```
-
-**Step 4: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:performance -- --grep "按钮点击应该在100ms内响应"`
-
-Expected: PASS
-
-**Step 5: 提交**
-
-```bash
-git add src/components/Button.tsx
-git commit -m "perf: improve button click response time with requestAnimationFrame"
-```
-
----
-
-### Task 6: 优化滚动性能
-
-**背景:** 性能测试显示滚动性能需要改善
-
-**Files:**
-- Create: `src/hooks/useThrottle.ts`
-- Modify: `src/components/Header.tsx`
-- Test: `e2e/src/tests/performance/performance.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/performance/performance.spec.ts
-test('滚动帧率应该保持在60fps', async ({ page }) => {
- await page.goto('/');
-
- const frameRates: number[] = [];
-
- for (let i = 0; i < 10; i++) {
- await page.evaluate(() => {
- window.scrollBy(0, 100);
- });
- await page.waitForTimeout(100);
-
- const fps = await page.evaluate(() => {
- return (window as any).performance?.fps || 60;
- });
- frameRates.push(fps);
- }
-
- const avgFps = frameRates.reduce((a, b) => a + b, 0) / frameRates.length;
- expect(avgFps).toBeGreaterThan(55);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:performance -- --grep "滚动帧率应该保持在60fps"`
-
-Expected: FAIL - 滚动帧率低于55fps
-
-**Step 3: 创建节流Hook**
-
-```typescript
-// src/hooks/useThrottle.ts
-import { useCallback, useRef } from 'react';
-
-export function useThrottle any>(
- callback: T,
- delay: number
-): T {
- const lastRan = useRef(Date.now());
-
- return useCallback(
- (...args: Parameters) => {
- if (Date.now() - lastRan.current >= delay) {
- callback(...args);
- lastRan.current = Date.now();
- }
- },
- [callback, delay]
- ) as T;
-}
-```
-
-**Step 4: 应用节流优化滚动事件**
-
-```typescript
-// src/components/Header.tsx
-import { useThrottle } from '@/hooks/useThrottle';
-
-export default function Header() {
- const handleScroll = useThrottle(() => {
- const isScrolled = window.scrollY > 50;
- // 更新滚动状态
- }, 100);
-
- useEffect(() => {
- window.addEventListener('scroll', handleScroll);
- return () => window.removeEventListener('scroll', handleScroll);
- }, [handleScroll]);
-}
-```
-
-**Step 5: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:performance -- --grep "滚动帧率应该保持在60fps"`
-
-Expected: PASS
-
-**Step 6: 提交**
-
-```bash
-git add src/hooks/useThrottle.ts src/components/Header.tsx
-git commit -m "perf: optimize scroll performance with throttle"
-```
-
----
-
-## 阶段3: 优先级3 - 响应式改进
-
-### Task 7: 完善移动端布局
-
-**背景:** 响应式测试显示移动端布局需要完善
-
-**Files:**
-- Modify: `src/app/contact/page.tsx`, `src/components/Header.tsx`
-- Test: `e2e/src/tests/responsive/responsive.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/responsive/responsive.spec.ts
-test('移动端布局应该正确显示', async ({ page }) => {
- await page.setViewportSize({ width: 375, height: 667 });
- await page.goto('/contact');
-
- const form = page.locator('form');
- const isVisible = await form.isVisible();
-
- expect(isVisible).toBeTruthy();
-
- const formWidth = await form.evaluate(el => el.getBoundingClientRect().width);
- expect(formWidth).toBeLessThan(375);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:responsive -- --grep "移动端布局应该正确显示"`
-
-Expected: FAIL - 移动端布局未优化
-
-**Step 3: 优化移动端表单布局**
-
-```typescript
-// src/app/contact/page.tsx
-export default function ContactPage() {
- return (
-
- );
-}
-```
-
-**Step 4: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:responsive -- --grep "移动端布局应该正确显示"`
-
-Expected: PASS
-
-**Step 5: 提交**
-
-```bash
-git add src/app/contact/page.tsx
-git commit -m "style: improve mobile responsive layout for contact form"
-```
-
----
-
-### Task 8: 优化平板端显示
-
-**背景:** 响应式测试显示平板端显示需要调整
-
-**Files:**
-- Modify: `src/app/contact/page.tsx`, `src/components/Header.tsx`
-- Test: `e2e/src/tests/responsive/responsive.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/responsive/responsive.spec.ts
-test('平板端布局应该正确显示', async ({ page }) => {
- await page.setViewportSize({ width: 768, height: 1024 });
- await page.goto('/contact');
-
- const form = page.locator('form');
- const isVisible = await form.isVisible();
-
- expect(isVisible).toBeTruthy();
-
- const formWidth = await form.evaluate(el => el.getBoundingClientRect().width);
- expect(formWidth).toBeGreaterThan(700);
- expect(formWidth).toBeLessThan(768);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:responsive -- --grep "平板端布局应该正确显示"`
-
-Expected: FAIL - 平板端布局未优化
-
-**Step 3: 优化平板端布局**
-
-```typescript
-// src/app/contact/page.tsx
-export default function ContactPage() {
- return (
-
-
-
- );
-}
-```
-
-**Step 4: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:responsive -- --grep "平板端布局应该正确显示"`
-
-Expected: PASS
-
-**Step 5: 提交**
-
-```bash
-git add src/app/contact/page.tsx
-git commit -m "style: improve tablet responsive layout"
-```
-
----
-
-### Task 9: 改善大屏幕体验
-
-**背景:** 响应式测试显示大屏幕显示需要优化
-
-**Files:**
-- Modify: `src/app/contact/page.tsx`, `src/app/page.tsx`
-- Test: `e2e/src/tests/responsive/responsive.spec.ts`
-
-**Step 1: 编写失败的测试**
-
-```typescript
-// e2e/src/tests/responsive/responsive.spec.ts
-test('大屏幕布局应该正确显示', async ({ page }) => {
- await page.setViewportSize({ width: 1920, height: 1080 });
- await page.goto('/contact');
-
- const form = page.locator('form');
- const isVisible = await form.isVisible();
-
- expect(isVisible).toBeTruthy();
-
- const formWidth = await form.evaluate(el => el.getBoundingClientRect().width);
- expect(formWidth).toBeGreaterThan(1200);
- expect(formWidth).toBeLessThan(1920);
-});
-```
-
-**Step 2: 运行测试验证失败**
-
-Run: `cd e2e && npm run test:responsive -- --grep "大屏幕布局应该正确显示"`
-
-Expected: FAIL - 大屏幕布局未优化
-
-**Step 3: 优化大屏幕布局**
-
-```typescript
-// src/app/contact/page.tsx
-export default function ContactPage() {
- return (
-
-
-
- );
-}
-```
-
-**Step 4: 运行测试验证通过**
-
-Run: `cd e2e && npm run test:responsive -- --grep "大屏幕布局应该正确显示"`
-
-Expected: PASS
-
-**Step 5: 提交**
-
-```bash
-git add src/app/contact/page.tsx
-git commit -m "style: improve large screen responsive layout"
-```
-
----
-
-## 验证和总结
-
-### Task 10: 运行完整测试套件验证改进
-
-**Files:**
-- Test: `e2e/src/tests/**/*.spec.ts`
-
-**Step 1: 运行所有测试**
-
-Run: `cd e2e && npm run test:all-with-progress`
-
-Expected: 所有测试通过率显著提升
-
-**Step 2: 生成测试报告**
-
-Run: `cd e2e && npm run test:report`
-
-Expected: 生成详细的HTML测试报告
-
-**Step 3: 更新测试报告文档**
-
-Modify: `e2e/test-report.md`
-
-添加改进前后的对比数据和总结
-
-**Step 4: 提交**
-
-```bash
-git add e2e/test-report.md
-git commit -m "docs: update test report with improvements"
-```
-
----
-
-## 执行策略
-
-### TDD流程
-每个任务都遵循以下TDD循环:
-1. **Red**: 编写失败的测试
-2. **Green**: 编写最小代码使测试通过
-3. **Refactor**: 重构代码(如果需要)
-4. **Commit**: 提交代码
-
-### 测试优先级
-- **冒烟测试**: 100%通过率(已达成)
-- **回归测试**: 目标80%+通过率
-- **性能测试**: 目标70%+通过率
-- **响应式测试**: 目标80%+通过率
-
-### 频繁提交
-每个任务完成后立即提交,保持代码历史清晰
-
----
-
-## 成功标准
-
-- [ ] 回归测试通过率达到80%以上
-- [ ] 性能测试通过率达到70%以上
-- [ ] 响应式测试通过率达到80%以上
-- [ ] 所有冒烟测试保持100%通过
-- [ ] 页面加载时间优化到2秒以内
-- [ ] 移动端菜单交互流畅
-- [ ] 联系表单提交功能完整
-- [ ] 平滑滚动正常工作
-
----
-
-## 风险和缓解
-
-### 风险1: 测试环境不稳定
-**缓解**: 使用Playwright的重试机制和超时配置
-
-### 风险2: 性能优化可能影响功能
-**缓解**: 每次优化后运行完整测试套件验证
-
-### 风险3: 响应式改动可能影响现有布局
-**缓解**: 逐步实施,每个改动后测试所有断点
-
----
-
-## 时间估算
-
-- 阶段1(关键功能修复): 2-3小时
-- 阶段2(性能优化): 2-3小时
-- 阶段3(响应式改进): 1-2小时
-- 验证和总结: 1小时
-
-**总计**: 6-9小时
diff --git a/docs/plans/2026-02-27-website-comprehensive-optimization.md b/docs/plans/2026-02-27-website-comprehensive-optimization.md
deleted file mode 100644
index 122b895..0000000
--- a/docs/plans/2026-02-27-website-comprehensive-optimization.md
+++ /dev/null
@@ -1,1420 +0,0 @@
-# 网站全面优化实施计划
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**Goal:** 全面优化睿新致远网站,提升导航一致性、测试覆盖率、错误处理、性能、移动端体验和SEO。
-
-**Architecture:** 采用渐进式优化策略,按优先级分阶段实施,每个阶段独立可验证和回滚。
-
-**Tech Stack:** Next.js 16.1.6, TypeScript, Framer Motion, Playwright, Tailwind CSS
-
----
-
-## 阶段一:高优先级修复(1-2天)
-
-### Task 1.1: 修复导航一致性问题
-
-**Files:**
-- Create: `src/components/layout/breadcrumb.tsx`
-- Modify: `src/components/layout/header.tsx:1-150`
-- Modify: `src/app/(marketing)/about/page.tsx:1-15`
-- Modify: `src/app/(marketing)/cases/page.tsx:1-20`
-- Modify: `src/app/(marketing)/services/page.tsx:1-20`
-- Modify: `src/app/(marketing)/products/page.tsx:1-20`
-- Modify: `src/app/(marketing)/solutions/page.tsx:1-20`
-- Modify: `src/app/(marketing)/contact/page.tsx:1-20`
-- Modify: `src/app/(marketing)/news/page.tsx:1-20`
-
-**Step 1: 创建面包屑导航组件**
-
-```typescript
-// src/components/layout/breadcrumb.tsx
-'use client';
-
-import Link from 'next/link';
-import { ChevronRight, Home } from 'lucide-react';
-
-interface BreadcrumbItem {
- label: string;
- href: string;
-}
-
-interface BreadcrumbProps {
- items: BreadcrumbItem[];
-}
-
-export function Breadcrumb({ items }: BreadcrumbProps) {
- return (
-
- );
-}
-```
-
-**Step 2: 运行测试验证组件创建**
-
-Run: `npm run build`
-
-Expected: BUILD SUCCESS
-
-**Step 3: 在各个页面集成面包屑导航**
-
-```typescript
-// 示例:src/app/(marketing)/about/page.tsx
-import { Breadcrumb } from '@/components/layout/breadcrumb';
-
-export default function AboutPage() {
- return (
-
-
- {/* 其他内容 */}
-
- );
-}
-```
-
-**Step 4: 更新 Header 组件以支持统一导航**
-
-```typescript
-// src/components/layout/header.tsx
-// 修改导航逻辑,使其在首页使用锚点,在详情页使用路由
-const getNavigationHref = (item: typeof NAVIGATION[number], isHomePage: boolean) => {
- return isHomePage ? item.href : `/${item.id}`;
-};
-```
-
-**Step 5: 运行测试验证导航一致性**
-
-Run: `npm run lint`
-
-Expected: No linting errors
-
-**Step 6: 提交代码**
-
-```bash
-git add src/components/layout/breadcrumb.tsx src/components/layout/header.tsx src/app/
-git commit -m "feat: implement consistent navigation with breadcrumbs"
-```
-
----
-
-### Task 1.2: 补充关键页面的E2E测试
-
-**Files:**
-- Create: `e2e/src/pages/AboutPage.ts`
-- Create: `e2e/src/pages/CasesPage.ts`
-- Create: `e2e/src/pages/ServicesPage.ts`
-- Create: `e2e/src/pages/ProductsPage.ts`
-- Create: `e2e/src/pages/SolutionsPage.ts`
-- Create: `e2e/src/pages/NewsPage.ts`
-- Create: `e2e/src/tests/smoke/about-page.smoke.spec.ts`
-- Create: `e2e/src/tests/smoke/cases-page.smoke.spec.ts`
-- Create: `e2e/src/tests/smoke/services-page.smoke.spec.ts`
-- Create: `e2e/src/tests/smoke/products-page.smoke.spec.ts`
-- Create: `e2e/src/tests/smoke/solutions-page.smoke.spec.ts`
-- Create: `e2e/src/tests/smoke/news-page.smoke.spec.ts`
-
-**Step 1: 创建 AboutPage Page Object**
-
-```typescript
-// e2e/src/pages/AboutPage.ts
-import { Page, Locator, expect } from '@playwright/test';
-
-export class AboutPage {
- readonly page: Page;
- readonly breadcrumb: Locator;
- readonly pageHeader: Locator;
-
- constructor(page: Page) {
- this.page = page;
- this.breadcrumb = page.locator('nav');
- this.pageHeader = page.locator('h1');
- }
-
- async goto() {
- await this.page.goto('/about');
- await this.page.waitForLoadState('networkidle');
- }
-
- async waitForPageLoad() {
- await this.page.waitForLoadState('networkidle');
- await expect(this.pageHeader).toBeVisible();
- }
-
- async getBreadcrumbItems() {
- return await this.breadcrumb.allTextContents();
- }
-}
-```
-
-**Step 2: 创建关于页面冒烟测试**
-
-```typescript
-// e2e/src/tests/smoke/about-page.smoke.spec.ts
-import { test, expect } from '../../fixtures/base.fixture';
-
-test.describe('关于页面冒烟测试 @smoke', () => {
- test.beforeEach(async ({ aboutPage }) => {
- await aboutPage.goto();
- await aboutPage.waitForPageLoad();
- });
-
- test('应该成功加载关于页面', async ({ aboutPage }) => {
- await expect(aboutPage.page).toHaveURL(/\/about/);
- await expect(aboutPage.pageHeader).toBeVisible();
- });
-
- test('应该显示面包屑导航', async ({ aboutPage }) => {
- const items = await aboutPage.getBreadcrumbItems();
- expect(items.length).toBeGreaterThan(0);
- });
-});
-```
-
-**Step 3: 运行测试验证失败**
-
-Run: `cd e2e && npm test --grep "关于页面冒烟测试"`
-
-Expected: FAIL with "aboutPage is not defined"
-
-**Step 4: 更新 fixtures 以包含新页面**
-
-```typescript
-// e2e/src/fixtures/base.fixture.ts
-import { test as base } from '@playwright/test';
-import { AboutPage } from '../pages/AboutPage';
-import { CasesPage } from '../pages/CasesPage';
-import { ServicesPage } from '../pages/ServicesPage';
-import { ProductsPage } from '../pages/ProductsPage';
-import { SolutionsPage } from '../pages/SolutionsPage';
-import { NewsPage } from '../pages/NewsPage';
-
-export const test = base.extend<{
- aboutPage: AboutPage;
- casesPage: CasesPage;
- servicesPage: ServicesPage;
- productsPage: ProductsPage;
- solutionsPage: SolutionsPage;
- newsPage: NewsPage;
-}>({
- aboutPage: async ({ page }, use) => {
- const aboutPage = new AboutPage(page);
- await use(aboutPage);
- },
- casesPage: async ({ page }, use) => {
- const casesPage = new CasesPage(page);
- await use(casesPage);
- },
- servicesPage: async ({ page }, use) => {
- const servicesPage = new ServicesPage(page);
- await use(servicesPage);
- },
- productsPage: async ({ page }, use) => {
- const productsPage = new ProductsPage(page);
- await use(productsPage);
- },
- solutionsPage: async ({ page }, use) => {
- const solutionsPage = new SolutionsPage(page);
- await use(solutionsPage);
- },
- newsPage: async ({ page }, use) => {
- const newsPage = new NewsPage(page);
- await use(newsPage);
- },
-});
-```
-
-**Step 5: 运行测试验证通过**
-
-Run: `cd e2e && npm test --grep "关于页面冒烟测试"`
-
-Expected: PASS
-
-**Step 6: 为其他页面创建类似的测试**
-
-重复步骤 1-5,为 CasesPage、ServicesPage、ProductsPage、SolutionsPage、NewsPage 创建 Page Objects 和测试。
-
-**Step 7: 提交代码**
-
-```bash
-git add e2e/src/pages/ e2e/src/tests/smoke/ e2e/src/fixtures/base.fixture.ts
-git commit -m "test: add smoke tests for all major pages"
-```
-
----
-
-### Task 1.3: 完善错误处理
-
-**Files:**
-- Create: `src/app/not-found.tsx`
-- Create: `src/app/error.tsx`
-- Create: `src/components/ui/error-boundary.tsx`
-- Modify: `src/app/layout.tsx:1-50`
-
-**Step 1: 创建 404 页面**
-
-```typescript
-// src/app/not-found.tsx
-import Link from 'next/link';
-import { Button } from '@/components/ui/button';
-import { Home, ArrowRight } from 'lucide-react';
-
-export default function NotFound() {
- return (
-
-
-
404
-
- 页面未找到
-
-
- 抱歉,您访问的页面不存在。
-
-
-
-
-
-
-
- );
-}
-```
-
-**Step 2: 创建全局错误页面**
-
-```typescript
-// src/app/error.tsx
-'use client';
-
-import { useEffect } from 'react';
-import { Button } from '@/components/ui/button';
-import Link from 'next/link';
-import { AlertCircle, RefreshCw } from 'lucide-react';
-
-export default function Error({
- error,
- reset,
-}: {
- error: Error & { digest?: string };
- reset: () => void;
-}) {
- useEffect(() => {
- console.error(error);
- }, [error]);
-
- return (
-
-
-
-
- 出错了
-
-
- 抱歉,页面加载时发生了错误。请刷新页面或联系我们的技术支持。
-
-
-
-
-
-
-
- );
-}
-```
-
-**Step 3: 创建错误边界组件**
-
-```typescript
-// src/components/ui/error-boundary.tsx
-'use client';
-
-import { Component, ReactNode } from 'react';
-
-interface ErrorBoundaryProps {
- children: ReactNode;
- fallback?: ReactNode;
-}
-
-interface ErrorBoundaryState {
- hasError: boolean;
-}
-
-export class ErrorBoundary extends Component<
- ErrorBoundaryProps,
- ErrorBoundaryState
-> {
- constructor(props: ErrorBoundaryProps) {
- super(props);
- this.state = { hasError: false };
- }
-
- static getDerivedStateFromError(_: Error): ErrorBoundaryState {
- return { hasError: true };
- }
-
- componentDidCatch(error: Error, errorInfo: any) {
- console.error('ErrorBoundary caught an error:', error, errorInfo);
- }
-
- render() {
- if (this.state.hasError) {
- return this.props.fallback || (
-
-
-
- 组件加载失败
-
-
- 抱歉,页面部分内容加载失败。请刷新页面重试。
-
-
-
- );
- }
-
- return this.props.children;
- }
-}
-```
-
-**Step 4: 在根布局中集成错误边界**
-
-```typescript
-// src/app/layout.tsx
-import { ErrorBoundary } from '@/components/ui/error-boundary';
-
-export default function RootLayout({ children }: { children: React.ReactNode }) {
- return (
-
-
-
- {children}
-
-
-
- );
-}
-```
-
-**Step 5: 运行测试验证错误处理**
-
-Run: `npm run build`
-
-Expected: BUILD SUCCESS
-
-**Step 6: 添加错误处理的E2E测试**
-
-```typescript
-// e2e/src/tests/smoke/error-handling.smoke.spec.ts
-import { test, expect } from '@playwright/test';
-
-test.describe('错误处理冒烟测试 @smoke', () => {
- test('应该显示404页面', async ({ page }) => {
- await page.goto('/non-existent-page');
- await expect(page.locator('h1')).toContainText('404');
- await expect(page.locator('h2')).toContainText('页面未找到');
- });
-
- test('404页面应该有返回首页按钮', async ({ page }) => {
- await page.goto('/non-existent-page');
- const homeButton = page.getByRole('link', { name: /返回首页/ });
- await expect(homeButton).toBeVisible();
- await homeButton.click();
- await expect(page).toHaveURL('/');
- });
-});
-```
-
-**Step 7: 提交代码**
-
-```bash
-git add src/app/not-found.tsx src/app/error.tsx src/components/ui/error-boundary.tsx src/app/layout.tsx e2e/src/tests/smoke/error-handling.smoke.spec.ts
-git commit -m "feat: implement comprehensive error handling with 404 and error pages"
-```
-
----
-
-## 阶段二:中优先级优化(1周)
-
-### Task 2.1: 优化加载性能
-
-**Files:**
-- Create: `src/components/ui/optimized-image.tsx`
-- Modify: `src/components/sections/hero-section.tsx:1-100`
-- Modify: `src/components/sections/services-section.tsx:1-100`
-- Modify: `src/components/sections/products-section.tsx:1-100`
-- Modify: `src/components/sections/cases-section.tsx:1-100`
-- Modify: `src/components/sections/news-section.tsx:1-100`
-- Modify: `next.config.ts:1-50`
-
-**Step 1: 创建优化的图片组件**
-
-```typescript
-// src/components/ui/optimized-image.tsx
-'use client';
-
-import Image from 'next/image';
-import { useState } from 'react';
-
-interface OptimizedImageProps {
- src: string;
- alt: string;
- width?: number;
- height?: number;
- className?: string;
- priority?: boolean;
-}
-
-export function OptimizedImage({
- src,
- alt,
- width = 800,
- height = 600,
- className,
- priority = false,
-}: OptimizedImageProps) {
- const [isLoading, setIsLoading] = useState(true);
-
- return (
-
- {isLoading && (
-
- )}
-
setIsLoading(false)}
- sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
- />
-
- );
-}
-```
-
-**Step 2: 更新 Next.js 配置以支持图片优化**
-
-```typescript
-// next.config.ts
-const nextConfig = {
- images: {
- remotePatterns: [
- {
- protocol: 'https',
- hostname: '**',
- },
- ],
- formats: ['image/avif', 'image/webp'],
- deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
- imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
- },
- // 其他配置...
-};
-```
-
-**Step 3: 在各个 section 中使用优化的图片组件**
-
-```typescript
-// 示例:src/components/sections/hero-section.tsx
-import { OptimizedImage } from '@/components/ui/optimized-image';
-
-// 替换所有
标签为
-
-```
-
-**Step 4: 实现代码分割和懒加载**
-
-```typescript
-// src/app/(marketing)/page.tsx
-import dynamic from 'next/dynamic';
-
-// 使用动态导入和懒加载
-const HeroSection = dynamic(
- () => import('@/components/sections/hero-section').then(mod => ({ default: mod.HeroSection })),
- { loading: () => , ssr: true }
-);
-
-const ServicesSection = dynamic(
- () => import('@/components/sections/services-section').then(mod => ({ default: mod.ServicesSection })),
- { loading: () => , ssr: false }
-);
-```
-
-**Step 5: 添加性能测试**
-
-```typescript
-// e2e/src/tests/performance/image-loading.spec.ts
-import { test, expect } from '@playwright/test';
-
-test.describe('图片加载性能测试 @performance', () => {
- test('应该使用优化的图片格式', async ({ page }) => {
- await page.goto('/');
-
- const images = await page.locator('img').all();
- for (const image of images) {
- const src = await image.getAttribute('src');
- if (src) {
- expect(src).toMatch(/\.(avif|webp|jpg|png)$/);
- }
- }
- });
-
- test('应该有合理的图片尺寸', async ({ page }) => {
- await page.goto('/');
-
- const images = await page.locator('img').all();
- for (const image of images) {
- const width = await image.getAttribute('width');
- const height = await image.getAttribute('height');
- expect(width).toBeTruthy();
- expect(height).toBeTruthy();
- }
- });
-});
-```
-
-**Step 6: 运行性能测试**
-
-Run: `cd e2e && npm test --grep "图片加载性能测试"`
-
-Expected: PASS
-
-**Step 7: 提交代码**
-
-```bash
-git add src/components/ui/optimized-image.tsx next.config.ts src/components/sections/ e2e/src/tests/performance/
-git commit -m "perf: implement image optimization and code splitting"
-```
-
----
-
-### Task 2.2: 改进移动端体验
-
-**Files:**
-- Modify: `src/components/layout/mobile-menu.tsx:1-200`
-- Modify: `src/components/layout/mobile-tab-bar.tsx:1-100`
-- Create: `e2e/src/tests/responsive/mobile-ux.spec.ts`
-
-**Step 1: 优化移动端菜单交互**
-
-```typescript
-// src/components/layout/mobile-menu.tsx
-'use client';
-
-import { useState, useEffect, useRef } from 'react';
-import { X } from 'lucide-react';
-
-export function MobileMenu({ isOpen, onClose, children }: any) {
- const menuRef = useRef(null);
-
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
- onClose();
- }
- };
-
- if (isOpen) {
- document.addEventListener('mousedown', handleClickOutside);
- document.body.style.overflow = 'hidden';
- } else {
- document.body.style.overflow = 'unset';
- }
-
- return () => {
- document.removeEventListener('mousedown', handleClickOutside);
- document.body.style.overflow = 'unset';
- };
- }, [isOpen, onClose]);
-
- if (!isOpen) return null;
-
- return (
-
- );
-}
-```
-
-**Step 2: 添加移动端触摸优化**
-
-```typescript
-// src/components/ui/touch-button.tsx
-'use client';
-
-import { Button } from './button';
-import { forwardRef } from 'react';
-
-export const TouchButton = forwardRef<
- HTMLButtonElement,
- React.ComponentProps
->((props, ref) => {
- return (
-
- );
-});
-```
-
-**Step 3: 添加移动端UX测试**
-
-```typescript
-// e2e/src/tests/responsive/mobile-ux.spec.ts
-import { test, expect } from '@playwright/test';
-
-test.describe('移动端UX测试 @responsive', () => {
- test.use({ viewport: { width: 375, height: 667 } });
-
- test('应该能够打开和关闭移动端菜单', async ({ page }) => {
- await page.goto('/');
-
- const menuButton = page.getByRole('button', { name: /菜单/ });
- await menuButton.tap();
- await expect(page.locator('[role="dialog"]')).toBeVisible();
-
- const closeButton = page.getByRole('button', { name: /关闭/ });
- await closeButton.tap();
- await expect(page.locator('[role="dialog"]')).not.toBeVisible();
- });
-
- test('应该能够通过触摸导航', async ({ page }) => {
- await page.goto('/');
-
- const menuButton = page.getByRole('button', { name: /菜单/ });
- await menuButton.tap();
-
- const navItem = page.getByRole('link', { name: /核心业务/ });
- await navItem.tap();
- await expect(page).toHaveURL(/services/);
- });
-
- test('触摸目标应该足够大', async ({ page }) => {
- await page.goto('/');
-
- const buttons = await page.locator('button, a[role="button"]').all();
- for (const button of buttons) {
- const box = await button.boundingBox();
- expect(box?.width).toBeGreaterThanOrEqual(44);
- expect(box?.height).toBeGreaterThanOrEqual(44);
- }
- });
-});
-```
-
-**Step 4: 运行移动端测试**
-
-Run: `cd e2e && npm test --grep "移动端UX测试"`
-
-Expected: PASS
-
-**Step 5: 提交代码**
-
-```bash
-git add src/components/layout/mobile-menu.tsx src/components/ui/touch-button.tsx e2e/src/tests/responsive/mobile-ux.spec.ts
-git commit -m "feat: improve mobile experience with optimized menu and touch targets"
-```
-
----
-
-### Task 2.3: SEO优化
-
-**Files:**
-- Create: `src/components/seo/structured-data.tsx`
-- Modify: `src/app/layout.tsx:1-50`
-- Modify: `src/app/(marketing)/page.tsx:1-20`
-- Modify: `src/app/(marketing)/about/page.tsx:1-15`
-- Modify: `src/app/(marketing)/cases/page.tsx:1-20`
-- Modify: `src/app/(marketing)/services/page.tsx:1-20`
-- Modify: `src/app/(marketing)/products/page.tsx:1-20`
-
-**Step 1: 创建结构化数据组件**
-
-```typescript
-// src/components/seo/structured-data.tsx
-interface StructuredDataProps {
- data: Record;
-}
-
-export function StructuredData({ data }: StructuredDataProps) {
- return (
-
- );
-}
-```
-
-**Step 2: 在根布局中添加基础SEO**
-
-```typescript
-// src/app/layout.tsx
-import { StructuredData } from '@/components/seo/structured-data';
-import { COMPANY_INFO } from '@/lib/constants';
-
-export const metadata = {
- metadataBase: new URL('http://localhost:3000'),
- title: {
- default: `${COMPANY_INFO.name} - ${COMPANY_INFO.slogan}`,
- template: `%s - ${COMPANY_INFO.name}`,
- },
- description: COMPANY_INFO.description,
- keywords: ['数字化转型', '软件开发', '云服务', '数据分析', '信息安全'],
- openGraph: {
- title: COMPANY_INFO.name,
- description: COMPANY_INFO.description,
- url: 'http://localhost:3000',
- siteName: COMPANY_INFO.name,
- images: [
- {
- url: '/logo.webp',
- width: 1200,
- height: 630,
- },
- ],
- },
-};
-
-export default function RootLayout({ children }: { children: React.ReactNode }) {
- const organizationData = {
- '@context': 'https://schema.org',
- '@type': 'Organization',
- name: COMPANY_INFO.name,
- url: 'http://localhost:3000',
- logo: 'http://localhost:3000/logo.webp',
- description: COMPANY_INFO.description,
- address: {
- '@type': 'PostalAddress',
- streetAddress: COMPANY_INFO.address,
- addressLocality: '成都市',
- addressRegion: '四川省',
- addressCountry: 'CN',
- },
- contactPoint: {
- '@type': 'ContactPoint',
- telephone: COMPANY_INFO.phone,
- email: COMPANY_INFO.email,
- },
- };
-
- return (
-
-
-
-
-
- {children}
-
-
- );
-}
-```
-
-**Step 3: 为各个页面添加特定的结构化数据**
-
-```typescript
-// 示例:src/app/(marketing)/services/page.tsx
-import { StructuredData } from '@/components/seo/structured-data';
-import { SERVICES } from '@/lib/constants';
-
-export const metadata = {
- title: '核心业务 - 睿新致远',
- description: '专业技术团队,为您提供全方位的数字化解决方案',
-};
-
-export default function ServicesPage() {
- const servicesData = {
- '@context': 'https://schema.org',
- '@type': 'ItemList',
- itemListElement: SERVICES.map((service) => ({
- '@type': 'Service',
- name: service.title,
- description: service.description,
- })),
- };
-
- return (
-
-
- {/* 页面内容 */}
-
- );
-}
-```
-
-**Step 4: 添加SEO验证测试**
-
-```typescript
-// e2e/src/tests/smoke/seo.smoke.spec.ts
-import { test, expect } from '@playwright/test';
-
-test.describe('SEO冒烟测试 @smoke', () => {
- test('应该有正确的页面标题', async ({ page }) => {
- await page.goto('/');
-
- const title = await page.title();
- expect(title).toContain('睿新致远');
- });
-
- test('应该有meta描述', async ({ page }) => {
- await page.goto('/');
-
- const description = await page.locator('meta[name="description"]').getAttribute('content');
- expect(description).toBeTruthy();
- expect(description?.length).toBeGreaterThan(50);
- });
-
- test('应该有结构化数据', async ({ page }) => {
- await page.goto('/');
-
- const structuredData = await page.locator('script[type="application/ld+json"]').count();
- expect(structuredData).toBeGreaterThan(0);
- });
-
- test('应该有Open Graph标签', async ({ page }) => {
- await page.goto('/');
-
- const ogTitle = await page.locator('meta[property="og:title"]').getAttribute('content');
- const ogDescription = await page.locator('meta[property="og:description"]').getAttribute('content');
- expect(ogTitle).toBeTruthy();
- expect(ogDescription).toBeTruthy();
- });
-});
-```
-
-**Step 5: 运行SEO测试**
-
-Run: `cd e2e && npm test --grep "SEO冒烟测试"`
-
-Expected: PASS
-
-**Step 6: 提交代码**
-
-```bash
-git add src/components/seo/structured-data.tsx src/app/layout.tsx src/app/ e2e/src/tests/smoke/seo.smoke.spec.ts
-git commit -m "feat: implement comprehensive SEO optimization with structured data"
-```
-
----
-
-## 阶段三:低优先级优化(1个月)
-
-### Task 3.1: 代码重构
-
-**Files:**
-- Create: `src/components/ui/page-header.tsx`
-- Modify: `src/app/(marketing)/about/page.tsx:1-15`
-- Modify: `src/app/(marketing)/cases/page.tsx:1-20`
-- Modify: `src/app/(marketing)/services/page.tsx:1-20`
-- Modify: `src/app/(marketing)/products/page.tsx:1-20`
-- Modify: `src/app/(marketing)/solutions/page.tsx:1-20`
-- Modify: `src/app/(marketing)/contact/page.tsx:1-20`
-- Modify: `src/app/(marketing)/news/page.tsx:1-20`
-
-**Step 1: 统一页面标题组件**
-
-```typescript
-// src/components/ui/page-header.tsx
-import { Badge } from './badge';
-
-interface PageHeaderProps {
- badge?: string;
- title: string;
- description: string;
-}
-
-export function PageHeader({ badge, title, description }: PageHeaderProps) {
- return (
-
-
- {badge && (
-
{badge}
- )}
-
- {title}
-
-
- {description}
-
-
-
- );
-}
-```
-
-**Step 2: 提取公共卡片组件**
-
-```typescript
-// src/components/ui/content-card.tsx
-import Link from 'next/link';
-import { Card, CardContent } from './card';
-import { Badge } from './badge';
-
-interface ContentCardProps {
- id: string;
- title: string;
- description: string;
- category?: string;
- date?: string;
- image?: string;
- href: string;
-}
-
-export function ContentCard({
- id,
- title,
- description,
- category,
- date,
- image,
- href,
-}: ContentCardProps) {
- return (
-
-
-
- {image && (
-
- 📰
-
- )}
-
- {category && (
-
- {category}
-
- )}
- {date && (
-
- {date}
-
- )}
-
- {title}
-
-
- {description}
-
-
-
-
-
- );
-}
-```
-
-**Step 3: 在各个页面中使用统一组件**
-
-```typescript
-// 示例:src/app/(marketing)/cases/page.tsx
-import { PageHeader } from '@/components/ui/page-header';
-import { ContentCard } from '@/components/ui/content-card';
-
-export default function CasesPage() {
- return (
-
-
-
-
- {CASES.map((caseItem) => (
-
- ))}
-
-
-
- );
-}
-```
-
-**Step 4: 运行测试验证重构**
-
-Run: `npm run lint && npm run build`
-
-Expected: No linting errors, BUILD SUCCESS
-
-**Step 5: 提交代码**
-
-```bash
-git add src/components/ui/page-header.tsx src/components/ui/content-card.tsx src/app/
-git commit -m "refactor: extract common components and unify page structure"
-```
-
----
-
-### Task 3.2: 视觉优化
-
-**Files:**
-- Create: `src/components/ui/animated-section.tsx`
-- Modify: `src/components/sections/hero-section.tsx:1-100`
-- Modify: `src/components/sections/services-section.tsx:1-100`
-- Modify: `src/components/sections/products-section.tsx:1-100`
-
-**Step 1: 创建优化的动画section组件**
-
-```typescript
-// src/components/ui/animated-section.tsx
-'use client';
-
-import { useRef, useEffect } from 'react';
-import { motion, useInView } from 'framer-motion';
-
-interface AnimatedSectionProps {
- children: React.ReactNode;
- className?: string;
- delay?: number;
-}
-
-export function AnimatedSection({
- children,
- className = '',
- delay = 0,
-}: AnimatedSectionProps) {
- const ref = useRef(null);
- const isInView = useInView(ref, { once: true, margin: '-100px' });
-
- return (
-
- {children}
-
- );
-}
-```
-
-**Step 2: 添加微交互效果**
-
-```typescript
-// src/components/ui/interactive-card.tsx
-'use client';
-
-import { motion } from 'framer-motion';
-import { Card } from './card';
-
-interface InteractiveCardProps {
- children: React.ReactNode;
- className?: string;
- onClick?: () => void;
-}
-
-export function InteractiveCard({
- children,
- className = '',
- onClick,
-}: InteractiveCardProps) {
- return (
-
- {children}
-
- );
-}
-```
-
-**Step 3: 添加视觉回归测试**
-
-```typescript
-// e2e/src/tests/visual/interactions.visual.spec.ts
-import { test, expect } from '@playwright/test';
-
-test.describe('交互视觉回归测试 @visual', () => {
- test('卡片悬停状态应该一致', async ({ page }) => {
- await page.goto('/services');
-
- const card = page.locator('.group').first();
- await card.hover();
- await expect(page).toHaveScreenshot('card-hover.png', {
- maxDiffPixels: 100,
- });
- });
-
- test('按钮点击状态应该一致', async ({ page }) => {
- await page.goto('/');
-
- const button = page.getByRole('button', { name: /立即咨询/ });
- await button.hover();
- await expect(page).toHaveScreenshot('button-hover.png', {
- maxDiffPixels: 100,
- });
- });
-});
-```
-
-**Step 4: 运行视觉测试**
-
-Run: `cd e2e && npm test --grep "交互视觉回归测试"`
-
-Expected: PASS
-
-**Step 5: 提交代码**
-
-```bash
-git add src/components/ui/animated-section.tsx src/components/ui/interactive-card.tsx e2e/src/tests/visual/interactions.visual.spec.ts
-git commit -m "feat: add enhanced animations and micro-interactions"
-```
-
----
-
-## 测试验证清单
-
-在每个阶段完成后,运行以下测试验证:
-
-### 阶段一验证
-```bash
-# 导航一致性测试
-cd e2e && npm test --grep "导航"
-
-# 页面冒烟测试
-cd e2e && npm test --grep "冒烟测试"
-
-# 错误处理测试
-cd e2e && npm test --grep "错误处理"
-```
-
-### 阶段二验证
-```bash
-# 性能测试
-cd e2e && npm test --grep "@performance"
-
-# 移动端测试
-cd e2e && npm test --grep "@responsive"
-
-# SEO测试
-cd e2e && npm test --grep "SEO"
-```
-
-### 阶段三验证
-```bash
-# 视觉测试
-cd e2e && npm test --grep "@visual"
-
-# 回归测试
-cd e2e && npm test --grep "@regression"
-
-# 完整测试套件
-cd e2e && npm test
-```
-
----
-
-## 代码质量检查
-
-在每个任务完成后,运行以下命令确保代码质量:
-
-```bash
-# Lint检查
-npm run lint
-
-# 类型检查
-npx tsc --noEmit
-
-# 构建检查
-npm run build
-
-# 格式化检查
-npx prettier --check "src/**/*.{ts,tsx}"
-```
-
----
-
-## 文档更新
-
-在完成每个阶段后,更新以下文档:
-
-### README.md
-- 更新项目结构
-- 添加新的组件说明
-- 更新测试命令
-
-### CHANGELOG.md
-```markdown
-## [版本号] - YYYY-MM-DD
-
-### 新增
-- 面包屑导航组件
-- 统一的错误处理页面
-- 优化的图片加载组件
-- 移动端触摸优化
-- SEO结构化数据
-
-### 改进
-- 导航一致性
-- 移动端体验
-- 页面加载性能
-- SEO优化
-
-### 修复
-- 修复服务详情页Link导入问题
-- 修复导航不一致问题
-```
-
----
-
-## 部署检查清单
-
-在部署到生产环境前,确保:
-
-- [ ] 所有测试通过
-- [ ] Lint检查通过
-- [ ] 类型检查通过
-- [ ] 构建成功
-- [ ] 环境变量配置正确
-- [ ] API端点配置正确
-- [ ] 图片资源优化
-- [ ] 性能指标达标(Lighthouse分数 > 90)
-- [ ] 无障碍检查通过(axe-core)
-- [ ] SEO检查通过(Google Rich Results Test)
-
----
-
-## 回滚计划
-
-如果某个阶段出现问题,可以按以下步骤回滚:
-
-```bash
-# 查看提交历史
-git log --oneline
-
-# 回滚到上一个稳定版本
-git revert
-
-# 或者回滚到特定提交
-git reset --hard
-
-# 强制推送(谨慎使用)
-git push --force
-```
-
----
-
-## 持续集成配置
-
-确保以下CI/CD配置正确:
-
-### .woodpecker.yml
-```yaml
-pipeline:
- test:
- image: node:18
- commands:
- - npm ci
- - npm run lint
- - npm run build
- - cd e2e && npm ci
- - cd e2e && npm test
-
- deploy:
- image: node:18
- commands:
- - npm run build
- - # 部署命令
-```
-
----
-
-## 总结
-
-本实施计划分为三个阶段,每个阶段包含多个bite-sized任务:
-
-1. **阶段一(1-2天)**:高优先级修复
- - 导航一致性
- - 测试覆盖
- - 错误处理
-
-2. **阶段二(1周)**:中优先级优化
- - 性能优化
- - 移动端体验
- - SEO优化
-
-3. **阶段三(1个月)**:低优先级优化
- - 代码重构
- - 视觉优化
-
-每个任务都遵循TDD原则,包含完整的测试、实现和验证步骤。建议按阶段顺序执行,每个阶段完成后进行完整的测试验证。
diff --git a/docs/plans/2026-02-28-e2e-test-migration-implementation.md b/docs/plans/2026-02-28-e2e-test-migration-implementation.md
deleted file mode 100644
index 42df1f9..0000000
--- a/docs/plans/2026-02-28-e2e-test-migration-implementation.md
+++ /dev/null
@@ -1,287 +0,0 @@
-# E2E测试框架统一迁移实施计划
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**Goal:** 将现有的Python+Pytest测试框架完全迁移到TypeScript+Playwright,建立金融级网站的完整E2E测试体系
-
-**Architecture:** 采用页面对象模式(POM)设计,分层架构(基础设施层、页面对象层、测试用例层、报告监控层),五层测试体系(Smoke、Regression、Performance、Security、Accessibility)
-
-**Tech Stack:** TypeScript 5, Playwright 1.48+, Node.js 20, Woodpecker CI, @axe-core/playwright
-
----
-
-## 阶段1: 评估与准备(1-2天)
-
-### Task 1: 分析现有Python测试用例
-
-**Files:**
-- Read: `e2e-tests/tests/*.py`
-- Create: `docs/test-migration-analysis.md`
-
-**Step 1: 读取所有Python测试文件**
-
-分析以下文件:
-- `e2e-tests/tests/test_contact_form.py`
-- `e2e-tests/tests/test_home_page.py`
-- `e2e-tests/tests/test_navigation.py`
-- `e2e-tests/tests/test_performance.py`
-- `e2e-tests/tests/test_responsive.py`
-
-**Step 2: 分析测试用例清单**
-
-创建测试用例清单,包含:
-- 测试场景描述
-- 测试类型(smoke/regression/performance等)
-- 优先级(高/中/低)
-- 迁移状态(待迁移/已迁移/需重构)
-- Playwright对应文件路径
-
-**Step 3: 生成分析报告**
-
-创建文档 `docs/test-migration-analysis.md`,包含:
-- 现有测试统计(总用例数、各类型分布)
-- 核心测试场景识别
-- 需要迁移的测试列表
-- 需要新增的测试列表
-- 风险评估
-
-**Step 4: 提交分析结果**
-
-```bash
-git add docs/test-migration-analysis.md
-git commit -m "docs: 添加Python测试用例分析报告"
-```
-
----
-
-### Task 2: 评估现有Playwright测试
-
-**Files:**
-- Read: `e2e/src/tests/**/*.spec.ts`
-- Read: `e2e/src/pages/*.ts`
-- Create: `docs/playwright-test-coverage.md`
-
-**Step 1: 分析现有Playwright测试结构**
-
-检查以下目录:
-- `e2e/src/tests/smoke/`
-- `e2e/src/tests/regression/`
-- `e2e/src/tests/performance/`
-- `e2e/src/tests/visual/`
-- `e2e/src/tests/mobile/`
-- `e2e/src/tests/responsive/`
-
-**Step 2: 评估页面对象模型**
-
-检查以下文件:
-- `e2e/src/pages/BasePage.ts`
-- `e2e/src/pages/HomePage.ts`
-- `e2e/src/pages/ContactPage.ts`
-- 其他页面对象文件
-
-**Step 3: 生成覆盖率报告**
-
-创建文档 `docs/playwright-test-coverage.md`,包含:
-- 现有测试覆盖率统计
-- 页面对象完整性评估
-- 缺失的测试场景
-- 需要改进的地方
-
-**Step 4: 提交评估结果**
-
-```bash
-git add docs/playwright-test-coverage.md
-git commit -m "docs: 添加Playwright测试覆盖率评估"
-```
-
----
-
-### Task 3: 准备测试数据管理
-
-**Files:**
-- Create: `e2e/test-data/contact-form.json`
-- Create: `e2e/test-data/products.json`
-- Create: `e2e/test-data/performance-budgets.json`
-- Modify: `e2e/src/utils/TestDataGenerator.ts`
-
-**Step 1: 创建联系表单测试数据**
-
-创建文件 `e2e/test-data/contact-form.json`:
-
-```json
-{
- "valid": {
- "name": "张三",
- "email": "zhangsan@example.com",
- "phone": "13800138000",
- "company": "测试公司",
- "message": "这是一条测试消息,用于验证联系表单功能。"
- },
- "invalid": {
- "emptyName": {
- "name": "",
- "email": "test@example.com",
- "message": "测试消息",
- "expectedError": "请输入姓名"
- },
- "emptyEmail": {
- "name": "测试用户",
- "email": "",
- "message": "测试消息",
- "expectedError": "请输入邮箱"
- },
- "invalidEmail": {
- "name": "测试用户",
- "email": "invalid-email",
- "message": "测试消息",
- "expectedError": "邮箱格式不正确"
- },
- "emptyMessage": {
- "name": "测试用户",
- "email": "test@example.com",
- "message": "",
- "expectedError": "请输入留言内容"
- }
- },
- "xss": {
- "scriptInjection": {
- "name": "",
- "email": "test@example.com",
- "message": "
"
- }
- }
-}
-```
-
-**Step 2: 创建产品测试数据**
-
-创建文件 `e2e/test-data/products.json`:
-
-```json
-{
- "products": [
- {
- "id": "product-1",
- "name": "智能风控系统",
- "category": "风险管理",
- "description": "基于AI的智能风控解决方案"
- }
- ]
-}
-```
-
-**Step 3: 创建性能预算配置**
-
-创建文件 `e2e/test-data/performance-budgets.json`:
-
-```json
-{
- "performanceBudgets": {
- "home": {
- "loadTime": 3000,
- "fcp": 1500,
- "lcp": 2500,
- "tti": 3500,
- "totalSize": 1500000
- },
- "contact": {
- "loadTime": 2500,
- "fcp": 1200,
- "lcp": 2000,
- "tti": 3000,
- "totalSize": 1200000
- }
- }
-}
-```
-
-**Step 4: 增强TestDataGenerator**
-
-修改文件 `e2e/src/utils/TestDataGenerator.ts`,添加数据加载功能。
-
-**Step 5: 提交测试数据**
-
-```bash
-git add e2e/test-data/ e2e/src/utils/TestDataGenerator.ts
-git commit -m "feat: 添加测试数据管理功能"
-```
-
----
-
-### Task 4: 配置多环境支持
-
-**Files:**
-- Create: `e2e/.env.development`
-- Create: `e2e/.env.staging`
-- Create: `e2e/.env.production`
-- Create: `e2e/.env.example`
-- Modify: `e2e/playwright.config.ts`
-
-**Step 1: 创建环境配置文件**
-
-创建各环境配置文件,支持development/staging/production环境。
-
-**Step 2: 更新Playwright配置**
-
-修改文件 `e2e/playwright.config.ts`,支持环境变量。
-
-**Step 3: 安装dotenv依赖**
-
-```bash
-cd e2e
-npm install --save-dev dotenv
-```
-
-**Step 4: 提交环境配置**
-
-```bash
-git add e2e/.env* e2e/playwright.config.ts e2e/package.json
-git commit -m "feat: 配置多环境支持"
-```
-
----
-
-## 阶段2: 核心测试迁移(3-5天)
-
-### Task 5-8: 完善页面对象和测试
-
-详细步骤包括:
-- Task 5: 完善BasePage页面对象
-- Task 6: 完善ContactPage页面对象
-- Task 7: 完善其他页面对象
-- Task 8: 迁移导航测试
-
-每个任务遵循TDD流程:编写测试 → 运行验证失败 → 实现功能 → 运行验证通过 → 提交代码。
-
----
-
-## 阶段3: 专项测试补充(3-4天)
-
-### Task 9-11: 实施专项测试
-
-- Task 9: 实施性能测试(Core Web Vitals)
-- Task 10: 实施安全测试(XSS防护、安全头)
-- Task 11: 实施可访问性测试(WCAG 2.1 AA)
-
----
-
-## 阶段4: CI/CD集成与清理(2-3天)
-
-### Task 12-15: CI配置和清理
-
-- Task 12: 配置Woodpecker CI
-- Task 13: 创建测试报告脚本
-- Task 14: 删除Python测试框架
-- Task 15: 创建测试指南文档
-
----
-
-## 总结
-
-本实施计划将整个迁移工作分解为15个具体任务,遵循TDD原则,每个任务都有明确的文件路径、代码示例和验证步骤。预计总工期9-14天,可根据实际情况调整。
-
-**关键原则**:
-- DRY (Don't Repeat Yourself)
-- YAGNI (You Aren't Gonna Need It)
-- TDD (Test-Driven Development)
-- 频繁提交
diff --git a/docs/plans/2026-02-28-e2e-test-unification-design.md b/docs/plans/2026-02-28-e2e-test-unification-design.md
deleted file mode 100644
index f1c9ce0..0000000
--- a/docs/plans/2026-02-28-e2e-test-unification-design.md
+++ /dev/null
@@ -1,944 +0,0 @@
-# Novalon Website E2E测试统一方案设计
-
-**创建时间**: 2026-02-28
-**目标**: 统一E2E测试框架,从Python+Pytest迁移到TypeScript+Playwright,建立金融级网站完整的测试体系
-
----
-
-## 一、背景与目标
-
-### 当前状态
-- **两套测试框架并存**:
- - TypeScript + Playwright (`e2e/` 目录)
- - Python + Pytest (`e2e-tests/` 目录)
-- **维护成本高**: 需要维护两套技术栈
-- **测试覆盖不完整**: 部分测试场景缺失或重复
-
-### 核心目标
-1. **统一技术栈**: 完全迁移到Playwright,与Next.js项目技术栈一致
-2. **全面测试覆盖**: 建立业务流程、性能、安全、可访问性完整测试体系
-3. **金融级质量**: 满足金融行业对安全、合规、可靠性的高要求
-4. **CI/CD集成**: 建立分层测试流程,平衡速度和覆盖率
-
----
-
-## 二、技术选型决策
-
-### 选择: TypeScript + Playwright
-
-**决策理由**:
-- ✅ 与项目技术栈一致(Next.js + TypeScript)
-- ✅ 可共享类型定义,更好的类型安全
-- ✅ Playwright功能强大,支持多浏览器、移动端、视觉测试
-- ✅ 社区活跃,文档完善,生态成熟
-- ✅ 原生支持并行执行,性能优异
-
-**放弃: Python + Pytest**
-- ❌ 与项目技术栈不一致,增加维护成本
-- ❌ 无法共享类型定义,降低开发效率
-- ❌ 需要维护两套依赖和环境
-
----
-
-## 三、整体架构设计
-
-### 3.1 分层架构
-
-```
-┌─────────────────────────────────────────────────┐
-│ 报告与监控层 (Reports & Monitoring) │
-│ HTML报告 | JSON/JUnit报告 | 性能指标 | 趋势分析 │
-└─────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────┐
-│ 测试用例层 (Test Cases) │
-│ Smoke | Regression | Performance | Security │
-│ Accessibility | Visual | Mobile │
-└─────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────┐
-│ 页面对象层 (Page Objects) │
-│ BasePage | HomePage | ContactPage | Products │
-│ Components (Header, Footer, Form) │
-└─────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────┐
-│ 基础设施层 (Infrastructure) │
-│ Playwright配置 | 测试数据 | 工具库 | Fixtures │
-└─────────────────────────────────────────────────┘
-```
-
-### 3.2 目录结构
-
-```
-e2e/
-├── src/
-│ ├── fixtures/ # 测试夹具
-│ │ ├── base.fixture.ts # 基础fixture
-│ │ ├── a11y.fixture.ts # 可访问性fixture
-│ │ └── auth.fixture.ts # 认证fixture(如需要)
-│ ├── pages/ # 页面对象
-│ │ ├── BasePage.ts # 基础页面
-│ │ ├── HomePage.ts # 首页
-│ │ ├── ContactPage.ts # 联系页面
-│ │ ├── ProductsPage.ts # 产品页面
-│ │ ├── ServicesPage.ts # 服务页面
-│ │ ├── AboutPage.ts # 关于页面
-│ │ ├── CasesPage.ts # 案例页面
-│ │ ├── SolutionsPage.ts # 解决方案页面
-│ │ └── NewsPage.ts # 新闻页面
-│ ├── tests/ # 测试用例
-│ │ ├── smoke/ # 冒烟测试
-│ │ ├── regression/ # 回归测试
-│ │ ├── performance/ # 性能测试
-│ │ ├── security/ # 安全测试
-│ │ ├── accessibility/ # 可访问性测试
-│ │ ├── visual/ # 视觉回归测试
-│ │ ├── mobile/ # 移动端测试
-│ │ ├── responsive/ # 响应式测试
-│ │ └── error-handling/ # 错误处理测试
-│ ├── types/ # 类型定义
-│ │ └── index.ts # 共享类型
-│ └── utils/ # 工具库
-│ ├── PerformanceMonitor.ts # 性能监控
-│ ├── TestDataGenerator.ts # 测试数据生成
-│ ├── devices.ts # 设备配置
-│ └── helpers.ts # 辅助函数
-├── test-data/ # 测试数据文件
-│ ├── contact-form.json # 联系表单数据
-│ ├── products.json # 产品数据
-│ └── performance-budgets.json # 性能预算
-├── playwright.config.ts # Playwright配置
-├── package.json # 依赖管理
-└── tsconfig.json # TypeScript配置
-```
-
----
-
-## 四、测试分层策略
-
-### 4.1 测试金字塔
-
-```
- ┌─────────┐
- │ Security│ (每周/发布前)
- │ Access │ 10-15分钟
- └─────────┘
- ┌───────────────┐
- │ Performance │ (每日/发布前)
- │ 10-20分钟 │
- └───────────────┘
- ┌─────────────────────┐
- │ Regression │ (PR合并前/每日)
- │ 15-30分钟 │
- └─────────────────────┘
- ┌───────────────────────────┐
- │ Smoke │ (每次提交)
- │ < 5分钟 │
- └───────────────────────────┘
-```
-
-### 4.2 各层测试详解
-
-#### Level 1: Smoke Tests(冒烟测试)
-
-**执行频率**: 每次代码提交
-**执行时间**: < 5分钟
-**标签**: `@smoke`
-
-**覆盖范围**:
-- ✅ 所有关键页面可访问性(首页、产品、服务、联系)
-- ✅ 核心导航功能
-- ✅ 关键表单提交(联系表单)
-- ✅ 页面基本渲染(无JS错误)
-
-**测试用例**:
-```typescript
-test.describe('Smoke Tests @smoke', () => {
- test('首页可访问', async ({ page }) => {
- await homePage.goto();
- await expect(page).toHaveTitle(/Novalon/);
- });
-
- test('导航功能正常', async ({ page }) => {
- await homePage.goto();
- await homePage.navigateTo('产品');
- await expect(page).toHaveURL(/products/);
- });
-
- test('联系表单可提交', async ({ page }) => {
- await contactPage.goto();
- await contactPage.fillForm({
- name: '测试用户',
- email: 'test@example.com',
- message: '测试消息'
- });
- await contactPage.submit();
- await expect(contactPage.successMessage).toBeVisible();
- });
-});
-```
-
-#### Level 2: Regression Tests(回归测试)
-
-**执行频率**: PR合并前、每日构建
-**执行时间**: 15-30分钟
-**标签**: `@regression`
-
-**覆盖范围**:
-- ✅ 所有业务流程完整测试
-- ✅ 表单验证(必填项、格式校验、错误提示)
-- ✅ 页面间跳转和数据传递
-- ✅ 响应式布局(桌面/平板/移动端)
-- ✅ 多浏览器兼容性
-
-**测试用例**:
-```typescript
-test.describe('Contact Form Regression @regression', () => {
- test('表单验证 - 必填项', async ({ page }) => {
- await contactPage.goto();
- await contactPage.submit();
- await expect(contactPage.nameError).toHaveText('请输入姓名');
- await expect(contactPage.emailError).toHaveText('请输入邮箱');
- });
-
- test('表单验证 - 邮箱格式', async ({ page }) => {
- await contactPage.goto();
- await contactPage.fillEmail('invalid-email');
- await contactPage.submit();
- await expect(contactPage.emailError).toHaveText('邮箱格式不正确');
- });
-
- test('表单提交成功', async ({ page }) => {
- await contactPage.goto();
- await contactPage.fillForm(testData.validContact);
- await contactPage.submit();
- await expect(contactPage.successMessage).toBeVisible();
- });
-});
-```
-
-#### Level 3: Performance Tests(性能测试)
-
-**执行频率**: 每日构建、发布前
-**执行时间**: 10-20分钟
-**标签**: `@performance`
-
-**覆盖范围**:
-- ✅ 页面加载时间(FCP、LCP、TTI)
-- ✅ 资源大小优化(图片、JS、CSS)
-- ✅ 网络请求数量和瀑布流
-- ✅ 核心交互响应时间
-- ✅ 性能预算验证
-
-**性能预算**:
-```json
-{
- "performanceBudgets": {
- "home": {
- "loadTime": 3000,
- "fcP": 1500,
- "lcp": 2500,
- "tti": 3500,
- "totalSize": 1500000
- },
- "contact": {
- "loadTime": 2500,
- "fcp": 1200,
- "lcp": 2000,
- "tti": 3000,
- "totalSize": 1200000
- }
- }
-}
-```
-
-**测试用例**:
-```typescript
-test.describe('Performance Tests @performance', () => {
- test('首页性能预算', async ({ page }) => {
- const metrics = await performanceMonitor.measurePageLoad(page, '/');
-
- expect(metrics.loadTime).toBeLessThan(budgets.home.loadTime);
- expect(metrics.fcp).toBeLessThan(budgets.home.fcp);
- expect(metrics.lcp).toBeLessThan(budgets.home.lcp);
- });
-
- test('图片优化验证', async ({ page }) => {
- await page.goto('/');
- const images = await page.$$eval('img', imgs =>
- imgs.map(img => ({
- src: img.src,
- naturalWidth: img.naturalWidth,
- naturalHeight: img.naturalHeight,
- displayWidth: img.width,
- displayHeight: img.height
- }))
- );
-
- for (const img of images) {
- expect(img.naturalWidth).toBeLessThanOrEqual(img.displayWidth * 2);
- }
- });
-});
-```
-
-#### Level 4: Security Tests(安全测试)
-
-**执行频率**: 每周、发布前
-**执行时间**: 10-15分钟
-**标签**: `@security`
-
-**覆盖范围**:
-- ✅ XSS漏洞检测(表单输入)
-- ✅ CSRF保护验证
-- ✅ 安全头验证(CSP、HSTS等)
-- ✅ 敏感数据处理(联系表单数据加密)
-- ✅ HTTPS强制跳转
-
-**测试用例**:
-```typescript
-test.describe('Security Tests @security', () => {
- test('XSS防护 - 联系表单', async ({ page }) => {
- await contactPage.goto();
- await contactPage.fillForm({
- name: '',
- email: 'test@example.com',
- message: '
'
- });
- await contactPage.submit();
-
- const pageContent = await page.content();
- expect(pageContent).not.toContain('
-
-
-
-
-
-