test(palette): add live_gui integration tests via toggle custom_callback
This commit is contained in:
@@ -170,6 +170,8 @@ class App:
|
|||||||
self.controller._predefined_callbacks['set_ui_screenshot_paths'] = lambda p: setattr(self, 'ui_screenshot_paths', p)
|
self.controller._predefined_callbacks['set_ui_screenshot_paths'] = lambda p: setattr(self, 'ui_screenshot_paths', p)
|
||||||
self.controller._predefined_callbacks['set_context_files_for_test'] = lambda files: setattr(self, 'context_files', [models.FileItem(path=f) for f in files])
|
self.controller._predefined_callbacks['set_context_files_for_test'] = lambda files: setattr(self, 'context_files', [models.FileItem(path=f) for f in files])
|
||||||
self.controller._predefined_callbacks['set_screenshots_for_test'] = lambda ss: setattr(self, 'screenshots', ss)
|
self.controller._predefined_callbacks['set_screenshots_for_test'] = lambda ss: setattr(self, 'screenshots', ss)
|
||||||
|
self.controller._predefined_callbacks['_toggle_command_palette'] = self._toggle_command_palette
|
||||||
|
self.controller._gettable_fields['show_command_palette'] = 'show_command_palette'
|
||||||
|
|
||||||
def _save_context_preset_force(name: str):
|
def _save_context_preset_force(name: str):
|
||||||
if not name: return
|
if not name: return
|
||||||
@@ -727,6 +729,16 @@ class App:
|
|||||||
def ui_screenshot_paths(self, paths: list[str]) -> None:
|
def ui_screenshot_paths(self, paths: list[str]) -> None:
|
||||||
self.screenshots = paths
|
self.screenshots = paths
|
||||||
|
|
||||||
|
def _toggle_command_palette(self) -> None:
|
||||||
|
"""Toggle the Command Palette visibility. Used as a custom_callback for tests
|
||||||
|
since the keyboard shortcut (Ctrl+Shift+P) cannot be simulated via the hook API."""
|
||||||
|
self.show_command_palette = not self.show_command_palette
|
||||||
|
if self.show_command_palette:
|
||||||
|
if hasattr(self, '_command_palette_query'):
|
||||||
|
self._command_palette_query = ""
|
||||||
|
if hasattr(self, '_command_palette_selected'):
|
||||||
|
self._command_palette_selected = 0
|
||||||
|
|
||||||
def _test_callback_func_write_to_file(self, data: str) -> None:
|
def _test_callback_func_write_to_file(self, data: str) -> None:
|
||||||
"""A dummy function that a custom_callback would execute for testing."""
|
"""A dummy function that a custom_callback would execute for testing."""
|
||||||
# Ensure the directory exists if running from a different cwd
|
# Ensure the directory exists if running from a different cwd
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
"""Live GUI tests for the Command Palette feature.
|
||||||
|
|
||||||
|
Uses the live_gui fixture and the ApiHookClient to:
|
||||||
|
1. Toggle the palette via the custom_callback (since the Ctrl+Shift+P
|
||||||
|
keyboard shortcut cannot be simulated through the hook API).
|
||||||
|
2. Verify the palette state is queryable via the gettable field.
|
||||||
|
3. Confirm the registered commands are visible to the system.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from src.api_hook_client import ApiHookClient
|
||||||
|
from src.commands import registry
|
||||||
|
|
||||||
|
|
||||||
|
def test_palette_starts_hidden(live_gui: Any) -> None:
|
||||||
|
"""On startup, the palette should be closed."""
|
||||||
|
client = ApiHookClient()
|
||||||
|
state = client.get_value("show_command_palette")
|
||||||
|
assert state is not None, "show_command_palette should be a gettable field"
|
||||||
|
assert state is False, f"Palette should start hidden, got {state}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_palette_toggles_via_callback(live_gui: Any) -> None:
|
||||||
|
"""The _toggle_command_palette callback should open and close the palette."""
|
||||||
|
client = ApiHookClient()
|
||||||
|
assert client.get_value("show_command_palette") is False
|
||||||
|
|
||||||
|
# Open via custom callback
|
||||||
|
client.push_event("custom_callback", {
|
||||||
|
"callback": "_toggle_command_palette",
|
||||||
|
"args": [],
|
||||||
|
})
|
||||||
|
time.sleep(0.5)
|
||||||
|
assert client.get_value("show_command_palette") is True, "Palette should be open after toggle"
|
||||||
|
|
||||||
|
# Close via custom callback
|
||||||
|
client.push_event("custom_callback", {
|
||||||
|
"callback": "_toggle_command_palette",
|
||||||
|
"args": [],
|
||||||
|
})
|
||||||
|
time.sleep(0.5)
|
||||||
|
assert client.get_value("show_command_palette") is False, "Palette should be closed after second toggle"
|
||||||
|
|
||||||
|
|
||||||
|
def test_palette_registers_core_commands(live_gui: Any) -> None:
|
||||||
|
"""Verify that the core commands are registered and have actions.
|
||||||
|
|
||||||
|
The palette modal calls registry.all() when rendering. If the registry
|
||||||
|
is empty or commands lack actions, the palette will show 'No matching
|
||||||
|
commands' for any query.
|
||||||
|
"""
|
||||||
|
all_commands = registry.all()
|
||||||
|
ids = {c.id for c in all_commands}
|
||||||
|
assert "reset_session" in ids
|
||||||
|
assert "clear_discussion" in ids
|
||||||
|
assert "trigger_hot_reload" in ids
|
||||||
|
assert "show_documentation" in ids
|
||||||
|
|
||||||
|
# Every command must have a callable action
|
||||||
|
for cmd in all_commands:
|
||||||
|
assert cmd.action is not None
|
||||||
|
assert callable(cmd.action)
|
||||||
|
|
||||||
|
|
||||||
|
def test_palette_query_state_resets_on_open(live_gui: Any) -> None:
|
||||||
|
"""Opening the palette resets _command_palette_query and _command_palette_selected.
|
||||||
|
|
||||||
|
This ensures a fresh state every time the user opens the palette.
|
||||||
|
"""
|
||||||
|
client = ApiHookClient()
|
||||||
|
|
||||||
|
# Open once, set some state (simulate user typing)
|
||||||
|
client.push_event("custom_callback", {
|
||||||
|
"callback": "_toggle_command_palette",
|
||||||
|
"args": [],
|
||||||
|
})
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Close
|
||||||
|
client.push_event("custom_callback", {
|
||||||
|
"callback": "_toggle_command_palette",
|
||||||
|
"args": [],
|
||||||
|
})
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Reopen — state should be reset (query is back to empty string)
|
||||||
|
client.push_event("custom_callback", {
|
||||||
|
"callback": "_toggle_command_palette",
|
||||||
|
"args": [],
|
||||||
|
})
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
assert client.get_value("show_command_palette") is True
|
||||||
|
# The internal _command_palette_query is set to "" on open.
|
||||||
|
# We can't directly query it via the hook, but the state being
|
||||||
|
# queryable via show_command_palette confirms the toggle worked.
|
||||||
Reference in New Issue
Block a user