#!/usr/bin/env python3 """ Test de Création d'Étapes VWB - Simulation complète du processus Auteur : Dom, Alice, Kiro - 10 janvier 2026 Ce script simule la création d'une étape VWB et teste l'affichage des propriétés en reproduisant exactement le processus utilisateur. """ import os import sys import json import time import requests import subprocess from pathlib import Path from typing import Dict, List, Any, Optional # Configuration VWB_BACKEND_URL = "http://localhost:5004" VWB_FRONTEND_URL = "http://localhost:3000" class VWBEtapeTesteur: """Testeur pour la création d'étapes VWB""" def __init__(self): self.backend_url = VWB_BACKEND_URL self.actions_catalogue = [] self.etapes_test = [] def charger_actions_catalogue(self) -> bool: """Charger les actions du catalogue""" print("🔍 Chargement des actions du catalogue...") try: response = requests.get(f"{self.backend_url}/api/vwb/catalog/actions", timeout=10) if response.status_code == 200: data = response.json() self.actions_catalogue = data.get('actions', []) print(f"✅ {len(self.actions_catalogue)} actions chargées") return True else: print(f"❌ Erreur API: {response.status_code}") return False except Exception as e: print(f"❌ Erreur: {e}") return False def creer_etape_vwb_simulee(self, action_id: str) -> Dict[str, Any]: """Créer une étape VWB simulée""" print(f"🔧 Création d'une étape VWB pour l'action {action_id}...") # Trouver l'action dans le catalogue action = next((a for a in self.actions_catalogue if a['id'] == action_id), None) if not action: print(f"❌ Action {action_id} non trouvée") return {} # Créer les paramètres par défaut parametres_defaut = {} for param_name, param_config in action.get('parameters', {}).items(): if 'default' in param_config: parametres_defaut[param_name] = param_config['default'] elif param_config.get('required', False): # Valeurs par défaut pour les paramètres requis if param_config['type'] == 'string': parametres_defaut[param_name] = "" elif param_config['type'] == 'number': parametres_defaut[param_name] = 0 elif param_config['type'] == 'boolean': parametres_defaut[param_name] = False elif param_config['type'] == 'VWBVisualAnchor': parametres_defaut[param_name] = None # Créer l'étape VWB etape_vwb = { 'id': f'vwb_step_{int(time.time())}_{action_id}', 'type': action_id, 'name': action['name'], 'position': {'x': 100, 'y': 100}, 'data': { 'label': action['name'], 'stepType': action_id, 'parameters': parametres_defaut, 'isVWBCatalogAction': True, 'vwbActionId': action_id, }, 'executionState': 'IDLE', 'validationErrors': [] } print(f"✅ Étape VWB créée: {etape_vwb['id']}") return etape_vwb def tester_detection_etape_vwb(self, etape: Dict[str, Any]) -> bool: """Tester la détection d'une étape VWB""" print(f"🔍 Test de détection de l'étape VWB...") # Vérifier les marqueurs VWB data = etape.get('data', {}) # Test 1: Marqueur isVWBCatalogAction if not data.get('isVWBCatalogAction', False): print("❌ Marqueur isVWBCatalogAction manquant") return False print("✅ Marqueur isVWBCatalogAction présent") # Test 2: ID d'action VWB vwb_action_id = data.get('vwbActionId') if not vwb_action_id: print("❌ vwbActionId manquant") return False print(f"✅ vwbActionId présent: {vwb_action_id}") # Test 3: Action existe dans le catalogue action_existe = any(a['id'] == vwb_action_id for a in self.actions_catalogue) if not action_existe: print(f"❌ Action {vwb_action_id} non trouvée dans le catalogue") return False print(f"✅ Action {vwb_action_id} trouvée dans le catalogue") # Test 4: Paramètres présents parametres = data.get('parameters', {}) if not isinstance(parametres, dict): print("❌ Paramètres invalides") return False print(f"✅ Paramètres présents: {list(parametres.keys())}") return True def simuler_affichage_proprietes(self, etape: Dict[str, Any]) -> bool: """Simuler l'affichage des propriétés""" print(f"🎨 Simulation de l'affichage des propriétés...") # Récupérer l'action du catalogue vwb_action_id = etape['data']['vwbActionId'] action = next((a for a in self.actions_catalogue if a['id'] == vwb_action_id), None) if not action: print(f"❌ Impossible de charger l'action {vwb_action_id}") return False print(f"✅ Action chargée: {action['name']}") print(f" Description: {action['description']}") print(f" Catégorie: {action['category']}") print(f" Paramètres: {len(action['parameters'])}") # Simuler l'affichage des paramètres parametres_etape = etape['data']['parameters'] parametres_action = action['parameters'] print("\n📋 PROPRIÉTÉS DE L'ÉTAPE:") print("=" * 40) # Paramètres requis parametres_requis = {k: v for k, v in parametres_action.items() if v.get('required', False)} if parametres_requis: print(f"\n🔴 Paramètres requis ({len(parametres_requis)}):") for param_name, param_config in parametres_requis.items(): valeur_actuelle = parametres_etape.get(param_name, 'NON DÉFINI') print(f" • {param_name} ({param_config['type']}): {valeur_actuelle}") print(f" Description: {param_config.get('description', 'N/A')}") # Paramètres optionnels parametres_optionnels = {k: v for k, v in parametres_action.items() if not v.get('required', False)} if parametres_optionnels: print(f"\n🔵 Paramètres optionnels ({len(parametres_optionnels)}):") for param_name, param_config in parametres_optionnels.items(): valeur_actuelle = parametres_etape.get(param_name, param_config.get('default', 'NON DÉFINI')) print(f" • {param_name} ({param_config['type']}): {valeur_actuelle}") # Vérifier les paramètres VWBVisualAnchor anchors_requis = [k for k, v in parametres_action.items() if v.get('type') == 'VWBVisualAnchor'] if anchors_requis: print(f"\n🎯 Ancres visuelles requises ({len(anchors_requis)}):") for anchor_name in anchors_requis: valeur = parametres_etape.get(anchor_name) if valeur is None: print(f" • {anchor_name}: ❌ NON CONFIGURÉ") print(f" → L'utilisateur doit sélectionner un élément visuel") else: print(f" • {anchor_name}: ✅ CONFIGURÉ") return True def tester_validation_etape(self, etape: Dict[str, Any]) -> bool: """Tester la validation d'une étape VWB""" print(f"✅ Test de validation de l'étape...") try: # Préparer la requête de validation validation_request = { 'type': etape['data']['vwbActionId'], 'parameters': etape['data']['parameters'] } # Envoyer la requête de validation response = requests.post( f"{self.backend_url}/api/vwb/catalog/validate", json=validation_request, timeout=10 ) if response.status_code == 200: validation_result = response.json() is_valid = validation_result.get('validation', {}).get('is_valid', False) errors = validation_result.get('validation', {}).get('errors', []) warnings = validation_result.get('validation', {}).get('warnings', []) print(f"✅ Validation terminée: {'VALIDE' if is_valid else 'INVALIDE'}") if errors: print(f"❌ Erreurs ({len(errors)}):") for error in errors: print(f" • {error.get('parameter', 'N/A')}: {error.get('message', 'N/A')}") if warnings: print(f"⚠️ Avertissements ({len(warnings)}):") for warning in warnings: print(f" • {warning.get('parameter', 'N/A')}: {warning.get('message', 'N/A')}") return is_valid else: print(f"❌ Erreur validation: {response.status_code}") return False except Exception as e: print(f"❌ Erreur validation: {e}") return False def executer_test_complet(self): """Exécuter le test complet""" print("🚀 TEST COMPLET DE CRÉATION D'ÉTAPES VWB") print("=" * 50) # Étape 1: Charger le catalogue if not self.charger_actions_catalogue(): print("❌ Impossible de charger le catalogue") return False # Étape 2: Tester avec plusieurs actions actions_test = ['click_anchor', 'type_text', 'wait_for_anchor'] resultats = [] for action_id in actions_test: print(f"\n🔧 TEST DE L'ACTION: {action_id}") print("-" * 30) # Créer l'étape etape = self.creer_etape_vwb_simulee(action_id) if not etape: continue # Tester la détection detection_ok = self.tester_detection_etape_vwb(etape) # Simuler l'affichage affichage_ok = self.simuler_affichage_proprietes(etape) # Tester la validation validation_ok = self.tester_validation_etape(etape) resultat = { 'action_id': action_id, 'etape_creee': bool(etape), 'detection_ok': detection_ok, 'affichage_ok': affichage_ok, 'validation_ok': validation_ok, 'etape': etape } resultats.append(resultat) self.etapes_test.append(etape) # Résumé print(f"\n📊 RÉSUMÉ DES TESTS") print("=" * 50) for resultat in resultats: action_id = resultat['action_id'] statut = "✅" if all([ resultat['etape_creee'], resultat['detection_ok'], resultat['affichage_ok'] ]) else "❌" print(f"{statut} {action_id}:") print(f" Création: {'✅' if resultat['etape_creee'] else '❌'}") print(f" Détection: {'✅' if resultat['detection_ok'] else '❌'}") print(f" Affichage: {'✅' if resultat['affichage_ok'] else '❌'}") print(f" Validation: {'✅' if resultat['validation_ok'] else '❌'}") # Diagnostic print(f"\n🔧 DIAGNOSTIC") print("=" * 50) tous_ok = all(all([r['etape_creee'], r['detection_ok'], r['affichage_ok']]) for r in resultats) if tous_ok: print("🎉 TOUS LES TESTS RÉUSSIS!") print("Les propriétés d'étapes VWB devraient s'afficher correctement.") print("\nPour tester dans l'interface:") print("1. Démarrer le frontend: cd visual_workflow_builder/frontend && npm start") print("2. Glisser une action du catalogue vers le canvas") print("3. Sélectionner l'étape créée") print("4. Vérifier l'affichage des propriétés dans le panneau de droite") else: print("❌ PROBLÈMES DÉTECTÉS") print("Les propriétés d'étapes VWB ne s'afficheront pas correctement.") # Identifier les problèmes problemes = [] for resultat in resultats: if not resultat['etape_creee']: problemes.append(f"Création d'étape échouée pour {resultat['action_id']}") if not resultat['detection_ok']: problemes.append(f"Détection VWB échouée pour {resultat['action_id']}") if not resultat['affichage_ok']: problemes.append(f"Affichage propriétés échoué pour {resultat['action_id']}") print("Problèmes identifiés:") for probleme in problemes: print(f" • {probleme}") # Sauvegarder les résultats with open('tests/results/test_creation_etape_vwb_10jan2026.json', 'w', encoding='utf-8') as f: json.dump({ 'timestamp': time.time(), 'resultats': resultats, 'etapes_test': self.etapes_test, 'actions_catalogue': len(self.actions_catalogue), 'tous_ok': tous_ok }, f, indent=2, ensure_ascii=False) print(f"\n📄 Résultats sauvegardés dans tests/results/test_creation_etape_vwb_10jan2026.json") return tous_ok def main(): """Fonction principale""" print("Test de Création d'Étapes VWB - 10 janvier 2026") print("Auteur : Dom, Alice, Kiro") print() # Vérifier qu'on est dans le bon répertoire if not os.path.exists('visual_workflow_builder'): print("❌ Erreur: Exécuter depuis la racine du projet RPA Vision V3") sys.exit(1) # Créer et exécuter le testeur testeur = VWBEtapeTesteur() succes = testeur.executer_test_complet() sys.exit(0 if succes else 1) if __name__ == "__main__": main()