From 1dab226bcc836969387241059b527362af52fa59 Mon Sep 17 00:00:00 2001 From: Lawrence Chen Date: Mon, 30 Mar 2026 18:38:39 -0700 Subject: [PATCH] Add ctrl-k command palette regression tests --- .../AppDelegateShortcutRoutingTests.swift | 66 +++++++++++++++++++ .../ShortcutAndCommandPaletteTests.swift | 25 ++++--- .../test_command_palette_navigation_keys.py | 8 +-- 3 files changed, 82 insertions(+), 17 deletions(-) diff --git a/cmuxTests/AppDelegateShortcutRoutingTests.swift b/cmuxTests/AppDelegateShortcutRoutingTests.swift index 22497040..ff80c175 100644 --- a/cmuxTests/AppDelegateShortcutRoutingTests.swift +++ b/cmuxTests/AppDelegateShortcutRoutingTests.swift @@ -2445,6 +2445,72 @@ final class AppDelegateShortcutRoutingTests: XCTestCase { XCTAssertEqual(observedDelta, 1) } + func testControlKDoesNotRoutePaletteMoveSelectionWhenSearchFieldIsFocused() { + guard let appDelegate = AppDelegate.shared else { + XCTFail("Expected AppDelegate.shared") + return + } + + let windowId = appDelegate.createMainWindow() + defer { + closeWindow(withId: windowId) + } + + guard let window = window(withId: windowId), + let contentView = window.contentView else { + XCTFail("Expected test window") + return + } + + let overlayContainer = NSView(frame: contentView.bounds) + overlayContainer.identifier = commandPaletteOverlayContainerIdentifier + overlayContainer.alphaValue = 1 + overlayContainer.isHidden = false + contentView.addSubview(overlayContainer) + + let fieldEditor = CommandPaletteMarkedTextFieldEditor(frame: NSRect(x: 0, y: 0, width: 200, height: 24)) + fieldEditor.isFieldEditor = true + overlayContainer.addSubview(fieldEditor) + XCTAssertTrue(window.makeFirstResponder(fieldEditor)) + + appDelegate.setCommandPaletteVisible(false, for: window) + defer { + overlayContainer.removeFromSuperview() + fieldEditor.removeFromSuperview() + } + + let moveExpectation = expectation( + description: "Ctrl+K should not be rerouted as command palette move-selection" + ) + moveExpectation.isInverted = true + let moveToken = NotificationCenter.default.addObserver( + forName: .commandPaletteMoveSelection, + object: nil, + queue: nil + ) { _ in + moveExpectation.fulfill() + } + defer { NotificationCenter.default.removeObserver(moveToken) } + + guard let controlKEvent = makeKeyDownEvent( + key: "\u{0b}", + modifiers: [.control], + keyCode: 40, + windowNumber: window.windowNumber + ) else { + XCTFail("Failed to construct Ctrl+K event") + return + } + +#if DEBUG + XCTAssertFalse(appDelegate.debugHandleCustomShortcut(event: controlKEvent)) +#else + XCTFail("debugHandleCustomShortcut is only available in DEBUG") +#endif + + wait(for: [moveExpectation], timeout: 0.2) + } + func testEscapeDismissesCommandPaletteWhenVisibilityStateStaysStalePastInitialPendingWindow() { guard let appDelegate = AppDelegate.shared else { XCTFail("Expected AppDelegate.shared") diff --git a/cmuxTests/ShortcutAndCommandPaletteTests.swift b/cmuxTests/ShortcutAndCommandPaletteTests.swift index 05e62cee..6fbdf863 100644 --- a/cmuxTests/ShortcutAndCommandPaletteTests.swift +++ b/cmuxTests/ShortcutAndCommandPaletteTests.swift @@ -213,7 +213,7 @@ final class CommandPaletteKeyboardNavigationTests: XCTestCase { ) } - func testControlLetterNavigationSupportsPrintableAndControlChars() { + func testControlLetterNavigationSupportsPrintableAndControlCharsForNPOnly() { XCTAssertEqual( commandPaletteSelectionDeltaForKeyboardNavigation( flags: [.control], @@ -246,37 +246,36 @@ final class CommandPaletteKeyboardNavigationTests: XCTestCase { ), -1 ) - XCTAssertEqual( + } + + func testDoesNotTreatControlJKAsPaletteNavigation() { + XCTAssertNil( commandPaletteSelectionDeltaForKeyboardNavigation( flags: [.control], chars: "j", keyCode: 38 - ), - 1 + ) ) - XCTAssertEqual( + XCTAssertNil( commandPaletteSelectionDeltaForKeyboardNavigation( flags: [.control], chars: "\u{0a}", keyCode: 38 - ), - 1 + ) ) - XCTAssertEqual( + XCTAssertNil( commandPaletteSelectionDeltaForKeyboardNavigation( flags: [.control], chars: "k", keyCode: 40 - ), - -1 + ) ) - XCTAssertEqual( + XCTAssertNil( commandPaletteSelectionDeltaForKeyboardNavigation( flags: [.control], chars: "\u{0b}", keyCode: 40 - ), - -1 + ) ) } diff --git a/tests_v2/test_command_palette_navigation_keys.py b/tests_v2/test_command_palette_navigation_keys.py index 6a3d4b2a..0bd64113 100644 --- a/tests_v2/test_command_palette_navigation_keys.py +++ b/tests_v2/test_command_palette_navigation_keys.py @@ -3,8 +3,8 @@ Regression test: command palette list navigation keys. Validates: -- Down: ArrowDown, Ctrl+N, Ctrl+J -- Up: ArrowUp, Ctrl+P, Ctrl+K +- Down: ArrowDown, Ctrl+N +- Up: ArrowUp, Ctrl+P """ import os @@ -125,10 +125,10 @@ def main() -> int: message="no focused surface available for command palette context", ) - for combo in ("down", "ctrl+n", "ctrl+j"): + for combo in ("down", "ctrl+n"): _assert_move(client, window_id, combo, start_index=0, expected_index=1) - for combo in ("up", "ctrl+p", "ctrl+k"): + for combo in ("up", "ctrl+p"): _assert_move(client, window_id, combo, start_index=1, expected_index=0) _assert_can_navigate_past_ten_results(client, window_id)