import '../../styles/app.css'; import { act } from 'react'; import type { Root } from 'react-dom/client'; import { createRoot } from 'react-dom/client'; import { Group, Panel, Separator } from 'react-resizable-panels'; import { afterEach, expect, test } from 'vite-plus/test'; import { commands, page } from 'vite-plus/test/context'; import { RESIZE_TARGET_MINIMUM_SIZE } from './resize-target'; const GROUP_WIDTH = 600; const GROUP_HEIGHT = 300; let container: HTMLElement | undefined; let root: Root | undefined; afterEach(() => { if (root) act(() => root?.unmount()); container?.remove(); container = undefined; root = undefined; }); test('resizes when the drag starts at the edge of the pointer hit target', async () => { // Match the iframe's content viewport to the harness size below so // Playwright's page-space coordinates map 1:1 onto the separator's own // coordinate system (otherwise the harness page can be scaled to fit the // runner viewport, throwing off the pixel-precise offsets this test relies // on). await page.viewport(GROUP_WIDTH, GROUP_HEIGHT); const firstPanel = renderLayout(); const widthBefore = firstPanel.current?.getBoundingClientRect().width ?? 0; // 7px out from the separator's centre: inside the 16px band we configure, // outside the 10px the library defaults to. Deliberately a literal rather // than derived from RESIZE_TARGET_MINIMUM_SIZE — a derived offset would // shrink along with the band and pass no matter how narrow it got. await commands.dragFromSeparator(7, -100); await expect .poll(() => firstPanel.current?.getBoundingClientRect().width ?? 0) .toBeLessThan(widthBefore - 50); }); test('does not resize when the drag starts outside the pointer hit target', async () => { await page.viewport(GROUP_WIDTH, GROUP_HEIGHT); const firstPanel = renderLayout(); const widthBefore = firstPanel.current?.getBoundingClientRect().width ?? 0; // 12px out, past the edge of the band. Pins the upper bound so the grab // area cannot quietly swallow clicks meant for the panes either side. await commands.dragFromSeparator(12, -100); const widthAfter = firstPanel.current?.getBoundingClientRect().width ?? 0; expect(Math.abs(widthAfter - widthBefore)).toBeLessThan(3); }); function renderLayout() { container = document.body.appendChild(document.createElement('div')); root = createRoot(container); const firstPanel: { current: HTMLDivElement | null } = { current: null }; act(() => { root?.render(); }); return firstPanel; } function Harness({ firstPanelRef }: { firstPanelRef: { current: HTMLDivElement | null } }) { return ( { firstPanelRef.current = element; }} minSize={80} /> ); }