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>
This commit is contained in:
357
scripts/test_creation_etape_vwb_10jan2026.py
Normal file
357
scripts/test_creation_etape_vwb_10jan2026.py
Normal file
@@ -0,0 +1,357 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user