- 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>
357 lines
14 KiB
Python
357 lines
14 KiB
Python
#!/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() |