ba2c4e1914
The Workspace page's lane strip moves into the sidebar as a project tree: workspaces grouped by git repository (new GET /api/projects, cached in memory, POST /api/projects/refresh), untracked worktrees with Adopt, inline rename, drag/Alt+arrow ordering and a right-click row menu. The selected workspace is the URL's ?lane=, one shared lane list feeds the tree, the new bottom status bar and the page. The Changes panel gains an activity bar (Files / Changes / Sessions, with resume), and split panes get a header.
66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
/**
|
|
* @file Sidebar.theme.test.tsx
|
|
* @description Tests for the Sidebar's theme controls: the expanded panel's Dark / Light / System buttons and the collapsed one-click toggle, both writing through useTheme.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { MemoryRouter } from "react-router-dom";
|
|
import { Sidebar } from "../Sidebar";
|
|
|
|
function renderSidebar(collapsed = false) {
|
|
return render(
|
|
<MemoryRouter>
|
|
<Sidebar
|
|
wsConnected
|
|
collapsed={collapsed}
|
|
onToggle={() => {}}
|
|
connectionOpen={false}
|
|
onConnectionOpenChange={() => {}}
|
|
/>
|
|
</MemoryRouter>
|
|
);
|
|
}
|
|
|
|
describe("Sidebar theme controls", () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
document.documentElement.classList.remove("dark");
|
|
});
|
|
|
|
it("expanded panel offers Dark, Light and System with Dark pressed by default", () => {
|
|
renderSidebar();
|
|
expect(screen.getByRole("button", { name: "Dark" })).toHaveAttribute("aria-pressed", "true");
|
|
expect(screen.getByRole("button", { name: "Light" })).toHaveAttribute("aria-pressed", "false");
|
|
expect(screen.getByRole("button", { name: "System" })).toHaveAttribute("aria-pressed", "false");
|
|
});
|
|
|
|
it("clicking System sets the mode and presses only System", async () => {
|
|
const user = userEvent.setup();
|
|
renderSidebar();
|
|
await user.click(screen.getByRole("button", { name: "System" }));
|
|
expect(localStorage.getItem("theme")).toBe("system");
|
|
expect(screen.getByRole("button", { name: "System" })).toHaveAttribute("aria-pressed", "true");
|
|
expect(screen.getByRole("button", { name: "Dark" })).toHaveAttribute("aria-pressed", "false");
|
|
});
|
|
|
|
it("clicking Light applies light mode to <html>", async () => {
|
|
const user = userEvent.setup();
|
|
renderSidebar();
|
|
await user.click(screen.getByRole("button", { name: "Light" }));
|
|
expect(localStorage.getItem("theme")).toBe("light");
|
|
expect(document.documentElement.classList.contains("dark")).toBe(false);
|
|
});
|
|
|
|
it("collapsed toggle flips to the opposite of the resolved mode", async () => {
|
|
const user = userEvent.setup();
|
|
localStorage.setItem("theme", "light");
|
|
renderSidebar(true);
|
|
await user.click(screen.getByRole("button", { name: "Switch to Dark" }));
|
|
expect(localStorage.getItem("theme")).toBe("dark");
|
|
expect(screen.getByRole("button", { name: "Switch to Light" })).toBeInTheDocument();
|
|
});
|
|
});
|