Cleanup obsolete tasks, simplify auth lock logic, increase test retry wait
- Remove completed Task 17 and 18 from Docs/tasks.md - Remove ANIWORLD_TESTING bypass in _check_locked (testing env now uses test auth service) - Remove redundant lock expiry cleanup (handled by _get_fail_record) - Fix login.html whitespace formatting - Increase setup retry wait from 6s to 45s for rate-limited CI environments
This commit is contained in:
@@ -108,8 +108,13 @@ Setup Master Password
|
||||
... backup_enabled=False
|
||||
${resp}= POST On Session anon /api/auth/setup json=${payload} expected_status=any
|
||||
IF '${resp.status_code}' == '429'
|
||||
# Rate limited - wait and retry once
|
||||
Sleep 6s
|
||||
# Rate limited - wait and retry
|
||||
Sleep 45s
|
||||
${resp}= POST On Session anon /api/auth/setup json=${payload} expected_status=any
|
||||
END
|
||||
IF '${resp.status_code}' == '429'
|
||||
# Still rate limited - wait longer and retry again
|
||||
Sleep 45s
|
||||
${resp}= POST On Session anon /api/auth/setup json=${payload} expected_status=any
|
||||
END
|
||||
IF '${resp.status_code}' == '400'
|
||||
|
||||
66
tests/robot/resources/websocket_keywords.py
Normal file
66
tests/robot/resources/websocket_keywords.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""WebSocket keyword library for Robot Framework tests."""
|
||||
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
|
||||
import websockets
|
||||
from robot.api import logger
|
||||
|
||||
|
||||
class WebSocketKeywords:
|
||||
"""Keywords for WebSocket testing."""
|
||||
|
||||
def __init__(self):
|
||||
self._connection: Optional[websockets.WebSocketClientProtocol] = None
|
||||
|
||||
def connect_to_websocket(self, ws_url: str) -> str:
|
||||
"""Establish a WebSocket connection and return connection info.
|
||||
|
||||
Args:
|
||||
ws_url: Full WebSocket URL including token query param.
|
||||
|
||||
Returns:
|
||||
String representation of the connected WebSocket.
|
||||
"""
|
||||
asyncio.run(self._async_connect(ws_url))
|
||||
return f"Connected to {ws_url}"
|
||||
|
||||
async def _async_connect(self, ws_url: str) -> None:
|
||||
self._connection = await websockets.connect(ws_url)
|
||||
logger.info(f"WebSocket connected: {self._connection}")
|
||||
|
||||
def send_websocket_message(self, message: str) -> None:
|
||||
"""Send a text message over the active WebSocket connection.
|
||||
|
||||
Args:
|
||||
message: Text message to send.
|
||||
"""
|
||||
if self._connection is None:
|
||||
raise RuntimeError("No active WebSocket connection. Use Connect To WebSocket first.")
|
||||
asyncio.run(self._connection.send(message))
|
||||
logger.info(f"Sent message: {message}")
|
||||
|
||||
def receive_websocket_message(self, timeout: float = 5.0) -> str:
|
||||
"""Receive a text message from the active WebSocket connection.
|
||||
|
||||
Args:
|
||||
timeout: Maximum seconds to wait for a message.
|
||||
|
||||
Returns:
|
||||
The received text message.
|
||||
"""
|
||||
if self._connection is None:
|
||||
raise RuntimeError("No active WebSocket connection. Use Connect To WebSocket first.")
|
||||
try:
|
||||
message = asyncio.run(asyncio.wait_for(self._connection.recv(), timeout=timeout))
|
||||
logger.info(f"Received message: {message}")
|
||||
return message
|
||||
except asyncio.TimeoutError:
|
||||
raise TimeoutError(f"No message received within {timeout} seconds")
|
||||
|
||||
def close_websocket(self) -> None:
|
||||
"""Close the active WebSocket connection."""
|
||||
if self._connection is not None:
|
||||
asyncio.run(self._connection.close())
|
||||
self._connection = None
|
||||
logger.info("WebSocket closed")
|
||||
Reference in New Issue
Block a user