37296b5717
改造概要(30项): - 第一轮:Hero重构/Section差异化/SocialProof强化/CTA对比度/About架构 - 第二轮:字体优化/背景交替/Solutions差异化/Footer五列/MegaDropdown修复 - 第三轮:卡片交互/表单层级/CTA统一/时间线标记/连接线/三列布局/移动导航/Button微交互/SEO Schema - P3-2:template.tsx+Framer Motion页面过渡/loading.tsx加载状态 - 清理:删除未用组件/hooks,修复重复移动导航,清理冗余CSS
143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
|
|
import { render, screen } from '@testing-library/react';
|
|
import '@testing-library/jest-dom';
|
|
import { MobileTabBar } from './mobile-tab-bar';
|
|
|
|
jest.mock('next/navigation', () => ({
|
|
usePathname: () => '/',
|
|
useSearchParams: () => new URLSearchParams(),
|
|
}));
|
|
|
|
jest.mock('framer-motion', () => ({
|
|
motion: {
|
|
div: ({ children, ...props }: { children: React.ReactNode; [key: string]: unknown }) => (
|
|
<div {...props}>{children}</div>
|
|
),
|
|
},
|
|
}));
|
|
|
|
jest.mock('next/link', () => {
|
|
const MockLink = ({ children, href }: { children: React.ReactNode; href: string }) => (
|
|
<a href={href}>{children}</a>
|
|
);
|
|
MockLink.displayName = 'MockLink';
|
|
return MockLink;
|
|
});
|
|
|
|
describe('MobileTabBar', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
it('should render tab bar', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
expect(nav).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render all tabs', () => {
|
|
render(<MobileTabBar />);
|
|
expect(screen.getByText('首页')).toBeInTheDocument();
|
|
expect(screen.getByText('服务')).toBeInTheDocument();
|
|
expect(screen.getByText('产品')).toBeInTheDocument();
|
|
expect(screen.getByText('关于')).toBeInTheDocument();
|
|
expect(screen.getByText('联系')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render tab icons', () => {
|
|
render(<MobileTabBar />);
|
|
const icons = document.querySelectorAll('svg');
|
|
expect(icons.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Active State', () => {
|
|
it('should highlight active tab', () => {
|
|
render(<MobileTabBar />);
|
|
const homeTab = screen.getByText('首页').closest('a');
|
|
expect(homeTab).toBeInTheDocument();
|
|
});
|
|
|
|
it('should show active indicator', () => {
|
|
render(<MobileTabBar />);
|
|
const activeIndicator = document.querySelector('.bg-\\[var\\(--color-brand-primary\\)\\]');
|
|
expect(activeIndicator).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('Navigation Links', () => {
|
|
it('should have correct href for home', () => {
|
|
render(<MobileTabBar />);
|
|
const homeLink = screen.getByText('首页').closest('a');
|
|
expect(homeLink).toHaveAttribute('href', '/');
|
|
});
|
|
|
|
it('should have correct href for services', () => {
|
|
render(<MobileTabBar />);
|
|
const servicesLink = screen.getByText('服务').closest('a');
|
|
expect(servicesLink).toHaveAttribute('href', '/services');
|
|
});
|
|
|
|
it('should have correct href for products', () => {
|
|
render(<MobileTabBar />);
|
|
const productsLink = screen.getByText('产品').closest('a');
|
|
expect(productsLink).toHaveAttribute('href', '/products');
|
|
});
|
|
|
|
it('should have correct href for about', () => {
|
|
render(<MobileTabBar />);
|
|
const aboutLink = screen.getByText('关于').closest('a');
|
|
expect(aboutLink).toHaveAttribute('href', '/about');
|
|
});
|
|
|
|
it('should have correct href for contact', () => {
|
|
render(<MobileTabBar />);
|
|
const contactLink = screen.getByText('联系').closest('a');
|
|
expect(contactLink).toHaveAttribute('href', '/contact');
|
|
});
|
|
});
|
|
|
|
describe('Accessibility', () => {
|
|
it('should have navigation role', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
expect(nav).toBeInTheDocument();
|
|
});
|
|
|
|
it('should have accessible tab labels', () => {
|
|
render(<MobileTabBar />);
|
|
const tabs = screen.getAllByRole('link');
|
|
expect(tabs.length).toBe(5);
|
|
});
|
|
});
|
|
|
|
describe('Styling', () => {
|
|
it('should have fixed positioning', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
expect(nav).toHaveClass('fixed');
|
|
expect(nav).toHaveClass('bottom-0');
|
|
});
|
|
|
|
it('should have responsive visibility', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
expect(nav).toHaveClass('md:hidden');
|
|
});
|
|
|
|
it('should have backdrop blur', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
expect(nav).toHaveClass('backdrop-blur-xl');
|
|
});
|
|
|
|
it('should have proper height', () => {
|
|
render(<MobileTabBar />);
|
|
const nav = screen.getByRole('navigation');
|
|
const heightDiv = nav.querySelector('.h-16');
|
|
expect(heightDiv).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|