import { render, screen, fireEvent, cleanup } from "@testing-library/react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { TerminalSessionTabs, type TerminalSessionInfo, } from "./terminal-session-tabs"; const mockSessions: TerminalSessionInfo[] = [ { id: "s1", name: "Session 1", status: "connected" }, { id: "s2", name: "Session 2", status: "connecting" }, { id: "s3", name: "Session 3", status: "disconnected" }, ]; afterEach(() => { cleanup(); }); describe("TerminalSessionTabs", () => { it("renders all tabs", () => { render( ); expect(screen.getByText("Session 1")).toBeInTheDocument(); expect(screen.getByText("Session 2")).toBeInTheDocument(); expect(screen.getByText("Session 3")).toBeInTheDocument(); expect(screen.getByRole("button", { name: /new session/i })).toBeInTheDocument(); }); it("clicking a tab calls onSelect", () => { const onSelect = vi.fn(); render( ); fireEvent.click(screen.getAllByText("Session 2")[0]); expect(onSelect).toHaveBeenCalledWith("s2"); }); it("close button calls onClose after confirmation", () => { const onClose = vi.fn(); render( ); const closeButton = screen.getByLabelText("Close session Session 1"); // First click shows confirm fireEvent.click(closeButton); expect(screen.getByText("Close?")).toBeInTheDocument(); // Click confirm text fireEvent.click(screen.getByText("Close?")); expect(onClose).toHaveBeenCalledWith("s1"); }); it("double-click enables rename and Enter commits", () => { const onRename = vi.fn(); render( ); fireEvent.doubleClick(screen.getAllByText("Session 1")[0]); const input = screen.getByLabelText("Rename session"); expect(input).toBeInTheDocument(); fireEvent.change(input, { target: { value: "Renamed" } }); fireEvent.keyDown(input, { key: "Enter" }); expect(onRename).toHaveBeenCalledWith("s1", "Renamed"); }); it("double-click enables rename and Escape cancels", () => { const onRename = vi.fn(); render( ); fireEvent.doubleClick(screen.getAllByText("Session 1")[0]); const input = screen.getByLabelText("Rename session"); fireEvent.change(input, { target: { value: "Renamed" } }); fireEvent.keyDown(input, { key: "Escape" }); expect(onRename).not.toHaveBeenCalled(); expect(screen.getByText("Session 1")).toBeInTheDocument(); }); it("plus button is disabled at 5 sessions", () => { const fiveSessions: TerminalSessionInfo[] = Array.from({ length: 5 }, (_, i) => ({ id: `s${i + 1}`, name: `Session ${i + 1}`, status: "connected", })); render( ); const newButton = screen.getByRole("button", { name: /new session/i }); expect(newButton).toBeDisabled(); }); it("status dot reflects connection state", () => { render( ); const tabs = screen.getAllByRole("tab"); expect(tabs).toHaveLength(3); expect(tabs[0].querySelector(".connected")).toBeInTheDocument(); expect(tabs[1].querySelector(".connecting")).toBeInTheDocument(); expect(tabs[2].querySelector(".disconnected")).toBeInTheDocument(); }); });