fix: prevent auto-approve menu overflow with scrollable container

- Add max-h-[400px] and overflow-y-auto Tailwind classes to expanded content
- Ensures menu remains usable when all 10 toggles are displayed
- Add tests to verify overflow behavior
This commit is contained in:
Daniel Riccio 2025-07-10 13:53:12 -05:00
parent 6fa918c275
commit 1c29772d8f
No known key found for this signature in database
GPG key ID: FFD5FD825F8E8209
2 changed files with 134 additions and 1 deletions

View file

@ -0,0 +1,133 @@
import { render, screen, fireEvent } from "@/utils/test-utils"
import { describe, it, expect, vi, beforeEach } from "vitest"
import AutoApproveMenu from "../components/chat/AutoApproveMenu"
// Mock vscode API
vi.mock("@src/utils/vscode", () => ({
vscode: {
postMessage: vi.fn(),
},
}))
// Mock window.postMessage
const mockPostMessage = vi.fn()
window.postMessage = mockPostMessage
// Mock useExtensionState
const mockUseExtensionState = vi.fn()
vi.mock("@src/context/ExtensionStateContext", () => ({
useExtensionState: () => mockUseExtensionState(),
ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}))
// Mock translation hook
vi.mock("@src/i18n/TranslationContext", () => ({
useAppTranslation: () => ({
t: (key: string) => key,
}),
}))
const createMockExtensionState = (overrides = {}) => ({
autoApprovalEnabled: false,
setAutoApprovalEnabled: vi.fn(),
alwaysAllowReadOnly: false,
alwaysAllowWrite: false,
alwaysAllowExecute: false,
alwaysAllowBrowser: false,
alwaysAllowMcp: false,
alwaysAllowModeSwitch: false,
alwaysAllowSubtasks: false,
alwaysApproveResubmit: false,
alwaysAllowFollowupQuestions: false,
alwaysAllowUpdateTodoList: false,
allowedMaxRequests: undefined,
setAlwaysAllowReadOnly: vi.fn(),
setAlwaysAllowWrite: vi.fn(),
setAlwaysAllowExecute: vi.fn(),
setAlwaysAllowBrowser: vi.fn(),
setAlwaysAllowMcp: vi.fn(),
setAlwaysAllowModeSwitch: vi.fn(),
setAlwaysAllowSubtasks: vi.fn(),
setAlwaysApproveResubmit: vi.fn(),
setAlwaysAllowFollowupQuestions: vi.fn(),
setAlwaysAllowUpdateTodoList: vi.fn(),
setAllowedMaxRequests: vi.fn(),
...overrides,
})
describe("AutoApproveMenu", () => {
beforeEach(() => {
vi.clearAllMocks()
mockUseExtensionState.mockReturnValue(createMockExtensionState())
})
it("renders without crashing", () => {
render(<AutoApproveMenu />)
expect(screen.getByText("chat:autoApprove.title")).toBeInTheDocument()
})
it("expands when clicked", () => {
render(<AutoApproveMenu />)
// Initially, the expanded content should not be visible
const expandedContainer = document.querySelector(".flex.flex-col.gap-2.max-h-\\[400px\\].overflow-y-auto")
expect(expandedContainer).not.toBeInTheDocument()
// Click to expand
const titleArea = screen.getByText("chat:autoApprove.title").parentElement?.parentElement
fireEvent.click(titleArea!)
// Now the expanded content should be visible
const expandedContent = document.querySelector(".flex.flex-col.gap-2.max-h-\\[400px\\].overflow-y-auto")
expect(expandedContent).toBeInTheDocument()
})
it("expanded content has max-height and overflow-y auto to prevent overflow", () => {
render(<AutoApproveMenu />)
// Click to expand
const titleArea = screen.getByText("chat:autoApprove.title").parentElement?.parentElement
fireEvent.click(titleArea!)
// Find the expanded content container
const expandedContent = document.querySelector(".flex.flex-col.gap-2.max-h-\\[400px\\].overflow-y-auto")
// Check that it exists and has the correct classes
expect(expandedContent).toBeInTheDocument()
expect(expandedContent).toHaveClass("max-h-[400px]", "overflow-y-auto")
})
it("collapses when clicked again", () => {
render(<AutoApproveMenu />)
// Click to expand
const titleArea = screen.getByText("chat:autoApprove.title").parentElement?.parentElement
fireEvent.click(titleArea!)
// Verify expanded
const expandedContent = document.querySelector(".flex.flex-col.gap-2.max-h-\\[400px\\].overflow-y-auto")
expect(expandedContent).toBeInTheDocument()
// Click to collapse
fireEvent.click(titleArea!)
// Verify collapsed
const collapsedContent = document.querySelector(".flex.flex-col.gap-2.max-h-\\[400px\\].overflow-y-auto")
expect(collapsedContent).not.toBeInTheDocument()
})
it("displays enabled actions list when toggles are enabled", () => {
mockUseExtensionState.mockReturnValue(
createMockExtensionState({
alwaysAllowReadOnly: true,
alwaysAllowWrite: true,
}),
)
render(<AutoApproveMenu />)
// Should show the enabled actions instead of "none"
expect(screen.queryByText("chat:autoApprove.none")).not.toBeInTheDocument()
})
})

View file

@ -201,7 +201,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
</div>
{isExpanded && (
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-2 max-h-[400px] overflow-y-auto">
<div
style={{
color: "var(--vscode-descriptionForeground)",