feat(e2e): 添加完整的E2E测试框架和测试用例
添加Playwright测试框架配置和基础页面对象 实现冒烟测试用例覆盖首页和联系页面核心功能 更新导航组件以支持滚动高亮功能 添加BackButton组件统一返回按钮行为 配置Woodpecker CI集成和测试报告生成
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { ArrowLeft, Calendar, Share2 } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useInView } from 'framer-motion';
|
||||
import { useRef } from 'react';
|
||||
@@ -18,13 +18,10 @@ interface NewsItem {
|
||||
content: string;
|
||||
}
|
||||
|
||||
interface NewsDetailClientProps {
|
||||
news: NewsItem;
|
||||
}
|
||||
|
||||
export function NewsDetailClient({ news }: NewsDetailClientProps) {
|
||||
const contentRef = useRef(null);
|
||||
const isContentInView = useInView(contentRef, { once: true, margin: '-100px' });
|
||||
const router = useRouter();
|
||||
|
||||
const relatedNews = NEWS
|
||||
.filter((n) => n.id !== news.id && n.category === news.category)
|
||||
@@ -34,13 +31,14 @@ export function NewsDetailClient({ news }: NewsDetailClientProps) {
|
||||
<div 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="/news"
|
||||
className="inline-flex items-center text-[#5C5C5C] hover:text-[#C41E3A] transition-colors mb-6"
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
返回新闻列表
|
||||
</Link>
|
||||
返回
|
||||
</Button>
|
||||
<div className="max-w-4xl">
|
||||
<div className="inline-block px-4 py-2 bg-[#C41E3A]/10 rounded-full text-[#C41E3A] text-sm mb-6">
|
||||
{news.category}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { PRODUCTS } from '@/lib/constants';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { BackButton } from '@/components/ui/back-button';
|
||||
import { ArrowLeft, CheckCircle2, Zap, Target, Layers, CreditCard, ArrowRight } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return PRODUCTS.map((product) => ({
|
||||
@@ -38,13 +39,7 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
|
||||
<div 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="/#products"
|
||||
className="inline-flex items-center text-[#5C5C5C] hover:text-[#C41E3A] transition-colors mb-6"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
返回产品列表
|
||||
</Link>
|
||||
<BackButton />
|
||||
<div className="max-w-4xl">
|
||||
<div className="inline-block px-4 py-2 bg-[#C41E3A]/10 rounded-full text-[#C41E3A] text-sm mb-6">
|
||||
{product.category}
|
||||
|
||||
Reference in New Issue
Block a user