diff --git a/packages/web/src/components/Dashboard.tsx b/packages/web/src/components/Dashboard.tsx index 4bbfa520f..cd36c63ee 100644 --- a/packages/web/src/components/Dashboard.tsx +++ b/packages/web/src/components/Dashboard.tsx @@ -169,6 +169,10 @@ function DashboardInner({ const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const isMobile = useMediaQuery(MOBILE_BREAKPOINT); + const debugParam = searchParams.get("debug"); + const showDebugBundleButton = + !isMobile && + (process.env.NODE_ENV === "development" || debugParam === "1" || debugParam === "true"); const showSidebar = projects.length >= 1; const { showToast } = useToast(); const [doneExpanded, setDoneExpanded] = useState(false); @@ -498,6 +502,7 @@ function DashboardInner({ {headerProjectLabel} ) : null} + {showDebugBundleButton ? : null}
{!allProjectsView && orchestratorHref ? ( @@ -549,7 +554,6 @@ function DashboardInner({ {isSpawningCurrentProject ? "Spawning..." : "Spawn Orchestrator"} ) : null} - {!isMobile ? : null}
diff --git a/packages/web/src/components/__tests__/Dashboard.debugBundleVisibility.test.tsx b/packages/web/src/components/__tests__/Dashboard.debugBundleVisibility.test.tsx new file mode 100644 index 000000000..216bd53e7 --- /dev/null +++ b/packages/web/src/components/__tests__/Dashboard.debugBundleVisibility.test.tsx @@ -0,0 +1,57 @@ +import { render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { Dashboard } from "../Dashboard"; + +let search = ""; + +vi.mock("next/navigation", () => ({ + useRouter: () => ({ push: vi.fn(), replace: vi.fn(), refresh: vi.fn() }), + usePathname: () => "/", + useSearchParams: () => new URLSearchParams(search), +})); + +function mockDesktopViewport() { + Object.defineProperty(window, "matchMedia", { + writable: true, + value: (query: string) => ({ + matches: !query.includes("max-width: 767px"), + media: query, + onchange: null, + addListener: () => {}, + removeListener: () => {}, + addEventListener: () => {}, + removeEventListener: () => {}, + dispatchEvent: () => false, + }), + }); +} + +describe("Dashboard debug bundle visibility", () => { + beforeEach(() => { + search = ""; + mockDesktopViewport(); + const eventSourceMock = { + onmessage: null, + onerror: null, + close: vi.fn(), + }; + const eventSourceConstructor = vi.fn(() => eventSourceMock as unknown as EventSource); + global.EventSource = Object.assign(eventSourceConstructor, { + CONNECTING: 0, + OPEN: 1, + CLOSED: 2, + }) as unknown as typeof EventSource; + global.fetch = vi.fn(); + }); + + it("hides debug bundle button by default", () => { + render(); + expect(screen.queryByRole("button", { name: /Copy debug bundle for issue reports/i })).toBeNull(); + }); + + it("shows debug bundle button when debug query flag is enabled", () => { + search = "debug=1"; + render(); + expect(screen.getByRole("button", { name: /Copy debug bundle for issue reports/i })).toBeInTheDocument(); + }); +});