import pytest import time import sys import os import json sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))) from src import api_hook_client @pytest.mark.integration @pytest.mark.timeout(60) def test_gui_ux_event_routing(live_gui) -> None: client = api_hook_client.ApiHookClient() assert client.wait_for_server(timeout=15), "Hook server did not start" # ------------------------------------------------------------------ # 1. Verify Streaming Event Routing # ------------------------------------------------------------------ print("[SIM] Testing Streaming Event Routing...") stream_id = "Tier 3 (Worker): T-SIM-001" # We use push_event which POSTs to /api/gui with action=mma_stream # As defined in AppController._process_event_queue client.push_event('mma_stream', {'stream_id': stream_id, 'text': 'Hello '}) time.sleep(0.5) client.push_event('mma_stream', {'stream_id': stream_id, 'text': 'World!'}) time.sleep(1.0) status = client.get_mma_status() streams = status.get('mma_streams', {}) assert streams.get(stream_id) == 'Hello World!', f"Streaming failed: {streams.get(stream_id)}" print("[SIM] Streaming event routing verified.") # ------------------------------------------------------------------ # 2. Verify State Update (Usage/Cost) Routing # ------------------------------------------------------------------ print("[SIM] Testing State Update Routing...") usage = { "Tier 1": {"input": 1000, "output": 500, "model": "gemini-3.1-pro-preview"}, "Tier 2": {"input": 2000, "output": 1000, "model": "gemini-3-flash-preview"} } client.push_event('mma_state_update', { 'status': 'simulating', 'tier_usage': usage, 'tickets': [] }) time.sleep(1.0) status = client.get_mma_status() assert status.get('mma_status') == 'simulating' # The app merges or replaces usage. Let's check what we got back. received_usage = status.get('mma_tier_usage', {}) assert received_usage.get('Tier 1', {}).get('input') == 1000 assert received_usage.get('Tier 2', {}).get('model') == 'gemini-3-flash-preview' print("[SIM] State update routing verified.") # ------------------------------------------------------------------ # 3. Verify Performance # ------------------------------------------------------------------ print("[SIM] Testing Performance...") # Poll for activity (frames or FPS) to allow data to accumulate fps = 0.0 total_frames = 0 for _ in range(20): # Up to 10 seconds time.sleep(0.5) perf_data = client.get_performance() if not perf_data: continue perf = perf_data.get('performance', {}) fps = perf.get('fps', 0.0) total_frames = perf.get('total_frames', 0) # In headless mode, we might just check if total_frames is increasing if total_frames > 5: break print(f"[SIM] Current FPS: {fps}, Total Frames: {total_frames}") # We accept either a non-zero FPS or a significant frame count as proof of activity assert fps >= 5.0 or total_frames > 0, f"Performance stagnation: {fps} FPS, {total_frames} frames" print("[SIM] Performance verified.") print("[SIM] Performance verified.") @pytest.mark.integration @pytest.mark.timeout(60) def test_gui_track_creation(live_gui) -> None: client = api_hook_client.ApiHookClient() assert client.wait_for_server(timeout=15), "Hook server did not start" print("[SIM] Testing Track Creation via GUI...") track_name = 'UX_SIM_TEST' track_desc = 'Simulation testing for GUI UX' track_type = 'feature' client.set_value('ui_new_track_name', track_name) client.set_value('ui_new_track_desc', track_desc) client.set_value('ui_new_track_type', track_type) client.click('btn_mma_create_track') time.sleep(2.0) # Check the temp workspace created by the live_gui fixture tracks_dir = 'tests/artifacts/live_gui_workspace/conductor/tracks/' found = False # The implementation lowercases and replaces spaces with underscores search_prefix = track_name.lower().replace(' ', '_') for entry in os.listdir(tracks_dir): if entry.startswith(search_prefix) and os.path.isdir(os.path.join(tracks_dir, entry)): found = True metadata_path = os.path.join(tracks_dir, entry, 'metadata.json') assert os.path.exists(metadata_path), f"metadata.json missing in {entry}" with open(metadata_path, 'r') as f: meta = json.load(f) assert meta.get('status') == 'new' assert meta.get('title') == track_name print(f"[SIM] Verified track directory: {entry}") break assert found, f"Track directory starting with {search_prefix} not found." print("[SIM] Track creation verified.") if __name__ == "__main__": pass