feat(e2e): 添加完整的E2E测试框架和测试用例

添加Playwright测试框架配置和基础页面对象
实现冒烟测试用例覆盖首页和联系页面核心功能
更新导航组件以支持滚动高亮功能
添加BackButton组件统一返回按钮行为
配置Woodpecker CI集成和测试报告生成
This commit is contained in:
张翔
2026-02-27 10:30:33 +08:00
parent 4a616fe96e
commit 5d5b7feb0a
50 changed files with 6765 additions and 46 deletions
+10 -7
View File
@@ -1,7 +1,7 @@
'use client';
import { useEffect, useRef, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ArrowLeft, CheckCircle2, TrendingUp, Users, Target, Quote, Clock, MessageCircle, Award } from 'lucide-react';
@@ -31,6 +31,7 @@ interface CaseDetailClientProps {
export function CaseDetailClient({ caseItem }: CaseDetailClientProps) {
const [isVisible, setIsVisible] = useState(false);
const contentRef = useRef<HTMLDivElement>(null);
const router = useRouter();
useEffect(() => {
const observer = new IntersectionObserver(
@@ -67,12 +68,14 @@ export function CaseDetailClient({ caseItem }: CaseDetailClientProps) {
<main className="min-h-screen bg-white">
<div className="relative overflow-hidden bg-gradient-to-b from-[#FAFAFA] to-white">
<div className="container-wide relative z-10 pt-32 pb-20">
<Link href="/cases">
<Button variant="ghost" className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10">
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
</Link>
<Button
variant="ghost"
className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10"
onClick={() => router.back()}
>
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
<div className="max-w-4xl mt-8">
<Badge className="mb-4 bg-[#C41E3A]/10 text-[#C41E3A] hover:bg-[#C41E3A]/20">
{caseItem.industry}
+10 -7
View File
@@ -1,7 +1,7 @@
'use client';
import { useRef } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import {
@@ -94,6 +94,7 @@ const outcomes = {
};
export function ServiceDetailClient({ service }: ServiceDetailClientProps) {
const router = useRouter();
const contentRef = useRef<HTMLDivElement>(null);
const serviceChallenges = challenges[service.id as keyof typeof challenges] || [];
@@ -106,12 +107,14 @@ export function ServiceDetailClient({ service }: ServiceDetailClientProps) {
<main className="min-h-screen bg-white">
<div className="relative overflow-hidden bg-gradient-to-b from-[#FAFAFA] to-white">
<div className="container-wide relative z-10 pt-32 pb-20">
<Link href="/services">
<Button variant="ghost" className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10">
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
</Link>
<Button
variant="ghost"
className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10"
onClick={() => router.back()}
>
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
<div className="max-w-4xl mt-8">
<div className="flex items-center gap-4 mb-6">
<div className="w-16 h-16 bg-[#C41E3A] rounded-2xl flex items-center justify-center text-white">