import { beforeEach, describe, expect, it, vi } from 'vitest' import { ref } from 'vue' const { mockTerminal, MockTerminal, mockFitAddon, MockFitAddon } = vi.hoisted( () => { const mockTerminal = { loadAddon: vi.fn(), attachCustomKeyEventHandler: vi.fn(), open: vi.fn(), dispose: vi.fn(), hasSelection: vi.fn<[], boolean>(), resize: vi.fn(), cols: 80, rows: 24 } const MockTerminal = vi.fn(function () { return mockTerminal }) const mockFitAddon = { proposeDimensions: vi.fn().mockReturnValue({ cols: 80, rows: 24 }) } const MockFitAddon = vi.fn(function () { return mockFitAddon }) return { mockTerminal, MockTerminal, mockFitAddon, MockFitAddon } } ) vi.mock('@xterm/xterm', () => ({ Terminal: MockTerminal })) vi.mock('@xterm/addon-fit', () => ({ FitAddon: MockFitAddon })) vi.mock('@xterm/xterm/css/xterm.css', () => ({})) import { withSetup } from '@/test/withSetup' import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal' function getKeyHandler(): (event: KeyboardEvent) => boolean { return mockTerminal.attachCustomKeyEventHandler.mock.calls[0][0] } describe('useTerminal key event handler', () => { beforeEach(() => { vi.clearAllMocks() mockTerminal.hasSelection.mockReturnValue(false) const element = ref(undefined) withSetup(() => useTerminal(element)) }) it('allows browser to handle copy when text is selected (Ctrl+C)', () => { mockTerminal.hasSelection.mockReturnValue(true) const event = { type: 'keydown', ctrlKey: true, metaKey: false, key: 'c' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(false) }) it('allows browser to handle copy when text is selected (Meta+C)', () => { mockTerminal.hasSelection.mockReturnValue(true) const event = { type: 'keydown', ctrlKey: false, metaKey: true, key: 'c' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(false) }) it('does not pass copy to browser when no text is selected', () => { mockTerminal.hasSelection.mockReturnValue(false) const event = { type: 'keydown', ctrlKey: true, metaKey: false, key: 'c' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(true) }) it('allows browser to handle paste (Ctrl+V)', () => { const event = { type: 'keydown', ctrlKey: true, metaKey: false, key: 'v' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(false) }) it('allows browser to handle paste (Meta+V)', () => { const event = { type: 'keydown', ctrlKey: false, metaKey: true, key: 'v' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(false) }) it('does not intercept non-keydown events', () => { mockTerminal.hasSelection.mockReturnValue(true) const event = { type: 'keyup', ctrlKey: true, metaKey: false, key: 'c' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(true) }) it('passes through unrelated key combinations', () => { const event = { type: 'keydown', ctrlKey: false, metaKey: false, key: 'Enter' } as KeyboardEvent expect(getKeyHandler()(event)).toBe(true) }) })