0fe78e7eff
CI / load-versions (pull_request) Successful in 17s
CI / push-validation (pull_request) Successful in 25s
CI / lint (pull_request) Successful in 33s
CI / build (pull_request) Successful in 39s
CI / helm (pull_request) Successful in 53s
CI / typecheck (pull_request) Successful in 1m11s
CI / security (pull_request) Successful in 1m17s
CI / quality (pull_request) Successful in 3m55s
CI / unit_tests (pull_request) Successful in 5m40s
CI / docker (pull_request) Successful in 2m13s
CI / integration_tests (pull_request) Successful in 8m32s
CI / coverage (pull_request) Successful in 9m33s
CI / status-check (pull_request) Successful in 1s
CI / load-versions (push) Successful in 12s
CI / push-validation (push) Successful in 24s
CI / build (push) Successful in 34s
CI / helm (push) Successful in 40s
CI / quality (push) Successful in 58s
CI / benchmark-publish (push) Has started running
CI / lint (push) Successful in 3m46s
CI / typecheck (push) Successful in 4m23s
CI / security (push) Successful in 4m45s
CI / integration_tests (push) Successful in 8m37s
CI / unit_tests (push) Successful in 14m53s
CI / status-check (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
CI / coverage (push) Has been cancelled
- Verify inherited Widget._render() returns non-None via MRO traversal - Actually invoke _refresh_display() and verify correct overlay content Refs: #11039
217 lines
9.5 KiB
Gherkin
217 lines
9.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 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 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 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 rendered text should contain "claude"
|
|
|
|
Scenario: render_actor_selection includes footer keybindings
|
|
When I render the actor selection with default actors
|
|
Then the rendered text should contain "enter Select"
|
|
And the rendered text should contain "j/k Navigate"
|
|
And the 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-sonnet-4-20250514"
|
|
|
|
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-sonnet-4-20250514"
|
|
|
|
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-sonnet-4-20250514"
|
|
Then the registry should contain a persona named "default"
|
|
And the persona bar should reflect the new actor
|
|
|
|
# -----------------------------------------------------------------------
|
|
# TDD regression: issue #11039 - no _render() shadowing Textual Widget._render
|
|
# -----------------------------------------------------------------------
|
|
# The overlay formerly defined its own _render() returning None, which
|
|
# shadowed textual.widgets.Static._render and caused layout-engine crashes.
|
|
# This scenario ensures the rename to _refresh_display eliminated that bug.
|
|
|
|
@tdd_issue @tdd_issue_11039
|
|
Scenario: ActorSelectionOverlay does not define its own _render method
|
|
Given a new ActorSelectionOverlay
|
|
Then the overlay should not override Textual Widget._render
|
|
And the inherited Widget._render should return a proper renderable
|
|
|
|
@tdd_issue @tdd_issue_11039
|
|
Scenario: ActorSelectionOverlay has refresh_display callable instead of render
|
|
Given a new ActorSelectionOverlay
|
|
When I call show on the overlay
|
|
Then the overlay _refresh_display method should be callable
|
|
And _refresh_display should produce correct overlay content
|