fix(tui): scope MainScreen behave steps
CI / load-versions (pull_request) Successful in 22s
CI / push-validation (pull_request) Successful in 29s
CI / lint (pull_request) Successful in 50s
CI / typecheck (pull_request) Successful in 57s
CI / build (pull_request) Successful in 52s
CI / security (pull_request) Successful in 1m23s
CI / quality (pull_request) Successful in 1m12s
CI / unit_tests (pull_request) Successful in 5m13s
CI / docker (pull_request) Successful in 1m35s
CI / integration_tests (pull_request) Successful in 8m50s
CI / helm (pull_request) Failing after 15m26s
CI / coverage (pull_request) Successful in 12m46s
CI / status-check (pull_request) Failing after 4s

This commit is contained in:
CleverAgents Bot
2026-06-18 06:20:02 -04:00
parent 404ea4356f
commit 4f4d5823dc
2 changed files with 74 additions and 4 deletions
+61 -2
View File
@@ -24,6 +24,7 @@ from cleveragents.tui.main_screen import (
Sidebar,
SidebarState,
Throbber,
_load_textual_attr,
)
@@ -35,6 +36,24 @@ _WIDGET_NAME_TO_CLASS: dict[str, type] = {
}
class _MainScreenActionHarness:
"""Minimal object implementing the query API used by MainScreen actions."""
def __init__(self) -> None:
self.flash_bar = FlashBar()
self.session_tabs = SessionTabs()
self.session_tabs.add_session("Session 1")
self.session_tabs.add_session("Session 2")
def query_one(self, selector, widget_type):
if selector == "#flash-bar" and widget_type is FlashBar:
return self.flash_bar
if selector == "#session-tabs" and widget_type is SessionTabs:
return self.session_tabs
msg = f"unexpected query_one({selector!r}, {widget_type!r})"
raise AssertionError(msg)
def _app_theme() -> str:
"""Return ``CleverAgentsTuiApp.THEME`` or the expected default.
@@ -100,7 +119,7 @@ def step_mainscreen_mounted(context):
context.throbber = Throbber()
@then('the theme should be "{theme}"')
@then('the MainScreen theme should be "{theme}"')
def step_theme_is(context, theme):
"""Verify the App's theme is the expected value."""
assert _app_theme() == theme, f"Expected theme {theme!r}, got {_app_theme()!r}"
@@ -403,7 +422,7 @@ def step_session_tabs_count(context, count, session_name):
)
@then("there is no active session")
@then("the MainScreen has no active session")
def step_no_active_session(context):
"""Verify the active session is None."""
assert context.session_tabs.active_session is None, (
@@ -416,3 +435,43 @@ def step_flash_bar_rendered_contains(context, expected):
"""Verify the raw rendered output of the flash bar contains ``expected``."""
rendered = context.flash_bar.render()
assert expected in rendered, f"Expected {expected!r} in {rendered!r}"
@given("a MainScreen action harness")
def step_main_screen_action_harness(context):
"""Create a minimal receiver for MainScreen action methods."""
context.action_harness = _MainScreenActionHarness()
context.flash_bar = context.action_harness.flash_bar
context.session_tabs = context.action_harness.session_tabs
@when(
'the MainScreen action shows a flash message "{message}" of type "{message_type}"'
)
def step_main_screen_action_show_flash_message(context, message, message_type):
"""Invoke MainScreen.action_show_flash_message against the harness."""
MainScreen.action_show_flash_message(
context.action_harness,
message,
message_type,
)
@when('the MainScreen action sets "{session_name}" as the active session')
def step_main_screen_action_set_active_session(context, session_name):
"""Invoke MainScreen.action_set_active_session against the harness."""
MainScreen.action_set_active_session(context.action_harness, session_name)
@when('the MainScreen import helper loads "{attr}" from "{module_name}"')
def step_main_screen_import_helper_loads(context, attr, module_name):
"""Load an existing attribute through the optional import helper."""
context.loaded_attr = _load_textual_attr(module_name, attr)
@then("the loaded attribute should be callable")
def step_loaded_attribute_callable(context):
"""Verify the import helper returned the requested attribute."""
assert callable(context.loaded_attr), (
f"Expected callable, got {context.loaded_attr!r}"
)
+13 -2
View File
@@ -9,7 +9,7 @@ Feature: TUI MainScreen with Dracula theme and 3-state sidebar
Scenario: MainScreen initializes with correct theme
When the MainScreen is mounted
Then the theme should be "dracula"
Then the MainScreen theme should be "dracula"
And the screen should have a session tabs widget
And the screen should have a sidebar widget
And the screen should have a flash bar widget
@@ -141,9 +141,20 @@ Feature: TUI MainScreen with Dracula theme and 3-state sidebar
And the session tabs contain "Session 1"
When the user sets "Session 1" as the active session
And the user removes the session "Session 1"
Then there is no active session
Then the MainScreen has no active session
Scenario: Flash bar with unknown message type uses generic prefix
Given the MainScreen is mounted
When the user shows a flash message "ping" of type "mystery"
Then the flash bar rendered output contains "* ping"
Scenario: MainScreen actions delegate to mounted widgets
Given a MainScreen action harness
When the MainScreen action shows a flash message "Saved" of type "success"
Then the flash bar rendered output contains "(v) Saved"
When the MainScreen action sets "Session 2" as the active session
Then "Session 2" should be the active session
Scenario: MainScreen import helper returns existing attributes
When the MainScreen import helper loads "import_module" from "importlib"
Then the loaded attribute should be callable