diff --git a/features/steps/tui_settings_session_screens_steps.py b/features/steps/tui_settings_session_screens_steps.py index 48cb581e7..c9403ae79 100644 --- a/features/steps/tui_settings_session_screens_steps.py +++ b/features/steps/tui_settings_session_screens_steps.py @@ -2,6 +2,7 @@ from behave import given, then, when +from cleveragents.tui.commands import TuiCommandRouter from cleveragents.tui.screens.session_management import ( SessionInfo, SessionManagementScreen, @@ -110,8 +111,14 @@ def step_verify_settings_not_visible(context): @then("the selected_index should be {index:d}") def step_verify_selected_index(context, index): - """Verify the selected index.""" - assert context.settings_screen.selected_index == index + """Verify the selected index on whichever screen was created in this scenario.""" + screen = getattr(context, "session_screen", None) or getattr( + context, "settings_screen", None + ) + assert screen is not None, "no screen widget created in this scenario" + assert screen.selected_index == index, ( + f"expected selected_index={index}, got {screen.selected_index}" + ) # --------------------------------------------------------------------------- @@ -221,3 +228,51 @@ def step_verify_selected_session_none(context): """Verify get_selected_session returns None.""" session = context.session_screen.get_selected_session() assert session is None + + +@then( + 'get_settings should return theme "{theme}", default_actor "{actor}", ' + 'safety_level "{level}"' +) +def step_verify_get_settings(context, theme, actor, level): + """Verify get_settings returns the expected settings dict.""" + settings = context.settings_screen.get_settings() + assert settings == { + "theme": theme, + "default_actor": actor, + "safety_level": level, + } + + +@then('the session screen rendered text should contain "{text}"') +def step_verify_session_rendered_text_contains(context, text): + """Verify the rendered SessionManagementScreen text contains the given fragment.""" + assert text in context.session_screen._text, ( + f"expected {text!r} in rendered text, got: {context.session_screen._text!r}" + ) + + +# --------------------------------------------------------------------------- +# TuiCommandRouter /settings route scenarios +# --------------------------------------------------------------------------- +class _FakePersonaRegistry: + """Minimal persona registry stub for /settings routing tests.""" + + def list_personas(self): + return [] + + +class _FakePersonaState: + """Minimal persona state stub for /settings routing tests.""" + + def get_active(self, session_id): + return None + + +@given("a TuiCommandRouter for settings tests") +def step_router_for_settings(context): + """Create a TuiCommandRouter with minimal stubs for the /settings route.""" + context.router = TuiCommandRouter( + persona_registry=_FakePersonaRegistry(), # type: ignore[arg-type] + persona_state=_FakePersonaState(), # type: ignore[arg-type] + ) diff --git a/features/tui_settings_session_screens.feature b/features/tui_settings_session_screens.feature index 13874862a..d11a1eedf 100644 --- a/features/tui_settings_session_screens.feature +++ b/features/tui_settings_session_screens.feature @@ -36,6 +36,13 @@ Feature: TUI Settings and Session Management Screens And the default_actor should be "admin" And the safety_level should be "high" + Scenario: SettingsScreen returns current settings as dict + Given a SettingsScreen widget + When I set the theme to "light" + And I set the default_actor to "admin" + And I set the safety_level to "high" + Then get_settings should return theme "light", default_actor "admin", safety_level "high" + # ---------- SessionManagementScreen ---------- Scenario: SessionManagementScreen initializes empty @@ -67,3 +74,18 @@ Feature: TUI Settings and Session Management Screens Scenario: SessionManagementScreen returns None when no sessions Given a SessionManagementScreen widget Then get_selected_session should return None + + Scenario: SessionManagementScreen renders sessions when visible + Given a SessionManagementScreen widget + When I show the session management screen + And I load 3 sessions + Then the session screen rendered text should contain "Session 1" + And the session screen rendered text should contain "10 msgs" + And the session screen rendered text should contain "[CURRENT]" + + # ---------- TuiCommandRouter /settings route ---------- + + Scenario: TuiCommandRouter routes /settings to settings command + Given a TuiCommandRouter for settings tests + When I call handle with raw input "settings" + Then the handle result should be "Settings screen opened" diff --git a/src/cleveragents/tui/screens/session_management.py b/src/cleveragents/tui/screens/session_management.py index a2a735d3f..df9dcac27 100644 --- a/src/cleveragents/tui/screens/session_management.py +++ b/src/cleveragents/tui/screens/session_management.py @@ -48,9 +48,7 @@ def _render_session_list( for i, session in enumerate(sessions): prefix = "❯ " if i == selected_index else " " # noqa: RUF001 current = " [CURRENT]" if session.session_id == current_session_id else "" - lines.append( - f"{prefix}{session.name} ({session.message_count} msgs){current}" - ) + lines.append(f"{prefix}{session.name} ({session.message_count} msgs){current}") return "\n".join(lines) @@ -70,9 +68,7 @@ def _render_session_details(session: SessionInfo | None) -> str: def _render_status_bar() -> str: """Render the status bar at the bottom of the screen.""" - return ( - "j/k Nav │ enter Switch │ r Rename │ d Delete │ n New │ esc Close" - ) + return "j/k Nav │ enter Switch │ r Rename │ d Delete │ n New │ esc Close" def _render_screen( @@ -85,9 +81,7 @@ def _render_screen( selected_session = sessions[selected_index] if sessions else None session_details = _render_session_details(selected_session) status_bar = _render_status_bar() - return ( - f"Session Management\n\n{session_list}\n\n{session_details}\n\n{status_bar}" - ) + return f"Session Management\n\n{session_list}\n\n{session_details}\n\n{status_bar}" class SessionManagementScreen(_StaticBase):