From 6ec259a0e71174651bae95d4628138bf6fd68742 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 16:19:35 -0400 Subject: refactor: packages/ --- .../excalidraw/components/Sidebar/Sidebar.test.tsx | 393 +++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 packages/excalidraw/components/Sidebar/Sidebar.test.tsx (limited to 'packages/excalidraw/components/Sidebar/Sidebar.test.tsx') diff --git a/packages/excalidraw/components/Sidebar/Sidebar.test.tsx b/packages/excalidraw/components/Sidebar/Sidebar.test.tsx new file mode 100644 index 0000000..b61529d --- /dev/null +++ b/packages/excalidraw/components/Sidebar/Sidebar.test.tsx @@ -0,0 +1,393 @@ +import React from "react"; +import { DEFAULT_SIDEBAR } from "../../constants"; +import { Excalidraw, Sidebar } from "../../index"; +import { + act, + fireEvent, + queryAllByTestId, + queryByTestId, + render, + waitFor, + withExcalidrawDimensions, +} from "../../tests/test-utils"; +import { vi } from "vitest"; +import { + assertExcalidrawWithSidebar, + assertSidebarDockButton, +} from "./siderbar.test.helpers"; + +const toggleSidebar = ( + ...args: Parameters +): Promise => { + return act(() => { + return window.h.app.toggleSidebar(...args); + }); +}; + +describe("Sidebar", () => { + describe("General behavior", () => { + it("should render custom sidebar", async () => { + const { container } = await render( + + +
42
+
+
, + ); + + const node = container.querySelector("#test-sidebar-content"); + expect(node).not.toBe(null); + }); + + it("should render only one sidebar and prefer the custom one", async () => { + const { container } = await render( + + +
42
+
+
, + ); + + await waitFor(() => { + // make sure the custom sidebar is rendered + const node = container.querySelector("#test-sidebar-content"); + expect(node).not.toBe(null); + + // make sure only one sidebar is rendered + const sidebars = container.querySelectorAll(".sidebar"); + expect(sidebars.length).toBe(1); + }); + }); + + it("should toggle sidebar using excalidrawAPI.toggleSidebar()", async () => { + const { container } = await render( + + +
42
+
+
, + ); + + // sidebar isn't rendered initially + // ------------------------------------------------------------------------- + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).toBe(null); + }); + + // toggle sidebar on + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: "customSidebar" })).toBe(true); + + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).not.toBe(null); + }); + + // toggle sidebar off + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: "customSidebar" })).toBe(false); + + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).toBe(null); + }); + + // force-toggle sidebar off (=> still hidden) + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: "customSidebar", force: false })).toBe( + false, + ); + + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).toBe(null); + }); + + // force-toggle sidebar on + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: "customSidebar", force: true })).toBe( + true, + ); + expect(await toggleSidebar({ name: "customSidebar", force: true })).toBe( + true, + ); + + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).not.toBe(null); + }); + + // toggle library (= hide custom sidebar) + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: DEFAULT_SIDEBAR.name })).toBe(true); + + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).toBe(null); + + // make sure only one sidebar is rendered + const sidebars = container.querySelectorAll(".sidebar"); + expect(sidebars.length).toBe(1); + }); + + // closing sidebar using `{ name: null }` + // ------------------------------------------------------------------------- + expect(await toggleSidebar({ name: "customSidebar" })).toBe(true); + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).not.toBe(null); + }); + + expect(await toggleSidebar({ name: null })).toBe(false); + await waitFor(() => { + const node = container.querySelector("#test-sidebar-content"); + expect(node).toBe(null); + }); + }); + }); + + describe("", () => { + it("should render custom sidebar header", async () => { + const { container } = await render( + + + +
42
+
+
+
, + ); + + const node = container.querySelector("#test-sidebar-header-content"); + expect(node).not.toBe(null); + // make sure we don't render the default fallback header, + // just the custom one + expect(queryAllByTestId(container, "sidebar-header").length).toBe(1); + }); + + it("should not render for custom sidebars by default", async () => { + const CustomExcalidraw = () => { + return ( + + + hello + + + ); + }; + + const { container } = await render(); + + const sidebar = container.querySelector(".test-sidebar"); + expect(sidebar).not.toBe(null); + const closeButton = queryByTestId(sidebar!, "sidebar-close"); + expect(closeButton).toBe(null); + }); + + it(" should render close button", async () => { + const onStateChange = vi.fn(); + const CustomExcalidraw = () => { + return ( + + + + + + ); + }; + + const { container } = await render(); + + // initial open + expect(onStateChange).toHaveBeenCalledWith({ name: "customSidebar" }); + + const sidebar = container.querySelector(".test-sidebar"); + expect(sidebar).not.toBe(null); + const closeButton = queryByTestId(sidebar!, "sidebar-close")!; + expect(closeButton).not.toBe(null); + + fireEvent.click(closeButton); + await waitFor(() => { + expect(container.querySelector(".test-sidebar")).toBe( + null, + ); + expect(onStateChange).toHaveBeenCalledWith(null); + }); + }); + }); + + describe("Docking behavior", () => { + it("shouldn't be user-dockable if `onDock` not supplied", async () => { + await assertExcalidrawWithSidebar( + + + , + "customSidebar", + async () => { + await assertSidebarDockButton(false); + }, + ); + }); + + it("shouldn't be user-dockable if `onDock` not supplied & `docked={true}`", async () => { + await assertExcalidrawWithSidebar( + + + , + "customSidebar", + async () => { + await assertSidebarDockButton(false); + }, + ); + }); + + it("shouldn't be user-dockable if `onDock` not supplied & docked={false}`", async () => { + await assertExcalidrawWithSidebar( + + + , + "customSidebar", + async () => { + await assertSidebarDockButton(false); + }, + ); + }); + + it("should be user-dockable when both `onDock` and `docked` supplied", async () => { + await render( + + {}} + docked + > + + + , + ); + + await withExcalidrawDimensions( + { width: 1920, height: 1080 }, + async () => { + await assertSidebarDockButton(true); + }, + ); + }); + + it("shouldn't be user-dockable when only `onDock` supplied w/o `docked`", async () => { + // we expect warnings in this test and don't want to pollute stdout + const mock = jest.spyOn(console, "warn").mockImplementation(() => {}); + + await render( + + {}} + > + + + , + ); + + await withExcalidrawDimensions( + { width: 1920, height: 1080 }, + async () => { + await assertSidebarDockButton(false); + }, + ); + + mock.mockRestore(); + }); + }); + + describe("Sidebar.tab", () => { + it("should toggle sidebars tabs correctly", async () => { + const { container } = await render( + + + + Library + Comments + + + , + ); + + await withExcalidrawDimensions( + { width: 1920, height: 1080 }, + async () => { + expect( + container.querySelector( + "[role=tabpanel][data-testid=library]", + ), + ).toBeNull(); + + // open library sidebar + expect(await toggleSidebar({ name: "custom", tab: "library" })).toBe( + true, + ); + expect( + container.querySelector( + "[role=tabpanel][data-testid=library]", + ), + ).not.toBeNull(); + + // switch to comments tab + expect(await toggleSidebar({ name: "custom", tab: "comments" })).toBe( + true, + ); + expect( + container.querySelector( + "[role=tabpanel][data-testid=comments]", + ), + ).not.toBeNull(); + + // toggle sidebar closed + expect(await toggleSidebar({ name: "custom", tab: "comments" })).toBe( + false, + ); + expect( + container.querySelector( + "[role=tabpanel][data-testid=comments]", + ), + ).toBeNull(); + + // toggle sidebar open + expect(await toggleSidebar({ name: "custom", tab: "comments" })).toBe( + true, + ); + expect( + container.querySelector( + "[role=tabpanel][data-testid=comments]", + ), + ).not.toBeNull(); + }, + ); + }); + }); +}); -- cgit v1.2.3