forked from cardosofelipe/fast-next-template
Add comprehensive E2E tests for homepage and refactor demo modal logic
- Implemented E2E tests for homepage sections: `HeroSection`, `Header`, `CTASection`, `AnimatedTerminal`, `FeatureSections`, and `Footer`, ensuring proper functionality, navigation, and accessibility. - Introduced tests for mobile menu interactions, demo credentials modal, and terminal animations. - Refactored demo modal logic to use a shared state managed in `page.tsx` for consistency across sections (`Header`, `HeroSection`, `CTASection`). - Updated `Header`, `HeroSection`, and `CTASection` to receive `onOpenDemoModal` as props for triggering the modal.
This commit is contained in:
@@ -5,15 +5,16 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Github, Star, Play, ArrowRight } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DemoCredentialsModal } from './DemoCredentialsModal';
|
||||
|
||||
export function CTASection() {
|
||||
const [demoModalOpen, setDemoModalOpen] = useState(false);
|
||||
interface CTASectionProps {
|
||||
onOpenDemoModal: () => void;
|
||||
}
|
||||
|
||||
export function CTASection({ onOpenDemoModal }: CTASectionProps) {
|
||||
|
||||
return (
|
||||
<section className="relative overflow-hidden bg-gradient-to-br from-primary/10 via-background to-background">
|
||||
@@ -66,7 +67,7 @@ export function CTASection() {
|
||||
</a>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setDemoModalOpen(true)}
|
||||
onClick={onOpenDemoModal}
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="gap-2 text-base group"
|
||||
@@ -113,12 +114,6 @@ export function CTASection() {
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Demo Credentials Modal */}
|
||||
<DemoCredentialsModal
|
||||
open={demoModalOpen}
|
||||
onClose={() => setDemoModalOpen(false)}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Menu, X, Github, Star } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DemoCredentialsModal } from './DemoCredentialsModal';
|
||||
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
|
||||
|
||||
export function Header() {
|
||||
const [demoModalOpen, setDemoModalOpen] = useState(false);
|
||||
interface HeaderProps {
|
||||
onOpenDemoModal: () => void;
|
||||
}
|
||||
|
||||
export function Header({ onOpenDemoModal }: HeaderProps) {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
const navLinks = [
|
||||
@@ -63,7 +65,7 @@ export function Header() {
|
||||
|
||||
{/* CTAs */}
|
||||
<Button
|
||||
onClick={() => setDemoModalOpen(true)}
|
||||
onClick={onOpenDemoModal}
|
||||
variant="default"
|
||||
size="sm"
|
||||
>
|
||||
@@ -98,7 +100,7 @@ export function Header() {
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="text-lg font-medium hover:text-primary transition-colors"
|
||||
>
|
||||
{link.href}
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
|
||||
@@ -122,7 +124,7 @@ export function Header() {
|
||||
<Button
|
||||
onClick={() => {
|
||||
setMobileMenuOpen(false);
|
||||
setDemoModalOpen(true);
|
||||
onOpenDemoModal();
|
||||
}}
|
||||
variant="default"
|
||||
className="w-full"
|
||||
@@ -144,12 +146,6 @@ export function Header() {
|
||||
</Sheet>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Demo Credentials Modal */}
|
||||
<DemoCredentialsModal
|
||||
open={demoModalOpen}
|
||||
onClose={() => setDemoModalOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowRight, Github, Play } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DemoCredentialsModal } from './DemoCredentialsModal';
|
||||
|
||||
export function HeroSection() {
|
||||
const [demoModalOpen, setDemoModalOpen] = useState(false);
|
||||
interface HeroSectionProps {
|
||||
onOpenDemoModal: () => void;
|
||||
}
|
||||
|
||||
export function HeroSection({ onOpenDemoModal }: HeroSectionProps) {
|
||||
|
||||
return (
|
||||
<section className="relative overflow-hidden">
|
||||
@@ -80,7 +81,7 @@ export function HeroSection() {
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
onClick={() => setDemoModalOpen(true)}
|
||||
onClick={onOpenDemoModal}
|
||||
className="gap-2 text-base group"
|
||||
>
|
||||
<Play className="h-5 w-5 group-hover:scale-110 transition-transform" aria-hidden="true" />
|
||||
@@ -139,12 +140,6 @@ export function HeroSection() {
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Demo Credentials Modal */}
|
||||
<DemoCredentialsModal
|
||||
open={demoModalOpen}
|
||||
onClose={() => setDemoModalOpen(false)}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user