import sys import os import time import pytest from typing import Any, Optional from api_hook_client import ApiHookClient from simulation.workflow_sim import WorkflowSimulator # Ensure project root is in path sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) class BaseSimulation: def __init__(self, client: ApiHookClient = None) -> None: if client is None: self.client = ApiHookClient() else: self.client = client self.sim = WorkflowSimulator(self.client) self.project_path = None def setup(self, project_name: str = "SimProject") -> None: print(f"\n[BaseSim] Connecting to GUI...") if not self.client.wait_for_server(timeout=5): raise RuntimeError("Could not connect to GUI. Ensure it is running with --enable-test-hooks") print("[BaseSim] Resetting session...") self.client.click("btn_reset") time.sleep(0.5) git_dir = os.path.abspath(".") self.project_path = os.path.abspath(f"tests/artifacts/temp_{project_name.lower()}.toml") if os.path.exists(self.project_path): os.remove(self.project_path) print(f"[BaseSim] Scaffolding Project: {project_name}") self.sim.setup_new_project(project_name, git_dir, self.project_path) # Standard test settings self.client.set_value("auto_add_history", True) self.client.set_value("current_provider", "gemini") self.client.set_value("current_model", "gemini-2.5-flash-lite") time.sleep(0.2) def teardown(self) -> None: if self.project_path and os.path.exists(self.project_path): # We keep it for debugging if it failed, but usually we'd clean up # os.remove(self.project_path) pass print("[BaseSim] Teardown complete.") def get_value(self, tag: str) -> Any: return self.client.get_value(tag) def wait_for_event(self, event_type: str, timeout: int = 5) -> Optional[dict]: return self.client.wait_for_event(event_type, timeout) def assert_panel_visible(self, panel_tag: str, msg: str = None) -> None: pass def wait_for_element(self, tag: str, timeout: int = 2) -> bool: start = time.time() while time.time() - start < timeout: try: # If we can get_value without error, it's likely there self.client.get_value(tag) return True except: time.sleep(0.1) return False def run_sim(sim_class: type) -> None: """Helper to run a simulation class standalone.""" sim = sim_class() try: sim.setup() sim.run() print(f"\n[SUCCESS] {sim_class.__name__} completed successfully.") except Exception as e: print(f"\n[FAILURE] {sim_class.__name__} failed: {e}") import traceback traceback.print_exc() sys.exit(1) finally: sim.teardown()