diff --git a/features/steps/tdd_tui_block_cursor_navigation_steps.py b/features/steps/tdd_tui_block_cursor_navigation_steps.py new file mode 100644 index 000000000..706b73b61 --- /dev/null +++ b/features/steps/tdd_tui_block_cursor_navigation_steps.py @@ -0,0 +1,54 @@ +"""Step definitions for tdd_tui_block_cursor_navigation.feature. + +This test captures bug #10371: the TUI application is missing ``alt+up`` +and ``alt+down`` key bindings for block cursor navigation. + +The scenario is tagged ``@tdd_expected_fail`` so the underlying assertion +failure (confirming the bug exists) is inverted to a CI pass. Once the +fix for #10371 is merged, remove the ``@tdd_expected_fail`` tag from the +feature file and this test will run normally as a regression guard. + +The ``Given the TUI app module is imported with mocked Textual`` step is +shared from ``tui_app_coverage_steps.py`` and is not redefined here. +""" + +from __future__ import annotations + +from typing import Any + +from behave import then, when + + +@when("I inspect the TUI app BINDINGS for block cursor navigation") +def step_inspect_bindings(context: Any) -> None: + """Collect the BINDINGS class variable from the reloaded TUI app module. + + The ``_tui_app_mod`` attribute is set by the shared + ``Given the TUI app module is imported with mocked Textual`` step + (defined in ``tui_app_coverage_steps.py``). + """ + app_mod = context._tui_app_mod + # _TextualCleverAgentsTuiApp is only defined when Textual is available. + # The Background step mocks Textual, so the class must exist here. + assert hasattr(app_mod, "_TextualCleverAgentsTuiApp"), ( + "Expected _TextualCleverAgentsTuiApp to be defined after mocking Textual" + ) + tui_class = app_mod._TextualCleverAgentsTuiApp + context.tdd_tui_bindings = list(tui_class.BINDINGS) + + +@then('the BINDINGS should include "{key}" key binding') +def step_bindings_include_key(context: Any, key: str) -> None: + """Assert that the given key is registered in the TUI app BINDINGS. + + Bug #10371: ``alt+up`` and ``alt+down`` are absent from BINDINGS, so + this assertion raises ``AssertionError`` while the bug is unfixed. + The ``@tdd_expected_fail`` tag inverts the failure to a CI pass. + """ + bindings: list[tuple[str, str, str]] = context.tdd_tui_bindings + bound_keys = [binding[0] for binding in bindings] + assert key in bound_keys, ( + f"Bug #10371: Key binding '{key}' is not registered in " + f"CleverAgentsTuiApp.BINDINGS. " + f"Current bindings: {bound_keys}" + ) diff --git a/features/tdd_tui_block_cursor_navigation.feature b/features/tdd_tui_block_cursor_navigation.feature new file mode 100644 index 000000000..1cc0fe827 --- /dev/null +++ b/features/tdd_tui_block_cursor_navigation.feature @@ -0,0 +1,19 @@ +@tdd_issue @tdd_issue_10371 +Feature: TDD Issue #10371 — Block cursor navigation (alt+up/alt+down) not implemented in TUI + + This test captures bug #10371: the TUI application is missing ``alt+up`` + and ``alt+down`` key bindings for block cursor navigation. + + The scenario is tagged ``@tdd_expected_fail`` so the underlying assertion + failure (confirming the bug exists) is inverted to a CI pass. Once the + fix for #10371 is merged, remove the ``@tdd_expected_fail`` tag from the + scenario and this test will run normally as a regression guard. + + See CONTRIBUTING.md > Bug Fix Workflow > TDD Issue Test Tags. + + @tdd_expected_fail + Scenario: TUI app BINDINGS includes alt+up and alt+down for block cursor navigation + Given the TUI app module is imported with mocked Textual + When I inspect the TUI app BINDINGS for block cursor navigation + Then the BINDINGS should include "alt+up" key binding + And the BINDINGS should include "alt+down" key binding