Files
cleveragents-core/features/client/websocket_updates.feature
freemo 8e9aa7af48 fix(client): address server client chain review findings
- Promote _request() to public method request() in ServerHttpClient
  to fix encapsulation violation across sync_client and remote_project
- Fix WebSocket connect() to raise NotImplementedError with clear TODO
  documenting that real websockets transport is not yet implemented
- Fix thread safety: protect last_event_id write under self._lock
  in ws_client.process_event()
- Broaden exception handling in sync() to catch ServerTimeoutError
  and A2aNotAvailableError in addition to ServerConnectionError
- Add has_next to PageResult in benchmark and test helpers
- Add comments explaining Retry-After header logging-only behavior
  and why blocking time.sleep is acceptable in sync client
- Update all test steps, robot helpers, and benchmarks to use the
  renamed public request() method and updated connect() behavior

Refs: #335, #336, #337, #338
2026-03-24 20:28:19 +00:00

136 lines
5.7 KiB
Gherkin

@phase2 @client @websocket
Feature: WebSocket updates client
As a developer
I want a WebSocket client for real-time plan updates
So that I can receive status, progress, and log events from the server
# ---------------------------------------------------------------------------
# Construction
# ---------------------------------------------------------------------------
Scenario: Create WebSocket client with default settings
Given a WebSocketClient with default settings
Then the ws_url should be "ws://localhost:8080/ws"
And the heartbeat interval should be 30.0
And the dedup capacity should be 1000
Scenario: Create WebSocket client with custom settings
Given a WebSocketClient with url "wss://example.com/ws" and token "tok_ws1234567890abcdef"
Then the ws_url should be "wss://example.com/ws"
# ---------------------------------------------------------------------------
# Connection lifecycle
# ---------------------------------------------------------------------------
Scenario: Connect raises NotImplementedError until real transport is available
Given a WebSocketClient with default settings
When I attempt to connect the ws client
Then a NotImplementedError should be raised from ws client
Scenario: Disconnect sets state to disconnected
Given a WebSocketClient with default settings
And the ws client state is set to connected
When I disconnect the ws client
Then the ws client should not be connected
# ---------------------------------------------------------------------------
# Reconnection
# ---------------------------------------------------------------------------
Scenario: Reconnect increments reconnect counter
Given a WebSocketClient with default settings and max_reconnects 5
And the ws client state is set to connected
When I simulate a reconnect
Then the reconnect count should be 1
And the ws client should be connected
Scenario: Reconnect exceeding max raises ServerConnectionError
Given a WebSocketClient with default settings and max_reconnects 2
When I exhaust reconnect attempts
Then a ServerConnectionError should be raised from ws client
# ---------------------------------------------------------------------------
# Event processing
# ---------------------------------------------------------------------------
Scenario: Process event dispatches to subscriber
Given a WebSocketClient with a subscriber
When I process a plan status event with id "evt-001"
Then the subscriber should receive event "evt-001"
And the last event id should be "evt-001"
Scenario: Process duplicate event is skipped
Given a WebSocketClient with a subscriber
When I process a plan status event with id "evt-dup-001"
And I process a plan status event with id "evt-dup-001" again
Then the subscriber should have received 1 event
Scenario: Unsubscribe removes callback
Given a WebSocketClient with a subscriber
When I unsubscribe the callback
And I process a plan status event with id "evt-unsub"
Then the subscriber should have received 0 events
# ---------------------------------------------------------------------------
# Heartbeat
# ---------------------------------------------------------------------------
Scenario: Heartbeat resets reconnect counter
Given a WebSocketClient with default settings and max_reconnects 5
And the ws client state is set to connected
When I simulate a reconnect
And I handle a heartbeat
Then the reconnect count should be 0
# ---------------------------------------------------------------------------
# Version negotiation
# ---------------------------------------------------------------------------
Scenario: Version negotiation stores agreed version
Given a WebSocketClient with default settings
When I negotiate ws version "1.0"
Then the negotiated ws version should be "1.0"
# ---------------------------------------------------------------------------
# EventDeduplicator
# ---------------------------------------------------------------------------
Scenario: Deduplicator detects duplicates
Given an EventDeduplicator with capacity 3
When I check event "a" for duplicate
Then the dedup result should be not duplicate
When I check event "a" for duplicate
Then the dedup result should be duplicate
Scenario: Deduplicator evicts oldest when full
Given an EventDeduplicator with capacity 2
When I add events "x" and "y" and "z" to the deduplicator
Then event "x" should not be tracked
And the deduplicator size should be 2
Scenario: Deduplicator clear removes all entries
Given an EventDeduplicator with capacity 10
When I add events "a" and "b" and "c" to the deduplicator
And I clear the deduplicator
Then the deduplicator size should be 0
# ---------------------------------------------------------------------------
# ConnectionState
# ---------------------------------------------------------------------------
Scenario: ConnectionState reset clears all fields
Given a ConnectionState with connected true and last_event_id "ev1"
When I reset the connection state
Then the connection state should be disconnected
And the connection state last_event_id should be empty
# ---------------------------------------------------------------------------
# Backoff helper
# ---------------------------------------------------------------------------
Scenario: WS backoff delay grows exponentially and is capped
When I compute ws backoff delay for attempt 0 base 1.0 max 30.0
Then the ws delay should be 1.0
When I compute ws backoff delay for attempt 10 base 1.0 max 30.0
Then the ws delay should be 30.0