Files
cleveragents-core/features/tui_first_run.feature
freemo a1cf8164f3 chore(ci): use matrix strategy for Python versions in unit and integration test jobs
Add a matrix strategy to the unit_tests and integration_tests jobs in
ci.yml so that tests run against all Python versions listed in
SUPPORTED_PYTHONS in noxfile.py (currently ["3.13"]).

Changes:
- Add strategy.matrix.python-version to unit_tests and integration_tests
- Set fail-fast: false so all matrix versions run even if one fails
- Use matrix.python-version in the container image tag
- Invoke nox with the versioned session name (e.g. unit_tests-3.13)
- Scope uv cache keys per Python version to avoid cross-version pollution
- Remove the now-unused global PYTHON_VERSION env var

When SUPPORTED_PYTHONS is extended in noxfile.py, only the matrix list
in ci.yml needs updating to add the new version.

ISSUES CLOSED: #1539
2026-04-03 02:07:28 +00:00

197 lines
8.5 KiB
Gherkin

Feature: TUI first-run experience with actor selection overlay
The TUI shows an actor selection overlay on first launch when no
personas are configured. After the user selects an actor a default
persona is created and the overlay is dismissed.
# -----------------------------------------------------------------------
# is_first_run helper
# -----------------------------------------------------------------------
Scenario: is_first_run returns True when registry has no personas
Given an empty persona registry
Then is_first_run should return True
Scenario: is_first_run returns False when registry has at least one persona
Given a persona registry with a default persona using actor "local/mock"
Then is_first_run should return False
# -----------------------------------------------------------------------
# create_default_persona_for_actor helper
# -----------------------------------------------------------------------
Scenario: create_default_persona_for_actor persists a default persona
Given an empty persona registry
When I call create_default_persona_for_actor with actor "anthropic/claude-4-sonnet"
Then the registry should contain a persona named "default"
And the default persona actor should be "anthropic/claude-4-sonnet"
Scenario: create_default_persona_for_actor sets last persona
Given an empty persona registry
When I call create_default_persona_for_actor with actor "openai/gpt-4o"
Then the registry last persona should be "default"
# -----------------------------------------------------------------------
# render_actor_selection helper
# -----------------------------------------------------------------------
Scenario: render_actor_selection includes welcome header
When I render the actor selection with default actors
Then the actor selection rendered text should contain "Welcome to CleverAgents"
Scenario: render_actor_selection marks the first actor as recommended
When I render the actor selection with default actors
Then the actor selection rendered text should contain "(recommended)"
Scenario: render_actor_selection highlights the selected actor with cursor
When I render the actor selection with selected index 2
Then the rendered text should contain a cursor marker
Scenario: render_actor_selection shows search prompt when query is empty
When I render the actor selection with default actors
Then the actor selection rendered text should contain "to search..."
Scenario: render_actor_selection shows active search query
When I render the actor selection with search query "claude"
Then the actor selection rendered text should contain "claude"
Scenario: render_actor_selection includes footer keybindings
When I render the actor selection with default actors
Then the actor selection rendered text should contain "enter Select"
And the actor selection rendered text should contain "j/k Navigate"
And the actor selection rendered text should contain "/ Search"
# -----------------------------------------------------------------------
# ActorSelectionOverlay widget
# -----------------------------------------------------------------------
Scenario: ActorSelectionOverlay starts hidden
Given a new ActorSelectionOverlay
Then the overlay should not be visible
Scenario: ActorSelectionOverlay show makes it visible
Given a new ActorSelectionOverlay
When I call show on the overlay
Then the overlay should be visible
Scenario: ActorSelectionOverlay hide makes it invisible
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call hide on the overlay
Then the overlay should not be visible
Scenario: ActorSelectionOverlay show populates default actors
Given a new ActorSelectionOverlay
When I call show on the overlay
Then the overlay actors list should contain "anthropic/claude-4-sonnet"
Scenario: ActorSelectionOverlay show accepts custom actor list
Given a new ActorSelectionOverlay
When I call show on the overlay with actors ["local/mock-a", "local/mock-b"]
Then the overlay actors list should contain "local/mock-a"
And the overlay actors list should contain "local/mock-b"
Scenario: ActorSelectionOverlay move_down advances selection
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call move_down on the overlay
Then the overlay selected index should be 1
Scenario: ActorSelectionOverlay move_up wraps to last item
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call move_up on the overlay
Then the overlay selected index should be the last index
Scenario: ActorSelectionOverlay move_down wraps to first item
Given a new ActorSelectionOverlay
When I call show on the overlay
And I move_down past the last actor
Then the overlay selected index should be 0
Scenario: ActorSelectionOverlay set_search filters actors
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call set_search with query "claude"
Then the overlay filtered actors should only contain actors matching "claude"
Scenario: ActorSelectionOverlay set_search with empty string clears filter
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call set_search with query "claude"
And I call set_search with query ""
Then the overlay filtered actors count should equal the full actors count
Scenario: ActorSelectionOverlay confirm returns selected actor
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call confirm on the overlay
Then the confirmed actor should be "anthropic/claude-4-sonnet"
Scenario: ActorSelectionOverlay confirm hides the overlay
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call confirm on the overlay
Then the overlay should not be visible
Scenario: ActorSelectionOverlay confirm sets confirmed flag
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call confirm on the overlay
Then the overlay confirmed flag should be True
Scenario: ActorSelectionOverlay confirm on empty filtered list returns None
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call set_search with query "zzz_no_match"
And I call confirm on the overlay
Then the confirmed actor should be None
Scenario: ActorSelectionOverlay move_down on empty list is a no-op
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call set_search with query "zzz_no_match"
And I call move_down on the overlay
Then the overlay selected index should be 0
Scenario: ActorSelectionOverlay move_up on empty list is a no-op
Given a new ActorSelectionOverlay
When I call show on the overlay
And I call set_search with query "zzz_no_match"
And I call move_up on the overlay
Then the overlay selected index should be 0
Scenario: ActorSelectionOverlay selected_actor is None before confirm
Given a new ActorSelectionOverlay
When I call show on the overlay
Then the overlay selected_actor should be None
Scenario: ActorSelectionOverlay search_query is empty after show
Given a new ActorSelectionOverlay
When I call show on the overlay
Then the overlay search_query should be ""
# -----------------------------------------------------------------------
# TUI app integration: on_mount shows overlay on first run
# -----------------------------------------------------------------------
Scenario: TUI app shows actor selection overlay on first run
Given the TUI app is initialised with an empty persona registry
When I call on_mount on the first-run app
Then the actor selection overlay should be visible
Scenario: TUI app hides actor selection overlay when personas exist
Given the TUI app is initialised with an existing persona registry
When I call on_mount on the first-run app
Then the actor selection overlay should not be visible
# -----------------------------------------------------------------------
# TUI app integration: _complete_first_run
# -----------------------------------------------------------------------
Scenario: _complete_first_run creates default persona and refreshes bar
Given the TUI app is initialised with an empty persona registry
When I call on_mount on the first-run app
And I call _complete_first_run with actor "anthropic/claude-4-sonnet"
Then the registry should contain a persona named "default"
And the persona bar should reflect the new actor