Files
novalon-website/src/components/ui/scroll-progress.test.tsx
T
张翔 a6ea2cc72c 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
2026-07-08 14:47:07 +08:00

96 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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');
});
});