a6ea2cc72c
- 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
96 lines
3.4 KiB
TypeScript
96 lines
3.4 KiB
TypeScript
import { render } from '@testing-library/react';
|
||
import '@testing-library/jest-dom';
|
||
import { ScrollProgress } from './scroll-progress';
|
||
|
||
// Mock useReducedMotion
|
||
jest.mock('@/hooks/use-reduced-motion', () => ({
|
||
useReducedMotion: () => false,
|
||
}));
|
||
|
||
describe('ScrollProgress', () => {
|
||
beforeEach(() => {
|
||
jest.clearAllMocks();
|
||
// Mock document/scroll geometry for predictable progress calculation
|
||
Object.defineProperty(document.documentElement, 'scrollHeight', {
|
||
value: 1000,
|
||
configurable: true,
|
||
});
|
||
Object.defineProperty(window, 'innerHeight', {
|
||
value: 500,
|
||
configurable: true,
|
||
});
|
||
Object.defineProperty(window, 'scrollY', {
|
||
value: 0,
|
||
configurable: true,
|
||
writable: true,
|
||
});
|
||
});
|
||
|
||
it('should always render the progress container', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
// ScrollProgress 始终渲染(带 aria-hidden="true")
|
||
expect(container.firstChild).not.toBeNull();
|
||
});
|
||
|
||
it('should have aria-hidden="true" for decorative purposes', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper).toHaveAttribute('aria-hidden', 'true');
|
||
});
|
||
|
||
it('should apply fixed positioning class', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper).toHaveClass('fixed');
|
||
expect(wrapper).toHaveClass('pointer-events-none');
|
||
});
|
||
|
||
it('should render inner progress bar div', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const innerBar = (container.firstChild as HTMLElement).firstChild as HTMLElement;
|
||
expect(innerBar).toBeInTheDocument();
|
||
// 默认 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', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper.style.height).toBe('2px');
|
||
});
|
||
|
||
it('should support custom height', () => {
|
||
const { container } = render(<ScrollProgress height={4} />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper.style.height).toBe('4px');
|
||
});
|
||
|
||
it('should apply default top position', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper.style.top).toBe('0px');
|
||
});
|
||
|
||
it('should support bottom position', () => {
|
||
const { container } = render(<ScrollProgress position="bottom" />);
|
||
const wrapper = container.firstChild as HTMLElement;
|
||
expect(wrapper.style.bottom).toBe('0px');
|
||
});
|
||
|
||
it('should use brand color by default', () => {
|
||
const { container } = render(<ScrollProgress />);
|
||
const innerBar = (container.firstChild as HTMLElement).firstChild as HTMLElement;
|
||
expect(innerBar.style.background).toBe('var(--color-brand)');
|
||
});
|
||
|
||
it('should support custom color', () => {
|
||
const { container } = render(<ScrollProgress color="#ff0000" />);
|
||
const innerBar = (container.firstChild as HTMLElement).firstChild as HTMLElement;
|
||
// jsdom 将 #ff0000 转换为 rgb(255, 0, 0)
|
||
expect(innerBar.style.background).toContain('255');
|
||
expect(innerBar.style.background).toContain('0');
|
||
});
|
||
});
|