// @vitest-environment jsdom // // The island — a scroll-driven progress bar. We mock // `@voltro/web`'s `island()` to the identity so the default export IS the raw // component, then assert it renders the progress-bar element and recomputes its // width on scroll. import { afterEach, describe, expect, test, vi } from 'vitest' import { act, createElement, type ComponentType, type ReactNode } from 'react' import { createRoot, type Root } from 'react-dom/client' vi.mock('@voltro/web', () => ({ island: (Component: ComponentType) => Component, })) const { default: ReadingProgress } = await import('./ReadingProgress.island') ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true let container: HTMLDivElement let root: Root const render = (node: ReactNode): void => { container = document.createElement('div') document.body.appendChild(container) act(() => { root = createRoot(container) root.render(node) }) } afterEach(() => { if (root) act(() => root.unmount()) container?.remove() document.body.innerHTML = '' }) describe('ReadingProgress island', () => { test('renders the progress-bar element, hidden from assistive tech', () => { render(createElement(ReadingProgress)) const bar = container.querySelector('.reading-progress') as HTMLElement expect(bar).not.toBeNull() expect(bar.getAttribute('aria-hidden')).toBe('true') }) test('starts at 0% when the document is not scrollable', () => { render(createElement(ReadingProgress)) const bar = container.querySelector('.reading-progress') as HTMLElement // jsdom reports scrollHeight === clientHeight (0), so max <= 0 → 0%. expect(bar.style.width).toBe('0%') }) test('recomputes width to 100% at the bottom of a scrollable document', () => { render(createElement(ReadingProgress)) const el = document.documentElement Object.defineProperty(el, 'scrollHeight', { value: 2000, configurable: true }) Object.defineProperty(el, 'clientHeight', { value: 1000, configurable: true }) Object.defineProperty(el, 'scrollTop', { value: 1000, configurable: true }) act(() => { window.dispatchEvent(new Event('scroll')) }) const bar = container.querySelector('.reading-progress') as HTMLElement expect(bar.style.width).toBe('100%') }) })