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(); }, ); }); }); });