// @ts-nocheck import type { HotkeyRegistrationView, SequenceRegistrationView } from '@tanstack/react-hotkeys' import { screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' import { ShortcutsReferenceSheet } from './ShortcutsReferenceSheet' import { SHORTCUT_DEFINITIONS, SHORTCUT_IDS, type ShortcutId } from '@/state/shortcuts/registry' import type { ShortcutHotkeyMeta } from '@/state/shortcuts/useShortcut' import { customRender } from '@/tests/lib/custom-render' const { mockUseHotkeyRegistrations } = vi.hoisted(() => ({ mockUseHotkeyRegistrations: vi.fn<() => { hotkeys: HotkeyRegistrationView[]; sequences: SequenceRegistrationView[] }>(), })) vi.mock('@tanstack/react-hotkeys', async () => { const actual = await vi.importActual('@tanstack/react-hotkeys') return { ...actual, useHotkeyRegistrations: mockUseHotkeyRegistrations, } }) const ACTIVE_SHORTCUT_IDS = [ SHORTCUT_IDS.COMMAND_MENU_OPEN, SHORTCUT_IDS.NAV_HOME, ] satisfies ShortcutId[] const ACTIVE_DATABASE_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.NAV_DATABASE_TABLES, ] satisfies ShortcutId[] const ACTIVE_AUTH_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.NAV_AUTH_USERS, ] satisfies ShortcutId[] const ACTIVE_FUNCTION_DETAIL_NAV_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.NAV_FUNCTION_DETAIL_OVERVIEW, ] satisfies ShortcutId[] const ACTIVE_REALTIME_NAV_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.NAV_REALTIME_INSPECTOR, ] satisfies ShortcutId[] const ACTIVE_REALTIME_INSPECTOR_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.INSPECTOR_JOIN_CHANNEL, SHORTCUT_IDS.INSPECTOR_TOGGLE_LISTENING, SHORTCUT_IDS.INSPECTOR_BROADCAST, SHORTCUT_IDS.INSPECTOR_COPY_MESSAGE, ] satisfies ShortcutId[] const ACTIVE_SURFACE_SHORTCUT_IDS = [ ...ACTIVE_SHORTCUT_IDS, SHORTCUT_IDS.AUTH_USERS_REFRESH, SHORTCUT_IDS.FUNCTION_DETAIL_OPEN_TEST, SHORTCUT_IDS.FUNCTION_OVERVIEW_INTERVAL_15MIN, SHORTCUT_IDS.FUNCTIONS_LIST_REFRESH, SHORTCUT_IDS.LOGS_PREVIEW_REFRESH, SHORTCUT_IDS.SQL_EDITOR_FORMAT, SHORTCUT_IDS.STORAGE_BUCKETS_REFRESH, SHORTCUT_IDS.STORAGE_EXPLORER_REFRESH, ] satisfies ShortcutId[] let sequenceIdCounter = 0 const buildSequenceRegistration = (id: ShortcutId): SequenceRegistrationView => { const definition = SHORTCUT_DEFINITIONS[id] const meta: ShortcutHotkeyMeta = { id: definition.id, name: definition.label, referenceGroup: definition.referenceGroup, } return { id: `sequence_${++sequenceIdCounter}`, sequence: definition.sequence, options: { enabled: true, meta, }, target: document, triggerCount: 0, hasFired: false, matchedStepCount: 0, partialMatchLastKeyTime: 0, } } const seedRegistrations = (ids: ShortcutId[]) => { mockUseHotkeyRegistrations.mockReturnValue({ hotkeys: [], sequences: ids.map(buildSequenceRegistration), }) } const renderShortcutsReferenceSheet = (ids: ShortcutId[] = ACTIVE_SHORTCUT_IDS) => { seedRegistrations(ids) const onOpenChange = vi.fn() customRender() return { onOpenChange } } describe('ShortcutsReferenceSheet', () => { beforeEach(() => { sequenceIdCounter = 0 mockUseHotkeyRegistrations.mockReset() mockUseHotkeyRegistrations.mockReturnValue({ hotkeys: [], sequences: [] }) }) it('renders the grouped shortcut list by default', async () => { renderShortcutsReferenceSheet() expect(await screen.findByText('Keyboard shortcuts')).toBeInTheDocument() expect(screen.getByLabelText('Search shortcuts')).toBeInTheDocument() expect(screen.getByText('Command Menu')).toBeInTheDocument() expect(screen.getByText('Navigation')).toBeInTheDocument() expect(screen.queryByText('Global Navigation')).not.toBeInTheDocument() expect(screen.queryByText('Database Navigation')).not.toBeInTheDocument() expect(screen.getByText('Open command menu')).toBeInTheDocument() expect(screen.getByText('Go to Project Overview')).toBeInTheDocument() }) it('shows only active shortcuts in a group when the group label matches the search', async () => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), 'navigation') expect(screen.getByText('Navigation')).toBeInTheDocument() expect(screen.getByText('Go to Project Overview')).toBeInTheDocument() expect(screen.queryByText('Command Menu')).not.toBeInTheDocument() expect(screen.queryByText('Go to Database')).not.toBeInTheDocument() }) it('keeps the parent group header when only an item label matches', async () => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), 'Go to Project Overview') expect(screen.getByText('Navigation')).toBeInTheDocument() expect(screen.getByText('Go to Project Overview')).toBeInTheDocument() expect(screen.queryByText('Open command menu')).not.toBeInTheDocument() expect(screen.queryByText('Command Menu')).not.toBeInTheDocument() }) it('shows the database navigation section when database shortcuts are active', async () => { renderShortcutsReferenceSheet(ACTIVE_DATABASE_SHORTCUT_IDS) expect(await screen.findByText('Global Navigation')).toBeInTheDocument() expect(screen.getByText('Database Navigation')).toBeInTheDocument() expect(screen.queryByText(/^Navigation$/)).not.toBeInTheDocument() expect(screen.getByText('Go to Tables')).toBeInTheDocument() }) it('shows the auth navigation section when auth shortcuts are active', async () => { renderShortcutsReferenceSheet(ACTIVE_AUTH_SHORTCUT_IDS) expect(await screen.findByText('Global Navigation')).toBeInTheDocument() expect(screen.getByText('Auth Navigation')).toBeInTheDocument() expect(screen.queryByText(/^Navigation$/)).not.toBeInTheDocument() expect(screen.getByText('Go to Users')).toBeInTheDocument() }) it('shows the edge function tabs section when function tab shortcuts are active', async () => { renderShortcutsReferenceSheet(ACTIVE_FUNCTION_DETAIL_NAV_SHORTCUT_IDS) expect(await screen.findByText('Global Navigation')).toBeInTheDocument() expect(screen.getByText('Edge Function Tabs')).toBeInTheDocument() expect(screen.queryByText('Edge Function Page Navigation')).not.toBeInTheDocument() expect(screen.getByText('Go to Overview')).toBeInTheDocument() }) it('shows the realtime navigation section when realtime shortcuts are active', async () => { renderShortcutsReferenceSheet(ACTIVE_REALTIME_NAV_SHORTCUT_IDS) expect(await screen.findByText('Global Navigation')).toBeInTheDocument() expect(screen.getByText('Realtime Navigation')).toBeInTheDocument() expect(screen.getByText('Go to Inspector')).toBeInTheDocument() }) it('uses human labels for realtime inspector shortcut groups', async () => { renderShortcutsReferenceSheet(ACTIVE_REALTIME_INSPECTOR_SHORTCUT_IDS) expect(await screen.findByText('Realtime Inspector')).toBeInTheDocument() expect(screen.getByText('Join a channel')).toBeInTheDocument() expect(screen.getByText('Start/Stop listening')).toBeInTheDocument() expect(screen.getByText('Broadcast a message')).toBeInTheDocument() expect(screen.getByText('Copy selected message')).toBeInTheDocument() expect(screen.queryByText('realtime-inspector')).not.toBeInTheDocument() }) it('uses human labels for active surface shortcut groups', async () => { renderShortcutsReferenceSheet(ACTIVE_SURFACE_SHORTCUT_IDS) expect(await screen.findByText('Auth Users')).toBeInTheDocument() expect(screen.getByText('Edge Function Actions')).toBeInTheDocument() expect(screen.getByText('Edge Function Overview')).toBeInTheDocument() expect(screen.getByText('Edge Functions')).toBeInTheDocument() expect(screen.getByText('Logs Explorer')).toBeInTheDocument() expect(screen.getByText('SQL Editor')).toBeInTheDocument() expect(screen.getByText('Storage Buckets')).toBeInTheDocument() expect(screen.getByText('Storage File Explorer')).toBeInTheDocument() expect(screen.queryByText('auth-users')).not.toBeInTheDocument() expect(screen.queryByText('functions-detail')).not.toBeInTheDocument() expect(screen.queryByText('functions-list')).not.toBeInTheDocument() expect(screen.queryByText('functions-overview')).not.toBeInTheDocument() expect(screen.queryByText('logs-preview')).not.toBeInTheDocument() expect(screen.queryByText('sql-editor')).not.toBeInTheDocument() expect(screen.queryByText('storage-buckets')).not.toBeInTheDocument() expect(screen.queryByText('storage-explorer')).not.toBeInTheDocument() }) it('does not show inactive database shortcuts in search results', async () => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), 'Go to Tables') expect(screen.getByText('No matching shortcuts found')).toBeInTheDocument() expect(screen.queryByText('Database Navigation')).not.toBeInTheDocument() }) it('hides shortcuts whose registration is soft-disabled', async () => { sequenceIdCounter = 0 const enabled = buildSequenceRegistration(SHORTCUT_IDS.COMMAND_MENU_OPEN) const disabled = buildSequenceRegistration(SHORTCUT_IDS.NAV_HOME) disabled.options = { ...disabled.options, enabled: false } mockUseHotkeyRegistrations.mockReturnValue({ hotkeys: [], sequences: [enabled, disabled], }) customRender() expect(await screen.findByText('Open command menu')).toBeInTheDocument() expect(screen.queryByText('Go to Project Overview')).not.toBeInTheDocument() }) it('shows a clear button when searching and resets the list when clicked', async () => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), 'navigation') expect(screen.getByRole('button', { name: 'Clear search' })).toBeInTheDocument() await user.click(screen.getByRole('button', { name: 'Clear search' })) expect(screen.getByLabelText('Search shortcuts')).toHaveValue('') expect(screen.getByText('Command Menu')).toBeInTheDocument() expect(screen.getByText('Navigation')).toBeInTheDocument() }) it.each(['⌘Esc', 'Mod+/'])('does not search shortcut values like %s', async (query) => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), query) expect(screen.getByText('No matching shortcuts found')).toBeInTheDocument() expect(screen.queryByText('Navigation')).not.toBeInTheDocument() }) it('shows an empty state when nothing matches', async () => { const user = userEvent.setup() renderShortcutsReferenceSheet() await user.type(screen.getByLabelText('Search shortcuts'), 'totally missing') expect(screen.getByText('No matching shortcuts found')).toBeInTheDocument() }) })