""" Tests d'intégration pour Phase 1 - Mode Light des structures UI Element. Vérifie que toutes les structures de données fonctionnent correctement ensemble. """ import sys import numpy as np from pathlib import Path from datetime import datetime # Ajouter le chemin du module sys.path.insert(0, str(Path(__file__).parent)) from geniusia2.core import ( UIElement, UIElementType, VisualData, TextData, ElementProperties, ElementContext, EnrichedScreenState, WindowInfo, RawData, PerceptionData, StateEmbedding, ContextData, ScreenStateManager ) from geniusia2.core.logger import Logger from geniusia2.core.workflow_state_adapter import WorkflowStateAdapter from geniusia2.core.workflow_detector import WorkflowStep def test_uielement_creation(): """Test création et sérialisation d'UIElement.""" print("\n" + "=" * 70) print("TEST 1: Création et sérialisation d'UIElement") print("=" * 70) # Créer un UIElement element_id = UIElement.generate_element_id( app_name="test_app", bbox=(100, 200, 300, 250), label="Valider" ) element = UIElement( element_id=element_id, type=UIElementType.BUTTON, role="validate_action", bbox=(100, 200, 300, 250), label="Valider", visual=VisualData( screenshot_path="data/elements/el_001.png", embedding_provider="openclip_ViT-B-32", embedding_vector_id="data/embeddings/el_001.npy" ), text=TextData( raw="Valider", normalized="valider", embedding_provider="clip_text", embedding_vector_id="data/embeddings/el_001_text.npy" ), properties=ElementProperties( is_clickable=True, is_focusable=True, is_dangerous=False ), context=ElementContext( app_name="test_app", window_title="Test Window", workflow_hint="WF_test" ), tags=["primary_action"], confidence=0.95, detection_method="heuristic_rectangle" ) print(f"✓ UIElement créé: {element.element_id}") print(f" Type: {element.type.value}") print(f" Label: {element.label}") print(f" Confidence: {element.confidence}") # Test sérialisation json_str = element.to_json() element_restored = UIElement.from_json(json_str) assert element_restored.element_id == element.element_id assert element_restored.type == element.type assert element_restored.label == element.label print(f"✓ Sérialisation/désérialisation réussie") # Test stabilité de l'ID element_id_2 = UIElement.generate_element_id( app_name="test_app", bbox=(100, 200, 300, 250), label="Valider" ) assert element_id == element_id_2 print(f"✓ Stabilité de l'element_id vérifiée") return element def test_enriched_screen_state_light_mode(): """Test création d'EnrichedScreenState en mode light.""" print("\n" + "=" * 70) print("TEST 2: EnrichedScreenState en mode light") print("=" * 70) window = WindowInfo( app_name="test_app", window_title="Test Window", screen_resolution=(1920, 1080) ) screen_state = EnrichedScreenState.create_light_mode( screen_state_id="screen_test_001", session_id="session_001", window=window, screenshot_path="data/screens/screen_001.png", image_embedding_provider="openclip_ViT-B-32", image_embedding_vector_id="data/embeddings/screen_001.npy" ) print(f"✓ EnrichedScreenState créé: {screen_state.screen_state_id}") print(f" Mode: {screen_state.mode}") print(f" UI Elements: {len(screen_state.ui_elements)}") print(f" State Embedding Provider: {screen_state.state_embedding.provider}") # Vérifier les propriétés du mode light assert screen_state.mode == "light" assert len(screen_state.ui_elements) == 0 assert screen_state.state_embedding.components is None print(f"✓ Mode light vérifié (ui_elements vide, pas de composantes)") # Test sérialisation json_str = screen_state.to_json() screen_state_restored = EnrichedScreenState.from_json(json_str) assert screen_state_restored.screen_state_id == screen_state.screen_state_id assert screen_state_restored.mode == screen_state.mode print(f"✓ Sérialisation/désérialisation réussie") return screen_state def test_screen_state_manager(): """Test du ScreenStateManager.""" print("\n" + "=" * 70) print("TEST 3: ScreenStateManager") print("=" * 70) logger = Logger(log_dir="test_logs") manager = ScreenStateManager( logger=logger, data_dir="test_data", mode="light" ) print(f"✓ ScreenStateManager initialisé en mode: {manager.mode}") # Créer un screen state screen_state = manager.create_screen_state( session_id="test_session_001", window_title="Test Window", app_name="test_app", screenshot_path="test_data/screens/test_001.png", screen_resolution=(1920, 1080), detected_text=["Test", "Button"], context_tags=["test"] ) print(f"✓ Screen state créé: {screen_state.screen_state_id}") # Sauvegarder avec embedding test_embedding = np.random.rand(512) state_file = manager.save_screen_state( screen_state, save_embedding=True, embedding_vector=test_embedding ) print(f"✓ Screen state sauvegardé: {state_file}") # Charger loaded_state = manager.load_screen_state(screen_state.screen_state_id) assert loaded_state is not None assert loaded_state.screen_state_id == screen_state.screen_state_id print(f"✓ Screen state chargé: {loaded_state.screen_state_id}") # Charger l'embedding loaded_embedding = manager.load_embedding(screen_state.state_embedding.vector_id) assert loaded_embedding is not None assert np.allclose(test_embedding, loaded_embedding) print(f"✓ Embedding chargé et vérifié") # Lister state_ids = manager.list_screen_states(session_id="test_session_001") assert len(state_ids) > 0 print(f"✓ Listage: {len(state_ids)} screen states trouvés") return manager def test_workflow_adapter(): """Test de l'adaptateur de workflow.""" print("\n" + "=" * 70) print("TEST 4: WorkflowStateAdapter (compatibilité arrière)") print("=" * 70) logger = Logger(log_dir="test_logs") manager = ScreenStateManager( logger=logger, data_dir="test_data", mode="light" ) adapter = WorkflowStateAdapter( screen_state_manager=manager, logger=logger ) print(f"✓ WorkflowStateAdapter initialisé") # Créer un WorkflowStep (ancien format) step = WorkflowStep( step_id=1, action_type="click", target_description="Valider Button", position=(100, 200), window="Test App - Main Window", embedding=np.random.rand(512), screenshot=None ) print(f"✓ WorkflowStep créé (ancien format)") # Convertir en EnrichedScreenState screen_state = adapter.workflow_step_to_screen_state( step=step, session_id="test_session", screenshot_path="test_data/screens/step_1.png" ) assert screen_state.window.window_title == step.window assert step.target_description in screen_state.perception.detected_text print(f"✓ Conversion WorkflowStep → EnrichedScreenState réussie") # Convertir en WorkflowStep (pour compatibilité) converted_step = adapter.screen_state_to_workflow_step( screen_state=screen_state, step_id=1, action_type="click", position=(100, 200) ) assert converted_step.step_id == step.step_id assert converted_step.action_type == step.action_type assert converted_step.window == step.window print(f"✓ Conversion EnrichedScreenState → WorkflowStep réussie") print(f"✓ Compatibilité arrière vérifiée") def test_compatibility(): """Test de compatibilité avec différents formats.""" print("\n" + "=" * 70) print("TEST 5: Compatibilité multi-format") print("=" * 70) # Test lecture de différents modes modes = ["light", "enriched", "complete"] for mode in modes: window = WindowInfo( app_name="test_app", window_title="Test Window", screen_resolution=(1920, 1080) ) if mode == "light": screen_state = EnrichedScreenState.create_light_mode( screen_state_id=f"screen_{mode}", session_id="session_001", window=window, screenshot_path="data/screens/screen.png", image_embedding_provider="openclip_ViT-B-32", image_embedding_vector_id="data/embeddings/screen.npy" ) else: screen_state = EnrichedScreenState( screen_state_id=f"screen_{mode}", timestamp=datetime.now(), session_id="session_001", window=window, raw=RawData(screenshot_path="data/screens/screen.png"), perception=PerceptionData(detected_text=[]), ui_elements=[], state_embedding=StateEmbedding( provider="openclip_ViT-B-32", vector_id="data/embeddings/screen.npy", components=None ), context=ContextData(), mode=mode ) # Sérialiser et désérialiser json_str = screen_state.to_json() restored = EnrichedScreenState.from_json(json_str) assert restored.mode == mode assert restored.screen_state_id == screen_state.screen_state_id print(f"✓ Mode '{mode}' compatible") print(f"✓ Tous les modes sont compatibles") def cleanup(): """Nettoie les fichiers de test.""" import shutil if Path("test_data").exists(): shutil.rmtree("test_data") if Path("test_logs").exists(): shutil.rmtree("test_logs") def main(): """Exécute tous les tests.""" print("\n" + "=" * 70) print("TESTS D'INTÉGRATION - PHASE 1 MODE LIGHT") print("UI Element Detection - Structures de Données de Base") print("=" * 70) try: # Test 1: UIElement element = test_uielement_creation() # Test 2: EnrichedScreenState screen_state = test_enriched_screen_state_light_mode() # Test 3: ScreenStateManager manager = test_screen_state_manager() # Test 4: WorkflowStateAdapter test_workflow_adapter() # Test 5: Compatibilité test_compatibility() print("\n" + "=" * 70) print("✓ TOUS LES TESTS RÉUSSIS!") print("=" * 70) print("\nRésumé:") print(" ✓ UIElement: Création, sérialisation, stabilité d'ID") print(" ✓ EnrichedScreenState: Mode light, sérialisation") print(" ✓ ScreenStateManager: Création, sauvegarde, chargement") print(" ✓ WorkflowStateAdapter: Compatibilité arrière") print(" ✓ Compatibilité: Lecture multi-format") print("\nPhase 1 (Mode Light) implémentée avec succès!") print("Les workflows existants continuent de fonctionner.") print("=" * 70) return True except Exception as e: print(f"\n✗ ÉCHEC DU TEST: {e}") import traceback traceback.print_exc() return False finally: cleanup() if __name__ == "__main__": success = main() sys.exit(0 if success else 1)