import { afterEach, describe, expect, test } from "bun:test"; import { act, useReducer, type ReactNode } from "react"; import { testRender } from "../../../renderers/opentui/test-utils"; import { AppContext, appReducer, createInitialState } from "../../../state/app/context"; import { Box, ScrollBox, Text, type ScrollBoxRenderable } from "../../../ui"; import { createDefaultConfig } from "../../../types/config"; import type { PaneProps } from "../../../types/plugin"; import { PaneContent } from "./content"; let testSetup: Awaited> | undefined; let scrollRef: ScrollBoxRenderable | null = null; let hiddenScrollRef: ScrollBoxRenderable | null = null; afterEach(() => { if (testSetup) { act(() => { testSetup!.renderer.destroy(); }); testSetup = undefined; } scrollRef = null; hiddenScrollRef = null; }); function emitDownArrow() { return act(async () => { testSetup!.mockInput.pressArrow("down"); await testSetup!.renderOnce(); }); } async function renderHarness(component: ReactNode) { await act(async () => { testSetup = await testRender(component, { width: 30, height: 5 }); }); await act(async () => { await testSetup!.renderOnce(); await testSetup!.renderOnce(); await testSetup!.renderOnce(); }); } function LongScrollPane({ width, height }: PaneProps) { return ( { scrollRef = node; }} height={height} scrollY focusable={false} > {Array.from({ length: 20 }, (_, index) => ( {`Row ${index}`} ))} ); } function HiddenMountedTabPane({ width, height }: PaneProps) { const renderRows = () => Array.from({ length: 20 }, (_, index) => ( {`Tab row ${index}`} )); return ( { scrollRef = node; }} height={height} scrollY focusable={false} > {renderRows()} { hiddenScrollRef = node; }} height={height} scrollY focusable={false} > {renderRows()} ); } function Harness({ component = LongScrollPane, focused = true, }: { component?: (props: PaneProps) => ReactNode; focused?: boolean; }) { const initialState = createInitialState(createDefaultConfig("/tmp/gloomberb-pane-keyboard-scroll-test")); const [state, dispatch] = useReducer(appReducer, initialState); return ( ); } describe("pane keyboard scrolling", () => { test("scrolls the focused pane's vertical scrollbox with arrow keys", async () => { await renderHarness(); expect(scrollRef?.scrollTop).toBe(0); await emitDownArrow(); expect(scrollRef?.scrollTop).toBe(3); }); test("ignores mounted scrollboxes inside hidden tabs", async () => { await renderHarness(); expect(scrollRef?.scrollTop).toBe(0); expect(hiddenScrollRef?.scrollTop).toBe(0); await emitDownArrow(); expect(scrollRef?.scrollTop).toBe(3); expect(hiddenScrollRef?.scrollTop).toBe(0); }); });