test(e2e,unit): add navigation edge cases and component coverage
- Add missing-paths E2E spec for desktop/mobile navigation and contrast - Add local Playwright config for dev server testing - Expand unit tests for CMS data server, products, contact and UI components - Adjust jest config for new test patterns
This commit is contained in:
@@ -258,6 +258,7 @@ const mockProduct = {
|
||||
specs: ['支持 10 万并发', '99.9% 可用性'],
|
||||
tags: ['ERP', '企业管理'],
|
||||
heroThemeId: 'erp',
|
||||
bundle: 'enterprise' as const,
|
||||
caseStudies: [
|
||||
{ client: '某制造企业', industry: '制造业', challenge: '库存管理混乱', solution: '实施ERP系统', result: '库存周转率提升200%' },
|
||||
],
|
||||
@@ -403,8 +404,7 @@ describe('ProductValueSection', () => {
|
||||
it('should render product title and overview', async () => {
|
||||
const { ProductValueSection } = await import('./detail-product-value');
|
||||
render(<ProductValueSection product={mockProduct} />);
|
||||
expect(screen.getByText('核心能力')).toBeInTheDocument();
|
||||
expect(screen.getByText(mockProduct.title)).toBeInTheDocument();
|
||||
expect(screen.getByRole('heading', { name: /为企业打造的/ })).toHaveTextContent(mockProduct.title);
|
||||
expect(screen.getByText(mockProduct.overview)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -434,7 +434,6 @@ describe('ProductValueSection', () => {
|
||||
it('should render data proofs when available', async () => {
|
||||
const { ProductValueSection } = await import('./detail-product-value');
|
||||
render(<ProductValueSection product={mockProduct} />);
|
||||
expect(screen.getByText('数据说话')).toBeInTheDocument();
|
||||
expect(screen.getByText('用真实效果证明价值')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -442,7 +441,7 @@ describe('ProductValueSection', () => {
|
||||
const { ProductValueSection } = await import('./detail-product-value');
|
||||
const productWithoutData = { ...mockProduct, dataProofs: [] };
|
||||
render(<ProductValueSection product={productWithoutData} />);
|
||||
expect(screen.queryByText('数据说话')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('用真实效果证明价值')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render ink glow cards for features', async () => {
|
||||
@@ -468,7 +467,6 @@ describe('DetailTrustSection', () => {
|
||||
dataProofs={mockProduct.dataProofs}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('数据说话')).toBeInTheDocument();
|
||||
expect(screen.getByText('用真实效果证明价值')).toBeInTheDocument();
|
||||
expect(screen.getByText(mockProduct.dataProofs[0]!.metric)).toBeInTheDocument();
|
||||
});
|
||||
@@ -480,7 +478,6 @@ describe('DetailTrustSection', () => {
|
||||
caseStudies={mockProduct.caseStudies}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('客户案例')).toBeInTheDocument();
|
||||
expect(screen.getByText('他们已经实现了转型突破')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('case-study-card')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('case-client')).toHaveTextContent('某制造企业');
|
||||
@@ -508,8 +505,8 @@ describe('DetailTrustSection', () => {
|
||||
accentColor="#C41E3A"
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('数据说话')).toBeInTheDocument();
|
||||
expect(screen.getByText('客户案例')).toBeInTheDocument();
|
||||
expect(screen.getByText('用真实效果证明价值')).toBeInTheDocument();
|
||||
expect(screen.getByText('他们已经实现了转型突破')).toBeInTheDocument();
|
||||
expect(screen.getByText('资质认证')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -248,11 +248,10 @@ describe('ProductCard', () => {
|
||||
});
|
||||
|
||||
describe('ServiceCard', () => {
|
||||
it('should render number, title, description and link', async () => {
|
||||
it('should render title, description and link', async () => {
|
||||
const { ServiceCard } = await import('./service-card');
|
||||
render(
|
||||
<ServiceCard
|
||||
number="01"
|
||||
title="战略咨询"
|
||||
description="业务诊断与战略规划"
|
||||
href="/services/consulting"
|
||||
@@ -268,7 +267,6 @@ describe('ServiceCard', () => {
|
||||
const { ServiceCard } = await import('./service-card');
|
||||
render(
|
||||
<ServiceCard
|
||||
number="02"
|
||||
title="Data"
|
||||
description="Analysis"
|
||||
href="/services/data"
|
||||
@@ -280,7 +278,7 @@ describe('ServiceCard', () => {
|
||||
expect(target).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should apply custom color', async () => {
|
||||
it('should accept optional number and color props for compatibility', async () => {
|
||||
const { ServiceCard } = await import('./service-card');
|
||||
render(
|
||||
<ServiceCard
|
||||
|
||||
@@ -10,7 +10,7 @@ jest.mock('@/hooks/use-reduced-motion', () => ({
|
||||
describe('ScrollProgress', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
// Mock document height for predictable progress calculation
|
||||
// Mock document/scroll geometry for predictable progress calculation
|
||||
Object.defineProperty(document.documentElement, 'scrollHeight', {
|
||||
value: 1000,
|
||||
configurable: true,
|
||||
@@ -19,6 +19,11 @@ describe('ScrollProgress', () => {
|
||||
value: 500,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window, 'scrollY', {
|
||||
value: 0,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should always render the progress container', () => {
|
||||
@@ -44,8 +49,10 @@ describe('ScrollProgress', () => {
|
||||
const { container } = render(<ScrollProgress />);
|
||||
const innerBar = (container.firstChild as HTMLElement).firstChild as HTMLElement;
|
||||
expect(innerBar).toBeInTheDocument();
|
||||
// 默认 progress 为 0,宽度为 0%
|
||||
expect(innerBar.style.width).toBe('0%');
|
||||
// 默认 progress 为 0,使用 transform scaleX 实现宽度变化
|
||||
expect(innerBar.style.width).toBe('100%');
|
||||
expect(innerBar.style.transform).toBe('scaleX(0)');
|
||||
expect(innerBar.style.transformOrigin).toBe('left');
|
||||
});
|
||||
|
||||
it('should apply default height of 2px', () => {
|
||||
|
||||
@@ -48,13 +48,16 @@ export function ScrollProgress({
|
||||
height: `${height}px`,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
data-testid="scroll-progress"
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: `${shouldReduceMotion ? 0 : progress}%`,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: color,
|
||||
transition: shouldReduceMotion ? 'none' : 'width 0.1s linear',
|
||||
transformOrigin: 'left',
|
||||
transform: `scaleX(${shouldReduceMotion ? 0 : progress / 100})`,
|
||||
transition: shouldReduceMotion ? 'none' : 'transform 0.1s linear',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user