#!/usr/bin/env python3 """ Démonstration Fiche #12 - Form Rows/Columns Auteur : Dom, Alice Kiro Date : 19 décembre 2024 """ from datetime import datetime from core.execution.target_resolver import TargetResolver, ResolutionContext from core.models.workflow_graph import TargetSpec from core.models.screen_state import ScreenState, RawLevel, PerceptionLevel, ContextLevel, WindowContext, EmbeddingRef from core.models.ui_element import UIElement, UIElementEmbeddings, VisualFeatures def create_element(eid, role, bbox, label="", etype="ui", conf=0.95): """Helper pour créer un UIElement""" return UIElement( element_id=eid, type=etype, role=role, bbox=bbox, center=(bbox[0]+bbox[2]//2, bbox[1]+bbox[3]//2), label=label, label_confidence=1.0 if label else 0.0, embeddings=UIElementEmbeddings(image=None, text=None), visual_features=VisualFeatures( dominant_color="#ffffff", has_icon=False, shape="rectangle", size_category="medium" ), confidence=conf, tags=[], metadata={} ) def create_screen(elements): """Helper pour créer un ScreenState""" return ScreenState( screen_state_id="demo_screen", timestamp=datetime.now(), session_id="demo_session", window=WindowContext(app_name="Demo App", window_title="Form Demo", screen_resolution=[1920,1080]), raw=RawLevel(screenshot_path="demo.png", capture_method="test", file_size_bytes=1024), perception=PerceptionLevel( embedding=EmbeddingRef(provider="demo", vector_id="demo_vector", dimensions=512), detected_text=[], text_detection_method="ocr", confidence_avg=0.9 ), context=ContextLevel(), ui_elements=elements ) def demo_form_login(): """Démonstration : Formulaire de connexion classique""" print("🔐 Démonstration : Formulaire de connexion") print("=" * 50) # Créer un formulaire de connexion réaliste elements = [ # Panel de connexion create_element("login_panel", "panel", (50, 50, 400, 300), "Login"), # Ligne 1 : Username create_element("lbl_username", "label", (80, 100, 100, 20), "Username"), create_element("inp_username", "input", (200, 95, 200, 30), "", etype="text_input"), # Ligne 2 : Password create_element("lbl_password", "label", (80, 150, 100, 20), "Password"), create_element("inp_password", "input", (200, 145, 200, 30), "", etype="text_input"), # Ligne 3 : Boutons create_element("btn_login", "button", (200, 200, 80, 35), "Login"), create_element("btn_cancel", "button", (300, 200, 80, 35), "Cancel"), # Éléments distracteurs create_element("inp_search", "input", (500, 100, 150, 30), "", etype="text_input"), create_element("lbl_search", "label", (500, 80, 100, 20), "Search"), ] screen = create_screen(elements) resolver = TargetResolver() context = ResolutionContext(screen_state=screen) # Test 1 : Trouver le champ Username print("\n📝 Test 1 : Chercher le champ pour 'Username'") spec1 = TargetSpec(by_role="input", context_hints={"field_for": "Username"}) result1 = resolver.resolve_target(spec1, screen, context) if result1: print(f"✅ Trouvé : {result1.element.element_id} (confiance: {result1.confidence:.2f})") print(f" Stratégie : {result1.strategy_used}") print(f" Ancre : {result1.resolution_details.get('anchor_id', 'N/A')}") else: print("❌ Aucun résultat") # Test 2 : Trouver le champ Password print("\n🔒 Test 2 : Chercher le champ pour 'Password'") spec2 = TargetSpec(by_role="input", context_hints={"field_for": "Password"}) result2 = resolver.resolve_target(spec2, screen, context) if result2: print(f"✅ Trouvé : {result2.element.element_id} (confiance: {result2.confidence:.2f})") print(f" Stratégie : {result2.strategy_used}") print(f" Ancre : {result2.resolution_details.get('anchor_id', 'N/A')}") else: print("❌ Aucun résultat") # Test 3 : Bonus same_row_as_text print("\n🎯 Test 3 : Bouton sur même ligne que 'Cancel'") spec3 = TargetSpec(by_role="button", by_text="Login", context_hints={"same_row_as_text": "Cancel"}) result3 = resolver.resolve_target(spec3, screen, context) if result3: print(f"✅ Trouvé : {result3.element.element_id} (confiance: {result3.confidence:.2f})") print(f" Stratégie : {result3.strategy_used}") else: print("❌ Aucun résultat") def demo_form_complex(): """Démonstration : Formulaire complexe avec fallback""" print("\n\n🏢 Démonstration : Formulaire complexe") print("=" * 50) # Formulaire avec layout vertical (fallback) elements = [ # Section 1 : Informations personnelles create_element("section1", "panel", (50, 50, 350, 200), "Personal Info"), # Nom (layout vertical - fallback) create_element("lbl_name", "label", (80, 80, 80, 20), "Full Name"), create_element("inp_name", "input", (80, 110, 250, 30), "", etype="text_input"), # Email (layout horizontal - priorité) create_element("lbl_email", "label", (80, 160, 60, 20), "Email"), create_element("inp_email", "input", (160, 155, 200, 30), "", etype="text_input"), # Section 2 : Adresse create_element("section2", "panel", (50, 280, 350, 150), "Address"), # Ville (avec contrainte de conteneur) create_element("lbl_city", "label", (80, 320, 60, 20), "City"), create_element("inp_city", "input", (160, 315, 150, 30), "", etype="text_input"), # Input distracteur hors section create_element("inp_other", "input", (500, 320, 150, 30), "", etype="text_input"), ] screen = create_screen(elements) resolver = TargetResolver() context = ResolutionContext(screen_state=screen) # Test 1 : Fallback vertical pour "Full Name" print("\n📝 Test 1 : Fallback vertical pour 'Full Name'") spec1 = TargetSpec(by_role="input", context_hints={"field_for": "Full Name"}) result1 = resolver.resolve_target(spec1, screen, context) if result1: print(f"✅ Trouvé : {result1.element.element_id} (confiance: {result1.confidence:.2f})") print(f" Mode : {'Même ligne' if result1.confidence >= 0.95 else 'Fallback vertical'}") else: print("❌ Aucun résultat") # Test 2 : Priorité horizontale pour "Email" print("\n📧 Test 2 : Priorité horizontale pour 'Email'") spec2 = TargetSpec(by_role="input", context_hints={"field_for": "Email"}) result2 = resolver.resolve_target(spec2, screen, context) if result2: print(f"✅ Trouvé : {result2.element.element_id} (confiance: {result2.confidence:.2f})") print(f" Mode : {'Même ligne' if result2.confidence >= 0.95 else 'Fallback vertical'}") else: print("❌ Aucun résultat") # Test 3 : Contrainte de conteneur print("\n🏠 Test 3 : Champ 'City' avec contrainte de conteneur") spec3 = TargetSpec( by_role="input", context_hints={"field_for": "City"}, hard_constraints={"within_container_text": "Address"} ) result3 = resolver.resolve_target(spec3, screen, context) if result3: print(f"✅ Trouvé : {result3.element.element_id} (confiance: {result3.confidence:.2f})") print(f" Respecte contrainte conteneur : ✅") else: print("❌ Aucun résultat") def demo_multi_anchor(): """Démonstration : Support multi-anchor""" print("\n\n🌍 Démonstration : Support multi-anchor (multilingue)") print("=" * 60) # Interface multilingue elements = [ # Labels en français create_element("lbl_identifiant", "label", (80, 100, 120, 20), "Identifiant"), create_element("inp_user", "input", (220, 95, 200, 30), "", etype="text_input"), # Labels en anglais (autre section) create_element("lbl_password_en", "label", (80, 150, 100, 20), "Password"), create_element("inp_pass", "input", (200, 145, 200, 30), "", etype="text_input"), ] screen = create_screen(elements) resolver = TargetResolver() context = ResolutionContext(screen_state=screen) # Test multi-anchor : chercher Username OU Identifiant print("\n🔍 Test : Chercher champ pour ['Username', 'Identifiant']") spec = TargetSpec( by_role="input", context_hints={"field_for": ["Username", "Identifiant", "User"]} ) result = resolver.resolve_target(spec, screen, context) if result: print(f"✅ Trouvé : {result.element.element_id} (confiance: {result.confidence:.2f})") print(f" Ancre utilisée : {result.resolution_details.get('anchor_id', 'N/A')}") print(f" Labels cherchés : {result.resolution_details.get('criteria_used', {}).get('field_for', [])}") else: print("❌ Aucun résultat") if __name__ == "__main__": print("🚀 Démonstration Fiche #12 - Form Rows/Columns") print("Auteur : Dom, Alice Kiro - 19 décembre 2024") print("=" * 60) try: demo_form_login() demo_form_complex() demo_multi_anchor() print("\n\n🎉 Démonstration terminée avec succès !") print("La Fiche #12 fonctionne parfaitement pour l'association label→champ.") except Exception as e: print(f"\n❌ Erreur durant la démonstration : {e}") import traceback traceback.print_exc()