From b577b9ad792eb6ae3f442cf7ab22ea0d55d7b0ca Mon Sep 17 00:00:00 2001 From: Ali Waseem Date: Mon, 6 Apr 2026 09:31:05 -0600 Subject: [PATCH] test(studio): add test to prevent per-cell context menu regression Asserts that only a single ContextMenu instance is mounted regardless of row count. This guards against the previous bug where each cell had its own Radix ContextMenu, causing thousands of document-level keydown listeners and freezing the browser. --- .../components/SQLEditor/Results.test.tsx | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 apps/studio/tests/components/SQLEditor/Results.test.tsx diff --git a/apps/studio/tests/components/SQLEditor/Results.test.tsx b/apps/studio/tests/components/SQLEditor/Results.test.tsx new file mode 100644 index 00000000000..4928cc8b66f --- /dev/null +++ b/apps/studio/tests/components/SQLEditor/Results.test.tsx @@ -0,0 +1,64 @@ +import { screen } from '@testing-library/react' +import Results from 'components/interfaces/SQLEditor/UtilityPanel/Results' +import { customRender as render } from 'tests/lib/custom-render' +import { expect, test, vi } from 'vitest' + +// Track how many times ContextMenu is mounted to detect per-cell instances +let contextMenuMountCount = 0 + +vi.mock('ui', async () => { + const actual = await vi.importActual('ui') + return { + ...actual, + ContextMenu_Shadcn_: (props: any) => { + contextMenuMountCount++ + return + }, + } +}) + +vi.mock('react-data-grid', () => ({ + default: ({ columns, rows }: any) => ( +
+
+ {columns.map((col: any, colIdx: number) => ( +
+ {col.renderHeaderCell ? col.renderHeaderCell({}) : col.name} +
+ ))} +
+ {rows.map((row: any, rowIdx: number) => ( +
+ {columns.map((col: any, colIdx: number) => ( +
+ {col.renderCell?.({ row, rowIdx, isCellSelected: false })} +
+ ))} +
+ ))} +
+ ), +})) + +function generateRows(count: number) { + return Array.from({ length: count }, (_, i) => ({ + id: i, + name: `row-${i}`, + })) +} + +test('renders a single context menu regardless of row count', () => { + contextMenuMountCount = 0 + const rows = generateRows(100) + render() + + // There should be exactly 1 ContextMenu instance (shared), not 1 per cell. + // Previously each cell rendered its own ContextMenu, causing thousands of + // document-level event listeners and freezing the browser on keystrokes. + expect(contextMenuMountCount).toBe(1) +}) + +test('shows empty state when no rows provided', () => { + render() + expect(screen.getByText('Success. No rows returned')).toBeTruthy() +})