380 lines
12 KiB
Python
380 lines
12 KiB
Python
"""
|
|
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)
|