diff --git a/apps/web/components/task/changes-panel-file-row.test.tsx b/apps/web/components/task/changes-panel-file-row.test.tsx index 6fc288717e..99d1c42086 100644 --- a/apps/web/components/task/changes-panel-file-row.test.tsx +++ b/apps/web/components/task/changes-panel-file-row.test.tsx @@ -1,18 +1,22 @@ import { afterEach, describe, it, expect, vi } from "vitest"; -import { render, fireEvent } from "@testing-library/react"; +import { cleanup, render, fireEvent } from "@testing-library/react"; import { TooltipProvider } from "@kandev/ui/tooltip"; import { FileRow } from "./changes-panel-file-row"; -const responsive = vi.hoisted(() => ({ isFinePointer: true })); +const responsive = vi.hoisted(() => ({ isFinePointer: true, isMobile: false })); vi.mock("@/hooks/use-responsive-breakpoint", () => ({ useResponsiveBreakpoint: () => responsive, })); afterEach(() => { + cleanup(); responsive.isFinePointer = true; + responsive.isMobile = false; }); +const moreActionsLabel = "Show more actions"; + const noop = () => {}; const noopSelect = () => false; @@ -233,21 +237,24 @@ describe("FileRow hover swap (stats <-> actions occupy same cell)", () => { expect(gridWrapper.className).toContain("row-start-1"); }); - it("hides statistics behind always-visible actions for coarse pointers", () => { + it("keeps statistics in the identity and exposes one menu for coarse pointers", () => { responsive.isFinePointer = false; - const { container } = renderRow("file.go"); - const li = container.querySelector("li") as HTMLElement; - const gridWrapper = li.children[1] as HTMLElement; - const statsLayer = gridWrapper.children[0] as HTMLElement; - const actionsLayer = gridWrapper.children[1] as HTMLElement; - - expect(statsLayer.className.split(/\s+/)).toContain("opacity-0"); - expect(actionsLayer.className.split(/\s+/)).toContain("opacity-100"); + const { getByTitle, getByRole, queryByTitle } = renderRow("file.go"); + expect(getByTitle("file.go").textContent).toContain("+18"); + expect(getByRole("button", { name: moreActionsLabel })).not.toBeNull(); + expect(queryByTitle("Stage file")).toBeNull(); }); - it("keeps the pending spinner inside a touch-sized target for coarse pointers", () => { + it("uses the touch menu on a phone even with a fine pointer", () => { + responsive.isMobile = true; + const { getByRole, queryByTitle } = renderRow("file.go"); + expect(getByRole("button", { name: moreActionsLabel })).not.toBeNull(); + expect(queryByTitle("Stage file")).toBeNull(); + }); + + it("keeps pending feedback in the identity and disables staging in the menu", async () => { responsive.isFinePointer = false; - const { container } = render( + const { container, getByTitle, getByRole, findByRole } = render(