|
|
@@ -66,6 +66,111 @@ def test_enter_sends_execute_and_e_opens_editor(server):
|
|
|
assert ("command_cancel", {}) in sent
|
|
|
|
|
|
|
|
|
+def test_c_key_confirms_before_clearing(server):
|
|
|
+ pytest.importorskip("textual")
|
|
|
+ from stt_daemon.tui.app import AssistantTUI
|
|
|
+
|
|
|
+ path, _service = server
|
|
|
+ app = AssistantTUI(path)
|
|
|
+ sent: list[tuple] = []
|
|
|
+
|
|
|
+ async def scenario():
|
|
|
+ async with app.run_test() as pilot:
|
|
|
+ await pilot.pause()
|
|
|
+ app.client.send = lambda type_, **fields: sent.append((type_, fields))
|
|
|
+
|
|
|
+ await pilot.press("c")
|
|
|
+ await pilot.pause()
|
|
|
+ assert not any(type_ == "clear" for type_, _ in sent), "clear sent before confirmation"
|
|
|
+
|
|
|
+ await pilot.press("y")
|
|
|
+ await pilot.pause()
|
|
|
+
|
|
|
+ asyncio.run(scenario())
|
|
|
+ assert ("clear", {}) in sent
|
|
|
+
|
|
|
+
|
|
|
+def test_c_key_cancel_does_not_clear(server):
|
|
|
+ pytest.importorskip("textual")
|
|
|
+ from stt_daemon.tui.app import AssistantTUI
|
|
|
+
|
|
|
+ path, _service = server
|
|
|
+ app = AssistantTUI(path)
|
|
|
+ sent: list[tuple] = []
|
|
|
+
|
|
|
+ async def scenario():
|
|
|
+ async with app.run_test() as pilot:
|
|
|
+ await pilot.pause()
|
|
|
+ app.client.send = lambda type_, **fields: sent.append((type_, fields))
|
|
|
+
|
|
|
+ await pilot.press("c")
|
|
|
+ await pilot.pause()
|
|
|
+ await pilot.press("n")
|
|
|
+ await pilot.pause()
|
|
|
+
|
|
|
+ asyncio.run(scenario())
|
|
|
+ assert not any(type_ == "clear" for type_, _ in sent)
|
|
|
+
|
|
|
+
|
|
|
+def test_c_key_escape_does_not_clear(server):
|
|
|
+ pytest.importorskip("textual")
|
|
|
+ from stt_daemon.tui.app import AssistantTUI
|
|
|
+
|
|
|
+ path, _service = server
|
|
|
+ app = AssistantTUI(path)
|
|
|
+ sent: list[tuple] = []
|
|
|
+
|
|
|
+ async def scenario():
|
|
|
+ async with app.run_test() as pilot:
|
|
|
+ await pilot.pause()
|
|
|
+ app.client.send = lambda type_, **fields: sent.append((type_, fields))
|
|
|
+
|
|
|
+ await pilot.press("c")
|
|
|
+ await pilot.pause()
|
|
|
+ await pilot.press("escape")
|
|
|
+ await pilot.pause()
|
|
|
+
|
|
|
+ asyncio.run(scenario())
|
|
|
+ assert not any(type_ == "clear" for type_, _ in sent)
|
|
|
+
|
|
|
+
|
|
|
+def test_c_key_clears_rendered_output(server):
|
|
|
+ """Pressing 'c' clears the conversation pane via the cleared event."""
|
|
|
+ pytest.importorskip("textual")
|
|
|
+ from textual.widgets import RichLog
|
|
|
+
|
|
|
+ from stt_daemon.tui.app import AssistantTUI
|
|
|
+
|
|
|
+ path, _service = server
|
|
|
+ app = AssistantTUI(path)
|
|
|
+
|
|
|
+ async def scenario():
|
|
|
+ async with app.run_test() as pilot:
|
|
|
+ await pilot.pause()
|
|
|
+ app.state.ingest({"type": "chat_message", "role": "user", "text": "hello"})
|
|
|
+ app.state.ingest(
|
|
|
+ {
|
|
|
+ "type": "tool_result",
|
|
|
+ "tool": "get_datetime",
|
|
|
+ "ok": True,
|
|
|
+ "result": "2026-09-21",
|
|
|
+ }
|
|
|
+ )
|
|
|
+ app._render()
|
|
|
+ await pilot.pause()
|
|
|
+
|
|
|
+ app.state.ingest({"type": "cleared"})
|
|
|
+ app._render()
|
|
|
+ await pilot.pause()
|
|
|
+
|
|
|
+ log = app.query_one("#chat", RichLog)
|
|
|
+ return list(log.lines)
|
|
|
+
|
|
|
+ lines = asyncio.run(scenario())
|
|
|
+ assert not any("hello" in str(line) for line in lines)
|
|
|
+ assert not any("2026-09-21" in str(line) for line in lines)
|
|
|
+
|
|
|
+
|
|
|
def test_tui_renders_command_output(server):
|
|
|
"""A tool result must actually reach a widget - otherwise 'nothing happens'."""
|
|
|
pytest.importorskip("textual")
|