import { describe, expect, it } from "vitest"; import { act, fireEvent, renderControlsPanelWithSchema, screen, vi, } from "../testing/controls-panel-test-utils"; import { createNavigationSchema, prepareScrollablePanel, } from "../testing/controls-panel-section-navigation-test-utils"; describe("ControlsPanel section navigation regressions", () => { it.each([0, 150, 300])( "opens on the replacement panel after reset at %dms of hover", (hoverDuration) => { vi.useFakeTimers(); try { const { container } = renderControlsPanelWithSchema( createNavigationSchema(), ); const { panel: originalPanel } = prepareScrollablePanel(container); act(() => vi.advanceTimersByTime(0)); if (hoverDuration > 0) { fireEvent.pointerMove(originalPanel, { clientX: 408, clientY: 120 }); act(() => vi.advanceTimersByTime(hoverDuration)); } fireEvent.click( screen.getByRole("button", { name: "Reset controls" }), ); const { panel, scrollTo } = prepareScrollablePanel(container); expect(panel).not.toBe(originalPanel); expect(originalPanel.isConnected).toBe(false); act(() => vi.advanceTimersByTime(500)); expect( screen.queryByRole("navigation", { name: "Panel sections" }), ).toBeNull(); fireEvent.pointerMove(panel, { clientX: 408, clientY: 120 }); act(() => vi.advanceTimersByTime(299)); expect( screen.queryByRole("navigation", { name: "Panel sections" }), ).toBeNull(); act(() => vi.advanceTimersByTime(1)); expect( screen.getByRole("navigation", { name: "Panel sections" }), ).toBeTruthy(); fireEvent.click(screen.getByRole("button", { name: "Wind" })); expect(scrollTo).toHaveBeenCalledWith({ behavior: "auto", top: 180 }); } finally { vi.useRealTimers(); } }, ); it("masks overflowing labels on the right without fading short labels", () => { vi.useFakeTimers(); try { const title = "Tab 4 points ยท Competitive Conquesting Customers"; const { container } = renderControlsPanelWithSchema( createNavigationSchema(title), ); const { panel } = prepareScrollablePanel(container); act(() => vi.advanceTimersByTime(0)); fireEvent.pointerMove(panel, { clientX: 408, clientY: 120 }); act(() => vi.advanceTimersByTime(300)); const labels = [[title, 380, "20px"], ["Wind", 80, "0px"]] as const; for (const [name, scrollWidth, fade] of labels) { const button = screen.getByRole("button", { name }); const label = button.querySelector( '[data-scroll-fade-viewport][data-side="right"]', ); expect(label).toBeTruthy(); Object.defineProperties(label!, { clientWidth: { configurable: true, value: 214 }, scrollWidth: { configurable: true, value: scrollWidth }, }); fireEvent.scroll(label!); expect( label!.style.getPropertyValue("--scroll-fade-trailing-fade"), ).toBe(fade); expect( label!.style.getPropertyValue("--scroll-fade-leading-fade"), ).toBe("0px"); expect(label!.className).toContain("overflow-x-hidden"); expect(label!.textContent).toBe(name); } } finally { vi.useRealTimers(); } }); });