Files
rpa_vision_v3/demo_fiche12_form_rows.py
Dom a27b74cf22 v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40)
- Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard)
- Ollama GPU fonctionnel
- Self-healing interactif
- Dashboard confiance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:23:51 +01:00

234 lines
9.5 KiB
Python

#!/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()