docs: 删除过时的文档和测试报告文件

删除不再需要的文档、测试报告和计划文件,包括标题层级规范、颜色优化报告、测试框架文档等
This commit is contained in:
张翔
2026-03-07 15:37:19 +08:00
parent feb646efe5
commit 0175799004
73 changed files with 2499 additions and 45463 deletions
@@ -1,693 +0,0 @@
# Novalon 官网重新设计方案
**设计日期:** 2026-02-21
**设计风格:** 极简科技风
**项目目标:** 品牌形象升级 + 用户体验优化
---
## 一、项目背景
### 当前状态
- 技术栈:Next.js 16 + React 19 + TypeScript + Tailwind CSS v4
- 现有页面:首页包含13个section,信息密度较高
- 目标用户:混合群体(企业决策者、技术人员、业务人员)
### 设计目标
1. **品牌形象升级** - 打造科技创新与前沿感的品牌调性
2. **用户体验优化** - 全方位改进导航、内容展示、交互体验和移动端适配
---
## 二、整体架构与导航结构
### 信息架构优化
**一级导航(顶部固定):**
- 首页
- 产品(下拉:ERP、CRM、OA、BI、IoT
- 解决方案(下拉:按行业、按场景)
- 案例
- 关于我们
- 联系我们
**首页结构精简(从13个section减少到8个):**
1. **Hero区域** - 核心价值主张 + 动态粒子背景
2. **核心优势** - 4个关键数据指标(动态计数)
3. **产品矩阵** - 卡片式展示核心产品
4. **解决方案** - 行业/场景分类展示
5. **成功案例** - 精选3个典型案例
6. **技术实力** - 技术栈展示
7. **客户评价** - 轮播式testimonial
8. **CTA区域** - 行动号召
**优化效果:**
- 减少到8个核心section,提升信息聚焦度
- 下拉菜单提供更清晰的信息层级
- 每个section都有明确的用户目标和转化路径
---
## 三、视觉设计系统
### 色彩系统
**主色调:**
- 深色背景:`#0A0A0A`(主背景)、`#1A1A1A`(次级背景)、`#2A2A2A`(卡片背景)
- 科技蓝:`#00D9FF`(主要强调色、CTA按钮)
- 紫色:`#A855F7`(次要强调色、装饰元素)
- 青色:`#06B6D4`(辅助色、图标)
**文字色彩:**
- 主文字:`#FFFFFF`(白色)
- 次级文字:`#A0A0A0`(灰色)
- 禁用文字:`#606060`(深灰)
**渐变色:**
- 主渐变:`linear-gradient(135deg, #00D9FF 0%, #A855F7 100%)`
- 背景渐变:`linear-gradient(180deg, #0A0A0A 0%, #1A1A1A 100%)`
- 光晕效果:`radial-gradient(circle, #00D9FF20 0%, transparent 70%)`
### 字体系统
**主字体:**
- 标题:`Inter``SF Pro Display`(现代无衬线字体)
- 正文:`Inter`(高可读性)
- 代码/数据:`JetBrains Mono`(等宽字体)
**字号规范:**
- H1`64px`Hero标题)
- H2`48px`Section标题)
- H3`32px`(卡片标题)
- Body`16px`(正文)
- Small`14px`(辅助文字)
### 间距系统
基于 8px 网格:
- xs`4px`
- sm`8px`
- md`16px`
- lg`24px`
- xl`32px`
- 2xl`48px`
- 3xl`64px`
### 圆角系统
- 小圆角:`8px`(按钮、标签)
- 中圆角:`12px`(卡片)
- 大圆角:`16px`(大卡片、容器)
- 全圆角:`9999px`(徽章、标签)
---
## 四、核心组件设计
### 1. Hero 区域设计
**布局:**
- 全屏高度(100vh
- 左侧:核心文案 + CTA按钮
- 右侧:动态粒子效果 + 抽象几何动画
- 底部:滚动提示动画
**视觉元素:**
- 背景:深色渐变 + 微妙的网格线
- 粒子效果:蓝色和紫色粒子缓慢漂浮
- 光晕:科技蓝的径向渐变光晕
- 文字:大标题 + 副标题 + 两个CTA按钮(主次分明)
**动效:**
- 文字淡入上移(staggered animation
- 粒子持续运动
- 按钮悬停发光效果
- 滚动提示上下浮动
### 2. 导航栏设计
**样式:**
- 固定顶部,滚动时背景变深(`backdrop-blur`
- Logo左侧,导航居中,CTA按钮右侧
- 高度:`64px`(桌面)、`56px`(移动端)
**交互:**
- 下拉菜单:悬停展开,带淡入动画
- 移动端:汉堡菜单,全屏抽屉式导航
- 当前页面:底部蓝色下划线指示
**特殊效果:**
- Logo悬停:微妙的发光效果
- 导航项悬停:文字颜色变科技蓝
- CTA按钮:渐变背景 + 悬停放大
### 3. 产品卡片设计
**布局:**
- 网格布局:桌面3列、平板2列、移动端1列
- 卡片高度:固定或自适应内容
- 卡片间距:`24px`
**卡片结构:**
- 顶部:产品图标/图片(带渐变边框)
- 中部:产品名称 + 简短描述
- 底部:核心特性标签 + "了解更多"链接
**视觉效果:**
- 背景:`#2A2A2A`,悬停时变亮
- 边框:1px灰色边框,悬停时科技蓝边框
- 阴影:悬停时添加发光阴影
- 图标:科技蓝或紫色渐变
**动效:**
- 悬停:卡片上移 `8px` + 边框发光
- 点击:轻微缩放反馈
- 加载:骨架屏或淡入动画
### 4. 数据可视化组件(使用 AntV)
**技术选型:**
- **@antv/g2** - 基础图表(折线图、柱状图、饼图等)
- **@antv/g6** - 关系图、拓扑图
- **@antv/l7** - 地理空间数据可视化
- **@antv/x6** - 流程图、架构图编辑
**统计数字展示:**
- 大号数字:`48-64px`,科技蓝色
- 动态计数动画:从0到目标值
- 标签:灰色小号文字
- 布局:4列网格,每项居中对齐
**图表配置:**
- 主题:深色主题定制
- 配色:科技蓝 `#00D9FF`、紫色 `#A855F7`、青色 `#06B6D4`
- 背景:透明或半透明深色
- 网格线:淡灰色,降低视觉干扰
- 动画:流畅的入场动画
**交互特性:**
- 悬停:显示详细数据 tooltip
- 点击:可配置的交互事件
- 缩放:支持图表缩放(如需要)
- 响应式:自适应容器大小
---
## 五、交互体验与动效设计
### 1. 页面过渡与滚动体验
**页面加载:**
- 首屏优先加载策略
- 骨架屏占位,提升感知速度
- 渐进式图片加载(blur-up 技术)
- 关键CSS内联,非关键CSS延迟加载
**滚动体验:**
- 平滑滚动:`scroll-behavior: smooth`
- 视差效果:背景元素随滚动缓慢移动
- 渐入动画:元素进入视口时触发淡入上移
- 进度指示:顶部细线显示页面滚动进度
**Section切换:**
- 每个Section进入视口时触发动画
- 标题先出现,内容依次淡入
- 数字计数动画在可见时触发
- 图表在可见时才开始渲染
### 2. 微交互设计
**按钮交互:**
- 悬停:背景渐变流动 + 轻微放大(scale 1.05
- 点击:缩小反馈(scale 0.95)+ 波纹效果
- 加载中:旋转图标 + 禁用状态
- 成功/失败:短暂的颜色变化反馈
**表单交互:**
- 输入框聚焦:边框变科技蓝 + 外发光
- 实时验证:输入时显示验证状态
- 错误提示:红色边框 + 错误信息淡入
- 提交成功:绿色勾选动画 + 成功消息
**卡片交互:**
- 悬停:上移 + 边框发光 + 阴影增强
- 点击:轻微缩放 + 跳转或展开详情
- 加载:骨架屏动画
- 收藏/分享:图标变化动画
### 3. 动画效果库
**入场动画:**
- 淡入上移:`fade-in-up`(最常用)
- 淡入缩放:`fade-in-scale`(适合卡片)
- 从左滑入:`slide-in-left`(适合侧边内容)
- 从右滑入:`slide-in-right`(适合侧边内容)
**持续动画:**
- 粒子漂浮:随机运动轨迹
- 光晕脉动:缓慢的透明度变化
- 渐变流动:背景渐变位置移动
- 图标旋转:加载状态的旋转动画
**退出动画:**
- 淡出:`fade-out`
- 缩小淡出:`scale-out-fade`
- 向上滑出:`slide-out-up`
**动画时长规范:**
- 快速:`150ms`(按钮反馈、状态切换)
- 标准:`300ms`(大多数过渡效果)
- 慢速:`500ms`(页面过渡、大型动画)
- 超慢:`1000ms+`(特殊强调效果)
### 4. 性能优化策略
**动画性能:**
- 优先使用 `transform``opacity`GPU加速)
- 避免动画 `width``height``top``left`
- 使用 `will-change` 提示浏览器优化
- 复杂动画使用 `requestAnimationFrame`
**移动端优化:**
- 减少移动端动画复杂度
- 使用 `prefers-reduced-motion` 媒体查询
- 触摸事件优化(防止滚动卡顿)
- 移动端禁用某些装饰性动画
**加载优化:**
- 动画库按需加载(如 `framer-motion`
- 图片懒加载 + WebP格式
- 代码分割,按路由加载
- 预加载关键资源
---
## 六、响应式设计与移动端体验
### 1. 响应式断点系统
**断点定义:**
- 移动端:`< 640px`sm
- 平板:`640px - 1024px`md
- 桌面:`1024px - 1280px`lg
- 大屏:`> 1280px`xl
**布局策略:**
- 移动优先设计
- 弹性网格系统
- 内容优先级排序
- 触摸友
好的交互区域
### 2. 移动端特殊设计
**导航栏:**
- 高度:`56px`
- Logo居左,汉堡菜单居右
- 点击展开全屏抽屉式导航
- 抽屉内容:垂直排列的导航项 + CTA按钮
- 关闭按钮:右上角X图标
**Hero区域:**
- 高度:`100vh`(移动端可能更高)
- 文案居中或左对齐
- 标题字号:`36-40px`(缩小但仍突出)
- 粒子效果:减少粒子数量,降低性能消耗
- CTA按钮:垂直堆叠,全宽
**内容区域:**
- 单列布局为主
- 卡片全宽显示
- 图片:自适应宽度,保持比例
- 文字:行高适当增加,提升可读性
**交互优化:**
- 最小触摸区域:`44px × 44px`
- 按钮全宽或大尺寸
- 表单输入框:大尺寸,易于点击
- 滑动操作:支持手势滑动(如轮播图)
### 3. 平板端设计
**布局调整:**
- 2列网格布局
- 导航栏:完整导航或简化版
- Hero区域:文案左侧,视觉元素右侧
- 卡片:2列排列
**交互优化:**
- 支持触摸和鼠标操作
- 下拉菜单:点击触发(非悬停)
- 表单:优化触摸输入体验
### 4. 桌面端设计
**布局优化:**
- 3列或4列网格
- 完整导航栏 + 下拉菜单
- Hero区域:左右分栏,视觉平衡
- 卡片:3列排列,悬停效果丰富
**交互增强:**
- 悬停效果:丰富的视觉反馈
- 键盘导航:支持Tab键导航
- 快捷键:如搜索(Cmd/Ctrl + K
### 5. 性能与可访问性
**移动端性能优化:**
- 图片:使用 `srcset` 提供不同尺寸
- 动画:减少复杂动画,优先性能
- 字体:使用 `font-display: swap`
- 懒加载:图片和组件按需加载
**可访问性(A11y):**
- 色彩对比度:符合WCAG 2.1 AA标准
- 键盘导航:所有交互元素可访问
- 屏幕阅读器:语义化HTML + ARIA标签
- 焦点管理:清晰的焦点指示器
- 减少动画:尊重 `prefers-reduced-motion`
**触摸体验:**
- 防止误触:按钮间距合理
- 触摸反馈:即时的视觉反馈
- 滚动优化:防止滚动卡顿
- 手势支持:滑动、缩放等
### 6. 特殊场景处理
**横屏模式:**
- 检测横屏,调整布局
- Hero区域:可能需要重新排版
- 导航:考虑底部导航栏
**小屏设备:**
- 内容优先级排序
- 隐藏次要信息
- 简化视觉元素
**大屏设备:**
- 最大内容宽度:`1440px``1600px`
- 内容居中,两侧留白
- 充分利用空间,展示更多信息
---
## 七、技术实现方案
### 1. 技术栈确认与增强
**现有技术栈:**
- Next.js 16.1.6App Router
- React 19.2.3
- TypeScript 5
- Tailwind CSS v4
- shadcn/ui + Radix UI
**新增依赖:**
- **动画库:** `framer-motion` - 流畅的动画效果
- **图表库:** `@antv/g2` - 数据可视化
- **图标库:** `lucide-react`(已有)
- **工具库:**
- `clsx` + `tailwind-merge`(已有)
- `class-variance-authority` - CVA变体管理
- `zod` - 数据验证(已有)
**开发工具:**
- ESLint + Prettier - 代码规范
- Husky + lint-staged - Git hooks
- Commitlint - 提交信息规范
### 2. 组件库架构
**目录结构:**
```
src/
├── components/
│ ├── ui/ # 基础UI组件
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── layout/ # 布局组件
│ │ ├── header.tsx
│ │ ├── footer.tsx
│ │ ├── mobile-menu.tsx
│ │ └── ...
│ ├── sections/ # 页面区块组件
│ │ ├── hero-section.tsx
│ │ ├── products-section.tsx
│ │ └── ...
│ ├── effects/ # 特效组件
│ │ ├── particle-background.tsx
│ │ ├── glow-effect.tsx
│ │ └── ...
│ └── charts/ # 图表组件
│ ├── line-chart.tsx
│ ├── bar-chart.tsx
│ └── ...
├── hooks/ # 自定义Hooks
│ ├── use-animation.ts
│ ├── use-intersection-observer.ts
│ └── ...
├── lib/ # 工具库
│ ├── utils.ts
│ ├── constants.ts
│ ├── theme.ts
│ └── ...
└── styles/ # 样式文件
├── globals.css
├── animations.css
└── ...
```
### 3. 样式系统设计
**Tailwind配置扩展:**
```typescript
// tailwind.config.ts
export default {
theme: {
extend: {
colors: {
// 深色主题
dark: {
DEFAULT: '#0A0A0A',
secondary: '#1A1A1A',
tertiary: '#2A2A2A',
},
// 科技色
tech: {
blue: '#00D9FF',
purple: '#A855F7',
cyan: '#06B6D4',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
animation: {
'fade-in-up': 'fadeInUp 0.6s ease-out',
'fade-in-scale': 'fadeInScale 0.6s ease-out',
'glow': 'glow 2s ease-in-out infinite',
},
keyframes: {
fadeInUp: {
'0%': { opacity: '0', transform: 'translateY(20px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
fadeInScale: {
'0%': { opacity: '0', transform: 'scale(0.95)' },
'100%': { opacity: '1', transform: 'scale(1)' },
},
glow: {
'0%, 100%': { boxShadow: '0 0 20px rgba(0, 217, 255, 0.3)' },
'50%': { boxShadow: '0 0 40px rgba(0, 217, 255, 0.6)' },
},
},
},
},
}
```
**CSS变量系统:**
```css
/* globals.css */
:root {
--color-dark: #0A0A0A;
--color-dark-secondary: #1A1A1A;
--color-dark-tertiary: #2A2A2A;
--color-tech-blue: #00D9FF;
--color-tech-purple: #A855F7;
--color-tech-cyan: #06B6D4;
--gradient-primary: linear-gradient(135deg, #00D9FF 0%, #A855F7 100%);
--gradient-dark: linear-gradient(180deg, #0A0A0A 0%, #1A1A1A 100%);
}
```
### 4. 开发流程与规范
**Git工作流:**
- 分支策略:`main`(生产)、`develop`(开发)、`feature/*`(功能)
- 提交规范:`feat:``fix:``style:``refactor:``docs:`
- Code Review:必须经过至少一人审查
**代码规范:**
- ESLint配置:基于 `eslint-config-next`
- Prettier配置:统一格式化规则
- TypeScript严格模式
- 组件命名:PascalCase
- 文件命名:kebab-case
**开发流程:**
1.`develop` 创建 `feature` 分支
2. 开发 + 单元测试
3. 提交PR + Code Review
4. 合并到 `develop`
5. 测试通过后合并到 `main`
6. 自动部署
### 5. 测试策略
**单元测试:**
- 框架:Vitest + React Testing Library
- 覆盖率目标:≥80%
- 重点:组件逻辑、Hooks、工具函数
**集成测试:**
- 测试关键用户流程
- API集成测试
- 状态管理测试
**E2E测试:**
- 框架:Playwright(已有)
- 重点:核心业务流程
- 视觉回归测试
**性能测试:**
- Lighthouse评分:≥90
- 首屏加载时间:<2s
- 交互响应时间:<100ms
### 6. 部署与监控
**部署方案:**
- 静态导出:`next build` + `next export`
- 托管:Vercel / 阿里云OSS + CDN
- CI/CDGitHub Actions
**监控与优化:**
- 性能监控:Web Vitals
- 错误追踪:Sentry
- 用户行为:Google Analytics
- SEO优化:meta标签、sitemap、robots.txt
---
## 八、实施计划
### 阶段一:基础架构(1-2周)
- 设计系统搭建(色彩、字体、间距)
- 基础UI组件库开发
- 布局组件重构(Header、Footer
- 响应式框架搭建
### 阶段二:核心页面(2-3周)
- Hero区域重构
- 产品展示页面
- 解决方案页面
- 案例展示页面
### 阶段三:交互优化(1-2周)
- 动画效果实现
- 微交互优化
- 性能优化
- 可访问性改进
### 阶段四:测试与上线(1周)
- 全面测试
- 性能优化
- 部署上线
- 监控配置
**总工期:5-8周**
---
## 九、设计决策记录
### 为什么选择深色科技风?
1. 符合科技创新与前沿感的品牌定位
2. 顶级科技公司的主流选择(Apple、Microsoft、GitHub、Vercel
3. 对企业决策者显得更加专业、高端、可信赖
4. 深色背景配合霓虹色点缀能更好突出关键信息
5. 移动端更受欢迎(省电、护眼)
### 为什么选择 AntV
1. 完善的中文文档和社区支持
2. 企业级稳定性,适合金融场景
3. 丰富的图表类型和交互能力
4. 良好的性能表现
### 为什么精简到8个section
1. 提升信息聚焦度,避免用户认知负担
2. 每个section都有明确的用户目标和转化路径
3. 更好的性能表现(减少渲染内容)
4. 更清晰的信息层级
---
## 十、下一步行动
1. ✅ 设计方案已完成并文档化
2. ⏭️ 准备进入实施阶段
3. ⏭️ 创建详细的实施计划(使用 `writing-plans` skill
4. ⏭️ 创建隔离的开发环境(使用 `using-git-worktrees` skill
---
**设计者:** AI Assistant
**审核者:** 待定
**最后更新:** 2026-02-21
File diff suppressed because it is too large Load Diff
@@ -1,802 +0,0 @@
# Novalon 官网医疗健康风格重构实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 将 Novalon 官网从深色科技风格重构为医疗健康风格(明亮、专业、可信赖)
**Architecture:** 采用专业蓝 `#005EB8` 为主色调,印章红 `#C41E3A` 作为品牌强调色,白色/浅灰背景。移除深色模式,统一使用明亮风格。重构所有 UI 组件、页面布局和内容策略。
**Tech Stack:** Next.js 16.1.6, React 19.2.3, TypeScript, Tailwind CSS 4.0, Framer Motion
---
## Phase 1: 配色系统更新
### Task 1: 更新 globals.css 配色变量
**Files:**
- Modify: `src/app/globals.css:1-200`
**Step 1: 替换 :root 变量为医疗健康配色**
`:root` 部分的配色变量替换为:
```css
:root {
/* 主色调 - 专业蓝系 */
--color-primary: #005EB8;
--color-primary-hover: #003B73;
--color-primary-light: #00A3E0;
--color-primary-lighter: #E8F4FD;
/* 品牌色 - 印章红 */
--color-brand-primary: #C41E3A;
--color-brand-primary-hover: #A01830;
--color-brand-primary-light: #E04A68;
--color-brand-primary-bg: #FEF2F4;
/* 背景色系 - 明亮健康风 */
--color-bg-primary: #FFFFFF;
--color-bg-secondary: #F5F7FA;
--color-bg-tertiary: #EEF2F7;
--color-bg-hover: #E8ECF2;
/* 文字色系 */
--color-text-primary: #1A1A2E;
--color-text-secondary: #4A5568;
--color-text-tertiary: #718096;
--color-text-muted: #A0AEC0;
/* 边框色系 */
--color-border-primary: #E2E8F0;
--color-border-secondary: #CBD5E0;
--color-border-accent: #005EB8;
/* 链接色 */
--color-link: #005EB8;
--color-link-hover: #003B73;
/* 状态色 */
--color-success: #16A34A;
--color-success-bg: #F0FDF4;
--color-warning: #D97706;
--color-warning-bg: #FFFBEB;
--color-info: #0284C7;
--color-info-bg: #F0F9FF;
--color-error: #DC2626;
--color-error-bg: #FEF2F2;
/* 阴影 */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.05);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.05);
/* 保留原有尺寸变量 */
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--font-size-3xl: 1.875rem;
--font-size-4xl: 2.25rem;
--font-size-5xl: 3rem;
--font-size-6xl: 3.75rem;
--line-height-tight: 1.1;
--line-height-snug: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
--letter-spacing-tight: -0.025em;
--letter-spacing-normal: 0;
--letter-spacing-wide: 0.025em;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
--spacing-2xl: 3rem;
--spacing-3xl: 4rem;
--spacing-4xl: 6rem;
--spacing-5xl: 8rem;
--border-width-thin: 0.5px;
--border-width-normal: 1px;
--transition-fast: 150ms;
--transition-normal: 200ms;
--transition-slow: 300ms;
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}
```
**Step 2: 移除 .dark 主题**
删除整个 `.dark` 选择器块(约 50 行),因为新设计只使用明亮风格。
**Step 3: 更新 body 背景和文字颜色**
```css
body {
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
font-family: var(--font-chinese), var(--font-sans), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: var(--line-height-normal);
letter-spacing: var(--letter-spacing-normal);
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(ellipse at 15% 20%, rgba(0, 94, 184, 0.03) 0%, transparent 50%),
radial-gradient(ellipse at 85% 80%, rgba(196, 30, 58, 0.02) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
```
**Step 4: 运行开发服务器验证**
Run: `npm run dev`
Expected: 页面显示明亮背景,配色正常
**Step 5: Commit**
```bash
git add src/app/globals.css
git commit -m "style: 更新配色系统为医疗健康风格
- 专业蓝 #005EB8 为主色调
- 印章红 #C41E3A 为品牌强调色
- 移除深色模式
- 明亮背景风格"
```
---
### Task 2: 更新 colors.ts 配色定义
**Files:**
- Modify: `src/lib/colors.ts:1-113`
**Step 1: 替换整个文件内容**
```typescript
export const brandColors = {
primary: {
600: '#005EB8',
700: '#003B73',
500: '#00A3E0',
400: '#33B8E8',
100: '#E8F4FD',
},
brand: {
600: '#C41E3A',
700: '#A01830',
500: '#E04A68',
400: '#F08C9F',
100: '#FEF2F4',
},
neutral: {
900: '#1A1A2E',
800: '#2D3748',
700: '#4A5568',
600: '#718096',
500: '#A0AEC0',
400: '#CBD5E0',
300: '#E2E8F0',
200: '#EDF2F7',
100: '#F5F7FA',
50: '#FFFFFF',
},
success: {
600: '#16A34A',
100: '#F0FDF4',
},
warning: {
600: '#D97706',
100: '#FFFBEB',
},
info: {
600: '#0284C7',
100: '#F0F9FF',
},
error: {
600: '#DC2626',
100: '#FEF2F2',
},
} as const;
export const colorValues = {
primary: '#005EB8',
primaryHover: '#003B73',
primaryLight: '#00A3E0',
primaryLighter: '#E8F4FD',
brand: '#C41E3A',
brandHover: '#A01830',
brandLight: '#E04A68',
brandBg: '#FEF2F4',
textPrimary: '#1A1A2E',
textSecondary: '#4A5568',
textTertiary: '#718096',
textMuted: '#A0AEC0',
bgPrimary: '#FFFFFF',
bgSecondary: '#F5F7FA',
bgTertiary: '#EEF2F7',
bgHover: '#E8ECF2',
border: '#E2E8F0',
borderSecondary: '#CBD5E0',
borderAccent: '#005EB8',
link: '#005EB8',
linkHover: '#003B73',
success: '#16A34A',
successBg: '#F0FDF4',
warning: '#D97706',
warningBg: '#FFFBEB',
info: '#0284C7',
infoBg: '#F0F9FF',
error: '#DC2626',
errorBg: '#FEF2F2',
} as const;
export const gradients = {
primary: 'linear-gradient(135deg, #005EB8 0%, #00A3E0 100%)',
hero: 'linear-gradient(180deg, #F5F7FA 0%, #FFFFFF 100%)',
brand: 'linear-gradient(135deg, #C41E3A 0%, #E04A68 100%)',
subtle: 'linear-gradient(180deg, #FFFFFF 0%, #F5F7FA 100%)',
} as const;
export type BrandColor = typeof brandColors;
export type ColorValue = typeof colorValues;
export type Gradient = typeof gradients;
```
**Step 2: 验证 TypeScript 编译**
Run: `npx tsc --noEmit`
Expected: 无错误
**Step 3: Commit**
```bash
git add src/lib/colors.ts
git commit -m "refactor: 更新 colors.ts 配色定义为医疗健康风格"
```
---
### Task 3: 更新 gradients.ts 渐变定义
**Files:**
- Modify: `src/lib/gradients.ts`
**Step 1: 替换文件内容**
```typescript
export const gradients = {
primary: 'linear-gradient(135deg, #005EB8 0%, #00A3E0 100%)',
hero: 'linear-gradient(180deg, #F5F7FA 0%, #FFFFFF 100%)',
brand: 'linear-gradient(135deg, #C41E3A 0%, #E04A68 100%)',
subtle: 'linear-gradient(180deg, #FFFFFF 0%, #F5F7FA 100%)',
card: 'linear-gradient(180deg, #FFFFFF 0%, #F5F7FA 100%)',
cta: 'linear-gradient(135deg, #C41E3A 0%, #A01830 100%)',
} as const;
export type GradientType = typeof gradients;
```
**Step 2: Commit**
```bash
git add src/lib/gradients.ts
git commit -m "refactor: 更新渐变定义为医疗健康风格"
```
---
## Phase 2: UI 组件重构
### Task 4: 重构 Button 组件
**Files:**
- Modify: `src/components/ui/button.tsx`
**Step 1: 更新 buttonVariants**
```typescript
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-[#005EB8] focus-visible:ring-offset-2 focus-visible:ring-offset-white",
{
variants: {
variant: {
default:
"bg-[#C41E3A] text-white hover:bg-[#A01830] hover:shadow-[0_4px_12px_rgba(196,30,58,0.25)] hover:-translate-y-0.5 active:scale-[0.98]",
secondary:
"bg-[#005EB8] text-white hover:bg-[#003B73] hover:shadow-[0_4px_12px_rgba(0,94,184,0.25)] hover:-translate-y-0.5 active:scale-[0.98]",
destructive:
"bg-[#DC2626] text-white hover:bg-[#B91C1C] focus-visible:ring-[#DC2626]",
outline:
"border-2 border-[#005EB8] bg-transparent text-[#005EB8] hover:bg-[#E8F4FD] hover:shadow-[0_2px_8px_rgba(0,94,184,0.15)]",
ghost:
"text-[#4A5568] hover:bg-[#F5F7FA] hover:text-[#1A1A2E]",
link:
"text-[#005EB8] underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-12 rounded-lg px-6 text-base",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
**Step 2: Commit**
```bash
git add src/components/ui/button.tsx
git commit -m "refactor: 更新 Button 组件为医疗健康风格"
```
---
### Task 5: 重构 Card 组件
**Files:**
- Modify: `src/components/ui/card.tsx`
**Step 1: 读取当前文件内容**
Run: `cat src/components/ui/card.tsx`
**Step 2: 更新卡片样式**
将所有卡片样式更新为:
- 背景:`#FFFFFF`
- 边框:`#E2E8F0`
- 圆角:`12px`
- 阴影:`0 2px 8px rgba(0, 0, 0, 0.04)`
- 悬停:上移 `4px` + 阴影增强
**Step 3: Commit**
```bash
git add src/components/ui/card.tsx
git commit -m "refactor: 更新 Card 组件为医疗健康风格"
```
---
### Task 6: 重构 Badge 组件
**Files:**
- Modify: `src/components/ui/badge.tsx`
**Step 1: 更新徽章样式**
使用专业蓝和印章红作为徽章颜色,移除科技感的渐变。
**Step 2: Commit**
```bash
git add src/components/ui/badge.tsx
git commit -m "refactor: 更新 Badge 组件为医疗健康风格"
```
---
### Task 7: 移除 ThemeToggle 组件
**Files:**
- Modify: `src/components/layout/header.tsx`
- Delete: `src/components/ui/theme-toggle.tsx`
- Modify: `src/contexts/theme-context.tsx`
**Step 1: 从 Header 中移除 ThemeToggle**
删除 `<ThemeToggle />` 相关代码。
**Step 2: 删除 theme-toggle.tsx 文件**
**Step 3: 简化 theme-context.tsx**
移除深色模式相关逻辑,只保留默认主题。
**Step 4: Commit**
```bash
git add src/components/layout/header.tsx src/components/ui/theme-toggle.tsx src/contexts/theme-context.tsx
git commit -m "refactor: 移除主题切换功能,统一使用明亮风格"
```
---
## Phase 3: 页面布局重构
### Task 8: 重构 Header 组件
**Files:**
- Modify: `src/components/layout/header.tsx`
**Step 1: 更新导航栏样式**
- 背景:`#FFFFFF` + 底部阴影
- 高度:`72px`
- Logo:保留印章红元素
- 导航链接:深灰文字 → 蓝色悬停
- CTA 按钮:印章红
**Step 2: Commit**
```bash
git add src/components/layout/header.tsx
git commit -m "refactor: 重构 Header 为医疗健康风格"
```
---
### Task 9: 重构 Footer 组件
**Files:**
- Modify: `src/components/layout/footer.tsx`
**Step 1: 更新页脚样式**
- 背景:`#F5F7FA`
- 文字:深色
- 链接:专业蓝
**Step 2: Commit**
```bash
git add src/components/layout/footer.tsx
git commit -m "refactor: 重构 Footer 为医疗健康风格"
```
---
### Task 10: 重构 HeroSection 组件
**Files:**
- Modify: `src/components/sections/hero-section.tsx`
**Step 1: 更新 Hero 区域**
- 背景:浅蓝渐变 `linear-gradient(180deg, #F5F7FA 0%, #FFFFFF 100%)`
- 布局:左文右图(桌面)
- 文字:深色
- 按钮:印章红 CTA + 蓝色轮廓
- 移除深色背景和科技感粒子效果
**Step 2: Commit**
```bash
git add src/components/sections/hero-section.tsx
git commit -m "refactor: 重构 HeroSection 为医疗健康风格"
```
---
### Task 11: 重构 ServicesSection 组件
**Files:**
- Modify: `src/components/sections/services-section.tsx`
**Step 1: 更新服务区域**
- 背景:白色
- 卡片:白色背景 + 浅灰边框
- 图标:专业蓝
- 悬停效果:上移 + 阴影
**Step 2: Commit**
```bash
git add src/components/sections/services-section.tsx
git commit -m "refactor: 重构 ServicesSection 为医疗健康风格"
```
---
### Task 12: 重构 ProductsSection 组件
**Files:**
- Modify: `src/components/sections/products-section.tsx`
**Step 1: 更新产品区域**
- 背景:`#F5F7FA`
- 卡片:白色
- 图标:专业蓝
- 标签:浅蓝背景
**Step 2: Commit**
```bash
git add src/components/sections/products-section.tsx
git commit -m "refactor: 重构 ProductsSection 为医疗健康风格"
```
---
### Task 13: 重构 AboutSection 组件
**Files:**
- Modify: `src/components/sections/about-section.tsx`
**Step 1: 更新关于我们区域**
- 背景:白色
- 数据卡片:左边框印章红强调
- 数字:印章红
**Step 2: Commit**
```bash
git add src/components/sections/about-section.tsx
git commit -m "refactor: 重构 AboutSection 为医疗健康风格"
```
---
### Task 14: 重构 NewsSection 组件
**Files:**
- Modify: `src/components/sections/news-section.tsx`
**Step 1: 更新新闻区域**
- 背景:`#F5F7FA`
- 卡片:白色
- 日期:专业蓝
**Step 2: Commit**
```bash
git add src/components/sections/news-section.tsx
git commit -m "refactor: 重构 NewsSection 为医疗健康风格"
```
---
### Task 15: 重构 ContactSection 组件
**Files:**
- Modify: `src/components/sections/contact-section.tsx`
**Step 1: 更新联系区域**
- 背景:印章红渐变
- 表单:白色卡片
- 输入框:浅灰边框,聚焦时蓝色边框
**Step 2: Commit**
```bash
git add src/components/sections/contact-section.tsx
git commit -m "refactor: 重构 ContactSection 为医疗健康风格"
```
---
## Phase 4: 内容与数据更新
### Task 16: 更新 constants.ts 内容
**Files:**
- Modify: `src/lib/constants.ts`
**Step 1: 更新公司信息和标语**
- 更新 `COMPANY_INFO.slogan` 为情感化表达
- 更新 `STATS` 数据
- 更新 `SERVICES` 描述为情感化内容
**Step 2: Commit**
```bash
git add src/lib/constants.ts
git commit -m "content: 更新内容为情感化叙事风格"
```
---
### Task 17: 添加信任背书 Section
**Files:**
- Create: `src/components/sections/trust-section.tsx`
- Modify: `src/app/(marketing)/page.tsx`
**Step 1: 创建信任背书组件**
包含:
- 客户 Logo 轮播
- 资质认证图标
- 标题:"与行业领袖同行"
**Step 2: 添加到首页**
在 Hero 后添加信任背书 Section。
**Step 3: Commit**
```bash
git add src/components/sections/trust-section.tsx src/app/\(marketing\)/page.tsx
git commit -m "feat: 添加信任背书 Section"
```
---
### Task 18: 添加创新研发 Section
**Files:**
- Create: `src/components/sections/innovation-section.tsx`
- Modify: `src/app/(marketing)/page.tsx`
**Step 1: 创建创新研发组件**
包含:
- 技术栈图标展示
- 研发成果数据
- 标题:"持续创新,引领未来"
**Step 2: 添加到首页**
在产品服务后添加创新研发 Section。
**Step 3: Commit**
```bash
git add src/components/sections/innovation-section.tsx src/app/\(marketing\)/page.tsx
git commit -m "feat: 添加创新研发 Section"
```
---
### Task 19: 添加客户支持入口
**Files:**
- Modify: `src/components/layout/footer.tsx`
- Modify: `src/components/sections/contact-section.tsx`
**Step 1: 在页脚添加客户支持链接**
- 多渠道联系方式
- FAQ 入口
- 服务承诺
**Step 2: 在联系区域添加支持信息**
**Step 3: Commit**
```bash
git add src/components/layout/footer.tsx src/components/sections/contact-section.tsx
git commit -m "feat: 添加客户支持体系入口"
```
---
## Phase 5: 响应式适配与优化
### Task 20: 更新 globals.css 响应式样式
**Files:**
- Modify: `src/app/globals.css`
**Step 1: 更新移动端样式**
确保所有样式在移动端正确显示:
- 字体大小适配
- 间距适配
- 布局适配
**Step 2: Commit**
```bash
git add src/app/globals.css
git commit -m "style: 优化响应式适配"
```
---
### Task 21: 测试所有页面
**Step 1: 运行开发服务器**
Run: `npm run dev`
**Step 2: 检查所有页面**
- 首页
- 关于我们
- 产品服务
- 新闻动态
- 联系我们
**Step 3: 检查响应式**
在以下断点测试:
- 移动端 (375px)
- 平板 (768px)
- 桌面 (1280px)
**Step 4: 修复发现的问题**
---
### Task 22: 运行 lint 和类型检查
**Step 1: 运行 ESLint**
Run: `npm run lint`
Expected: 无错误
**Step 2: 运行 TypeScript 检查**
Run: `npx tsc --noEmit`
Expected: 无错误
**Step 3: 修复发现的问题**
---
### Task 23: 最终提交
**Step 1: 检查所有更改**
Run: `git status`
**Step 2: 提交所有更改**
```bash
git add .
git commit -m "feat: 完成医疗健康风格重构
- 专业蓝 #005EB8 为主色调
- 印章红 #C41E3A 为品牌强调色
- 明亮背景风格
- 移除深色模式
- 更新所有 UI 组件
- 添加信任背书和创新研发 Section
- 添加客户支持体系"
```
---
## 验收清单
- [ ] 配色系统与设计稿一致
- [ ] 所有 UI 组件样式正确
- [ ] 响应式布局正常
- [ ] 无深色模式残留
- [ ] ESLint 无错误
- [ ] TypeScript 无错误
- [ ] 所有页面正常显示
- [ ] 交互效果正常
@@ -1,413 +0,0 @@
# Novalon 官网医疗健康风格重构设计方案
**设计日期:** 2026-02-22
**设计风格:** 医疗健康风格(明亮、温暖、专业)
**参考对象:** 辉瑞、强生、阿斯利康等全球制药企业官网
**项目目标:** 全面重构网站,采用医疗健康风格,保留印章红品牌元素
---
## 一、设计背景与目标
### 重构背景
参考 GSK(葛兰素史克)等全球制药企业的官网设计,借鉴其专业、可信赖的视觉风格和情感化叙事方式,对 Novalon 官网进行全面重构。
### 设计目标
1. **视觉升级**:从深色科技风转向明亮医疗健康风格
2. **品牌延续**:保留印章红作为品牌识别元素
3. **信任感建立**:通过数据展示、情感化叙事增强用户信任
4. **用户体验优化**:清晰的信息层级、流畅的交互体验
### 业务定位
保持金融科技/企业服务的业务定位,借鉴制药企业网站的设计元素:
- 创新研发展示
- 客户支持体系
- 情感化叙事
- 数据可视化
---
## 二、核心配色系统
### 主色调 - 专业蓝系
| 名称 | 色值 | 用途 |
|------|------|------|
| 主色 | `#005EB8` | 导航栏、按钮、重要标题 |
| 深色 | `#003B73` | 悬停状态、强调元素 |
| 浅色 | `#00A3E0` | 链接、图标、装饰元素 |
| 极浅 | `#E8F4FD` | 卡片背景、高亮区域 |
### 品牌色 - 印章红(保留)
| 名称 | 色值 | 用途 |
|------|------|------|
| 主色 | `#C41E3A` | Logo、CTA 按钮、核心数据 |
| 深色 | `#A01830` | 悬停状态 |
| 浅色 | `#E04A68` | 装饰元素 |
| 背景 | `#FEF2F4` | 浅色模式下的强调区域 |
### 背景色系 - 明亮健康风
| 名称 | 色值 | 用途 |
|------|------|------|
| 主背景 | `#FFFFFF` | 页面主背景 |
| 次级背景 | `#F5F7FA` | Section 背景 |
| 卡片背景 | `#FFFFFF` | 卡片、容器 |
| 悬停背景 | `#EEF2F7` | 交互状态 |
### 文字色系
| 名称 | 色值 | 用途 |
|------|------|------|
| 主文字 | `#1A1A2E` | 标题、重要内容 |
| 次级文字 | `#4A5568` | 正文、描述 |
| 辅助文字 | `#718096` | 提示、标签 |
| 禁用文字 | `#A0AEC0` | 禁用状态 |
### 边框与分割线
| 名称 | 色值 | 用途 |
|------|------|------|
| 主边框 | `#E2E8F0` | 卡片边框、分割线 |
| 次级边框 | `#CBD5E0` | 强调边框 |
| 聚焦边框 | `#005EB8` | 输入框聚焦状态 |
---
## 三、页面布局设计
### Hero 区域(首屏)
**布局结构**
- 高度:`100vh`(全屏)
- 布局:左文右图(桌面)/ 上下布局(移动端)
- 背景:浅蓝渐变 `linear-gradient(180deg, #F5F7FA 0%, #FFFFFF 100%)`
**左侧内容(60%**
- 品牌标语:"金融科技 · 智创未来"
- 主标题:大号深色文字
- 副标题:企业核心价值主张
- CTA 按钮:印章红"立即咨询" + 蓝色轮廓"了解更多"
**右侧视觉(40%**
- 抽象几何图形 + 粒子动画
- 印章元素(半透明装饰)
### 首页 Section 结构
精简为 **6 个核心板块**
| 序号 | Section | 功能 |
|------|---------|------|
| 1 | 信任背书区 | 客户 Logo 轮播 + 资质认证图标 |
| 2 | 核心数据 | 4 个关键指标(动态计数)+ 印章红强调 |
| 3 | 产品服务 | 3 列卡片网格,蓝色图标 + 白色卡片 |
| 4 | 创新研发 | 技术栈展示 + 研发成果数据 |
| 5 | 客户案例 | 精选案例卡片 + 客户评价轮播 |
| 6 | 行动号召 | 印章红背景 + 联系表单入口 |
### Section 间距
| 设备 | 间距 |
|------|------|
| 桌面 | `120px` |
| 平板 | `80px` |
| 移动端 | `60px` |
### 内容最大宽度
| 设备 | 宽度 |
|------|------|
| 桌面 | `1280px` |
| 大屏 | `1440px` |
| 内边距 | `24px`(移动端)→ `48px`(桌面) |
---
## 四、UI 组件设计规范
### 按钮系统
#### 主要按钮(印章红 CTA
- 背景:`#C41E3A` → 悬停 `#A01830`
- 文字:`#FFFFFF`
- 圆角:`8px`
- 阴影:`0 4px 12px rgba(196, 30, 58, 0.25)`
- 动效:悬停上移 `2px` + 阴影增强
#### 次要按钮(专业蓝)
- 背景:`#005EB8` → 悬停 `#003B73`
- 文字:`#FFFFFF`
- 圆角:`8px`
- 阴影:`0 4px 12px rgba(0, 94, 184, 0.25)`
#### 轮廓按钮
- 背景:透明
- 文字:`#005EB8`
- 边框:`2px solid #005EB8`
- 悬停:背景 `#E8F4FD`
#### 按钮尺寸
- 大号:高度 `48px`,内边距 `16px 32px`,字号 `16px`
- 中号:高度 `40px`,内边距 `12px 24px`,字号 `14px`
- 小号:高度 `32px`,内边距 `8px 16px`,字号 `14px`
### 卡片系统
#### 基础卡片
- 背景:`#FFFFFF`
- 边框:`1px solid #E2E8F0`
- 圆角:`12px`
- 阴影:`0 2px 8px rgba(0, 0, 0, 0.04)`
- 悬停:上移 `4px` + 阴影 `0 8px 24px rgba(0, 94, 184, 0.12)`
#### 数据卡片(强调型)
- 背景:`#FFFFFF`
- 左边框:`4px solid #C41E3A`(印章红强调)
- 数字:`48px` 印章红
- 标签:`14px` 深灰
#### 产品卡片
- 背景:`#FFFFFF`
- 边框:`1px solid #E2E8F0`
- 圆角:`16px`
- 结构:
- 顶部:产品图标(专业蓝)
- 中部:产品名称 + 描述
- 底部:特性标签
### 导航栏设计
#### 桌面导航
- 高度:`72px`
- 背景:`#FFFFFF` + 底部阴影 `0 1px 3px rgba(0, 0, 0, 0.08)`
- 布局:
- 左侧:Logo(印章红元素)
- 中间:导航链接
- 右侧:CTA 按钮(印章红)
#### 导航链接样式
- 文字:`#4A5568`(默认)→ `#005EB8`(悬停)
- 当前页:文字 `#005EB8` + 底部 `2px` 下划线
#### 移动端导航
- 高度:`56px`
- 汉堡菜单:点击展开全屏抽屉
- 抽屉背景:`#FFFFFF`
---
## 五、情感化叙事与内容策略
### 品牌叙事框架
**核心使命声明**
- 主标题:"为金融创新,注入健康力量"
- 副标题:"我们相信,科技应该让每一次金融服务都更安全、更高效、更有温度"
### 情感化表达原则
1. 用"我们"代替"公司",建立亲近感
2. 用"帮助/赋能/守护"代替"提供/销售"
3. 用真实数据和案例支撑每一个主张
### 各 Section 内容策略
| Section | 情感化标题 | 内容重点 |
|---------|-----------|---------|
| Hero | "金融科技 · 智创未来" | 核心价值主张 + 行动号召 |
| 信任背书 | "与行业领袖同行" | 客户 Logo + 合作故事 |
| 核心数据 | "用数字说话" | 关键指标 + 成长曲线 |
| 产品服务 | "为您的业务赋能" | 痛点解决 + 价值交付 |
| 创新研发 | "持续创新,引领未来" | 技术投入 + 研发成果 |
| 客户案例 | "他们的成功,我们的骄傲" | 真实故事 + 客户评价 |
| 行动号召 | "让我们一起创造价值" | 联系入口 + 承诺保障 |
### 客户支持体系
借鉴辉瑞的客户支持设计:
- 醒目的"客户支持"入口
- 多渠道联系方式(电话、邮件、在线客服)
- 常见问题 FAQ 快速入口
- 服务承诺响应时间
---
## 六、数据可视化与交互设计
### 数据展示类型
#### 关键指标卡片
- 布局:4 列网格(桌面)→ 2 列(平板)→ 1 列(移动端)
- 样式:大号数字 + 印章红强调 + 单位标签 + 增长趋势箭头
- 动效:数字从 0 计数到目标值(2 秒)
**示例数据**
- 服务客户:500+ 家
- 交易处理:10 亿+ 笔/年
- 系统可用性:99.99%
- 客户满意度:98%
#### 研发管线展示
- 环形进度图:展示研发项目分布
- 时间线:展示技术演进历程
- 技术栈图标:横向滚动展示
### 交互设计规范
#### 滚动揭示动效
- 初始状态:`opacity: 0` + `translateY(30px)`
- 进入视口:`opacity: 1` + `translateY(0)`
- 过渡时间:`600ms ease-out`
- 子元素延迟:`100ms` 递增
#### 悬停交互
- 卡片:上移 `4px` + 阴影增强
- 按钮:上移 `2px` + 阴影扩散
- 链接:颜色过渡 + 下划线动画
- 图片:轻微放大 `1.02`
#### 数字计数动画
- 起始值:`0`
- 目标值:实际数据
- 持续时间:`2000ms`
- 缓动函数:`ease-out`
- 触发:进入视口时开始
---
## 七、响应式设计
### 断点系统
| 断点 | 宽度 | 设备 |
|------|------|------|
| `sm` | 640px | 小平板 |
| `md` | 768px | 平板竖屏 |
| `lg` | 1024px | 平板横屏/小笔记本 |
| `xl` | 1280px | 桌面 |
| `2xl` | 1536px | 大屏桌面 |
### 布局适配策略
#### 导航栏
- 桌面(≥1024px):水平导航
- 平板(768px-1023px):简化导航项
- 移动端(<768px):汉堡菜单
#### Hero 区域
- 桌面:左右分栏(60% / 40%)
- 平板:上下布局
- 移动端:单列布局
#### 卡片网格
- 桌面(≥1280px):3 列
- 平板(768px-1279px):2 列
- 移动端(<768px):1 列
### 字体大小适配
#### 标题字号
- H1`64px`(桌面)→ `48px`(平板)→ `36px`(移动端)
- H2`48px`(桌面)→ `36px`(平板)→ `28px`(移动端)
- H3`32px`(桌面)→ `24px`(平板)→ `20px`(移动端)
#### 正文字号
- 正文:`16px`(桌面)→ `15px`(移动端)
- 小字:`14px`(桌面)→ `13px`(移动端)
---
## 八、技术栈
### 核心框架
```json
{
"next": "16.1.6",
"react": "19.2.3",
"react-dom": "19.2.3",
"typescript": "^5"
}
```
### 样式方案
```json
{
"tailwindcss": "^4.0.0",
"framer-motion": "^12.34.3"
}
```
### UI 组件库
```json
{
"lucide-react": "^0.563.0",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"tailwind-merge": "^3.4.0"
}
```
---
## 九、实施优先级
### Phase 1:配色系统更新(高优先级)
1. 更新 `globals.css` 中的 CSS 变量
2. 更新 `colors.ts` 中的色彩定义
3. 移除深色模式,统一使用明亮风格
### Phase 2UI 组件重构(高优先级)
1. 重构按钮组件样式
2. 重构卡片组件样式
3. 重构导航栏组件
### Phase 3:页面布局重构(中优先级)
1. 重构 Hero 区域
2. 精简首页 Section
3. 添加滚动揭示动效
### Phase 4:内容与数据展示(中优先级)
1. 实现数据可视化组件
2. 添加客户支持入口
3. 优化内容策略
### Phase 5:响应式适配(中优先级)
1. 测试各断点布局
2. 优化移动端体验
3. 性能优化
---
## 十、验收标准
### 视觉验收
- 配色方案与设计稿一致
- 组件样式符合设计规范
- 响应式布局在各设备正常显示
### 性能验收
- 首屏加载时间 < 2s
- Lighthouse 性能分数 ≥ 90
- 无明显的卡顿或延迟
### 可访问性验收
- Lighthouse 可访问性分数 ≥ 95
- 键盘导航正常
- 屏幕阅读器兼容
- 色彩对比度符合 WCAG AA 标准
---
## 十一、总结
本设计方案通过**医疗健康风格**的视觉语言,将 Novalon 的**金融科技专业性**与**医疗行业的信任感**完美融合。以**专业蓝**为主色调传达可信赖,**印章红**作为品牌识别和强调色,**明亮背景**营造专业、健康的氛围。
设计系统遵循**极简主义**原则,注重**情感化叙事**和**数据可视化**,确保用户能够快速建立信任并理解企业价值。
---
**设计团队:** AI 设计助手
**审核状态:** 已确认
**下一步:** 创建实施计划 → 开始开发
@@ -1,584 +0,0 @@
# Novalon 官网重新设计方案
**设计日期:** 2026-02-22
**设计风格:** 数字未来风(未来科技感)
**项目目标:** 采用更现代、更前沿的设计语言,全方位升级配色、UI/UE/UX
---
## 一、设计理念与品牌定位
### 品牌定位
- **企业类型:** 综合型科技集团
- **业务领域:** 金融科技、企业级软件服务、科技创新等多领域
- **品牌内涵:** "睿新致遠" - 传统底蕴与科技创新的融合
### 设计风格
**数字未来风** - 深色背景 + 渐变光效(蓝紫渐变、青色光晕),流畅而现代
### 设计原则
1. **品牌识别优先** - 印章红色作为核心识别色
2. **科技感与专业性平衡** - 蓝紫渐变营造未来感,深色背景体现专业
3. **传统与现代融合** - 红色印章代表传统,蓝紫渐变代表创新
---
## 二、核心配色系统
### 主色调 - 数字未来风渐变
#### 科技蓝系列
- **主色:** `#00D9FF`(电光蓝)- 主要交互元素、链接、图标
- **深色:** `#00B8D9`(深电光蓝)- 悬停状态
- **浅色:** `#33E1FF`(亮电光蓝)- 光晕效果
#### 紫色系列
- **主色:** `#A855F7`(霓虹紫)- 装饰元素、渐变终点
- **深色:** `#9333EA`(深紫)- 悬停状态
- **浅色:** `#C084FC`(亮紫)- 光晕效果
#### 渐变组合
- **主渐变:** `linear-gradient(135deg, #00D9FF 0%, #A855F7 100%)`
- **反向渐变:** `linear-gradient(135deg, #A855F7 0%, #00D9FF 100%)`
- **光晕渐变:** `radial-gradient(circle, rgba(0, 217, 255, 0.15) 0%, transparent 70%)`
### 品牌色 - 印章红
- **主色:** `#C41E3A`(印章红)- Logo、CTA 按钮、重要信息
- **深色:** `#A01830`(深红)- 悬停状态
- **浅色:** `#E04A68`(亮红)- 背景装饰
- **背景色:** `#FEF2F4`(淡红背景)- 浅色模式下的卡片背景
### 背景色系
#### 深色背景(默认)
- **主背景:** `#0A0A0A`(深黑)- 页面主背景
- **次级背景:** `#141414`(炭黑)- Section 背景
- **卡片背景:** `#1A1A1A`(深灰)- 卡片、容器
- **悬停背景:** `#242424`(中灰)- 交互状态
#### 浅色背景(可选模式)
- **主背景:** `#FAFAFA`(浅灰白)
- **次级背景:** `#FFFFFF`(纯白)
- **卡片背景:** `#FFFFFF`(纯白)
- **悬停背景:** `#F5F5F5`(浅灰)
### 文字色系
#### 深色模式文字
- **主文字:** `#FAFAFA`(近白)- 标题、重要内容
- **次级文字:** `#D4D4D4`(浅灰)- 正文、描述
- **辅助文字:** `#A3A3A3`(中灰)- 提示、标签
- **禁用文字:** `#737373`(深灰)- 禁用状态
#### 浅色模式文字
- **主文字:** `#171717`(深黑)
- **次级文字:** `#525252`(深灰)
- **辅助文字:** `#737373`(中灰)
- **禁用文字:** `#A3A3A3`(浅灰)
### 边框与分割线
- **主边框:** `#262626`(深灰)- 深色模式
- **次级边框:** `#333333`(中深灰)
- **浅色边框:** `#E5E5E5`(浅灰)- 浅色模式
- **强调边框:** `#00D9FF`(科技蓝)- 聚焦状态
---
## 三、UI 组件设计
### 按钮系统
#### 主要按钮
**CTA 按钮(印章红):**
- 背景:`#C41E3A` → 悬停 `#A01830`
- 文字:`#FFFFFF`(白色)
- 边框:无
- 圆角:`8px`
- 阴影:悬停时添加 `0 0 20px rgba(196, 30, 58, 0.4)` 发光效果
- 动效:悬停时轻微上移 `2px` + 发光增强
**次要按钮(科技蓝渐变):**
- 背景:`linear-gradient(135deg, #00D9FF 0%, #A855F7 100%)`
- 文字:`#FFFFFF`
- 边框:无
- 圆角:`8px`
- 阴影:悬停时添加 `0 0 20px rgba(0, 217, 255, 0.3)` 发光效果
- 动效:悬停时渐变角度旋转 + 发光增强
#### 辅助按钮
**轮廓按钮:**
- 背景:透明
- 文字:`#00D9FF`(科技蓝)
- 边框:`1px solid #00D9FF`
- 悬停:背景变为 `rgba(0, 217, 255, 0.1)` + 发光边框
**幽灵按钮:**
- 背景:透明
- 文字:`#D4D4D4`
- 边框:无
- 悬停:背景变为 `rgba(255, 255, 255, 0.05)`
#### 按钮尺寸
- **大号:** 高度 `48px`,内边距 `16px 32px`,字号 `16px`
- **中号:** 高度 `40px`,内边距 `12px 24px`,字号 `14px`
- **小号:** 高度 `32px`,内边距 `8px 16px`,字号 `14px`
### 卡片系统
#### 基础卡片
- 背景:`#1A1A1A`(深灰)
- 边框:`1px solid #262626`
- 圆角:`12px`
- 内边距:`24px`
- 阴影:无(保持极简)
- 悬停效果:
- 上移 `4px`
- 边框变为 `#00D9FF`
- 添加 `0 0 30px rgba(0, 217, 255, 0.15)` 发光
#### 产品卡片(增强版)
- 背景:`#1A1A1A`
- 边框:`1px solid #262626`
- 圆角:`16px`
- 结构:
- 顶部:产品图标(科技蓝渐变)+ 渐变边框装饰
- 中部:产品名称(白色)+ 描述(浅灰)
- 底部:特性标签(胶囊形状,科技蓝边框)
- 悬停:边框渐变发光 + 图标放大 `1.05`
#### 数据卡片
- 背景:`#141414`(更深)
- 边框:`1px solid #333333`
- 圆角:`12px`
- 内容:大号数字(科技蓝)+ 标签(浅灰)
- 动效:数字计数动画(从 0 到目标值)
### 导航栏设计
#### 桌面导航
- 高度:`64px`
- 背景:`rgba(10, 10, 10, 0.8)` + `backdrop-blur(12px)`
- 边框:底部 `1px solid #262626`
- 布局:
- 左侧:Logo(印章 + 文字)
- 中间:导航链接(首页、产品、解决方案、案例、关于)
- 右侧:主题切换 + CTA 按钮(印章红)
#### 导航链接样式
- 文字:`#D4D4D4`(默认)→ `#00D9FF`(悬停)
- 当前页:文字 `#00D9FF` + 底部 `2px` 下划线
- 下拉菜单:
- 背景:`#1A1A1A` + `backdrop-blur(12px)`
- 边框:`1px solid #262626`
- 圆角:`8px`
- 阴影:`0 8px 32px rgba(0, 0, 0, 0.4)`
#### 移动端导航
- 高度:`56px`
- 汉堡菜单:点击展开全屏抽屉
- 抽屉背景:`#0A0A0A` + 半透明遮罩
- 菜单项:垂直排列,每项高度 `56px`
---
## 四、页面布局设计
### Hero 区域设计
#### 布局结构
- 高度:`100vh`(全屏)
- 背景:`#0A0A0A` + 微妙的网格线(`rgba(0, 217, 255, 0.03)`
- 左侧(60%):核心文案 + CTA 按钮
- 右侧(40%):动态视觉元素
#### 视觉元素
- **粒子效果:** 科技蓝和紫色粒子缓慢漂浮(使用 Framer Motion
- **光晕:** 多个径向渐变光晕(`rgba(0, 217, 255, 0.1)``rgba(168, 85, 247, 0.1)`
- **几何图形:** 半透明的六边形、圆形线条装饰
- **Logo 印章:** 右下角大尺寸半透明印章(`opacity: 0.05`
#### 文案设计
- **主标题:** `64px`,白色,字重 `700`
- **副标题:** `24px`,浅灰(`#D4D4D4`),字重 `400`
- **描述文字:** `16px`,中灰(`#A3A3A3`
#### CTA 按钮组
- **主按钮:** 印章红背景,"立即体验"
- **次按钮:** 科技蓝渐变背景,"了解更多"
#### 动效
- 文字:淡入上移(staggered animation,延迟 100ms
- 粒子:持续漂浮运动
- 光晕:缓慢脉动(scale 1.0 → 1.1
- 滚动提示:底部向下箭头,上下浮动动画
### 首页布局结构
精简为 **8 个核心 Section**
1. **Hero** - 核心价值主张 + 动态背景
2. **核心优势** - 4 个数据指标(动态计数)
3. **产品矩阵** - 3 列卡片网格
4. **解决方案** - 行业/场景分类展示
5. **成功案例** - 精选 3 个案例卡片
6. **技术实力** - 技术栈图标展示
7. **客户评价** - 轮播式 testimonial
8. **CTA 区域** - 行动号召 + 联系方式
#### Section 间距
- 桌面:`120px`(上下)
- 平板:`80px`
- 移动端:`60px`
#### 内容最大宽度
- 桌面:`1280px`
- 大屏:`1440px`
- 内边距:`24px`(移动端)→ `48px`(桌面)
---
## 五、交互设计与动效规范
### 微交互设计
#### 按钮交互
- 悬停:`transform: translateY(-2px)` + 发光阴影增强
- 点击:`transform: scale(0.98)` + 快速反馈
- 加载:旋转图标 + 文字变淡
- 过渡时间:`200ms cubic-bezier(0.16, 1, 0.3, 1)`
#### 卡片交互
- 悬停:上移 `4px` + 边框发光 + 阴影增强
- 点击:轻微缩放 `scale(0.99)`
- 进入视口:淡入上移(Intersection Observer
- 过渡时间:`300ms cubic-bezier(0.16, 1, 0.3, 1)`
#### 导航交互
- 链接悬停:文字颜色渐变过渡
- 下拉菜单:淡入 + 下移 `8px`
- 移动端菜单:从右侧滑入 + 背景遮罩淡入
- 过渡时间:`200ms`
### 页面过渡动效
#### 滚动揭示
- 元素初始:`opacity: 0` + `translateY(30px)`
- 进入视口:`opacity: 1` + `translateY(0)`
- 延迟:子元素依次延迟 `100ms`
- 过渡时间:`600ms cubic-bezier(0.16, 1, 0.3, 1)`
#### 数字计数动画
- 起始值:`0`
- 目标值:实际数据
- 持续时间:`2000ms`
- 缓动函数:`ease-out`
- 触发:进入视口时开始
#### 粒子效果
- 数量:30-50 个粒子
- 颜色:科技蓝(60%)+ 紫色(40%)
- 运动:随机漂浮,速度缓慢
- 交互:鼠标悬停时粒子轻微远离
### 光效与渐变动画
#### 光晕脉动
- 动画:`scale 1.0 → 1.15 → 1.0`
- 透明度:`0.1 → 0.15 → 0.1`
- 持续时间:`4000ms`
- 循环:无限循环
#### 渐变流动
- 动画:渐变角度 `135deg → 225deg → 135deg`
- 持续时间:`8000ms`
- 应用:CTA 按钮背景、装饰元素
#### 边框发光
- 状态:悬停时触发
- 效果:`box-shadow: 0 0 20px rgba(0, 217, 255, 0.3)`
- 过渡:`300ms`
### 性能优化
#### 动效性能
- 使用 `transform``opacity`GPU 加速)
- 避免动画 `width``height``margin`
- 使用 `will-change` 提示浏览器优化
- 移动端减少动效复杂度
#### 加载优化
- 骨架屏:灰色占位 + 脉冲动画
- 图片懒加载:进入视口时加载
- 代码分割:按路由分割,减少首屏加载
---
## 六、响应式设计与移动端适配
### 断点系统
**Tailwind CSS 断点:**
- `sm``640px`(小平板)
- `md``768px`(平板竖屏)
- `lg``1024px`(平板横屏/小笔记本)
- `xl``1280px`(桌面)
- `2xl``1536px`(大屏桌面)
### 布局适配策略
#### 导航栏
- 桌面(≥1024px):水平导航,Logo 左侧,链接居中,CTA 右侧
- 平板(768px-1023px):Logo 左侧,汉堡菜单右侧,简化导航项
- 移动端(<768px):汉堡菜单,全屏抽屉式导航
#### Hero 区域
- 桌面:左右分栏(60% / 40%)
- 平板:上下布局,文案在上,视觉元素在下
- 移动端:单列布局,视觉元素简化或移除
#### 卡片网格
- 桌面(≥1280px):3 列
- 平板(768px-1279px):2 列
- 移动端(<768px):1 列
### 字体大小适配
#### 标题字号
- H1`64px`(桌面)→ `48px`(平板)→ `36px`(移动端)
- H2`48px`(桌面)→ `36px`(平板)→ `28px`(移动端)
- H3`32px`(桌面)→ `24px`(平板)→ `20px`(移动端)
#### 正文字号
- 正文:`16px`(桌面)→ `15px`(移动端)
- 小字:`14px`(桌面)→ `13px`(移动端)
### 间距适配
#### Section 间距
- 桌面:`120px`
- 平板:`80px`
- 移动端:`60px`
#### 卡片内边距
- 桌面:`24px`
- 平板:`20px`
- 移动端:`16px`
#### 按钮尺寸
- 桌面:高度 `48px`,内边距 `16px 32px`
- 移动端:高度 `44px`,内边距 `14px 24px`(增大点击区域)
### 移动端特殊优化
#### 触摸交互
- 最小点击区域:`44px × 44px`(符合 WCAG 标准)
- 按钮间距:至少 `12px`
- 禁用 hover 效果(使用 `:active` 状态)
#### 性能优化
- 减少粒子数量:50 个 → 20 个
- 简化光效:移除复杂渐变动画
- 图片优化:使用 WebP 格式,懒加载
- 减少重绘:避免复杂的 CSS 动画
#### 手势支持
- 滑动切换:testimonial 轮播、案例展示
- 下拉刷新:新闻列表页
- 双击缩放:产品详情图片
### 横屏适配
#### 平板横屏
- 保持桌面布局,适当缩小间距
- 导航栏保持水平布局
- 卡片网格:2-3 列
#### 移动端横屏
- 简化导航,保持汉堡菜单
- Hero 区域:左右分栏,文案左侧
- 卡片:2 列布局
---
## 七、技术栈与实施
### 技术栈推荐
#### 核心框架
```json
{
"next": "16.1.6",
"react": "19.2.3",
"react-dom": "19.2.3",
"typescript": "^5"
}
```
#### 数据可视化(AntV 生态)
```json
{
"@antv/g2": "^5.4.8", // 基础图表(折线、柱状、饼图等)
"@antv/g6": "^5.0.0", // 关系图、拓扑图、组织架构图
"@antv/l7": "^2.0.0", // 地理可视化(如有地图需求)
"@antv/s2": "^2.0.0" // 高性能表格(如有大数据表格需求)
}
```
**AntV 应用场景:**
- **@antv/g2**:数据统计图表、业务指标展示
- **@antv/g6**:技术架构图、业务流程图、关系网络图
- **@antv/l7**:客户分布地图、区域数据可视化
- **@antv/s2**:大数据表格、多维分析表格
#### 动效库
```json
{
"framer-motion": "^12.34.3", // 主要动效库
"gsap": "^3.12.0" // 复杂动画场景(可选)
}
```
#### UI 组件库
```json
{
"lucide-react": "^0.563.0", // 图标库
"@radix-ui/react-dropdown-menu": "^2.1.16", // 下拉菜单
"class-variance-authority": "^0.7.1", // 样式变体
"clsx": "^2.1.1", // 类名合并
"tailwind-merge": "^3.4.0" // Tailwind 类名合并
}
```
#### 工具库
```json
{
"date-fns": "^3.0.0", // 日期处理
"zod": "^4.3.6" // 数据验证
}
```
#### 性能监控
```json
{
"@vercel/analytics": "^1.0.0", // Vercel 分析
"web-vitals": "^4.0.0" // 性能指标采集
}
```
### AntV 与设计系统集成
#### 色彩系统集成
```typescript
import { Chart } from '@antv/g2';
const chart = new Chart({
theme: {
defaultColor: '#00D9FF',
colors10: [
'#00D9FF', // 科技蓝
'#A855F7', // 紫色
'#C41E3A', // 印章红
'#06B6D4', // 青色
'#33E1FF', // 亮蓝
],
},
});
```
#### 动效集成
```typescript
import { Chart } from '@antv/g2';
const chart = new Chart({
animate: {
enter: {
type: 'fadeIn',
duration: 600,
easing: 'easeOutQuart',
},
},
});
```
### 设计系统文件结构
```
src/lib/
├── colors.ts # 色彩系统定义
├── typography.ts # 字体系统定义
├── spacing.ts # 间距系统定义
├── animations.ts # 动效配置
└── design-tokens.ts # 设计 Token 统一导出
src/components/ui/
├── button.tsx # 按钮组件(已存在,需更新)
├── card.tsx # 卡片组件(已存在,需更新)
├── badge.tsx # 徽章组件(已存在)
└── ... 其他 UI 组件
```
### 实施优先级
#### Phase 1:核心配色系统(高优先级)
1. 更新 `globals.css` 中的 CSS 变量
2. 更新 `colors.ts` 中的色彩定义
3. 测试深色/浅色模式切换
#### Phase 2UI 组件更新(高优先级)
1. 更新按钮组件样式
2. 更新卡片组件样式
3. 更新导航栏组件
#### Phase 3:页面布局优化(中优先级)
1. 优化 Hero 区域设计
2. 精简首页 Section 数量
3. 添加滚动揭示动效
#### Phase 4:动效与交互(中优先级)
1. 添加粒子效果
2. 实现数字计数动画
3. 优化微交互反馈
#### Phase 5:响应式适配(中优先级)
1. 测试各断点布局
2. 优化移动端体验
3. 性能优化
---
## 八、验收标准
### 视觉验收
- 配色方案与设计稿一致
- 组件样式符合设计规范
- 响应式布局在各设备正常显示
### 性能验收
- 首屏加载时间 < 2s
- Lighthouse 性能分数 ≥ 90
- 无明显的卡顿或延迟
### 可访问性验收
- Lighthouse 可访问性分数 ≥ 95
- 键盘导航正常
- 屏幕阅读器兼容
- 色彩对比度符合 WCAG AA 标准
- 为动效提供 `prefers-reduced-motion` 支持
---
## 九、总结
本设计方案通过**数字未来风**的设计语言,将 Novalon 的**传统印章文化**与**科技创新未来**完美融合。以**印章红**作为品牌识别核心,**蓝紫渐变**营造科技感,**深色背景**体现专业性,打造出一个既具有文化底蕴又充满未来感的品牌形象。
设计系统遵循**极简主义**原则,注重**性能优化**和**可访问性**,确保在各种设备和网络环境下都能提供优秀的用户体验。通过 AntV 生态的可视化能力,为数据展示提供强大的支持。
---
**设计团队:** AI 设计助手
**审核状态:** 待审核
**下一步:** 提交审核 → 开始实施
File diff suppressed because it is too large Load Diff
@@ -1,534 +0,0 @@
# 网站设计优化实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use `executing-plans` to implement this plan task-by-task.
**Goal:** 融合 Stripe 和 Wickret 设计风格,全面优化网站视觉体验,保留品牌红色作为点缀色
**Architecture:** 采用深色主题为主(Stripe 风格)+ 现代渐变色彩(Wickret 风格),通过 CSS 变量管理主题,Framer Motion 实现动画
**Tech Stack:** Next.js 14, Tailwind CSS, Framer Motion, TypeScript
---
## 阶段一:色彩与主题系统升级
### Task 1: 更新全局 CSS 变量色彩系统
**Files:**
- Modify: `src/app/globals.css:1-120`
**Step 1: 添加新的深色主题色彩变量**
```css
/* 在 :root 后添加新的色彩变量 */
--color-dark-bg: #0A0A0A;
--color-dark-surface: #141414;
--color-dark-elevated: #1A1A1A;
--color-dark-border: #2A2A2A;
/* 渐变色彩 - Wickret 风格 */
--color-gradient-start: #6366F1;
--color-gradient-mid: #8B5CF6;
--color-gradient-end: #D946EF;
/* 品牌红色保留作为点缀 */
--color-accent-red: #C41E3A;
--color-accent-red-glow: rgba(196, 30, 58, 0.4);
```
**Step 2: 验证无语法错误**
Run: `npm run build 2>&1 | head -20`
Expected: 无 CSS 错误
---
### Task 2: 创建渐变工具类
**Files:**
- Modify: `src/app/globals.css`
**Step 1: 添加渐变背景和文字工具类**
```css
@layer utilities {
.bg-gradient-modern {
background: linear-gradient(135deg, var(--color-dark-bg) 0%, #1a1a2e 50%, #16213e 100%);
}
.text-gradient-brand {
background: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-mid), var(--color-gradient-end));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.bg-glow-red {
background: radial-gradient(circle at center, var(--color-accent-red-glow) 0%, transparent 70%);
}
}
```
**Step 2: 运行构建验证**
Run: `npm run build 2>&1 | head -20`
Expected: 构建成功
---
## 阶段二:Hero 区域深度优化
### Task 3: 重构 HeroSection 背景效果
**Files:**
- Modify: `src/components/sections/hero-section.tsx:40-70`
**Step 1: 替换背景为深色渐变**
```tsx
// 替换现有的浅色背景
className="relative min-h-screen flex items-center pt-16 overflow-hidden bg-dark-bg"
```
**Step 2: 添加新的光效元素**
```tsx
<div className="absolute inset-0 pointer-events-none overflow-hidden bg-dark-bg">
{/* 主渐变背景 */}
<div className="absolute inset-0 bg-gradient-to-br from-[#0A0A0A] via-[#1a1a2e] to-[#0A0A0A]" />
{/* 动态光效 - 类似 Stripe */}
<div className="absolute top-0 left-1/4 w-[600px] h-[600px] bg-gradient-radial from-indigo-500/20 via-purple-500/10 to-transparent rounded-full blur-3xl animate-pulse" />
<div className="absolute bottom-0 right-1/4 w-[500px] h-[500px] bg-gradient-radial from-pink-500/15 via-red-500/5 to-transparent rounded-full blur-3xl animate-pulse" style={{ animationDelay: '1.5s' }} />
{/* 网格背景 - Stripe 风格 */}
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:60px_60px]" />
</div>
```
**Step 3: 验证视觉效果**
Run: `npm run dev`
Expected: 深色背景正常显示
---
### Task 4: 优化 Hero 标题和文字样式
**Files:**
- Modify: `src/components/sections/hero-section.tsx:75-95`
**Step 1: 更新标题样式为渐变文字**
```tsx
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-bold tracking-tight mb-8">
<span className="text-gradient-brand">{COMPANY_INFO.shortName}</span>
<br />
<span className="text-white/90"></span>
</h1>
```
**Step 2: 更新描述文字**
```tsx
<p className="text-lg sm:text-xl text-gray-400 mb-10 max-w-2xl mx-auto leading-relaxed">
Stripe +
</p>
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 5: 升级 CTA 按钮为渐变风格
**Files:**
- Modify: `src/components/sections/hero-section.tsx:97-112`
**Step 1: 更新主按钮样式**
```tsx
<Button
size="lg"
onClick={() => handleScrollTo('about')}
className="relative overflow-hidden group bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 hover:from-indigo-600 hover:via-purple-600 hover:to-pink-600 text-white border-0 shadow-lg shadow-purple-500/25 hover:shadow-purple-500/40 transition-all duration-300"
>
<span className="relative z-10 flex items-center">
<ArrowRight className="w-4 h-4 ml-2" />
</span>
<div className="absolute inset-0 bg-white/20 translate-y-full group-hover:translate-y-0 transition-transform duration-300" />
</Button>
```
**Step 2: 更新次按钮样式**
```tsx
<Button
size="lg"
variant="outline"
onClick={() => handleScrollTo('contact')}
className="border-gray-700 text-white hover:bg-gray-800/50 hover:border-gray-600 bg-transparent"
>
</Button>
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 6: 优化统计数字展示区
**Files:**
- Modify: `src/components/sections/hero-section.tsx:140-180`
**Step 1: 更新统计区背景和样式**
```tsx
<motion.div
id="stats-section"
className="pt-16 border-t border-gray-800/50"
>
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12">
{STATS.map((stat, index) => (
<StatItem
key={stat.label}
stat={stat}
index={index}
shouldAnimate={statsVisible}
/>
))}
</div>
</motion.div>
```
**Step 2: 更新 StatItem 样式**
```tsx
function StatItem({ stat, index, shouldAnimate }: {
stat: { value: string; label: string };
index: number;
shouldAnimate: boolean;
}) {
return (
<motion.div
className="group cursor-default text-center"
>
<div className="text-4xl sm:text-5xl font-bold text-gradient-brand mb-3">
{shouldAnimate ? (
<AnimatedCounter value={numericValue} suffix={suffix} />
) : (
<span className="text-white/30">0{suffix}</span>
)}
</div>
<div className="text-sm text-gray-500 group-hover:text-gray-400 transition-colors">
{stat.label}
</div>
</motion.div>
);
}
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
## 阶段三:服务卡片升级
### Task 7: 优化 GlassCard 组件
**Files:**
- Modify: `src/components/ui/glass-card.tsx`
**Step 1: 更新 GlassCard 变体**
```tsx
const glassCardVariants = cva(
"rounded-2xl border backdrop-blur-xl transition-all duration-300",
{
variants: {
variant: {
default:
"border-gray-800/50 bg-gray-900/50 hover:border-purple-500/50 hover:bg-gray-800/60 hover:shadow-[0_0_40px_rgba(139,92,246,0.15)] hover:-translate-y-1",
elevated:
"border-gray-800 bg-gray-900/80 shadow-2xl hover:border-purple-500/50 hover:shadow-purple-500/20 hover:-translate-y-2",
outline:
"border-gray-800/50 bg-transparent hover:border-purple-500/30 hover:bg-gray-900/30",
glow:
"border-gray-800/50 bg-gray-900/40 relative overflow-hidden hover:border-purple-500/40",
},
},
defaultVariants: {
variant: "default",
},
}
)
```
**Step 2: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 8: 重构 ServicesSection
**Files:**
- Modify: `src/components/sections/services-section.tsx`
**Step 1: 更新区域背景和标题**
```tsx
<section id="services" className="py-24 bg-dark-bg relative overflow-hidden">
{/* 背景装饰 */}
<div className="absolute top-1/2 left-0 w-[400px] h-[400px] bg-purple-500/10 rounded-full blur-3xl" />
<div className="absolute top-1/3 right-0 w-[300px] h-[300px] bg-pink-500/10 rounded-full blur-3xl" />
<div className="container-wide relative z-10">
{/* 标题区域 */}
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold text-white mb-4">
<span className="text-gradient-brand"></span>
</h2>
<p className="text-gray-400 max-w-2xl mx-auto text-lg">
</p>
</div>
```
**Step 2: 更新服务卡片布局**
```tsx
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{SERVICES.map((service, index) => (
<motion.div
key={service.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1 }}
>
<GlassCard variant="default" className="p-6 h-full group cursor-pointer">
{/* 卡片内容 */}
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
<IconComponent name={service.icon} className="w-6 h-6 text-white" />
</div>
<h3 className="text-xl font-semibold text-white mb-3">{service.title}</h3>
<p className="text-gray-400 text-sm leading-relaxed">{service.description}</p>
</GlassCard>
</motion.div>
))}
</div>
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
## 阶段四:关于我们与产品区域
### Task 9: 优化 AboutSection
**Files:**
- Modify: `src/components/sections/about-section.tsx`
**Step 1: 更新背景为深色**
```tsx
<section id="about" className="py-24 bg-dark-surface relative">
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.01)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.01)_1px,transparent_1px)] bg-[size:40px_40px]" />
```
**Step 2: 更新文字颜色**
```tsx
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">
<span className="text-gradient-brand">{COMPANY_INFO.shortName}</span>
</h2>
<p className="text-gray-400 text-lg leading-relaxed max-w-3xl">
{COMPANY_INFO.description}
</p>
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 10: 优化 ProductsSection
**Files:**
- Modify: `src/components/sections/products-section.tsx`
**Step 1: 更新产品卡片样式**
```tsx
<div className="space-y-8">
{PRODUCTS.map((product, index) => (
<motion.div
key={product.id}
initial={{ opacity: 0, x: index % 2 === 0 ? -20 : 20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }}
>
<GlassCard variant="elevated" className="p-8 group hover:border-purple-500/30">
{/* 产品内容 */}
</GlassCard>
</motion.div>
))}
</div>
```
**Step 2: 验证**
Run: `npm run build`
Expected: 构建成功
---
## 阶段五:联系区域与 Footer
### Task 11: 优化 ContactSection
**Files:**
- Modify: `src/components/sections/contact-section.tsx`
**Step 1: 更新背景和样式**
```tsx
<section id="contact" className="py-24 bg-dark-bg relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-radial from-purple-500/10 via-transparent to-transparent" />
```
**Step 2: 更新表单样式**
```tsx
<input className="w-full px-4 py-3 bg-gray-900/50 border border-gray-800 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:border-purple-500/50 focus:ring-2 focus:ring-purple-500/20 transition-all"
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 12: 优化 Header 组件
**Files:**
- Modify: `src/components/layout/header.tsx`
**Step 1: 更新 Header 背景**
```tsx
<header className="fixed top-0 left-0 right-0 z-50 bg-dark-bg/80 backdrop-blur-xl border-b border-gray-800/50">
```
**Step 2: 更新导航链接颜色**
```tsx
<nav className="flex items-center gap-8">
{NAVIGATION.map((item) => (
<a
key={item.id}
href={item.href}
className="text-sm text-gray-400 hover:text-white transition-colors relative group"
>
{item.label}
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-gradient-to-r from-indigo-500 to-purple-500 group-hover:w-full transition-all duration-300" />
</a>
))}
</nav>
```
**Step 3: 验证**
Run: `npm run build`
Expected: 构建成功
---
### Task 13: 优化 Footer 组件
**Files:**
- Modify: `src/components/layout/footer.tsx`
**Step 1: 更新 Footer 背景**
```tsx
<footer className="bg-dark-surface border-t border-gray-800/50 py-12">
```
**Step 2: 验证**
Run: `npm run build`
Expected: 构建成功
---
## 阶段六:最终验证与测试
### Task 14: 运行完整构建和类型检查
**Step 1: 运行构建**
Run: `npm run build`
Expected: 构建成功,无错误
**Step 2: 运行类型检查**
Run: `npm run lint`
Expected: 无 lint 错误
**Step 3: 启动开发服务器验证**
Run: `npm run dev`
Expected: 开发服务器正常启动
---
## 执行总结
此计划涵盖 14 个任务,分为 6 个阶段:
1. **色彩与主题系统** (Task 1-2): CSS 变量和工具类
2. **Hero 区域** (Task 3-6): 背景、标题、按钮、统计数字
3. **服务卡片** (Task 7-8): GlassCard 升级和服务区域
4. **关于与产品** (Task 9-10): 页面深色主题
5. **联系与导航** (Task 11-13): 表单和页眉页脚
6. **验证测试** (Task 14): 构建和检查
每个任务都设计为独立可验证,确保逐步改进网站设计。
@@ -1,446 +0,0 @@
# Novalon 官网设计方案 - 金融科技中国风融合版
**设计日期:** 2026-02-22
**设计风格:** 金融科技风 + 中国传统美学融合
**项目目标:** 融合 Wickret 金融科技设计语言 + 中国传统印章元素,打造兼具国际视野与文化底蕴的企业官网
---
## 一、设计理念与品牌定位
### 1.1 核心概念
**"数字印章,智连未来"**
将中国传统印章(诚信、权威、稳重)的意象与现代金融科技(创新、安全、高效)相结合,形成独特的设计语言。
### 1.2 设计风格定位
| 维度 | 融合方案 |
|------|---------|
| **国际视野** | Wickret 金融科技风格 - 深色背景、渐变光晕、专业简洁 |
| **文化底蕴** | 中国传统印章元素 - 红色点缀、方正布局、留白意境 |
| **科技感** | 现代渐变色彩 - 科技蓝、紫罗兰、粉紫渐变 |
| **情感连接** | 温暖而有力量 - 红色传递热情与信任 |
### 1.3 设计原则
1. **色彩平衡** - 科技蓝紫为主色调(70%),印章红为点缀色(20%),中性灰为辅助(10%)
2. **层次分明** - 借鉴 Wickret 的信息层次设计,大标题 + 关键点 + 详情
3. **动静结合** - 优雅的微动效,不过度炫技,注重体验流畅
4. **留白呼吸** - 借鉴东方美学的大面积留白,让信息有呼吸空间
---
## 二、色彩系统
### 2.1 配色比例
```
┌─────────────────────────────────────────────────────────┐
│ 主色调(科技渐变) 70% 深色背景 + 蓝紫渐变 │
│ 品牌色(印章红) 20% 点缀、CTA、强调 │
│ 辅助色(中性灰) 10% 文字、边框、次要信息 │
└─────────────────────────────────────────────────────────┘
```
### 2.2 核心配色
#### 深色背景(主背景)
```css
--bg-primary: #0A0A0A /* 主背景 - 深黑 */
--bg-secondary: #141414 /* 次级背景 - 炭黑 */
--bg-tertiary: #1A1A1A /* 卡片背景 - 深灰 */
--bg-elevated: #242424 /* 悬停状态 - 中灰 */
```
#### 科技渐变色系(70%
```css
--tech-blue: #00D9FF /* 电光蓝 - 主交互色 */
--tech-blue-hover: #00B8D9 /* 悬停态 */
--tech-purple: #A855F7 /* 霓虹紫 - 渐变终点 */
--tech-purple-hover: #9333EA
--tech-pink: #D946EF /* 粉紫 - 渐变中间色 */
--tech-cyan: #06B6D4 /* 青色 - 点缀 */
```
**渐变组合:**
- 主渐变:`linear-gradient(135deg, #00D9FF 0%, #A855F7 50%, #D946EF 100%)`
- 柔和渐变:`linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%)`
- 光晕效果:`radial-gradient(circle at 50% 0%, rgba(0, 217, 255, 0.15) 0%, transparent 50%)`
#### 印章红色系(20%
```css
--brand-primary: #C41E3A /* 印章红 - 主品牌色 */
--brand-hover: #A01830 /* 悬停态 */
--brand-light: #E04A68 /* 浅色点缀 */
--brand-glow: rgba(196, 30, 58, 0.4) /* 发光效果 */
```
**使用场景:**
- Logo/图标
- CTA 按钮(主按钮)
- 重要数据强调
- 装饰性点缀元素
- 悬停高亮
#### 中性灰色系(10%
```css
--text-primary: #FAFAFA /* 主文字 - 近白 */
--text-secondary: #D4D4D4 /* 次级文字 - 浅灰 */
--text-tertiary: #A3A3A3 /* 辅助文字 - 中灰 */
--text-muted: #737373 /* 禁用/提示 - 深灰 */
--border-default: #262626 /* 默认边框 */
--border-hover: #333333 /* 悬停边框 */
--border-accent: #00D9FF /* 聚焦边框 */
```
### 2.3 浅色模式配色(可选)
```css
--bg-primary-light: #FFFFFF
--bg-secondary-light: #FAFAFA
--text-primary-light: #171717
--text-secondary-light: #525252
--brand-primary-light: #C41E3A
```
---
## 三、页面布局设计
### 3.1 首页整体结构
```
┌────────────────────────────────────────────────────────────┐
│ HEADER (64px) │
│ [Logo] [首页] [产品] [解决方案] [案例] [关于] [CTA] │
├────────────────────────────────────────────────────────────┤
│ │
│ HERO SECTION (100vh) │
│ │
│ ┌─────────────────────┐ ┌──────────────────────────┐ │
│ │ │ │ │ │
│ │ 主标题文案 │ │ 动态视觉元素 │ │
│ │ 副标题描述 │ │ - 光晕渐变 │ │
│ │ CTA 按钮组 │ │ - 抽象图形 │ │
│ │ 特性标签 │ │ - 微妙动效 │ │
│ │ │ │ │ │
│ └─────────────────────┘ └──────────────────────────┘ │
│ │
├────────────────────────────────────────────────────────────┤
│ SERVICES SECTION │
│ [图标] 服务领域1 [图标] 服务领域2 [图标] ... │
├────────────────────────────────────────────────────────────┤
│ PRODUCTS SECTION │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 产品卡1 │ │ 产品卡2 │ │ 产品卡3 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├────────────────────────────────────────────────────────────┤
│ ABOUT SECTION │
│ ┌──────────────┐ ┌─────────────────────────────────┐ │
│ │ 关于我们 │ │ 核心数据 / 成就展示 │ │
│ │ 企业理念 │ │ [数字动画] │ │
│ └──────────────┘ └─────────────────────────────────┘ │
├────────────────────────────────────────────────────────────┤
│ NEWS SECTION │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 新闻卡1 │ │ 新闻卡2 │ │ 新闻卡3 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├────────────────────────────────────────────────────────────┤
│ CONTACT SECTION │
│ [联系表单] [联系信息] │
├────────────────────────────────────────────────────────────┤
│ FOOTER │
│ [Logo] [导航链接] [社交媒体] [版权信息] │
└────────────────────────────────────────────────────────────┘
```
### 3.2 Hero 区域设计
#### 布局结构
- **高度:** 100vh(首屏全屏)
- **左右比例:** 60% 文案 / 40% 视觉元素
#### 视觉层次
**背景层:**
1. 深色底 `#0A0A0A`
2. 微妙网格线 `rgba(255,255,255)`Stripe,0.02 风格)
3. 顶部渐变光晕 `radial-gradient(from 50% 0%, rgba(0, 217, 255, 0.1), transparent 50%)`
4. 底部暖色光晕 `radial-gradient(to 50% 100%, rgba(196, 30, 58, 0.08), transparent 40%)`
**文案层:**
- 主标题:品牌名 + Slogan
- 副标题:价值主张(2-3行)
- CTA 按钮组:主按钮(印章红)+ 次按钮(渐变轮廓)
- 特性标签:3个核心优势点
**视觉层:**
- 右侧抽象图形:圆形/线条组合(象征连接、印章)
- 动态光晕:缓慢脉动的渐变圆
- 微妙粒子:缓慢漂浮(可选)
### 3.3 内容区块设计
**通用规则:**
- 上下间距:`120px`(桌面)/ `80px`(移动)
- 最大内容宽度:`1280px`
- 内边距:`24px`(桌面)/ `16px`(移动)
---
## 四、UI 组件设计
### 4.1 按钮系统
#### 主按钮(CTA - 印章红)
```css
/* 默认状态 */
background: #C41E3A;
color: #FFFFFF;
border-radius: 8px;
padding: 12px 32px;
font-weight: 600;
transition: all 0.3s ease;
/* 悬停状态 */
background: #A01830;
transform: translateY(-2px);
box-shadow: 0 0 30px rgba(196, 30, 58, 0.4);
/* 点击状态 */
transform: translateY(0);
box-shadow: 0 0 15px rgba(196, 30, 58, 0.3);
```
#### 次按钮(渐变轮廓)
```css
/* 默认状态 */
background: transparent;
border: 1px solid rgba(0, 217, 255, 0.5);
color: #00D9FF;
border-radius: 8px;
/* 悬停状态 */
background: rgba(0, 217, 255, 0.1);
border-color: #00D9FF;
box-shadow: 0 0 20px rgba(0, 217, 255, 0.2);
```
#### 渐变按钮
```css
/* 默认状态 */
background: linear-gradient(135deg, #00D9FF 0%, #A855F7 100%);
color: #FFFFFF;
border-radius: 8px;
/* 悬停状态 */
background: linear-gradient(135deg, #00B8D9 0%, #9333EA 100%);
box-shadow: 0 0 30px rgba(0, 217, 255, 0.3);
```
### 4.2 卡片系统
#### 服务/产品卡片
```css
/* 背景 */
background: #1A1A1A;
border: 1px solid #262626;
border-radius: 16px;
padding: 32px;
/* 悬停 */
border-color: #00D9FF;
transform: translateY(-4px);
box-shadow: 0 0 40px rgba(0, 217, 255, 0.1);
/* 图标容器 */
background: linear-gradient(135deg, rgba(0, 217, 255, 0.1), rgba(168, 85, 247, 0.1));
border-radius: 12px;
```
#### 数据卡片
```css
/* 背景 */
background: #141414;
border: 1px solid #333333;
border-radius: 12px;
padding: 24px;
/* 数字样式 */
color: #00D9FF;
font-size: 48px;
font-weight: 700;
/* 标签样式 */
color: #A3A3A3;
font-size: 14px;
```
### 4.3 导航栏
```css
/* 背景 */
background: rgba(10, 10, 10, 0.8);
backdrop-filter: blur(12px);
border-bottom: 1px solid #262626;
height: 64px;
/* Logo */
color: #C41E3A印章红 Logo
color: #FAFAFA公司名
/* 导航链接 */
color: #D4D4D4默认
color: #00D9FF悬停/当前
```
### 4.4 表单组件
```css
/* 输入框 */
background: #1A1A1A;
border: 1px solid #262626;
border-radius: 8px;
color: #FAFAFA;
padding: 12px 16px;
/* 聚焦状态 */
border-color: #00D9FF;
box-shadow: 0 0 0 3px rgba(0, 217, 255, 0.1);
/* 占位符 */
color: #737373;
```
---
## 五、动效系统
### 5.1 全局动效参数
```css
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--duration-fast: 150ms;
--duration-normal: 300ms;
--duration-slow: 500ms;
```
### 5.2 动效类型
#### 进入动效(页面加载)
- 元素从下方淡入
- 交错延迟:每元素 50ms
- 持续时间:500ms
#### 悬停动效
- 卡片上移 + 边框发光
- 按钮轻微上浮 + 阴影增强
- 持续时间:300ms
#### 背景动效
- 光晕缓慢脉动(4-6秒周期)
- 粒子缓慢漂浮(可选)
- 微妙流畅,不过度
---
## 六、响应式断点
```css
/* 移动优先设计 */
--breakpoint-sm: 640px; /* 手机横屏 */
--breakpoint-md: 768px; /* 平板 */
--breakpoint-lg: 1024px; /* 小笔记本 */
--breakpoint-xl: 1280px; /* 桌面 */
--breakpoint-2xl: 1536px; /* 大桌面 */
```
---
## 七、中国风元素设计
### 7.1 印章元素
**Logo/图标区:**
- 保留现有红色印章 Logo
- 印章可作为页面的"签名"元素出现在适当位置
**装饰元素:**
- 细线方形框(类似传统画框)
- 红色点缀线条
### 7.2 排版风格
**借鉴东方美学:**
- 大标题简洁有力
- 适当留白(padding/margin 略大)
- 信息层次清晰但不拥挤
**文字排版:**
- 标题:Bold, 紧凑字间距
- 正文:Regular, 宽松行高(1.6-1.8
### 7.3 色彩呼应
- 科技蓝紫渐变 = 科技、创新
- 印章红 = 诚信、权威、稳重
- 深色背景 = 专业、神秘感
---
## 八、验收标准
### 8.1 视觉验收
- [ ] 深色背景正确显示(#0A0A0A
- [ ] 蓝紫渐变正确应用
- [ ] 印章红作为点缀正确使用
- [ ] 卡片悬停效果流畅
- [ ] 动效优雅不卡顿
- [ ] 响应式布局正常
### 8.2 功能验收
- [ ] 导航链接正常工作
- [ ] CTA 按钮点击正常
- [ ] 表单交互正常
- [ ] 主题切换正常(如保留)
- [ ] 移动端菜单正常
### 8.3 性能验收
- [ ] 首屏加载 < 3s
- [ ] 动画流畅(60fps
- [ ] 无控制台错误
---
## 九、实施优先级
### Phase 1: 核心视觉
1. 更新全局配色系统
2. 重构 Hero 区域
3. 更新按钮和卡片样式
### Phase 2: 组件优化
4. 优化导航栏
5. 更新服务/产品区块
6. 添加动效
### Phase 3: 完善细节
7. 响应式优化
8. 性能优化
9. 跨浏览器测试
@@ -1,457 +0,0 @@
# Novalon 官网重构实施计划 - 金融科技中国风融合版
> **For Claude:** REQUIRED SUB-SKILL: Use `executing-plans` to implement this plan task-by-task.
> **After each task:** Use `requesting-code-review` skill for code review.
**Goal:** 将 Novalon 官网升级为金融科技中国风融合设计,包含配色系统、Hero 区域、按钮卡片样式、导航栏、动效等全面优化。
**Architecture:** 采用渐进式升级策略,从核心配色系统开始,逐步更新 UI 组件、页面布局和动效。使用 Tailwind CSS 的 CSS 变量系统实现主题切换,使用 Framer Motion 实现动效。
**Tech Stack:** Next.js 16, React 19, TypeScript, Tailwind CSS, Framer Motion, Lucide React
---
## Phase 1: 核心配色系统
### Task 1: 更新全局 CSS 配色变量
**Files:**
- Modify: `src/app/globals.css`
**Step 1: 更新深色模式配色变量**
`.dark` 类中更新配色变量,添加新的科技渐变色:
```css
.dark {
--color-bg-primary: #0A0A0A;
--color-bg-secondary: #141414;
--color-bg-tertiary: #1A1A1A;
--color-bg-elevated: #242424;
--color-text-primary: #FAFAFA;
--color-text-secondary: #D4D4D4;
--color-text-tertiary: #A3A3A3;
--color-text-muted: #737373;
--color-border-primary: #262626;
--color-border-secondary: #333333;
--color-border-accent: #00D9FF;
--color-brand-primary: #C41E3A;
--color-brand-primary-hover: #A01830;
--color-brand-primary-light: #E04A68;
--color-brand-glow: rgba(196, 30, 58, 0.4);
--color-tech-blue: #00D9FF;
--color-tech-blue-hover: #00B8D9;
--color-tech-blue-light: #33E1FF;
--color-tech-purple: #A855F7;
--color-tech-purple-hover: #9333EA;
--color-tech-purple-light: #C084FC;
--color-tech-pink: #D946EF;
--color-tech-cyan: #06B6D4;
}
```
**Step 2: 添加渐变工具类**
```css
@layer utilities {
.text-gradient-tech {
background: linear-gradient(135deg, #00D9FF 0%, #A855F7 50%, #D946EF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.bg-gradient-tech {
background: linear-gradient(135deg, #00D9FF 0%, #A855F7 100%);
}
.bg-glow-blue {
background: radial-gradient(circle at 50% 0%, rgba(0, 217, 255, 0.15) 0%, transparent 50%);
}
.bg-glow-red {
background: radial-gradient(circle at 50% 100%, rgba(196, 30, 58, 0.1) 0%, transparent 40%);
}
}
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功,无 CSS 错误
---
### Task 2: 更新 colors.ts 和 gradients.ts
**Files:**
- Modify: `src/lib/colors.ts`
- Modify: `src/lib/gradients.ts`
**Step 1: 更新 colors.ts**
添加新的科技色彩变量:
```typescript
tech: {
blue: {
DEFAULT: '#00D9FF',
hover: '#00B8D9',
light: '#33E1FF',
},
purple: {
DEFAULT: '#A855F7',
hover: '#9333EA',
light: '#C084FC',
},
pink: '#D946EF',
cyan: '#06B6D4',
},
brand: {
primary: '#C41E3A',
hover: '#A01830',
light: '#E04A68',
glow: 'rgba(196, 30, 58, 0.4)',
}
```
**Step 2: 更新 gradients.ts**
添加新的渐变组合:
```typescript
tech: 'linear-gradient(135deg, #00D9FF 0%, #A855F7 50%, #D946EF 100%)',
techSoft: 'linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%)',
glowBlue: 'radial-gradient(circle at 50% 0%, rgba(0, 217, 255, 0.15) 0%, transparent 50%)',
glowRed: 'radial-gradient(circle at 50% 100%, rgba(196, 30, 58, 0.1) 0%, transparent 40%)',
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功,无 TypeScript 错误
---
## Phase 2: Hero 区域重构
### Task 3: 重构 HeroSection 组件
**Files:**
- Modify: `src/components/sections/hero-section.tsx`
**Step 1: 更新背景层**
替换现有背景为深色渐变 + 光晕效果:
```tsx
<div className="absolute inset-0 pointer-events-none overflow-hidden">
<div className="absolute inset-0 bg-[#0A0A0A]" />
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:60px_60px]" />
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-[800px] h-[600px] bg-[radial-gradient(ellipse_at_center,rgba(0,217,255,0.1)_0%,transparent_60%)]" />
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] bg-[radial-gradient(ellipse_at_center,rgba(196,30,58,0.08)_0%,transparent_50%)]" />
</div>
```
**Step 2: 更新标题样式**
使用渐变文字效果:
```tsx
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-bold tracking-tight mb-6">
<span className="text-gradient-tech"></span>
</h1>
<p className="text-xl sm:text-2xl text-[var(--color-text-secondary)] mb-4">
</p>
<p className="text-lg text-[var(--color-text-tertiary)] mb-10 max-w-2xl">
</p>
```
**Step 3: 更新 CTA 按钮组**
```tsx
<div className="flex flex-col sm:flex-row gap-4 justify-center lg:justify-start">
<button className="px-8 py-4 bg-[#C41E3A] hover:bg-[#A01830] text-white font-semibold rounded-lg transition-all duration-300 hover:-translate-y-0.5 hover:shadow-[0_0_30px_rgba(196,30,58,0.4)]">
</button>
<button className="px-8 py-4 bg-transparent border border-[rgba(0,217,255,0.5)] text-[#00D9FF] font-semibold rounded-lg transition-all duration-300 hover:bg-[rgba(0,217,255,0.1)] hover:border-[#00D9FF] hover:shadow-[0_0_20px_rgba(0,217,255,0.2)]">
</button>
</div>
```
**Verification:**
- Run: `npm run dev`
- Check: Hero 区域显示正确的深色背景和渐变效果
---
### Task 4: 添加特性标签组件
**Files:**
- Modify: `src/components/sections/hero-section.tsx`
**Step 1: 添加特性标签**
在 CTA 按钮下方添加:
```tsx
<div className="flex flex-wrap gap-4 justify-center lg:justify-start mt-8">
{[
{ icon: Shield, text: '安全可靠' },
{ icon: Zap, text: '高效便捷' },
{ icon: Award, text: '专业服务' },
].map((feature, index) => (
<div key={index} className="flex items-center gap-2 px-4 py-2 rounded-full bg-[var(--color-bg-tertiary)] border border-[var(--color-border-primary)]">
<feature.icon className="w-4 h-4 text-[#00D9FF]" />
<span className="text-sm text-[var(--color-text-secondary)]">{feature.text}</span>
</div>
))}
</div>
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功
---
## Phase 3: 按钮和卡片样式
### Task 5: 更新 Button 组件
**Files:**
- Modify: `src/components/ui/button.tsx`
**Step 1: 添加新的变体样式**
```tsx
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-lg font-semibold transition-all duration-300",
{
variants: {
variant: {
default: "bg-[#C41E3A] text-white hover:bg-[#A01830] hover:-translate-y-0.5 hover:shadow-[0_0_30px_rgba(196,30,58,0.4)]",
secondary: "bg-[var(--color-bg-tertiary)] text-[var(--color-text-primary)] border border-[var(--color-border-primary)] hover:border-[#00D9FF] hover:shadow-[0_0_20px_rgba(0,217,255,0.2)]",
outline: "bg-transparent border border-[rgba(0,217,255,0.5)] text-[#00D9FF] hover:bg-[rgba(0,217,255,0.1)] hover:border-[#00D9FF] hover:shadow-[0_0_20px_rgba(0,217,255,0.2)]",
gradient: "bg-gradient-to-r from-[#00D9FF] to-[#A855F7] text-white hover:shadow-[0_0_30px_rgba(0,217,255,0.3)]",
ghost: "bg-transparent text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-elevated)]",
},
size: {
default: "h-10 px-6 py-2",
sm: "h-8 px-4 text-sm",
lg: "h-12 px-8 text-lg",
},
},
}
)
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功
---
### Task 6: 更新 Card 组件
**Files:**
- Modify: `src/components/ui/card.tsx`
**Step 1: 更新卡片样式**
```tsx
const cardVariants = cva(
"rounded-2xl bg-[var(--color-bg-tertiary)] border border-[var(--color-border-primary)] transition-all duration-300",
{
variants: {
variant: {
default: "hover:border-[#00D9FF] hover:-translate-y-1 hover:shadow-[0_0_40px_rgba(0,217,255,0.1)]",
elevated: "bg-[var(--color-bg-secondary)] shadow-lg",
interactive: "cursor-pointer hover:border-[#00D9FF] hover:-translate-y-1 hover:shadow-[0_0_40px_rgba(0,217,255,0.1)]",
},
},
}
)
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功
---
## Phase 4: 导航栏优化
### Task 7: 更新 Header 组件
**Files:**
- Modify: `src/components/layout/header.tsx`
**Step 1: 更新导航栏样式**
```tsx
<header className="fixed top-0 left-0 right-0 z-50 h-16 bg-[rgba(10,10,10,0.8)] backdrop-blur-xl border-b border-[var(--color-border-primary)]">
<nav className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-full flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded bg-[#C41E3A] flex items-center justify-center">
<span className="text-white font-bold text-sm"></span>
</div>
<span className="text-[var(--color-text-primary)] font-semibold text-lg">Novalon</span>
</div>
<div className="hidden md:flex items-center gap-8">
{navLinks.map((link) => (
<a
key={link.href}
href={link.href}
className="text-[var(--color-text-secondary)] hover:text-[#00D9FF] transition-colors duration-200"
>
{link.label}
</a>
))}
</div>
<button className="px-4 py-2 bg-[#C41E3A] hover:bg-[#A01830] text-white font-medium rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(196,30,58,0.3)]">
</button>
</nav>
</header>
```
**Verification:**
- Run: `npm run dev`
- Check: 导航栏显示正确的样式
---
## Phase 5: 服务区块优化
### Task 8: 更新 ServicesSection 组件
**Files:**
- Modify: `src/components/sections/services-section.tsx`
**Step 1: 更新服务卡片样式**
```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{services.map((service, index) => (
<div
key={index}
className="group p-6 rounded-2xl bg-[var(--color-bg-tertiary)] border border-[var(--color-border-primary)] transition-all duration-300 hover:border-[#00D9FF] hover:-translate-y-1 hover:shadow-[0_0_40px_rgba(0,217,255,0.1)]"
>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-[rgba(0,217,255,0.1)] to-[rgba(168,85,247,0.1)] flex items-center justify-center mb-4 group-hover:shadow-[0_0_20px_rgba(0,217,255,0.2)] transition-shadow duration-300">
<service.icon className="w-6 h-6 text-[#00D9FF]" />
</div>
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-2">
{service.title}
</h3>
<p className="text-[var(--color-text-tertiary)] text-sm">
{service.description}
</p>
</div>
))}
</div>
```
**Verification:**
- Run: `npm run build`
- Expected: 构建成功
---
## Phase 6: 动效添加
### Task 9: 添加滚动动画效果
**Files:**
- Modify: `src/hooks/use-scroll-reveal.ts`
**Step 1: 优化滚动动画参数**
```typescript
export function useScrollReveal(options = {}) {
const defaultOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px',
triggerOnce: true,
};
return useIntersectionObserver({
...defaultOptions,
...options,
});
}
```
**Step 2: 在组件中应用动画**
使用 Framer Motion 添加进入动画:
```tsx
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, ease: [0.16, 1, 0.3, 1] }}
>
{/* 内容 */}
</motion.div>
```
**Verification:**
- Run: `npm run dev`
- Check: 滚动动画流畅
---
## Phase 7: 最终验证
### Task 10: 全面测试和构建验证
**Step 1: 运行构建**
```bash
npm run build
```
**Step 2: 运行 lint**
```bash
npm run lint
```
**Step 3: 本地预览**
```bash
npm run dev
```
**Verification:**
- 构建成功
- 无 lint 错误
- 页面显示正确
- 动画流畅
---
## 验收标准
- [ ] 深色背景正确显示 (#0A0A0A)
- [ ] 蓝紫渐变正确应用
- [ ] 印章红作为点缀正确使用
- [ ] 卡片悬停效果流畅
- [ ] 动效优雅不卡顿
- [ ] 响应式布局正常
- [ ] 导航链接正常工作
- [ ] CTA 按钮点击正常
- [ ] 首屏加载 < 3s
- [ ] 无控制台错误
File diff suppressed because it is too large Load Diff
@@ -1,200 +0,0 @@
# TypeScript + Playwright E2E 测试框架实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**目标:** 为 Novalon Website 构建一个完整的、类型安全的 E2E 测试框架,使用 Playwright + TypeScript,实现全面的功能、性能、响应式和视觉测试覆盖,并集成 Woodpecker CI 自动化流程。
**架构:** 采用页面对象模式 (POM) 设计,所有测试代码使用 TypeScript 编写以获得类型安全,与 Next.js 项目共享类型定义。测试框架分为页面对象层、测试用例层、工具层和配置层,支持并行执行和多浏览器测试。
**技术栈:** Playwright (TypeScript), Vitest/Playwright Test, TypeScript 5, Woodpecker CI, @axe-core/playwright (可访问性测试)
---
## 阶段 1: 基础框架搭建
### Task 1: 初始化 Playwright 项目
**Files:**
- Create: `e2e/package.json`
- Create: `e2e/tsconfig.json`
- Create: `e2e/playwright.config.ts`
- Create: `e2e/.env.example`
**Step 1: 创建 e2e/package.json**
```json
{
"name": "e2e-tests",
"version": "1.0.0",
"private": true,
"scripts": {
"test": "playwright test",
"test:ui": "playwright test --ui",
"test:debug": "playwright test --debug",
"test:headed": "playwright test --headed",
"test:smoke": "playwright test --grep @smoke",
"test:regression": "playwright test --grep @regression",
"test:performance": "playwright test --grep @performance",
"test:responsive": "playwright test --grep @responsive",
"test:visual": "playwright test --grep @visual",
"test:report": "playwright show-report",
"install": "playwright install --with-deps"
},
"devDependencies": {
"@playwright/test": "^1.48.0",
"@axe-core/playwright": "^4.9.0",
"@types/node": "^20.11.0",
"typescript": "^5.3.0"
}
}
```
**Step 2: 创建 e2e/tsconfig.json**
```json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"jsx": "react",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": "..",
"paths": {
"@/*": ["src/*"],
"@e2e/*": ["e2e/*"]
}
},
"include": ["e2e/**/*"],
"exclude": ["node_modules", "dist", ".next"]
}
```
**Step 3: 创建 e2e/playwright.config.ts**
```typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 30 * 1000,
expect: {
timeout: 5000
},
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : 4,
reporter: [
['html', { outputFolder: 'playwright-report', open: 'never' }],
['json', { outputFile: 'test-results.json' }],
['junit', { outputFile: 'test-results.xml' }],
['list']
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
viewport: { width: 1920, height: 1080 },
ignoreHTTPSErrors: true,
contextOptions: {
locale: 'zh-CN',
timezoneId: 'Asia/Shanghai'
}
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
}
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
});
```
**Step 4: 创建 e2e/.env.example**
```bash
BASE_URL=http://localhost:3000
TEST_ENV=development
HEADLESS=true
PARALLEL_WORKERS=4
SCREENSHOT_ON_FAILURE=true
VIDEO_ON_FAILURE=true
```
**Step 5: 安装依赖**
Run: `cd e2e && npm install`
Expected: 依赖安装成功,node_modules 目录创建
**Step 6: 安装 Playwright 浏览器**
Run: `cd e2e && npx playwright install --with-deps`
Expected: 浏览器安装成功
**Step 7: 提交**
```bash
git add e2e/package.json e2e/tsconfig.json e2e/playwright.config.ts e2e/.env.example
git commit -m "feat: initialize Playwright TypeScript E2E test framework"
```
---
## 总结
实施计划已创建完成,包含以下阶段:
1. **阶段 1: 基础框架搭建** - 6 个任务
2. **阶段 2: 核心页面对象实现** - 2 个任务
3. **阶段 3: 冒烟测试实现** - 3 个任务
4. **阶段 4: 回归测试实现** - 2 个任务
5. **阶段 5: 性能测试实现** - 3 个任务
6. **阶段 6: 响应式测试实现** - 3 个任务
7. **阶段 7: 视觉回归测试** - 2 个任务
8. **阶段 8: Woodpecker CI 集成** - 1 个任务
总计:22 个任务,预计 8-10 周完成。
每个任务都包含:
- 详细的代码实现
- 运行验证步骤
- 预期结果
- Git 提交命令
---
## 下一步
**Plan complete and saved to `docs/plans/2026-02-26-e2e-test-framework-implementation.md`.**
**Two execution options:**
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
**Which approach?**
File diff suppressed because it is too large Load Diff
@@ -1,120 +0,0 @@
# 网站优化重构设计方案
**日期**: 2026-02-26
---
## 一、设计背景
当前网站存在以下问题:
1. 交互模式不统一:服务使用模态框,产品和案例使用独立页面
2. 首页 About Section 与 `/about` 页面内容高度重复
3. 导航链接不一致:混合使用锚点链接和页面链接
4. 配色方案不统一:同时使用品牌红和紫色
5. 首页缺少案例展示区块
---
## 二、设计决策
### 2.1 交互模式
**决策**: 统一使用独立页面,无弹窗交互
| 页面类型 | 首页展示 | 独立页面 | 交互方式 |
|---------|---------|---------|---------|
| 服务 | 概览卡片 | `/services/[id]` | 点击跳转 |
| 产品 | 概览卡片 | `/products/[id]` | 点击跳转 |
| 案例 | 概览卡片 | `/cases/[id]` | 点击跳转 |
| 新闻 | 概览卡片 | `/news/[slug]` | 点击跳转 |
| 关于 | 简短介绍 | `/about` | 点击跳转 |
### 2.2 服务详情页设计
**决策**: 采用故事化叙事风格
页面结构:
```
您可能面临的挑战 → 我们如何帮助您 → 服务流程 → 您将获得的改变 → 相关案例 → CTA
```
### 2.3 首页 About Section
**决策**: 精简版 + 核心数据 + CTA
内容:
- 品牌口号
- 品牌故事摘要(精简版)
- 核心数据(STATS
- "了解更多"按钮跳转到 `/about`
### 2.4 首页 Cases Section
**决策**: 新增,展示3个精选案例
### 2.5 导航结构
**决策**: 全部改为独立页面链接
```
首页 → /
核心业务 → /services
产品服务 → /products
关于我们 → /about
新闻动态 → /news
联系我们 → /contact
```
### 2.6 配色方案
**决策**: 统一使用品牌红色系,移除紫色
配色体系:
```
主色调
├── 品牌红 #C41E3A(主强调色)
├── 深红 #A01830hover状态)
└── 浅红 #FEF2F4(背景色)
中性色
├── 主文字 #1C1C1C
├── 次文字 #5C5C5C
├── 辅助文字 #718096
├── 边框 #E5E5E5
└── 背景 #FAFAFA / #F5F7FA
```
---
## 三、首页结构
调整后的首页 Section 顺序:
| 序号 | Section | 说明 |
|------|---------|------|
| 1 | Hero | 品牌展示 + 核心数据 |
| 2 | Services | 4个服务卡片(点击跳转详情页) |
| 3 | Products | 3个产品卡片(点击跳转详情页) |
| 4 | Cases | 3个精选案例(新增) |
| 5 | About | 精简版品牌故事 + 核心数据 |
| 6 | News | 最新动态 |
| 7 | Contact | 联系表单 |
---
## 四、任务清单
### 高优先级
1. 创建服务详情页 `/services/[id]`
2. 删除服务详情模态框
3. 精简首页 About Section
4. 首页新增 Cases Section
### 中优先级
5. 更新导航链接
6. 统一配色方案
7. 创建服务列表页 `/services`
### 低优先级
8. 优化 Footer 链接结构
9. 检查所有页面的设计风格一致性
File diff suppressed because it is too large Load Diff
@@ -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 (
<form onSubmit={handleSubmit}>
{/* 表单字段 */}
{submitResult && (
<div className={submitResult.success ? 'text-green-600' : 'text-red-600'}>
{submitResult.message}
</div>
)}
</form>
);
}
```
**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 (
<header>
<button
onClick={toggleMobileMenu}
aria-label={isMobileMenuOpen ? "关闭菜单" : "打开菜单"}
aria-expanded={isMobileMenuOpen}
>
<svg>...</svg>
</button>
<nav
id="mobile-menu-panel"
className={isMobileMenuOpen ? 'block' : 'hidden'}
aria-hidden={!isMobileMenuOpen}
>
{/* 菜单项 */}
</nav>
</header>
);
}
```
**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 (
<div>
<a href="#contact-form"></a>
<section id="contact-form">
{/* 表单 */}
</section>
</div>
);
}
```
**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 (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
);
}
```
**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<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
({ children, onClick, ...props }, ref) => {
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
requestAnimationFrame(() => {
onClick?.(e);
});
};
return (
<button
ref={ref}
onClick={handleClick}
className="..."
{...props}
>
{children}
</button>
);
}
);
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<T extends (...args: any[]) => any>(
callback: T,
delay: number
): T {
const lastRan = useRef(Date.now());
return useCallback(
(...args: Parameters<T>) => {
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 (
<div className="container mx-auto px-4 py-8">
<form className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
<div className="md:col-span-2">
<label className="block text-sm font-medium mb-2"></label>
<input
type="text"
name="name"
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2"></label>
<input
type="email"
name="email"
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2"></label>
<input
type="tel"
name="phone"
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="md:col-span-2">
<label className="block text-sm font-medium mb-2"></label>
<textarea
name="message"
rows={4}
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div className="md:col-span-2">
<button
type="submit"
className="w-full bg-blue-600 text-white py-3 rounded-lg hover:bg-blue-700 transition-colors"
>
</button>
</div>
</form>
</div>
);
}
```
**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 (
<div className="container mx-auto px-4 md:px-8 py-8 md:py-12">
<form className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
{/* 表单字段 - 使用md:前缀优化平板端 */}
</form>
</div>
);
}
```
**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 (
<div className="container mx-auto px-4 md:px-8 lg:px-16 py-8 md:py-12 lg:py-16">
<form className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-6xl mx-auto">
{/* 表单字段 - 使用lg:前缀优化大屏幕 */}
</form>
</div>
);
}
```
**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小时
File diff suppressed because it is too large Load Diff
@@ -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": "<script>alert('XSS')</script>",
"email": "test@example.com",
"message": "<img src=x onerror=alert('XSS')>"
}
}
}
```
**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)
- 频繁提交
@@ -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: '<script>alert("XSS")</script>',
email: 'test@example.com',
message: '<img src=x onerror=alert("XSS")>'
});
await contactPage.submit();
const pageContent = await page.content();
expect(pageContent).not.toContain('<script>alert');
expect(pageContent).not.toContain('onerror=alert');
});
test('安全头验证', async ({ page }) => {
const response = await page.goto('/');
const headers = response.headers();
expect(headers['x-frame-options']).toBeDefined();
expect(headers['x-content-type-options']).toBe('nosniff');
expect(headers['strict-transport-security']).toBeDefined();
});
test('HTTPS强制跳转', async ({ page }) => {
await page.goto('http://localhost:3000');
expect(page.url()).toMatch(/^https:/);
});
});
```
#### Level 5: Accessibility Tests(可访问性测试)
**执行频率**: 每周、发布前
**执行时间**: 10-15分钟
**标签**: `@accessibility`
**覆盖范围**:
- ✅ WCAG 2.1 AA标准合规
- ✅ 键盘导航测试
- ✅ 屏幕阅读器兼容性
- ✅ 颜色对比度验证
- ✅ 表单标签和ARIA属性
**测试用例**:
```typescript
test.describe('Accessibility Tests @accessibility', () => {
test('WCAG 2.1 AA合规 - 首页', async ({ page }) => {
await page.goto('/');
const accessibilityScanResults = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa'])
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
test('键盘导航', async ({ page }) => {
await page.goto('/');
await page.keyboard.press('Tab');
await expect(page.locator(':focus')).toBeVisible();
for (let i = 0; i < 10; i++) {
await page.keyboard.press('Tab');
const focusedElement = page.locator(':focus');
await expect(focusedElement).toBeVisible();
}
});
test('颜色对比度', async ({ page }) => {
await page.goto('/');
const contrastResults = await new AxeBuilder({ page })
.withRules(['color-contrast'])
.analyze();
expect(contrastResults.violations).toEqual([]);
});
});
```
---
## 五、迁移计划与实施步骤
### 5.1 迁移阶段划分
#### 阶段1: 评估与准备(1-2天)
**任务清单**:
- [ ] 分析现有Python测试用例,识别核心测试场景
- [ ] 评估现有Playwright测试的完整性和质量
- [ ] 确定需要迁移、重构、新增的测试用例
- [ ] 制定详细的测试用例清单和优先级
- [ ] 准备测试数据和测试环境配置
**产出物**:
- 测试用例迁移清单(Excel/Markdown
- 测试覆盖率分析报告
- 风险评估文档
#### 阶段2: 核心测试迁移(3-5天)
**任务清单**:
- [ ] 迁移smoke测试(确保基础功能覆盖)
- [ ] 页面可访问性测试
- [ ] 导航功能测试
- [ ] 关键表单测试
- [ ] 迁移regression测试(核心业务流程)
- [ ] 联系表单完整测试
- [ ] 产品展示测试
- [ ] 服务流程测试
- [ ] 建立完整的页面对象模型
- [ ] 配置测试数据管理
**产出物**:
- 完整的页面对象模型
- Smoke测试套件
- Regression测试套件
- 测试数据文件
#### 阶段3: 专项测试补充(3-4天)
**任务清单**:
- [ ] 补充performance测试(性能监控)
- [ ] 页面加载性能测试
- [ ] 资源优化验证
- [ ] 性能预算测试
- [ ] 补充security测试(安全合规)
- [ ] XSS漏洞测试
- [ ] 安全头验证
- [ ] HTTPS验证
- [ ] 补充accessibility测试(无障碍访问)
- [ ] WCAG合规测试
- [ ] 键盘导航测试
- [ ] 颜色对比度测试
- [ ] 补充visual regression测试(视觉回归)
- [ ] 关键页面截图对比
- [ ] 组件视觉测试
**产出物**:
- Performance测试套件
- Security测试套件
- Accessibility测试套件
- Visual regression测试套件
#### 阶段4: CI/CD集成与清理(2-3天)
**任务清单**:
- [ ] 配置Woodpecker CI流程
- [ ] 快速验证流程(每次提交)
- [ ] 完整测试流程(PR合并前)
- [ ] 定时测试流程(每日构建)
- [ ] 建立测试报告和通知机制
- [ ] HTML报告生成
- [ ] 失败通知配置
- [ ] 性能告警配置
- [ ] 删除Python测试框架(`e2e-tests/`目录)
- [ ] 更新项目文档
- [ ] README更新
- [ ] 测试指南编写
- [ ] CI/CD文档
**产出物**:
- Woodpecker CI配置文件
- 测试报告系统
- 更新的项目文档
### 5.2 迁移优先级矩阵
| 测试类型 | 优先级 | 迁移阶段 | 说明 |
|---------|--------|---------|------|
| 页面可访问性 | 高 | 阶段2 | 核心功能,必须覆盖 |
| 导航功能 | 高 | 阶段2 | 核心功能,必须覆盖 |
| 联系表单 | 高 | 阶段2 | 核心业务,必须覆盖 |
| 表单验证 | 高 | 阶段2 | 核心业务,必须覆盖 |
| 响应式测试 | 中 | 阶段2 | 重要但可后续优化 |
| 性能测试 | 中 | 阶段3 | 专项测试,独立实施 |
| 安全测试 | 中 | 阶段3 | 专项测试,独立实施 |
| 可访问性测试 | 中 | 阶段3 | 专项测试,独立实施 |
| 视觉回归 | 低 | 阶段3 | 可选,根据需求决定 |
### 5.3 风险控制
**风险识别**:
1. **测试覆盖不足**: 迁移过程中可能遗漏测试场景
2. **测试不稳定**: 新测试可能存在时序问题或环境依赖
3. **性能下降**: 测试执行时间可能超出预期
4. **CI流程中断**: 配置错误可能导致CI失败
**缓解措施**:
1. **保留Python测试**: 在Playwright测试完全覆盖前,保留Python测试作为备份
2. **渐进式迁移**: 分阶段迁移,每个阶段完成后进行验证
3. **并行执行**: 在迁移期间,两套框架并行运行,对比测试结果
4. **回滚机制**: 准备回滚方案,出现问题可快速恢复
---
## 六、CI/CD集成方案
### 6.1 Woodpecker CI流程设计
#### Level 1: 快速验证(每次提交触发)
```yaml
# .woodpecker.yml
when:
event: [push, pull_request]
steps:
- name: install-dependencies
image: node:20
commands:
- cd e2e
- npm ci
- name: smoke-tests
image: mcr.microsoft.com/playwright:v1.48.0-jammy
environment:
CI: true
commands:
- cd e2e
- npx playwright test --grep @smoke --project=chromium
when:
status: success
- name: upload-results
image: plugins/s3
settings:
bucket: test-results
source: e2e/test-results/**/*
target: /${CI_BUILD_NUMBER}/
when:
status: [success, failure]
```
**执行时间**: < 5分钟
**触发条件**: 每次代码提交
**失败处理**: 阻止合并,发送通知
#### Level 2: 完整测试(PR合并前触发)
```yaml
when:
event: pull_request
branch: main
steps:
- name: regression-tests
image: mcr.microsoft.com/playwright:v1.48.0-jammy
environment:
CI: true
commands:
- cd e2e
- npx playwright test --grep @regression
# 执行时间:15-30分钟
- name: performance-tests
image: mcr.microsoft.com/playwright:v1.48.0-jammy
commands:
- cd e2e
- npx playwright test --grep @performance
# 执行时间:10-20分钟
- name: generate-report
image: node:20
commands:
- cd e2e
- npx playwright show-report --host 0.0.0.0
```
**执行时间**: 25-50分钟
**触发条件**: PR合并前
**失败处理**: 阻止合并,生成详细报告
#### Level 3: 全面测试(定时执行)
```yaml
when:
event: cron
cron: "0 2 * * *" # 每天凌晨2点
steps:
- name: full-test-suite
image: mcr.microsoft.com/playwright:v1.48.0-jammy
environment:
CI: true
commands:
- cd e2e
- npx playwright test
# 执行完整测试套件
- name: security-tests
commands:
- npx playwright test --grep @security
- name: accessibility-tests
commands:
- npx playwright test --grep @accessibility
- name: generate-trend-report
commands:
- node scripts/generate-trend-report.js
```
**执行时间**: 1-2小时
**触发条件**: 每日凌晨2点
**失败处理**: 发送通知,生成趋势报告
### 6.2 测试报告与通知
#### 报告生成
**HTML报告**:
```typescript
// playwright.config.ts
reporter: [
['html', {
outputFolder: 'test-results/html-report',
open: 'never'
}],
['json', {
outputFile: 'test-results/results.json'
}],
['junit', {
outputFile: 'test-results/junit.xml'
}],
['list']
]
```
**报告内容**:
- 测试执行摘要(通过/失败/跳过)
- 失败测试详情(截图、视频、trace)
- 性能指标趋势
- 测试覆盖率统计
#### 通知机制
**失败通知**:
```yaml
- name: notify-failure
image: plugins/slack
settings:
webhook: ${SLACK_WEBHOOK}
channel: testing
template: |
❌ E2E测试失败
构建号: {{build.number}}
分支: {{build.branch}}
提交: {{build.commit}}
失败测试: {{failures}}
报告链接: {{report_url}}
when:
status: failure
```
**性能告警**:
```typescript
// scripts/check-performance-regression.ts
const currentMetrics = await getCurrentMetrics();
const baselineMetrics = await getBaselineMetrics();
if (currentMetrics.loadTime > baselineMetrics.loadTime * 1.2) {
await sendAlert({
type: 'performance_regression',
message: `页面加载时间退化20%: ${currentMetrics.loadTime}ms vs ${baselineMetrics.loadTime}ms`
});
}
```
### 6.3 质量门禁
#### PR合并条件
**必须满足**:
- ✅ Smoke测试100%通过
- ✅ Regression测试通过率 ≥ 95%
- ✅ 无新增严重缺陷
- ✅ 性能指标在预算范围内
**可选条件**:
- ⚠️ Performance测试通过率 ≥ 90%
- ⚠️ 测试覆盖率 ≥ 80%
#### 质量指标跟踪
```typescript
// scripts/quality-metrics.ts
interface QualityMetrics {
smokePassRate: number; // 目标: 100%
regressionPassRate: number; // 目标: ≥ 95%
performanceBudget: number; // 目标: 100%符合预算
testCoverage: number; // 目标: ≥ 80%
avgExecutionTime: number; // 目标: < 30分钟
}
async function checkQualityGate(metrics: QualityMetrics): Promise<boolean> {
return (
metrics.smokePassRate === 100 &&
metrics.regressionPassRate >= 95 &&
metrics.performanceBudget === 100 &&
metrics.testCoverage >= 80
);
}
```
---
## 七、测试数据管理
### 7.1 测试数据策略
**数据源分类**:
1. **静态测试数据**: JSON/YAML文件,存储在`test-data/`目录
2. **动态测试数据**: 运行时生成,使用TestDataGenerator
3. **环境特定数据**: 通过环境变量配置
### 7.2 数据文件示例
**联系表单测试数据** (`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": "请输入姓名"
},
"invalidEmail": {
"name": "测试用户",
"email": "invalid-email",
"message": "测试消息",
"expectedError": "邮箱格式不正确"
}
}
}
```
### 7.3 数据生成器
```typescript
// src/utils/TestDataGenerator.ts
export class TestDataGenerator {
static generateContactForm(overrides = {}) {
return {
name: `测试用户_${Date.now()}`,
email: `test_${Date.now()}@example.com`,
phone: this.generatePhone(),
company: '测试公司',
message: `测试消息_${Date.now()}`,
...overrides
};
}
static generatePhone() {
return `1${Math.floor(Math.random() * 9000000000 + 1000000000)}`;
}
}
```
---
## 八、最佳实践与规范
### 8.1 测试编写规范
**命名规范**:
```typescript
// ✅ 好的命名
test('联系表单 - 提交成功', async ({ page }) => {});
test('联系表单 - 邮箱格式验证', async ({ page }) => {});
// ❌ 不好的命名
test('test1', async ({ page }) => {});
test('表单测试', async ({ page }) => {});
```
**测试结构**:
```typescript
test.describe('功能模块 @tag', () => {
test.beforeEach(async ({ page }) => {
// 前置条件
});
test('测试场景 - 具体描述', async ({ page }) => {
// Arrange: 准备测试数据
const testData = TestDataGenerator.generateContactForm();
// Act: 执行测试操作
await contactPage.fillForm(testData);
await contactPage.submit();
// Assert: 验证结果
await expect(contactPage.successMessage).toBeVisible();
});
test.afterEach(async ({ page }) => {
// 清理工作
});
});
```
### 8.2 页面对象模式
**BasePage示例**:
```typescript
// src/pages/BasePage.ts
export abstract class BasePage {
constructor(protected page: Page) {}
async goto(path: string = '/') {
await this.page.goto(path);
await this.waitForPageLoad();
}
async waitForPageLoad() {
await this.page.waitForLoadState('networkidle');
}
async screenshot(name: string) {
await this.page.screenshot({
path: `screenshots/${name}.png`,
fullPage: true
});
}
async waitForElement(selector: string, timeout = 30000) {
await this.page.waitForSelector(selector, { timeout });
}
}
```
**ContactPage示例**:
```typescript
// src/pages/ContactPage.ts
export class ContactPage extends BasePage {
readonly nameInput = this.page.locator('input[name="name"]');
readonly emailInput = this.page.locator('input[name="email"]');
readonly messageInput = this.page.locator('textarea[name="message"]');
readonly submitButton = this.page.locator('button[type="submit"]');
readonly successMessage = this.page.locator('.success-message');
readonly nameError = this.page.locator('.error-name');
readonly emailError = this.page.locator('.error-email');
async goto() {
await super.goto('/contact');
}
async fillForm(data: ContactFormData) {
await this.nameInput.fill(data.name);
await this.emailInput.fill(data.email);
if (data.phone) await this.page.locator('input[name="phone"]').fill(data.phone);
if (data.company) await this.page.locator('input[name="company"]').fill(data.company);
await this.messageInput.fill(data.message);
}
async submit() {
await this.submitButton.click();
await this.page.waitForLoadState('networkidle');
}
}
```
### 8.3 断言最佳实践
```typescript
// ✅ 好的断言
await expect(page).toHaveURL(/contact/);
await expect(element).toBeVisible();
await expect(element).toHaveText('预期文本');
await expect(element).toHaveAttribute('href', '/expected-path');
// ❌ 不好的断言
expect(await element.isVisible()).toBe(true);
expect(await element.textContent()).toContain('文本');
```
---
## 九、监控与持续改进
### 9.1 测试质量指标
**关键指标**:
- 测试通过率
- 测试覆盖率
- 平均执行时间
- Flaky测试率
- 缺陷逃逸率
### 9.2 持续改进计划
**定期评估**:
- 每周回顾测试结果,识别不稳定测试
- 每月分析测试覆盖率,补充缺失场景
- 每季度评估测试策略,优化测试金字塔
**优化方向**:
- 减少测试执行时间
- 提高测试稳定性
- 增强测试覆盖率
- 改进测试报告
---
## 十、总结
### 核心价值
1. **统一技术栈**: 降低维护成本,提高开发效率
2. **全面覆盖**: 业务、性能、安全、可访问性全覆盖
3. **金融级质量**: 满足金融行业高标准要求
4. **CI/CD集成**: 自动化测试流程,快速反馈
### 预期收益
- **开发效率**: 减少30%的测试维护时间
- **质量保障**: 缺陷逃逸率降低50%
- **发布速度**: 测试反馈时间缩短60%
- **团队协作**: 统一技术栈,降低学习成本
### 下一步行动
1. ✅ 完成设计文档评审
2. ⏭️ 开始阶段1:评估与准备
3. ⏭️ 按计划推进迁移工作
4. ⏭️ 建立CI/CD流程
5. ⏭️ 持续优化和改进
---
**文档版本**: v1.0
**最后更新**: 2026-02-28
**维护者**: 张翔
@@ -1,253 +0,0 @@
# Footer 全面升级设计方案
**日期:** 2026-03-04
**设计风格:** 浅色现代风格
**布局结构:** 4列布局
---
## 一、整体布局与视觉风格
### 1.1 背景与色彩体系
**背景设计:**
- 主背景:保持浅色背景 `#F5F5F5`
- 渐变效果:从上到下微妙渐变(`#F5F5F5``#FAFAFA`
- 顶部阴影:`shadow-[0_-4px_20px_rgba(0,0,0,0.03)]`
**色彩体系:**
- 强调色:品牌深红 `#C41E3A`(图标、链接悬停、分隔线)
- 文字层次:
- 标题:`#1C1C1C` 深色
- 正文:`#3D3D3D` 中灰色
- 辅助文字:`#5C5C5C` 浅灰色
### 1.2 布局结构
**4列布局:**
```
[品牌信息+二维码] [快速链接] [服务项目] [联系方式]
```
**间距优化:**
- 列间距:`gap-8 lg:gap-12`
- 内边距:`py-16`(增加呼吸感)
- 元素间距:统一使用 `space-y-4``space-y-6`
---
## 二、品牌信息区域设计(第一列)
### 2.1 品牌展示区(顶部)
**Logo区域:**
- Logo尺寸:保持当前 `h-10`
- 悬停效果:`hover:scale-105 hover:shadow-md transition-all duration-200`
- 公司名称:Logo右侧添加"睿新致遠"`font-semibold text-lg text-[#1C1C1C]`
- Slogan:名称下方添加"智连未来,成长伙伴",`text-sm text-[#5C5C5C] mt-1`
**公司描述:**
- 保持当前内容
- 优化行高:`leading-relaxed`
### 2.2 二维码区域(中部)
**分隔线:**
- 使用 `border-t border-[#E5E5E5]` 与上方内容区分
**二维码展示:**
- 标题:"关注公众号"`text-sm font-medium text-[#1C1C1C] mb-3`
- 卡片样式:
- 白色背景 + 边框
- 阴影:`shadow-sm hover:shadow-md transition-shadow`
- 内边距:`p-3`
- 尺寸:140x140px
- 引导文字:"扫码关注获取最新资讯",`text-xs text-[#718096] mt-2`
---
## 三、其他三列设计
### 3.1 第二列:快速链接
**标题设计:**
- 文字:"快速链接"
- 样式:`font-semibold text-lg text-[#1C1C1C] mb-6`
- 左侧装饰:品牌色竖线 `w-1 h-6 bg-[#C41E3A] rounded-full`
**链接列表:**
- 保持当前导航项
- 样式优化:
- 默认:`text-[#3D3D3D] text-sm`
- 悬停:`hover:text-[#C41E3A] hover:translate-x-1 transition-all duration-200`
- 间距:`space-y-3`
- 图标前缀:小圆点 `w-1.5 h-1.5 bg-[#C41E3A] rounded-full`
### 3.2 第三列:服务项目
**标题设计:**
- 文字:"服务项目"
- 样式:与快速链接标题保持一致
**服务列表:**
- 保持当前服务项
- 样式:与快速链接保持一致
### 3.3 第四列:联系方式
**标题设计:**
- 文字:"联系方式"
- 样式:与其他列标题保持一致
**联系信息:**
- 保持图标 + 文字布局
- 样式优化:
- 图标:`w-5 h-5 text-[#C41E3A]`
- 文字:`text-[#3D3D3D] text-sm`
- 悬停:`group-hover:translate-x-1`
- 间距:`space-y-4`
---
## 四、底部信息区域设计
### 4.1 版权与合规信息区
**分隔线:**
- 使用 `border-t border-[#E5E5E5] mt-12 pt-8`
**布局:**
- `flex flex-col md:flex-row justify-between items-center gap-4`
**左侧:**
- 版权信息:`© 2026 四川睿新致远科技有限公司 All rights reserved.`
- 样式:`text-[#5C5C5C] text-sm`
**右侧:**
- 隐私政策、服务条款链接
- 样式:`text-[#5C5C5C] hover:text-[#C41E3A] text-sm transition-colors`
- 间距:`gap-6`
### 4.2 备案信息
**位置:**
- 版权信息下方
- 样式:`text-center mt-4 pt-4 border-t border-[#E5E5E5]`
**内容:**
- ICP备案号:`蜀ICP备XXXXXXXX号-1`
- 公安备案:`川公网安备 XXXXXXXXXXX号`
- 样式:`text-xs text-[#718096]`
- 链接:备案号可链接到工信部查询页面
---
## 五、响应式设计
### 5.1 移动端(< 768px
**布局:**
- 单列堆叠:`grid-cols-1`
- 间距:`gap-8`
- 内边距:`py-12`
**顺序:**
1. 品牌信息 + 二维码
2. 快速链接
3. 服务项目
4. 联系方式
**二维码:**
- 居中显示:`mx-auto`
### 5.2 平板端(768px - 1024px
**布局:**
- 2列网格:`md:grid-cols-2`
- 间距:`gap-8`
### 5.3 桌面端(> 1024px
**布局:**
- 4列网格:`lg:grid-cols-4`
- 间距:`gap-12`
- 内边距:`py-16`
---
## 六、交互细节优化
### 6.1 链接悬停效果
- 快速链接、服务项目:`hover:text-[#C41E3A] hover:translate-x-1 transition-all duration-200`
- 联系方式:整个项目悬停时轻微右移
- 底部链接:`hover:text-[#C41E3A] transition-colors`
### 6.2 二维码交互
- 悬停效果:阴影增强 `hover:shadow-lg`
- 可选:点击放大功能(使用Dialog组件)
### 6.3 Logo悬停
- 轻微放大:`hover:scale-105`
- 添加阴影:`hover:shadow-md`
- 过渡效果:`transition-all duration-200`
### 6.4 可访问性优化
- 所有链接添加 `aria-label`
- 图标添加 `aria-hidden="true"`
- 确保颜色对比度符合 WCAG AA 标准
- 键盘导航友好
---
## 七、性能优化
### 7.1 图片优化
- Logo:使用 `priority` 属性(首屏加载)
- 二维码:使用 `loading="lazy"`(懒加载)
- 添加 `sizes` 属性优化响应式图片
### 7.2 CSS优化
- 使用 Tailwind CSS 的 JIT 模式
- 避免重复的类名组合
- 使用组件化的样式方案
---
## 八、实施计划
### 8.1 实施步骤
1. 更新 `footer.tsx` 组件代码
2. 添加必要的图标组件(如果需要)
3. 更新 `constants.ts` 添加备案信息
4. 测试响应式布局
5. 验证可访问性
6. 性能优化检查
### 8.2 预期效果
- ✅ 视觉层次更清晰
- ✅ 品牌形象更突出
- ✅ 用户体验更友好
- ✅ 符合金融级标准
- ✅ 响应式适配完善
- ✅ 可访问性达标
---
## 九、未来扩展
### 9.1 预留区域
- 合作伙伴展示区(已设计,暂时隐藏)
- 认证资质标识区(已设计,暂时隐藏)
### 9.2 扩展方式
需要时取消注释相关代码即可启用。
File diff suppressed because it is too large Load Diff
@@ -1,255 +0,0 @@
# 移动端测试完善 - 并行会话执行指南
## 📋 概述
本文档指导您如何在新的工作树中打开新会话来执行移动端测试完善实施计划。
## 🎯 执行目标
按照 `docs/plans/2026-03-05-mobile-testing-implementation-plan.md` 中的实施计划,分四个阶段完成移动端测试体系的建立。
## 📂 工作树信息
**工作树位置**: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website-mobile-testing`
**当前分支**: `feature/mobile-testing-enhancement`
**基础提交**: `f7904cb` - docs: add mobile testing enhancement design document
## 🚀 执行步骤
### 步骤 1: 切换到工作树
在新的终端中,切换到工作树目录:
```bash
cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website-mobile-testing
```
### 步骤 2: 安装依赖
确保所有依赖都已安装:
```bash
cd e2e
npm install
```
### 步骤 3: 验证环境
验证 Playwright 环境是否正常:
```bash
npx playwright --version
npx playwright install chromium
```
### 步骤 4: 打开新会话
在 Trae IDE 中,打开新会话并设置工作目录为:
```
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website-mobile-testing
```
### 步骤 5: 在新会话中调用 executing-plans skill
在新会话中,明确告知 AI
```
我需要在工作树 /Users/zhangxiang/Codes/Gitee/home-page/novalon-website-mobile-testing 中执行移动端测试完善实施计划。
请使用 executing-plans skill 来执行 docs/plans/2026-03-05-mobile-testing-implementation-plan.md 中的计划。
按照计划中的任务顺序执行,每个任务完成后提交代码,并在检查点暂停等待审查。
```
## 📝 实施计划概览
### Phase 1: 基础设施扩展(1-2 周)
**任务列表**:
1. Task 1.1: 扩展设备配置 - 添加 iPhone 系列
2. Task 1.2: 扩展设备配置 - 添加 Android 系列
3. Task 1.3: 扩展设备配置 - 添加 iPad 系列
4. Task 1.4: 创建网络配置文件
5. Task 1.5: 创建移动端测试数据生成器
6. Task 1.6: 扩展 Playwright 配置
**检查点**: Phase 1 完成后,暂停等待审查
### Phase 2: 核心测试工具开发(2-3 周)
**任务列表**:
1. Task 2.1: 创建手势模拟器 - 基础结构
2. Task 2.2: 实现手势模拟器 - 单指滑动
3. Task 2.3: 实现手势模拟器 - 双指捏合
4. Task 2.4: 实现手势模拟器 - 长按和双击
5. Task 2.5: 实现手势模拟器 - 拖拽
6. Task 2.6: 创建网络环境模拟器 - 基础结构
7. Task 2.7: 实现网络环境模拟器 - 网络条件设置
8. Task 2.8: 创建移动端性能监控器 - 基础结构
9. Task 2.9: 实现移动端性能监控器 - Core Web Vitals
10. Task 2.10: 实现移动端性能监控器 - Lighthouse 集成
**检查点**: Phase 2 完成后,暂停等待审查
### Phase 3: 测试用例开发(3-4 周)
**任务列表**:
1. Task 3.1: 创建移动端性能测试套件
2. Task 3.2: 创建移动端兼容性测试套件
3. Task 3.3: 创建移动端手势交互测试套件
4. Task 3.4: 创建移动端 PWA 功能测试套件
**检查点**: Phase 3 完成后,暂停等待审查
### Phase 4: 高级功能和优化(2-3 周)
**任务列表**:
1. Task 4.1: 创建移动端测试报告系统
2. Task 4.2: 实现移动端测试报告 - HTML 报告
3. Task 4.3: 优化测试执行效率 - 并行测试
4. Task 4.4: 创建测试文档
**检查点**: Phase 4 完成后,暂停等待审查
## 🔍 检查点审查清单
在每个 Phase 完成后,进行以下审查:
### Phase 1 审查清单
- [ ] 所有新设备配置正确(iPhone、Android、iPad
- [ ] 测试数据生成器功能完整
- [ ] Playwright 配置支持多设备并行测试
- [ ] 所有测试通过
### Phase 2 审查清单
- [ ] 手势模拟器支持所有基本手势(滑动、捏合、长按、双击、拖拽)
- [ ] 网络模拟器支持所有网络场景(在线、离线、弱网、网络切换)
- [ ] 性能监控器能准确测量 Core Web Vitals
- [ ] Lighthouse 集成正常工作
- [ ] 所有测试通过
### Phase 3 审查清单
- [ ] 所有测试用例通过
- [ ] 测试覆盖率达到预期目标
- [ ] 测试执行时间在可接受范围内
- [ ] 无严重缺陷
### Phase 4 审查清单
- [ ] 测试报告系统生成完整的移动端报告
- [ ] 测试执行效率提升 30% 以上
- [ ] 文档完整且易于理解
- [ ] 所有测试通过
## 📊 进度跟踪
使用以下命令跟踪进度:
```bash
# 查看提交历史
git log --oneline --graph
# 查看分支状态
git status
# 查看与主分支的差异
git diff feat-init
```
## 🔄 同步主分支
定期同步主分支以获取最新更改:
```bash
# 拉取最新更改
git fetch origin
# 合并主分支
git merge origin/feat-init
# 解决冲突(如果有)
git add .
git commit -m "merge: resolve conflicts with feat-init"
```
## 📤 推送更改
在每个 Phase 完成并审查通过后,推送更改:
```bash
git push origin feature/mobile-testing-enhancement
```
## 🐛 问题处理
### 常见问题
**问题 1**: Playwright 浏览器未安装
```bash
npx playwright install
```
**问题 2**: 依赖安装失败
```bash
rm -rf node_modules package-lock.json
npm install
```
**问题 3**: 测试失败
```bash
# 查看详细错误信息
npm run test -- --reporter=list
# 运行特定测试
npm run test -- --grep "test-name"
```
**问题 4**: Git 冲突
```bash
# 查看冲突文件
git status
# 手动解决冲突
# 编辑冲突文件
# 标记冲突已解决
git add <conflicted-file>
git commit
```
## 📞 支持和反馈
如果在执行过程中遇到问题:
1. 查看实施计划文档中的详细步骤
2. 查看相关代码文件中的注释
3. 运行测试验证更改
4. 在检查点暂停并请求审查
## ✅ 完成标准
当满足以下条件时,认为实施完成:
- [ ] 所有 4 个 Phase 的任务都已完成
- [ ] 所有测试通过
- [ ] 所有验收标准都满足
- [ ] 文档完整且准确
- [ ] 代码已推送到远程仓库
## 📚 相关文档
- 设计文档: `docs/plans/2026-03-05-mobile-testing-enhancement-design.md`
- 实施计划: `docs/plans/2026-03-05-mobile-testing-implementation-plan.md`
- 测试指南: `e2e/docs/mobile-testing-guide.md`(将在 Phase 4 中创建)
---
**创建日期**: 2026-03-05
**文档版本**: 1.0
**状态**: 准备执行
File diff suppressed because it is too large Load Diff
@@ -1,830 +0,0 @@
# 冒烟测试失败修复实施计划
> **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. 优化测试执行时间
@@ -1,789 +0,0 @@
# Test Suite Execution and Code Optimization Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Run the complete E2E test suite, identify failures, and fix or optimize code to ensure all tests pass.
**Architecture:** Execute Playwright test suite in phases (smoke → regression → performance → accessibility), analyze failures, implement fixes following TDD principles, and verify with re-runs.
**Tech Stack:** Playwright, TypeScript, Next.js, React, Tailwind CSS
---
### Task 1: Prepare Test Environment and Dependencies
**Files:**
- Check: `e2e/package.json`
- Check: `package.json`
**Step 1: Verify Playwright installation**
Run: `cd e2e && npx playwright --version`
Expected: Playwright version displayed (e.g., 1.58.2)
**Step 2: Install Playwright browsers if needed**
Run: `cd e2e && npm run install`
Expected: Browsers installed successfully
**Step 3: Verify development server is not running**
Run: `lsof -ti:3000`
Expected: No output (port 3000 is free)
---
### Task 2: Run Smoke Tests (Critical Path Validation)
**Files:**
- Test: `e2e/src/tests/smoke/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run smoke tests**
Run: `cd e2e && npm run test:smoke`
Expected: All smoke tests pass or specific failures identified
**Step 2: Analyze smoke test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document smoke test failures**
Create: `test-results/smoke-failures.md`
```markdown
# Smoke Test Failures
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Common Issues
- Issue 1: Description
- Issue 2: Description
```
---
### Task 3: Fix Smoke Test Failures
**Files:**
- Modify: Based on specific failures
- Test: `e2e/src/tests/smoke/*.spec.ts`
**Step 1: Identify root cause of first failure**
Run: `cd e2e && npx playwright test --grep @smoke --debug`
Expected: Debug mode opens, allows inspection
**Step 2: Implement fix for first failure**
Modify: [Specific file based on failure]
```typescript
// Fix implementation based on test failure
```
**Step 3: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-test-name"`
Expected: Test passes
**Step 4: Commit fix**
Run: `git add [modified-files] && git commit -m "fix: resolve smoke test failure - [test-name]"`
Expected: Commit successful
**Step 5: Repeat for all smoke test failures**
Run: `cd e2e && npm run test:smoke`
Expected: All smoke tests pass
---
### Task 4: Run Regression Tests (Feature Validation)
**Files:**
- Test: `e2e/src/tests/regression/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run regression tests**
Run: `cd e2e && npm run test:regression`
Expected: All regression tests pass or specific failures identified
**Step 2: Analyze regression test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document regression test failures**
Create: `test-results/regression-failures.md`
```markdown
# Regression Test Failures
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Common Issues
- Issue 1: Description
- Issue 2: Description
```
---
### Task 5: Fix Regression Test Failures
**Files:**
- Modify: Based on specific failures
- Test: `e2e/src/tests/regression/*.spec.ts`
**Step 1: Identify root cause of first failure**
Run: `cd e2e && npx playwright test --grep @regression --debug`
Expected: Debug mode opens, allows inspection
**Step 2: Implement fix for first failure**
Modify: [Specific file based on failure]
```typescript
// Fix implementation based on test failure
```
**Step 3: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-test-name"`
Expected: Test passes
**Step 4: Commit fix**
Run: `git add [modified-files] && git commit -m "fix: resolve regression test failure - [test-name]"`
Expected: Commit successful
**Step 5: Repeat for all regression test failures**
Run: `cd e2e && npm run test:regression`
Expected: All regression tests pass
---
### Task 6: Run Performance Tests
**Files:**
- Test: `e2e/src/tests/performance/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run performance tests**
Run: `cd e2e && npm run test:performance`
Expected: All performance tests pass or specific failures identified
**Step 2: Analyze performance test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document performance issues**
Create: `test-results/performance-issues.md`
```markdown
# Performance Test Issues
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Performance Metrics
- LCP (Largest Contentful Paint): [value]s (target: < 2.5s)
- FID (First Input Delay): [value]ms (target: < 100ms)
- CLS (Cumulative Layout Shift): [value] (target: < 0.1)
## Optimization Opportunities
- Issue 1: Description
- Issue 2: Description
```
---
### Task 7: Optimize Performance Issues
**Files:**
- Modify: Based on performance issues
- Test: `e2e/src/tests/performance/*.spec.ts`
**Step 1: Optimize first performance issue**
Modify: [Specific file based on issue]
```typescript
// Performance optimization implementation
```
**Step 2: Verify optimization with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-performance-test"`
Expected: Test passes with improved metrics
**Step 3: Commit optimization**
Run: `git add [modified-files] && git commit -m "perf: optimize [component/feature] - [improvement]"`
Expected: Commit successful
**Step 4: Repeat for all performance issues**
Run: `cd e2e && npm run test:performance`
Expected: All performance tests pass
---
### Task 8: Run Accessibility Tests
**Files:**
- Test: `e2e/src/tests/accessibility/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run accessibility tests**
Run: `cd e2e && npm run test:accessibility`
Expected: All accessibility tests pass or specific failures identified
**Step 2: Analyze accessibility test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document accessibility issues**
Create: `test-results/accessibility-issues.md`
```markdown
# Accessibility Test Issues
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## WCAG Violations
- Level A: [count] violations
- Level AA: [count] violations
- Level AAA: [count] violations
## Common Issues
- Issue 1: Description
- Issue 2: Description
```
---
### Task 9: Fix Accessibility Issues
**Files:**
- Modify: Based on accessibility issues
- Test: `e2e/src/tests/accessibility/*.spec.ts`
**Step 1: Fix first accessibility issue**
Modify: [Specific file based on issue]
```typescript
// Accessibility fix implementation
```
**Step 2: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-accessibility-test"`
Expected: Test passes
**Step 3: Commit fix**
Run: `git add [modified-files] && git commit -m "a11y: fix [accessibility-issue] - [wcag-guideline]"`
Expected: Commit successful
**Step 4: Repeat for all accessibility issues**
Run: `cd e2e && npm run test:accessibility`
Expected: All accessibility tests pass
---
### Task 10: Run Visual Regression Tests
**Files:**
- Test: `e2e/src/tests/visual/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run visual regression tests**
Run: `cd e2e && npm run test:visual`
Expected: All visual tests pass or specific failures identified
**Step 2: Analyze visual test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Review visual differences**
Run: `cd e2e && npx playwright show-report`
Expected: Visual comparison shows differences
**Step 4: Document visual issues**
Create: `test-results/visual-issues.md`
```markdown
# Visual Regression Test Issues
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Visual Differences
- Component 1: [description of difference]
- Component 2: [description of difference]
## Action Required
- [ ] Accept changes (intentional design updates)
- [ ] Fix issues (unintended visual regressions)
```
---
### Task 11: Fix Visual Regression Issues
**Files:**
- Modify: Based on visual issues
- Test: `e2e/src/tests/visual/*.spec.ts`
**Step 1: Determine if visual difference is intentional**
Run: `cd e2e && npx playwright test --grep "specific-visual-test" --update-snapshots`
Expected: Only run if difference is intentional
**Step 2: Fix unintended visual regression**
Modify: [Specific file based on issue]
```typescript
// Visual regression fix implementation
```
**Step 3: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-visual-test"`
Expected: Test passes
**Step 4: Commit fix**
Run: `git add [modified-files] && git commit -m "fix: resolve visual regression - [component]"`
Expected: Commit successful
**Step 5: Repeat for all visual issues**
Run: `cd e2e && npm run test:visual`
Expected: All visual tests pass
---
### Task 12: Run Responsive Tests
**Files:**
- Test: `e2e/src/tests/responsive/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run responsive tests**
Run: `cd e2e && npm run test:responsive`
Expected: All responsive tests pass or specific failures identified
**Step 2: Analyze responsive test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document responsive issues**
Create: `test-results/responsive-issues.md`
```markdown
# Responsive Test Issues
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Breakpoint Issues
- Mobile (< 768px): [count] issues
- Tablet (768px - 1024px): [count] issues
- Desktop (> 1024px): [count] issues
## Common Issues
- Issue 1: Description
- Issue 2: Description
```
---
### Task 13: Fix Responsive Issues
**Files:**
- Modify: Based on responsive issues
- Test: `e2e/src/tests/responsive/*.spec.ts`
**Step 1: Fix first responsive issue**
Modify: [Specific file based on issue]
```typescript
// Responsive fix implementation
```
**Step 2: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-responsive-test"`
Expected: Test passes
**Step 3: Commit fix**
Run: `git add [modified-files] && git commit -m "fix: resolve responsive issue - [breakpoint/component]"`
Expected: Commit successful
**Step 4: Repeat for all responsive issues**
Run: `cd e2e && npm run test:responsive`
Expected: All responsive tests pass
---
### Task 14: Run Security Tests
**Files:**
- Test: `e2e/src/tests/security/*.spec.ts`
- Modify: Based on test failures
**Step 1: Run security tests**
Run: `cd e2e && npm run test:security`
Expected: All security tests pass or specific failures identified
**Step 2: Analyze security test results**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing test results
**Step 3: Document security issues**
Create: `test-results/security-issues.md`
```markdown
# Security Test Issues
## Failed Tests
- [ ] Test Name: Description of failure
- [ ] Test Name: Description of failure
## Security Vulnerabilities
- XSS: [count] issues
- CSRF: [count] issues
- Content Security Policy: [count] issues
## Common Issues
- Issue 1: Description
- Issue 2: Description
```
---
### Task 15: Fix Security Issues
**Files:**
- Modify: Based on security issues
- Test: `e2e/src/tests/security/*.spec.ts`
**Step 1: Fix first security issue**
Modify: [Specific file based on issue]
```typescript
// Security fix implementation
```
**Step 2: Verify fix with targeted test**
Run: `cd e2e && npx playwright test --grep "specific-security-test"`
Expected: Test passes
**Step 3: Commit fix**
Run: `git add [modified-files] && git commit -m "security: fix [security-issue] - [cwe/owasp]"`
Expected: Commit successful
**Step 4: Repeat for all security issues**
Run: `cd e2e && npm run test:security`
Expected: All security tests pass
---
### Task 16: Run Complete Test Suite
**Files:**
- Test: `e2e/src/tests/**/*.spec.ts`
**Step 1: Run all tests**
Run: `cd e2e && npm run test`
Expected: All tests pass or specific failures identified
**Step 2: Generate comprehensive test report**
Run: `cd e2e && npm run test:report`
Expected: HTML report opens showing all test results
**Step 3: Generate Allure report**
Run: `cd e2e && npm run test:allure && npm run test:allure:open`
Expected: Allure report opens with detailed metrics
---
### Task 17: Final Code Quality Check
**Files:**
- Check: All modified files
**Step 1: Run ESLint**
Run: `npm run lint`
Expected: No linting errors
**Step 2: Fix any linting issues**
Modify: Files with linting errors
```typescript
// Linting fix implementation
```
**Step 3: Verify linting passes**
Run: `npm run lint`
Expected: No linting errors
**Step 4: Commit linting fixes**
Run: `git add [modified-files] && git commit -m "style: fix linting issues"`
Expected: Commit successful
---
### Task 18: Generate Final Test Report
**Files:**
- Create: `test-results/final-test-report.md`
**Step 1: Create comprehensive test report**
Create: `test-results/final-test-report.md`
```markdown
# Final Test Report
## Test Execution Summary
- Total Tests: [count]
- Passed: [count]
- Failed: [count]
- Skipped: [count]
- Flaky: [count]
## Test Categories
- Smoke: [passed]/[total]
- Regression: [passed]/[total]
- Performance: [passed]/[total]
- Accessibility: [passed]/[total]
- Visual: [passed]/[total]
- Responsive: [passed]/[total]
- Security: [passed]/[total]
## Fixes Applied
- Smoke Test Fixes: [count]
- Regression Fixes: [count]
- Performance Optimizations: [count]
- Accessibility Fixes: [count]
- Visual Fixes: [count]
- Responsive Fixes: [count]
- Security Fixes: [count]
## Remaining Issues
- [ ] Issue 1: Description
- [ ] Issue 2: Description
## Recommendations
- Recommendation 1: Description
- Recommendation 2: Description
```
**Step 2: Commit final report**
Run: `git add test-results/final-test-report.md && git commit -m "docs: add final test report"`
Expected: Commit successful
---
### Task 19: Verify Production Build
**Files:**
- Check: `package.json`
**Step 1: Run production build**
Run: `npm run build`
Expected: Build completes successfully
**Step 2: Fix any build errors**
Modify: Files with build errors
```typescript
// Build error fix implementation
```
**Step 3: Verify build passes**
Run: `npm run build`
Expected: Build completes successfully
**Step 4: Commit build fixes**
Run: `git add [modified-files] && git commit -m "fix: resolve build errors"`
Expected: Commit successful
---
### Task 20: Final Verification and Documentation
**Files:**
- Create: `test-results/optimization-summary.md`
**Step 1: Create optimization summary**
Create: `test-results/optimization-summary.md`
```markdown
# Test Suite Execution and Code Optimization Summary
## Overview
Executed complete E2E test suite and fixed all identified issues.
## Test Results
- Smoke Tests: ✅ All passed
- Regression Tests: ✅ All passed
- Performance Tests: ✅ All passed
- Accessibility Tests: ✅ All passed
- Visual Tests: ✅ All passed
- Responsive Tests: ✅ All passed
- Security Tests: ✅ All passed
## Code Improvements
- Performance Optimizations: [count]
- Accessibility Improvements: [count]
- Bug Fixes: [count]
- Security Enhancements: [count]
## Metrics
- Test Coverage: [percentage]%
- Performance Improvement: [percentage]%
- Accessibility Score: [score]/100
## Next Steps
- [ ] Monitor test results in CI/CD
- [ ] Schedule regular test runs
- [ ] Update test cases as needed
```
**Step 2: Commit optimization summary**
Run: `git add test-results/optimization-summary.md && git commit -m "docs: add optimization summary"`
Expected: Commit successful
---
## Success Criteria
- ✅ All E2E tests pass (100% pass rate)
- ✅ No linting errors
- ✅ Production build succeeds
- ✅ Performance metrics meet targets
- ✅ Accessibility compliance achieved
- ✅ Security vulnerabilities resolved
- ✅ Visual regressions fixed
- ✅ Responsive design verified
## Notes
- Each test category should be run sequentially
- Fix issues immediately after identification
- Commit frequently with descriptive messages
- Use debug mode for complex failures
- Update test cases if requirements change
- Monitor flaky tests and stabilize them
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,465 +0,0 @@
# 测试框架重构设计文档
## 概述
本文档描述了将现有的E2E测试框架和开发环境测试脚本整合为一个统一、可复用的测试框架的设计方案。
## 目标
1. **统一技术栈** - 所有测试使用Playwright + TypeScript
2. **代码复用** - 创建共享的页面对象、配置和工具类
3. **类型安全** - 利用TypeScript提供完整的类型检查
4. **渐进式迁移** - 保持现有测试稳定的同时逐步整合
5. **可维护性** - 提高测试代码的可维护性和可扩展性
## 当前状态分析
### 现有测试系统
#### 1. E2E测试框架 (e2e/)
- **技术栈**: Playwright + TypeScript
- **结构**:
- 页面对象模式 (BasePage, HomePage等)
- 测试分类 (smoke, regression, performance等)
- Fixtures和配置管理
- 完整的测试报告系统
- **优势**:
- 成熟的页面对象模式
- 丰富的测试覆盖
- 良好的类型安全
- **劣势**:
- 部分工具类功能重复
- 配置分散
#### 2. 开发环境测试脚本 (scripts/)
- **技术栈**: Node.js + JavaScript
- **结构**:
- 独立的脚本文件
- 工具类 (lighthouse-runner, axe-runner等)
- Shell脚本执行器
- **优势**:
- 快速执行
- 专注于性能、SEO、可访问性
- **劣势**:
- 缺乏类型安全
- 代码复用性低
- 与E2E测试隔离
## 重构架构设计
### 整体架构
```
test-framework/
├── shared/ # 共享层
│ ├── config/ # 配置管理
│ │ ├── base.config.ts # 基础配置
│ │ ├── environments.ts # 环境配置
│ │ ├── test-pages.ts # 测试页面配置
│ │ └── test-data.ts # 测试数据配置
│ ├── pages/ # 页面对象(统一)
│ │ ├── BasePage.ts # 基础页面对象
│ │ ├── HomePage.ts # 首页
│ │ ├── AboutPage.ts # 关于页面
│ │ ├── ContactPage.ts # 联系页面
│ │ ├── ProductsPage.ts # 产品页面
│ │ ├── ServicesPage.ts # 服务页面
│ │ ├── CasesPage.ts # 案例页面
│ │ └── NewsPage.ts # 新闻页面
│ ├── utils/ # 工具类
│ │ ├── performance/ # 性能测试工具
│ │ │ ├── PerformanceMonitor.ts
│ │ │ ├── LighthouseRunner.ts
│ │ │ └── CoreWebVitals.ts
│ │ ├── seo/ # SEO测试工具
│ │ │ ├── SEOValidator.ts
│ │ │ ├── MetaTagChecker.ts
│ │ │ └── LinkValidator.ts
│ │ ├── accessibility/ # 可访问性测试工具
│ │ │ ├── AccessibilityTester.ts
│ │ │ ├── AxeRunner.ts
│ │ │ └── WCAGCompliance.ts
│ │ ├── forms/ # 表单测试工具
│ │ │ ├── FormTester.ts
│ │ │ ├── FieldValidator.ts
│ │ │ └── FormSubmitter.ts
│ │ ├── mobile/ # 移动端测试工具
│ │ │ ├── GestureSimulator.ts
│ │ │ ├── MobilePerformanceMonitor.ts
│ │ │ └── NetworkSimulator.ts
│ │ ├── reporting/ # 报告生成工具
│ │ │ ├── TestReporter.ts
│ │ │ ├── HTMLReportGenerator.ts
│ │ │ └── JSONReportGenerator.ts
│ │ └── common/ # 通用工具
│ │ ├── TestDataGenerator.ts
│ │ ├── WaitHelper.ts
│ │ └── ScreenshotHelper.ts
│ ├── fixtures/ # 共享Fixtures
│ │ ├── base.fixture.ts # 基础fixture
│ │ ├── performance.fixture.ts # 性能测试fixture
│ │ ├── accessibility.fixture.ts # 可访问性测试fixture
│ │ └── mobile.fixture.ts # 移动端测试fixture
│ └── types/ # 类型定义
│ ├── page.types.ts # 页面对象类型
│ ├── test.types.ts # 测试类型
│ ├── performance.types.ts # 性能测试类型
│ └── accessibility.types.ts # 可访问性测试类型
├── e2e/ # E2E测试(保持不变)
│ ├── tests/
│ │ ├── smoke/ # 冒烟测试
│ │ ├── regression/ # 回归测试
│ │ ├── performance/ # 性能测试
│ │ ├── accessibility/ # 可访问性测试
│ │ ├── mobile/ # 移动端测试
│ │ ├── security/ # 安全测试
│ │ ├── visual/ # 视觉回归测试
│ │ └── responsive/ # 响应式测试
│ ├── fixtures/
│ └── playwright.config.ts
├── dev-audit/ # 开发环境测试(重构)
│ ├── performance/
│ │ ├── performance.spec.ts # 性能审计测试
│ │ ├── lighthouse.spec.ts # Lighthouse测试
│ │ └── core-web-vitals.spec.ts # Core Web Vitals测试
│ ├── seo/
│ │ ├── seo.spec.ts # SEO检查测试
│ │ ├── meta-tags.spec.ts # Meta标签测试
│ │ └── links.spec.ts # 链接检查测试
│ ├── accessibility/
│ │ ├── accessibility.spec.ts # 可访问性测试
│ │ └── wcag-compliance.spec.ts # WCAG合规测试
│ └── forms/
│ ├── forms.spec.ts # 表单验证测试
│ └── validation.spec.ts # 字段验证测试
└── reports/ # 测试报告
├── html/ # HTML报告
├── json/ # JSON报告
└── screenshots/ # 截图
```
### 核心设计原则
#### 1. 页面对象统一
所有测试使用相同的页面对象,确保测试的一致性和可维护性。
```typescript
// shared/pages/BasePage.ts
export class BasePage {
readonly page: Page;
readonly config: TestConfig;
constructor(page: Page, config?: TestConfig) {
this.page = page;
this.config = config || defaultConfig;
}
// 通用方法
async navigate(url: string): Promise<void> { }
async click(locator: Locator | string): Promise<void> { }
async fill(locator: Locator | string, value: string): Promise<void> { }
// 性能监控方法
async measurePerformance(): Promise<PerformanceMetrics> { }
async getCoreWebVitals(): Promise<CoreWebVitals> { }
// 可访问性方法
async runAccessibilityCheck(): Promise<AccessibilityResult> { }
// SEO方法
async validateSEO(): Promise<SEOResult> { }
}
```
#### 2. 配置集中管理
所有配置集中管理,便于维护和切换环境。
```typescript
// shared/config/environments.ts
export const environments = {
development: {
baseURL: 'http://localhost:3000',
timeout: 5000,
retries: 3
},
staging: {
baseURL: 'https://staging.example.com',
timeout: 10000,
retries: 2
},
production: {
baseURL: 'https://www.example.com',
timeout: 10000,
retries: 1
}
};
// shared/config/test-pages.ts
export const testPages = {
home: { name: '首页', url: '/', selectors: { title: 'h1' } },
about: { name: '关于我们', url: '/about', selectors: { title: 'h1' } },
contact: { name: '联系我们', url: '/contact', selectors: { title: 'h1' } },
products: { name: '产品', url: '/products', selectors: { title: 'h1' } },
services: { name: '服务', url: '/services', selectors: { title: 'h1' } },
cases: { name: '案例', url: '/cases', selectors: { title: 'h1' } },
news: { name: '新闻', url: '/news', selectors: { title: 'h1' } }
};
```
#### 3. 工具类复用
创建可复用的工具类,避免代码重复。
```typescript
// shared/utils/performance/PerformanceMonitor.ts
export class PerformanceMonitor {
async measurePageLoad(page: Page): Promise<PageLoadMetrics> { }
async measureCoreWebVitals(page: Page): Promise<CoreWebVitals> { }
async measureResourceTiming(page: Page): Promise<ResourceTiming[]> { }
}
// shared/utils/accessibility/AccessibilityTester.ts
export class AccessibilityTester {
async runAxeScan(page: Page): Promise<AxeResults> { }
async checkWCAGCompliance(page: Page): Promise<WCAGResult> { }
async generateAccessibilityReport(results: AxeResults): Promise<string> { }
}
// shared/utils/seo/SEOValidator.ts
export class SEOValidator {
async validateMetaTags(page: Page): Promise<MetaTagResult> { }
async validateLinks(page: Page): Promise<LinkResult> { }
async validateHeadings(page: Page): Promise<HeadingResult> { }
}
```
#### 4. 类型安全
使用TypeScript提供完整的类型定义。
```typescript
// shared/types/performance.types.ts
export interface PerformanceMetrics {
loadTime: number;
domContentLoaded: number;
firstPaint: number;
firstContentfulPaint: number;
}
export interface CoreWebVitals {
largestContentfulPaint: number;
firstInputDelay: number;
cumulativeLayoutShift: number;
}
// shared/types/accessibility.types.ts
export interface AccessibilityResult {
score: number;
violations: Violation[];
passes: number;
incomplete: number;
}
export interface Violation {
id: string;
impact: string;
description: string;
help: string;
helpUrl: string;
nodes: number;
}
// shared/types/test.types.ts
export interface TestConfig {
baseURL: string;
timeout: number;
retries: number;
environment: string;
}
export interface TestResult {
name: string;
status: 'passed' | 'failed' | 'skipped';
duration: number;
errors?: Error[];
}
```
## 实施计划
### 阶段1:创建共享层(不破坏现有测试)
**目标**: 创建共享的基础层,为后续迁移做准备
**任务**:
1. 创建 `test-framework/shared/` 目录结构
2. 提取E2E测试中的页面对象到shared层
3. 创建统一的配置管理系统
4. 创建工具类框架
5. 创建类型定义
**时间估计**: 2-3天
**验收标准**:
- [ ] 共享层目录结构创建完成
- [ ] 页面对象迁移完成
- [ ] 配置管理系统创建完成
- [ ] 工具类框架创建完成
- [ ] 类型定义创建完成
- [ ] 现有E2E测试仍然正常运行
### 阶段2:迁移开发环境测试
**目标**: 将开发环境测试迁移到TypeScript和Playwright
**任务**:
1. 创建 `test-framework/dev-audit/` 目录结构
2. 将性能审计脚本迁移到TypeScript
3. 将SEO检查脚本迁移到TypeScript
4. 将可访问性测试迁移到TypeScript
5. 将表单验证迁移到TypeScript
6. 使用共享的页面对象和工具类
7. 保留scripts/作为向后兼容
**时间估计**: 3-4天
**验收标准**:
- [ ] 所有开发环境测试迁移完成
- [ ] 使用TypeScript重写
- [ ] 使用Playwright API
- [ ] 使用共享的页面对象
- [ ] 使用共享的工具类
- [ ] 测试结果与原有脚本一致
- [ ] 旧scripts/仍然可用
### 阶段3:优化和清理
**目标**: 优化测试框架,移除冗余代码
**任务**:
1. 移除旧的scripts/目录
2. 统一测试报告格式
3. 添加共享的测试数据生成器
4. 优化测试执行性能
5. 添加测试覆盖率统计
6. 更新文档
**时间估计**: 2-3天
**验收标准**:
- [ ] 旧scripts/目录移除
- [ ] 测试报告格式统一
- [ ] 测试数据生成器创建完成
- [ ] 测试执行性能优化
- [ ] 测试覆盖率统计添加
- [ ] 文档更新完成
### 阶段4:集成和验证
**目标**: 验证整个测试框架的集成和功能
**任务**:
1. 运行完整的测试套件
2. 验证所有测试结果
3. 性能基准测试
4. 创建CI/CD集成
5. 编写使用文档
**时间估计**: 2-3天
**验收标准**:
- [ ] 完整测试套件运行成功
- [ ] 所有测试结果验证通过
- [ ] 性能基准测试完成
- [ ] CI/CD集成完成
- [ ] 使用文档编写完成
## 测试执行流程
### E2E测试执行
```bash
# 运行所有E2E测试
npm run test:e2e
# 运行特定类型的E2E测试
npm run test:e2e:smoke
npm run test:e2e:regression
npm run test:e2e:performance
```
### 开发环境测试执行
```bash
# 运行所有开发环境测试
npm run test:dev-audit
# 运行特定类型的开发环境测试
npm run test:dev-audit:performance
npm run test:dev-audit:seo
npm run test:dev-audit:accessibility
npm run test:dev-audit:forms
```
### 综合测试执行
```bash
# 运行所有测试
npm run test:all
# 生成综合报告
npm run test:report
```
## 测试报告
### 报告格式
1. **HTML报告** - 可视化的测试报告,包含图表和详细信息
2. **JSON报告** - 机器可读的测试结果,便于CI/CD集成
3. **截图** - 测试失败时的截图,便于调试
### 报告内容
- 测试摘要(总数、通过数、失败数、跳过数)
- 测试详情(每个测试的执行时间、状态、错误信息)
- 性能指标(页面加载时间、Core Web Vitals等)
- 可访问性评分(WCAG合规性、违规项等)
- SEO评分(Meta标签、链接、标题等)
- 表单验证结果(必填字段、格式验证等)
## 风险和缓解措施
### 风险1:迁移过程中破坏现有测试
**缓解措施**:
- 采用渐进式迁移策略
- 每个阶段都进行完整的测试验证
- 保留原有测试作为备份
### 风险2:性能测试结果不一致
**缓解措施**:
- 建立性能基准
- 使用相同的测试环境
- 多次运行取平均值
### 风险3:学习曲线
**缓解措施**:
- 提供详细的文档
- 提供示例代码
- 进行团队培训
## 成功标准
1. **功能完整性** - 所有现有测试功能在新框架中都能正常工作
2. **性能提升** - 测试执行时间不超过原有框架的120%
3. **代码质量** - TypeScript编译无错误,测试覆盖率不低于80%
4. **可维护性** - 代码结构清晰,易于理解和维护
5. **文档完整性** - 提供完整的文档和示例
## 总结
本设计文档提供了一个渐进式的测试框架重构方案,通过创建共享层、统一技术栈、提高代码复用性,最终实现一个统一、可维护、可扩展的测试框架。该方案采用渐进式迁移策略,确保在重构过程中不破坏现有测试,同时为未来的测试开发提供良好的基础。
File diff suppressed because it is too large Load Diff
-544
View File
@@ -1,544 +0,0 @@
# 测试套件修复计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**目标:** 修复表单测试中的元素定位、CSS选择器和Toast组件处理问题,使所有9个失败的表单测试通过。
**架构:** 通过在系统代码中添加data-testid属性、修正测试代码的CSS选择器、更新Toast组件处理逻辑,实现测试与实际UI的同步。
**技术栈:** Playwright测试框架、React组件、TypeScript、CSS选择器
---
## 问题分析
当前9个表单测试失败的根本原因:
1. **元素定位器不匹配** - 测试使用了不存在的`data-testid`属性
2. **CSS选择器转义错误** - 错误消息选择器使用了双转义
3. **Toast组件处理不当** - 测试没有正确处理动态Toast显示
4. **缺少等待机制** - 没有等待异步UI更新完成
---
### Task 1: 在系统代码中添加data-testid属性
**目标:** 为表单元素添加data-testid属性,使测试能够正确定位元素。
**文件:**
- 修改: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/sections/contact-section.tsx`
**Step 1: 为姓名输入框添加data-testid**
```tsx
<Input
label="姓名"
id="name"
placeholder="请输入您的姓名"
required
data-testid="name-input"
value={formData.name}
onChange={(e) => handleChange('name', e.target.value)}
onBlur={(e) => handleBlur('name', e.target.value)}
error={errors.name}
/>
```
**Step 2: 为电话输入框添加data-testid**
```tsx
<Input
label="电话"
id="phone"
type="tel"
placeholder="请输入您的电话"
required
data-testid="phone-input"
value={formData.phone}
onChange={(e) => handleChange('phone', e.target.value)}
onBlur={(e) => handleBlur('phone', e.target.value)}
error={errors.phone}
/>
```
**Step 3: 为邮箱输入框添加data-testid**
```tsx
<Input
label="邮箱"
id="email"
type="email"
placeholder="请输入您的邮箱"
required
data-testid="email-input"
value={formData.email}
onChange={(e) => handleChange('email', e.target.value)}
onBlur={(e) => handleBlur('email', e.target.value)}
error={errors.email}
/>
```
**Step 4: 为留言输入框添加data-testid**
```tsx
<Textarea
label="留言内容"
id="message"
placeholder="请输入您想咨询的内容"
rows={5}
required
data-testid="message-input"
value={formData.message}
onChange={(e) => handleChange('message', e.target.value)}
onBlur={(e) => handleBlur('message', e.target.value)}
error={errors.message}
/>
```
**Step 5: 为提交按钮添加data-testid**
```tsx
<Button
type="submit"
size="lg"
className="w-full group mt-auto min-h-[52px] md:min-h-0"
disabled={isSubmitting}
data-testid="submit-button"
>
```
**Step 6: 为成功消息添加data-testid**
```tsx
{isSubmitted ? (
<div className="text-center py-12 flex-1 flex items-center justify-center" data-testid="success-message">
<div className="w-16 h-16 bg-[#C41E3A] rounded-full flex items-center justify-center mx-auto mb-4 animate-stamp-in">
<CheckCircle2 className="w-8 h-8 text-white" />
</div>
<h4 className="text-xl font-semibold text-[#1A1A2E] mb-2"></h4>
<p className="text-[#718096]"></p>
</div>
) : (
```
**Step 7: 为Toast组件添加data-testid**
```tsx
{showToast && (
<Toast
message={toastMessage}
type={toastType}
onClose={() => setShowToast(false)}
data-testid="toast-notification"
/>
)}
```
**Step 8: 为错误消息容器添加data-testid**
在Input组件中,为错误消息添加data-testid
```tsx
{error && (
<p id={errorId} className="mt-1 text-sm text-[#C41E3A]" role="alert" data-testid="error-message">
{error}
</p>
)}
```
**Step 9: 验证data-testid属性已正确添加**
运行: `cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website && npm run dev`
预期: 开发服务器正常启动,无编译错误
**Step 10: 提交更改**
```bash
git add src/components/sections/contact-section.tsx src/components/ui/input.tsx src/components/ui/textarea.tsx
git commit -m "feat: add data-testid attributes for form elements to improve testability"
```
---
### Task 2: 修正测试代码中的CSS选择器
**目标:** 修正ContactPage中的CSS选择器,使用正确的转义和data-testid定位。
**文件:**
- 修改: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/test-framework/shared/pages/ContactPage.ts`
**Step 1: 修正getFormErrorMessage方法**
```typescript
async getFormErrorMessage(): Promise<string> {
const errorElement = await this.page.locator('[data-testid="error-message"]').first();
return await errorElement.textContent() || '';
}
```
**Step 2: 修正getFormSuccessMessage方法**
```typescript
async getFormSuccessMessage(): Promise<string> {
await this.page.waitForTimeout(1000);
const successElement = await this.page.locator('[data-testid="success-message"]');
if (await successElement.count() > 0) {
return await successElement.textContent() || '';
}
return '';
}
```
**Step 3: 添加getToastMessage方法**
```typescript
async getToastMessage(): Promise<{ message: string; type: 'success' | 'error' }> {
const toastElement = await this.page.locator('[data-testid="toast-notification"]');
if (await toastElement.count() > 0) {
const message = await toastElement.textContent() || '';
const type = await toastElement.getAttribute('data-type') as 'success' | 'error';
return { message, type };
}
return { message: '', type: 'success' };
}
```
**Step 4: 添加waitForToast方法**
```typescript
async waitForToast(timeout: number = 5000): Promise<boolean> {
try {
await this.page.waitForSelector('[data-testid="toast-notification"]', { timeout });
return true;
} catch {
return false;
}
}
```
**Step 5: 添加waitForToastHidden方法**
```typescript
async waitForToastHidden(timeout: number = 5000): Promise<boolean> {
try {
await this.page.waitForSelector('[data-testid="toast-notification"]', { state: 'hidden', timeout });
return true;
} catch {
return false;
}
}
```
**Step 6: 运行表单测试验证选择器修复**
运行: `cd test-framework && npm run test:dev-audit:forms`
预期: 部分测试通过,元素定位错误减少
**Step 7: 提交更改**
```bash
git add test-framework/shared/pages/ContactPage.ts
git commit -m "fix: correct CSS selectors and add toast handling methods in ContactPage"
```
---
### Task 3: 更新表单测试以正确处理Toast组件
**目标:** 修改测试用例,正确处理Toast组件的异步显示和消失。
**文件:**
- 修改: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/test-framework/dev-audit/forms/forms.spec.ts`
**Step 1: 修改"联系表单 - 有效数据提交"测试**
```typescript
test('联系表单 - 有效数据提交', async ({ page }) => {
const contactPage = new ContactPage(page);
await page.route('**/api/contact', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ success: true, message: '消息已发送' })
});
});
await contactPage.navigate();
await contactPage.fillContactForm({
name: formData.valid.name,
email: formData.valid.email,
phone: formData.valid.phone,
message: formData.valid.message,
subject: '测试主题'
});
await contactPage.submitForm();
await contactPage.waitForToast();
const toastMessage = await contactPage.getToastMessage();
expect(toastMessage.message).toContain('成功');
expect(toastMessage.type).toBe('success');
await contactPage.waitForToastHidden();
});
```
**Step 2: 修改"联系表单 - 必填字段验证"测试**
```typescript
test('联系表单 - 必填字段验证', async ({ page }) => {
const contactPage = new ContactPage(page);
await contactPage.navigate();
await contactPage.fillContactForm({
name: '',
email: '',
phone: '',
message: '',
subject: ''
});
await contactPage.submitForm();
await page.waitForTimeout(500);
const errorMessage = await contactPage.getFormErrorMessage();
expect(errorMessage).toBeTruthy();
});
```
**Step 3: 修改"联系表单 - 邮箱格式验证"测试**
```typescript
test('联系表单 - 邮箱格式验证', async ({ page }) => {
const contactPage = new ContactPage(page);
await contactPage.navigate();
await contactPage.fillContactForm({
name: '测试用户',
email: formData.invalid.email,
phone: '13800138000',
message: '测试消息',
subject: '测试主题'
});
await contactPage.submitForm();
await page.waitForTimeout(500);
const errorMessage = await contactPage.getFormErrorMessage();
expect(errorMessage).toContain('邮箱');
});
```
**Step 4: 修改"联系表单 - API错误处理"测试**
```typescript
test('联系表单 - API错误处理', async ({ page }) => {
const contactPage = new ContactPage(page);
await page.route('**/api/contact', async route => {
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({ success: false, message: '服务器错误' })
});
});
await contactPage.navigate();
await contactPage.fillContactForm({
name: formData.valid.name,
email: formData.valid.email,
phone: formData.valid.phone,
message: formData.valid.message,
subject: '测试主题'
});
await contactPage.submitForm();
await contactPage.waitForToast();
const toastMessage = await contactPage.getToastMessage();
expect(toastMessage.message).toContain('失败');
expect(toastMessage.type).toBe('error');
await contactPage.waitForToastHidden();
});
```
**Step 5: 运行表单测试验证Toast处理**
运行: `cd test-framework && npm run test:dev-audit:forms`
预期: 所有表单测试通过,Toast组件正确处理
**Step 6: 提交更改**
```bash
git add test-framework/dev-audit/forms/forms.spec.ts
git commit -m "fix: update form tests to properly handle toast component and async UI updates"
```
---
### Task 4: 更新Input和Textarea组件以支持data-testid
**目标:** 确保UI组件正确传递data-testid属性。
**文件:**
- 修改: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/ui/input.tsx`
- 修改: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/ui/textarea.tsx`
**Step 1: 更新Input组件接口**
```typescript
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string
error?: string
'data-testid'?: string
}
```
**Step 2: 在Input组件中使用data-testid**
```typescript
<input
type={type}
id={inputId}
data-slot="input"
data-testid={props['data-testid']}
className={cn(
// ... existing className
)}
ref={ref}
aria-required={props.required ? "true" : undefined}
aria-invalid={error ? "true" : "false"}
aria-describedby={error ? errorId : undefined}
{...props}
/>
```
**Step 3: 更新Textarea组件接口**
```typescript
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
label?: string
error?: string
'data-testid'?: string
}
```
**Step 4: 在Textarea组件中使用data-testid**
```typescript
<textarea
id={textareaId}
data-slot="textarea"
data-testid={props['data-testid']}
className={cn(
// ... existing className
)}
ref={ref}
aria-required={props.required ? "true" : undefined}
aria-invalid={error ? "true" : "false"}
aria-describedby={error ? errorId : undefined}
{...props}
/>
```
**Step 5: 验证组件正确传递data-testid**
运行: `cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website && npm run dev`
预期: 开发服务器正常启动,组件正确编译
**Step 6: 提交更改**
```bash
git add src/components/ui/input.tsx src/components/ui/textarea.tsx
git commit -m "feat: add data-testid support to Input and Textarea components"
```
---
### Task 5: 运行完整测试套件验证修复
**目标:** 运行所有测试验证修复效果。
**文件:**
- 无需修改
**Step 1: 运行表单测试**
运行: `cd test-framework && npm run test:dev-audit:forms`
预期: 所有表单测试通过(20/20)
**Step 2: 运行性能测试**
运行: `cd test-framework && npm run test:dev-audit:performance`
预期: 所有性能测试通过(35/35)
**Step 3: 运行完整测试套件**
运行: `cd test-framework && npm run test:dev-audit`
预期: 所有测试通过(85/85),通过率100%
**Step 4: 生成测试报告**
运行: `cd test-framework && npx ts-node scripts/generate-report.ts`
预期: 生成完整的测试报告,显示所有测试通过
**Step 5: 查看测试结果**
运行: `cat test-framework/reports/results.json | jq '.stats'`
预期输出:
```json
{
"startTime": "2026-03-06T...",
"duration": ...,
"expected": 85,
"skipped": 0,
"unexpected": 0,
"flaky": 0
}
```
**Step 6: 提交最终验证**
```bash
git add test-framework/reports/
git commit -m "test: verify all tests passing after test suite fixes"
```
---
## 验收标准
- [ ] 所有表单测试通过(20/20
- [ ] 所有性能测试通过(35/35
- [ ] 所有SEO测试通过
- [ ] 所有可访问性测试通过
- [ ] 完整测试套件通过率100%(85/85)
- [ ] 测试报告显示所有测试通过
- [ ] 无测试超时错误
- [ ] 无元素定位错误
---
## 风险与注意事项
1. **Toast组件时序问题** - 需要确保测试等待足够时间让Toast显示和消失
2. **移动端兼容性** - 某些测试在移动设备上可能需要额外的等待时间
3. **并发测试冲突** - 多个测试同时运行可能导致状态污染,确保每个测试独立运行
4. **API模拟准确性** - 确保API模拟响应与真实API响应格式一致
---
## 后续优化建议
1. **添加视觉回归测试** - 使用Percy或Applitools进行UI视觉测试
2. **增加测试覆盖率** - 添加更多边界条件和异常场景测试
3. **性能基准测试** - 建立性能基准,监控性能回归
4. **测试数据管理** - 使用测试数据工厂生成更多样化的测试数据
5. **CI/CD集成** - 将测试集成到持续集成流程中
@@ -1,554 +0,0 @@
# Critical Issues Fix Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Fix all critical and high-priority issues identified in the deployment readiness assessment to achieve 95%+ test pass rate and enable safe deployment.
**Architecture:** Fix mobile navigation issues, update page selectors, correct page titles, and improve scrolling functionality using Playwright E2E tests with TDD approach.
**Tech Stack:** Playwright, TypeScript, Next.js 16, React 19, Tailwind CSS 4
---
## Task 1: Fix Mobile Navigation Menu Functionality
**Priority:** P0 (Critical)
**Estimated Time:** 2-3 hours
**Files:**
- Modify: `e2e/src/pages/BasePage.ts`
- Modify: `e2e/src/pages/HomePage.ts`
- Modify: `src/components/layout/mobile-menu.tsx`
- Test: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
**Step 1: Analyze the mobile menu component structure**
Run: `cat src/components/layout/mobile-menu.tsx`
Expected: Identify the mobile menu button and menu container structure
**Step 2: Update BasePage mobile menu selectors**
```typescript
// e2e/src/pages/BasePage.ts
export class BasePage {
readonly page: Page;
readonly mobileMenuButton: Locator;
readonly mobileMenu: Locator;
readonly mobileMenuCloseButton: Locator;
constructor(page: Page) {
this.page = page;
this.mobileMenuButton = page.getByRole('button', { name: /打开菜单|menu/i });
this.mobileMenu = page.locator('[role="dialog"], [role="navigation"], .mobile-menu');
this.mobileMenuCloseButton = page.getByRole('button', { name: /关闭|close/i });
}
async openMobileMenu() {
await this.mobileMenuButton.click();
await this.mobileMenu.waitFor({ state: 'visible', timeout: 5000 });
}
async closeMobileMenu() {
if (await this.mobileMenu.isVisible()) {
await this.mobileMenuCloseButton.click();
await this.mobileMenu.waitFor({ state: 'hidden', timeout: 5000 });
}
}
async isMobileMenuOpen() {
return await this.mobileMenu.isVisible();
}
}
```
**Step 3: Update HomePage to extend BasePage properly**
```typescript
// e2e/src/pages/HomePage.ts
import { BasePage } from './BasePage';
export class HomePage extends BasePage {
readonly navigation: Locator;
readonly logo: Locator;
constructor(page: Page) {
super(page);
this.navigation = page.locator('nav, [role="navigation"]');
this.logo = page.getByRole('link', { name: /四川睿新致远|novalon/i });
}
}
```
**Step 4: Run navigation smoke tests to verify fixes**
Run: `cd e2e && npm run test:smoke -- --grep "导航冒烟测试"`
Expected: See current failures for mobile menu tests
**Step 5: Fix mobile menu component if needed**
Check: `src/components/layout/mobile-menu.tsx`
Ensure the mobile menu has proper ARIA attributes:
```tsx
<button
aria-label="打开菜单"
aria-expanded={isOpen}
onClick={toggleMenu}
>
{/* Menu icon */}
</button>
{isOpen && (
<nav
role="navigation"
aria-label="主导航"
className="mobile-menu"
>
{/* Menu items */}
<button
aria-label="关闭菜单"
onClick={toggleMenu}
>
{/* Close icon */}
</button>
</nav>
)}
```
**Step 6: Run navigation smoke tests again**
Run: `cd e2e && npm run test:smoke -- --grep "导航冒烟测试"`
Expected: Mobile menu tests should pass
**Step 7: Commit mobile menu fixes**
```bash
git add e2e/src/pages/BasePage.ts e2e/src/pages/HomePage.ts src/components/layout/mobile-menu.tsx
git commit -m "fix: resolve mobile navigation menu selector issues"
```
---
## Task 2: Fix Main Navigation Menu Display
**Priority:** P0 (Critical)
**Estimated Time:** 1-2 hours
**Files:**
- Modify: `e2e/src/pages/HomePage.ts`
- Modify: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
- Modify: `src/components/layout/header.tsx`
**Step 1: Update HomePage navigation selector to use Locator**
```typescript
// e2e/src/pages/HomePage.ts
export class HomePage extends BasePage {
readonly navigation: Locator;
constructor(page: Page) {
super(page);
this.navigation = page.locator('nav, [role="navigation"], .main-nav');
}
}
```
**Step 2: Update navigation smoke test to use proper Locator**
```typescript
// e2e/src/tests/smoke/navigation.smoke.spec.ts
test('应该显示主导航菜单', async ({ homePage }) => {
const nav = homePage.page.locator('nav, [role="navigation"]');
await expect(nav.first()).toBeVisible();
});
```
**Step 3: Ensure header component has proper semantic HTML**
Check: `src/components/layout/header.tsx`
```tsx
<nav role="navigation" aria-label="主导航" className="main-nav">
<ul>
<li><a href="/services"></a></li>
<li><a href="/products"></a></li>
<li><a href="/cases"></a></li>
<li><a href="/news"></a></li>
<li><a href="/about"></a></li>
</ul>
</nav>
```
**Step 4: Run navigation tests**
Run: `cd e2e && npm run test:smoke -- --grep "应该显示主导航菜单"`
Expected: Test should pass
**Step 5: Commit navigation display fixes**
```bash
git add e2e/src/pages/HomePage.ts e2e/src/tests/smoke/navigation.smoke.spec.ts src/components/layout/header.tsx
git commit -m "fix: resolve main navigation menu display issues"
```
---
## Task 3: Fix Page Section Display Issues
**Priority:** P0 (Critical)
**Estimated Time:** 2-3 hours
**Files:**
- Modify: `e2e/src/pages/HomePage.ts`
- Modify: `e2e/src/tests/smoke/home-page.smoke.spec.ts`
- Modify: `src/components/sections/*.tsx`
**Step 1: Add section locators to HomePage**
```typescript
// e2e/src/pages/HomePage.ts
export class HomePage extends BasePage {
readonly heroSection: Locator;
readonly servicesSection: Locator;
readonly productsSection: Locator;
readonly casesSection: Locator;
readonly footer: Locator;
constructor(page: Page) {
super(page);
this.heroSection = page.locator('section:has(h1), [role="region"]:has(h1)');
this.servicesSection = page.getByRole('region', { name: /核心业务|服务/i });
this.productsSection = page.getByRole('region', { name: /产品/i });
this.casesSection = page.getByRole('region', { name: /案例/i });
this.footer = page.locator('footer');
}
async scrollToSection(section: Locator) {
await section.scrollIntoViewIfNeeded();
await this.page.waitForTimeout(500);
}
}
```
**Step 2: Update home page smoke tests to use section locators**
```typescript
// e2e/src/tests/smoke/home-page.smoke.spec.ts
test('应该显示所有主要区块', async ({ homePage }) => {
await expect(homePage.heroSection).toBeVisible();
await expect(homePage.servicesSection).toBeVisible();
await expect(homePage.productsSection).toBeVisible();
await expect(homePage.casesSection).toBeVisible();
});
test('应该显示页脚', async ({ homePage }) => {
await expect(homePage.footer).toBeVisible();
});
```
**Step 3: Ensure sections have proper ARIA roles**
Check each section component and add role if missing:
```tsx
<section role="region" aria-labelledby="services-heading">
<h2 id="services-heading"> </h2>
{/* Section content */}
</section>
```
**Step 4: Run home page smoke tests**
Run: `cd e2e && npm run test:smoke -- --grep "首页冒烟测试"`
Expected: Section display tests should pass
**Step 5: Commit section display fixes**
```bash
git add e2e/src/pages/HomePage.ts e2e/src/tests/smoke/home-page.smoke.spec.ts src/components/sections/
git commit -m "fix: resolve page section display issues"
```
---
## Task 4: Fix Work Hours Information Retrieval
**Priority:** P1 (High)
**Estimated Time:** 30 minutes
**Files:**
- Modify: `e2e/src/pages/ContactPage.ts`
- Modify: `src/app/(marketing)/contact/page.tsx`
**Step 1: Update ContactPage work hours selector**
```typescript
// e2e/src/pages/ContactPage.ts
export class ContactPage extends BasePage {
async getWorkHours() {
const workHoursItems = this.page.locator('[aria-label="工作时间"] + div, .work-hours > div');
const count = await workHoursItems.count();
const items = [];
for (let i = 0; i < count; i++) {
const item = workHoursItems.nth(i);
const day = await item.locator('div').first().textContent();
const hours = await item.locator('div').nth(1).textContent();
if (day && hours) {
items.push({ day: day.trim(), hours: hours.trim() });
}
}
return items;
}
}
```
**Step 2: Ensure contact page has proper work hours structure**
Check: `src/app/(marketing)/contact/page.tsx`
```tsx
<div aria-label="工作时间" className="work-hours">
<div>
<div></div>
<div>9:00 - 18:00</div>
</div>
</div>
```
**Step 3: Run contact page smoke tests**
Run: `cd e2e && npm run test:smoke -- --grep "联系页面冒烟测试.*工作时间"`
Expected: Work hours tests should pass
**Step 4: Commit work hours fixes**
```bash
git add e2e/src/pages/ContactPage.ts src/app/(marketing)/contact/page.tsx
git commit -m "fix: resolve work hours information retrieval"
```
---
## Task 5: Fix Page Scrolling Functionality
**Priority:** P1 (High)
**Estimated Time:** 1-2 hours
**Files:**
- Modify: `e2e/src/pages/BasePage.ts`
- Modify: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
- Modify: `e2e/src/tests/smoke/home-page.smoke.spec.ts`
**Step 1: Add robust scrolling methods to BasePage**
```typescript
// e2e/src/pages/BasePage.ts
async scrollToTop() {
await this.page.evaluate(() => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
await this.page.waitForTimeout(1000);
}
async scrollToBottom() {
await this.page.evaluate(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
await this.page.waitForTimeout(1000);
}
async scrollToElement(selector: string) {
const element = this.page.locator(selector);
await element.scrollIntoViewIfNeeded({ timeout: 5000 });
await this.page.waitForTimeout(500);
}
```
**Step 2: Update scrolling tests with better error handling**
```typescript
// e2e/src/tests/smoke/navigation.smoke.spec.ts
test('应该能够滚动到页面顶部', async ({ homePage }) => {
await homePage.scrollToBottom();
await homePage.scrollToTop();
const scrollPosition = await homePage.page.evaluate(() => window.scrollY);
expect(scrollPosition).toBeLessThan(100);
});
test('应该能够滚动到页面底部', async ({ homePage }) => {
await homePage.scrollToBottom();
const scrollPosition = await homePage.page.evaluate(() => {
return window.scrollY + window.innerHeight;
});
const pageHeight = await homePage.page.evaluate(() => document.body.scrollHeight);
expect(scrollPosition).toBeGreaterThanOrEqual(pageHeight - 100);
});
```
**Step 3: Run scrolling tests**
Run: `cd e2e && npm run test:smoke -- --grep "滚动"`
Expected: Scrolling tests should pass
**Step 4: Commit scrolling fixes**
```bash
git add e2e/src/pages/BasePage.ts e2e/src/tests/smoke/navigation.smoke.spec.ts e2e/src/tests/smoke/home-page.smoke.spec.ts
git commit -m "fix: resolve page scrolling functionality issues"
```
---
## Task 6: Fix Contact Page Title
**Priority:** P2 (Medium)
**Estimated Time:** 10 minutes
**Files:**
- Modify: `src/app/(marketing)/contact/page.tsx`
- Modify: `e2e/src/tests/smoke/contact-page.smoke.spec.ts`
**Step 1: Update contact page title**
```typescript
// src/app/(marketing)/contact/page.tsx
export const metadata = {
title: '联系我们 - 四川睿新致远科技有限公司',
description: '无论您有任何问题或合作意向,我们都很乐意与您交流',
};
```
**Step 2: Update page heading to match title**
```tsx
// src/app/(marketing)/contact/page.tsx
<h1></h1>
```
**Step 3: Update test to match actual title**
```typescript
// e2e/src/tests/smoke/contact-page.smoke.spec.ts
test('应该显示正确的页面标题', async ({ contactPage }) => {
const title = await contactPage.page.title();
expect(title).toBeTruthy();
expect(title.length).toBeGreaterThan(0);
expect(title).toContain('联系');
});
```
**Step 4: Run contact page title test**
Run: `cd e2e && npm run test:smoke -- --grep "应该显示正确的页面标题"`
Expected: Title test should pass
**Step 5: Commit title fixes**
```bash
git add src/app/(marketing)/contact/page.tsx e2e/src/tests/smoke/contact-page.smoke.spec.ts
git commit -m "fix: correct contact page title"
```
---
## Task 7: Run Full Test Suite and Verify
**Priority:** P0 (Critical)
**Estimated Time:** 45 minutes
**Files:**
- Test: All smoke tests
**Step 1: Run all smoke tests**
Run: `cd e2e && npm run test:smoke`
Expected: All smoke tests should pass with >95% pass rate
**Step 2: Generate test report**
Run: `cd e2e && npm run test:report`
Expected: HTML report generated
**Step 3: Check test results**
Run: `cd e2e && node analyze-results.js`
Expected: Pass rate should be >95%
**Step 4: If any tests fail, analyze and fix**
Run: `cd e2e && npx playwright show-report`
Expected: Identify any remaining failures and create additional fix tasks
**Step 5: Commit test results**
```bash
git add e2e/test-results/ e2e/analyze-results.js
git commit -m "test: verify all critical fixes with full test suite"
```
---
## Task 8: Create Deployment Readiness Report
**Priority:** P0 (Critical)
**Estimated Time:** 30 minutes
**Files:**
- Create: `docs/reports/2026-03-07-fixes-completion-report.md`
**Step 1: Generate completion report**
Create report with:
- Summary of all fixes implemented
- Before and after test results
- Remaining issues (if any)
- Deployment readiness status
- Recommendations
**Step 2: Commit report**
```bash
git add docs/reports/2026-03-07-fixes-completion-report.md
git commit -m "docs: add fixes completion report"
```
---
## Verification Checklist
After completing all tasks, verify:
- [ ] All P0 issues fixed (mobile navigation, main navigation, page sections)
- [ ] All P1 issues fixed (work hours, scrolling)
- [ ] All P2 issues fixed (page title)
- [ ] Smoke test pass rate >95%
- [ ] No critical failures remaining
- [ ] All changes committed with clear messages
- [ ] Completion report generated
---
## Rollback Plan
If any fix introduces new issues:
1. Identify the problematic commit
2. Revert the specific commit: `git revert <commit-hash>`
3. Re-run tests to verify stability
4. Document the issue for future investigation
---
## Success Criteria
- Smoke test pass rate: >95%
- Navigation tests: 100% pass
- Home page tests: 100% pass
- Contact page tests: 100% pass
- Zero P0 or P1 issues remaining
- Ready for deployment with confidence
-267
View File
@@ -1,267 +0,0 @@
# 独立会话执行指导
## 📋 工作环境已准备就绪
**Worktree路径**: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website-fix-critical-issues`
**分支名称**: `fix/critical-issues`
**基础分支**: `feat-init`
---
## 🚀 执行步骤
### 步骤1: 打开新的IDE会话
在新的IDE窗口或终端中打开worktree目录:
```bash
cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website-fix-critical-issues
```
### 步骤2: 验证环境
```bash
# 检查当前分支
git branch
# 应该显示: * fix/critical-issues
# 检查git状态
git status
# 应该显示: clean working directory
```
### 步骤3: 安装依赖(如果需要)
```bash
# 如果node_modules不存在,安装依赖
npm install
# 如果e2e目录需要依赖
cd e2e && npm install
```
### 步骤4: 启动开发服务器
```bash
# 在worktree根目录启动开发服务器
npm run dev
# 服务器将在 http://localhost:3000 启动
```
### 步骤5: 在新会话中调用executing-plans技能
在新的Trae IDE会话中,执行以下操作:
1. **打开新会话**
- 在新的IDE窗口中打开worktree目录
- 确保工作目录是: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website-fix-critical-issues`
2. **调用executing-plans技能**
```
@executing-plans
```
3. **指定修复计划文件**
```
请执行修复计划: docs/plans/2026-03-07-critical-issues-fix.md
```
---
## 📝 修复计划概览
修复计划包含8个任务:
1. **Task 1**: 修复移动端导航菜单功能 (P0, 2-3小时)
2. **Task 2**: 修复主导航菜单显示 (P0, 1-2小时)
3. **Task 3**: 修复页面区块显示问题 (P0, 2-3小时)
4. **Task 4**: 修复工作时间信息获取 (P1, 30分钟)
5. **Task 5**: 修复页面滚动功能 (P1, 1-2小时)
6. **Task 6**: 修复联系页面标题 (P2, 10分钟)
7. **Task 7**: 运行完整测试套件验证 (P0, 45分钟)
8. **Task 8**: 创建修复完成报告 (P0, 30分钟)
**预计总时间**: 1-2个工作日
---
## 🔍 执行检查点
### 检查点1: P0问题修复完成
**时间**: 第1天下午
**验证**:
- [ ] 移动端导航菜单功能正常
- [ ] 主导航菜单显示正常
- [ ] 页面区块显示完整
**测试命令**:
```bash
cd e2e
npm run test:smoke -- --grep "导航冒烟测试"
npm run test:smoke -- --grep "首页冒烟测试"
```
### 检查点2: 所有问题修复完成
**时间**: 第2天上午
**验证**:
- [ ] P0问题全部修复
- [ ] P1问题全部修复
- [ ] P2问题全部修复
**测试命令**:
```bash
cd e2e
npm run test:smoke
```
### 检查点3: 测试通过率达到标
**时间**: 第2天下午
**验证**:
- [ ] 测试通过率 >95%
- [ ] 无P0或P1问题
- [ ] 准备上线
**测试命令**:
```bash
cd e2e
npm run test:smoke
node analyze-results.js
```
---
## 📊 成功标准
修复完成后,应该达到以下标准:
- ✅ 测试通过率 >95%
- ✅ 导航测试 100%通过
- ✅ 首页测试 100%通过
- ✅ 联系页面测试 100%通过
- ✅ 零个P0或P1问题
- ✅ 准备上线
---
## 🔄 回滚计划
如果修复过程中出现问题:
### 回滚单个提交
```bash
# 查看提交历史
git log --oneline
# 回滚到指定提交
git revert <commit-hash>
# 重新测试
cd e2e && npm run test:smoke
```
### 回滚到初始状态
```bash
# 重置到worktree创建时的状态
git reset --hard b7d400e
# 清理未跟踪的文件
git clean -fd
```
---
## 📞 技术支持
**遇到问题时**:
1. 检查修复计划文件: `docs/plans/2026-03-07-critical-issues-fix.md`
2. 查看测试报告: `e2e/test-results/results.json`
3. 运行测试分析: `e2e/analyze-results.js`
**常见问题**:
- **问题**: 测试超时
- **解决**: 增加测试超时时间或检查网络连接
- **问题**: 选择器找不到元素
- **解决**: 检查页面结构,更新选择器
- **问题**: 移动端菜单无法打开
- **解决**: 检查mobile-menu组件的ARIA属性
---
## ✅ 完成后的操作
修复完成后,执行以下操作:
### 1. 生成最终测试报告
```bash
cd e2e
npm run test:smoke
node analyze-results.js
```
### 2. 创建修复完成报告
修复计划中的Task 8会自动生成报告
### 3. 合并到主分支
```bash
# 切换到主分支
cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website
git checkout feat-init
# 合并修复分支
git merge fix/critical-issues
# 推送到远程
git push
```
### 4. 清理worktree
```bash
# 删除worktree
git worktree remove /Users/zhangxiang/Codes/Gitee/home-page/novalon-website-fix-critical-issues
```
---
## 📋 执行清单
在开始执行前,确认:
- [ ] 已打开新的IDE会话
- [ ] 工作目录是worktree路径
- [ ] 开发服务器已启动
- [ ] 已调用executing-plans技能
- [ ] 已指定修复计划文件
---
## 🎯 下一步
**现在请执行以下操作**:
1. 在新的IDE窗口中打开: `/Users/zhangxiang/Codes/Gitee/home-page/novalon-website-fix-critical-issues`
2. 在新会话中调用:
```
@executing-plans
```
3. 指定修复计划:
```
请执行修复计划: docs/plans/2026-03-07-critical-issues-fix.md
```
4. 按照计划逐个任务执行
---
**祝您修复顺利!** 🚀
如有任何问题,请参考修复计划文件或联系技术支持。