- 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>
401 lines
16 KiB
Python
401 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test d'Intégration Executor VWB - Validation de l'extension d'exécution
|
|
Auteur : Dom, Alice, Kiro - 10 janvier 2026
|
|
|
|
Ce script teste l'intégration du système d'exécution VWB dans le composant Executor,
|
|
vérifiant que les actions VisionOnly peuvent être exécutées avec feedback visuel.
|
|
"""
|
|
|
|
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 TestIntegrationExecutorVWB:
|
|
"""Test d'intégration pour l'Executor VWB"""
|
|
|
|
def __init__(self):
|
|
self.backend_url = VWB_BACKEND_URL
|
|
self.frontend_url = VWB_FRONTEND_URL
|
|
self.resultats_test = {
|
|
'backend_disponible': False,
|
|
'composants_executor': {},
|
|
'services_execution': {},
|
|
'hooks_integration': {},
|
|
'tests_fonctionnels': {},
|
|
'score_integration': 0
|
|
}
|
|
|
|
def afficher_banniere(self):
|
|
"""Afficher la bannière de test"""
|
|
print("🧪" + "="*70 + "🧪")
|
|
print("🚀 TEST D'INTÉGRATION EXECUTOR VWB")
|
|
print("="*74)
|
|
print("📅 Date : 10 janvier 2026")
|
|
print("👥 Auteur : Dom, Alice, Kiro")
|
|
print("🎯 Objectif : Valider l'intégration du système d'exécution VWB")
|
|
print("="*74)
|
|
print()
|
|
|
|
def verifier_backend_disponible(self) -> bool:
|
|
"""Vérifier que le backend catalogue est disponible"""
|
|
print("🔍 Vérification du backend catalogue...")
|
|
|
|
try:
|
|
response = requests.get(f"{self.backend_url}/health", timeout=5)
|
|
if response.status_code == 200:
|
|
health_data = response.json()
|
|
print(f"✅ Backend disponible - Mode: {health_data.get('mode', 'unknown')}")
|
|
|
|
# Vérifier les actions
|
|
response = requests.get(f"{self.backend_url}/api/vwb/catalog/actions", timeout=5)
|
|
if response.status_code == 200:
|
|
actions_data = response.json()
|
|
actions_count = len(actions_data.get('actions', []))
|
|
print(f"✅ {actions_count} actions VWB disponibles")
|
|
self.resultats_test['backend_disponible'] = True
|
|
return True
|
|
else:
|
|
print("❌ API catalogue non accessible")
|
|
return False
|
|
else:
|
|
print(f"❌ Backend non disponible (code {response.status_code})")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur backend: {e}")
|
|
return False
|
|
|
|
def verifier_composants_executor(self) -> bool:
|
|
"""Vérifier les composants Executor VWB"""
|
|
print("\n🔍 Vérification des composants Executor...")
|
|
|
|
composants_requis = {
|
|
'Executor Principal': 'visual_workflow_builder/frontend/src/components/Executor/index.tsx',
|
|
'Extension VWB': 'visual_workflow_builder/frontend/src/components/Executor/VWBExecutorExtension.tsx',
|
|
'Service Exécution VWB': 'visual_workflow_builder/frontend/src/services/vwbExecutionService.ts',
|
|
'Hook Exécution VWB': 'visual_workflow_builder/frontend/src/hooks/useVWBExecution.ts',
|
|
}
|
|
|
|
composants_valides = 0
|
|
|
|
for nom, chemin in composants_requis.items():
|
|
if Path(chemin).exists():
|
|
# Vérifier le contenu
|
|
try:
|
|
with open(chemin, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
# Vérifications spécifiques selon le composant
|
|
if 'VWBExecutorExtension' in nom:
|
|
checks = ['VWBExecutorExtension', 'useVWBExecution', 'VWBExecutionSummary']
|
|
elif 'Service Exécution' in nom:
|
|
checks = ['VWBExecutionService', 'executeStep', 'validateStep']
|
|
elif 'Hook Exécution' in nom:
|
|
checks = ['useVWBExecution', 'startExecution', 'VWBExecutionState']
|
|
else:
|
|
checks = ['VWBExecutorExtension', 'enableVWBMode']
|
|
|
|
if all(check in contenu for check in checks):
|
|
print(f"✅ {nom} validé")
|
|
self.resultats_test['composants_executor'][nom] = True
|
|
composants_valides += 1
|
|
else:
|
|
print(f"❌ {nom} incomplet")
|
|
self.resultats_test['composants_executor'][nom] = False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lecture {nom}: {e}")
|
|
self.resultats_test['composants_executor'][nom] = False
|
|
else:
|
|
print(f"❌ {nom} manquant: {chemin}")
|
|
self.resultats_test['composants_executor'][nom] = False
|
|
|
|
return composants_valides == len(composants_requis)
|
|
|
|
def tester_service_execution_vwb(self) -> bool:
|
|
"""Tester le service d'exécution VWB"""
|
|
print("\n🔍 Test du service d'exécution VWB...")
|
|
|
|
# Vérifier la structure du service
|
|
service_file = Path("visual_workflow_builder/frontend/src/services/vwbExecutionService.ts")
|
|
if not service_file.exists():
|
|
print("❌ Service d'exécution VWB manquant")
|
|
return False
|
|
|
|
try:
|
|
with open(service_file, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
# Vérifications essentielles
|
|
checks = [
|
|
('VWBExecutionService', 'Classe principale du service'),
|
|
('executeStep', 'Méthode d\'exécution d\'étape'),
|
|
('validateStep', 'Méthode de validation'),
|
|
('isVWBStep', 'Détection d\'étapes VWB'),
|
|
('cancelExecution', 'Annulation d\'exécution'),
|
|
('VWBExecutionResult', 'Interface de résultat'),
|
|
('VWBExecutionOptions', 'Options d\'exécution'),
|
|
]
|
|
|
|
tests_reussis = 0
|
|
for check, description in checks:
|
|
if check in contenu:
|
|
print(f" ✅ {description}")
|
|
tests_reussis += 1
|
|
else:
|
|
print(f" ❌ {description} manquant")
|
|
|
|
self.resultats_test['services_execution']['structure'] = tests_reussis == len(checks)
|
|
self.resultats_test['services_execution']['tests_reussis'] = tests_reussis
|
|
self.resultats_test['services_execution']['tests_total'] = len(checks)
|
|
|
|
if tests_reussis >= len(checks) * 0.8: # 80% minimum
|
|
print("✅ Service d'exécution VWB validé")
|
|
return True
|
|
else:
|
|
print(f"❌ Service incomplet ({tests_reussis}/{len(checks)})")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur test service: {e}")
|
|
return False
|
|
|
|
def tester_hook_execution_vwb(self) -> bool:
|
|
"""Tester le hook d'exécution VWB"""
|
|
print("\n🔍 Test du hook d'exécution VWB...")
|
|
|
|
hook_file = Path("visual_workflow_builder/frontend/src/hooks/useVWBExecution.ts")
|
|
if not hook_file.exists():
|
|
print("❌ Hook d'exécution VWB manquant")
|
|
return False
|
|
|
|
try:
|
|
with open(hook_file, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
# Vérifications du hook
|
|
checks = [
|
|
('useVWBExecution', 'Hook principal'),
|
|
('VWBExecutionState', 'État d\'exécution'),
|
|
('VWBExecutionCallbacks', 'Callbacks d\'exécution'),
|
|
('startExecution', 'Démarrage d\'exécution'),
|
|
('pauseExecution', 'Pause d\'exécution'),
|
|
('stopExecution', 'Arrêt d\'exécution'),
|
|
('VWBExecutionSummary', 'Résumé d\'exécution'),
|
|
]
|
|
|
|
tests_reussis = 0
|
|
for check, description in checks:
|
|
if check in contenu:
|
|
print(f" ✅ {description}")
|
|
tests_reussis += 1
|
|
else:
|
|
print(f" ❌ {description} manquant")
|
|
|
|
self.resultats_test['hooks_integration']['structure'] = tests_reussis == len(checks)
|
|
self.resultats_test['hooks_integration']['tests_reussis'] = tests_reussis
|
|
self.resultats_test['hooks_integration']['tests_total'] = len(checks)
|
|
|
|
if tests_reussis >= len(checks) * 0.8:
|
|
print("✅ Hook d'exécution VWB validé")
|
|
return True
|
|
else:
|
|
print(f"❌ Hook incomplet ({tests_reussis}/{len(checks)})")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur test hook: {e}")
|
|
return False
|
|
|
|
def tester_integration_executor(self) -> bool:
|
|
"""Tester l'intégration dans le composant Executor"""
|
|
print("\n🔍 Test de l'intégration Executor...")
|
|
|
|
executor_file = Path("visual_workflow_builder/frontend/src/components/Executor/index.tsx")
|
|
if not executor_file.exists():
|
|
print("❌ Composant Executor manquant")
|
|
return False
|
|
|
|
try:
|
|
with open(executor_file, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
# Vérifications d'intégration
|
|
checks = [
|
|
('VWBExecutorExtension', 'Import de l\'extension VWB'),
|
|
('useVWBExecutionService', 'Import du service VWB'),
|
|
('enableVWBMode', 'Prop pour activer le mode VWB'),
|
|
('onEvidenceGenerated', 'Callback pour les Evidence'),
|
|
('variables', 'Support des variables'),
|
|
]
|
|
|
|
tests_reussis = 0
|
|
for check, description in checks:
|
|
if check in contenu:
|
|
print(f" ✅ {description}")
|
|
tests_reussis += 1
|
|
else:
|
|
print(f" ❌ {description} manquant")
|
|
|
|
self.resultats_test['tests_fonctionnels']['integration'] = tests_reussis >= len(checks) * 0.6
|
|
self.resultats_test['tests_fonctionnels']['tests_reussis'] = tests_reussis
|
|
self.resultats_test['tests_fonctionnels']['tests_total'] = len(checks)
|
|
|
|
if tests_reussis >= len(checks) * 0.6: # 60% minimum pour l'intégration
|
|
print("✅ Intégration Executor validée")
|
|
return True
|
|
else:
|
|
print(f"❌ Intégration incomplète ({tests_reussis}/{len(checks)})")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur test intégration: {e}")
|
|
return False
|
|
|
|
def calculer_score_integration(self) -> int:
|
|
"""Calculer le score global d'intégration"""
|
|
score = 0
|
|
total = 5
|
|
|
|
if self.resultats_test['backend_disponible']:
|
|
score += 1
|
|
|
|
composants_valides = sum(1 for v in self.resultats_test['composants_executor'].values() if v)
|
|
if composants_valides >= 3: # Au moins 3 composants sur 4
|
|
score += 1
|
|
|
|
if self.resultats_test['services_execution'].get('structure', False):
|
|
score += 1
|
|
|
|
if self.resultats_test['hooks_integration'].get('structure', False):
|
|
score += 1
|
|
|
|
if self.resultats_test['tests_fonctionnels'].get('integration', False):
|
|
score += 1
|
|
|
|
self.resultats_test['score_integration'] = score
|
|
return score
|
|
|
|
def generer_rapport_final(self):
|
|
"""Générer le rapport final de test"""
|
|
print("\n" + "🎯" + "="*70 + "🎯")
|
|
print("📊 RAPPORT FINAL - INTÉGRATION EXECUTOR VWB")
|
|
print("="*74)
|
|
|
|
score = self.resultats_test['score_integration']
|
|
total = 5
|
|
pourcentage = (score / total) * 100
|
|
|
|
print(f"\n🎯 SCORE GLOBAL: {score}/{total} ({pourcentage:.1f}%)")
|
|
|
|
if score == total:
|
|
print("🎉 INTÉGRATION COMPLÈTEMENT RÉUSSIE!")
|
|
print("✅ Le système d'exécution VWB est entièrement intégré")
|
|
elif score >= 4:
|
|
print("✅ INTÉGRATION MAJORITAIREMENT RÉUSSIE")
|
|
print("⚠️ Quelques ajustements mineurs possibles")
|
|
else:
|
|
print("❌ INTÉGRATION INCOMPLÈTE")
|
|
print("🔧 Des corrections importantes sont nécessaires")
|
|
|
|
print(f"\n📋 DÉTAILS DE L'INTÉGRATION:")
|
|
print(f" Backend Disponible: {'✅' if self.resultats_test['backend_disponible'] else '❌'}")
|
|
|
|
composants_valides = sum(1 for v in self.resultats_test['composants_executor'].values() if v)
|
|
print(f" Composants Executor: {composants_valides}/4")
|
|
|
|
services_score = self.resultats_test['services_execution'].get('tests_reussis', 0)
|
|
services_total = self.resultats_test['services_execution'].get('tests_total', 7)
|
|
print(f" Service Exécution: {services_score}/{services_total}")
|
|
|
|
hooks_score = self.resultats_test['hooks_integration'].get('tests_reussis', 0)
|
|
hooks_total = self.resultats_test['hooks_integration'].get('tests_total', 7)
|
|
print(f" Hook Exécution: {hooks_score}/{hooks_total}")
|
|
|
|
fonctionnel_score = self.resultats_test['tests_fonctionnels'].get('tests_reussis', 0)
|
|
fonctionnel_total = self.resultats_test['tests_fonctionnels'].get('tests_total', 5)
|
|
print(f" Tests Fonctionnels: {fonctionnel_score}/{fonctionnel_total}")
|
|
|
|
print(f"\n🎯 PROCHAINES ÉTAPES:")
|
|
if score == total:
|
|
print(" 🚀 Continuer avec la Tâche 3.1.2 : États Visuels sur le Canvas")
|
|
print(" 📋 Implémenter les animations et indicateurs de progression")
|
|
else:
|
|
print(" 🔧 Corriger les composants manquants ou incomplets")
|
|
print(" 🧪 Relancer les tests après corrections")
|
|
|
|
print(f"\n📄 Rapport sauvegardé dans: tests/results/integration_executor_vwb_10jan2026.json")
|
|
|
|
def sauvegarder_resultats(self):
|
|
"""Sauvegarder les résultats de test"""
|
|
resultats_complets = {
|
|
'timestamp': time.time(),
|
|
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
|
'test': self.resultats_test,
|
|
'statut': 'SUCCÈS' if self.resultats_test['score_integration'] >= 4 else 'PARTIEL'
|
|
}
|
|
|
|
os.makedirs('tests/results', exist_ok=True)
|
|
|
|
with open('tests/results/integration_executor_vwb_10jan2026.json', 'w', encoding='utf-8') as f:
|
|
json.dump(resultats_complets, f, indent=2, ensure_ascii=False)
|
|
|
|
def executer_test_complet(self):
|
|
"""Exécuter le test complet d'intégration"""
|
|
self.afficher_banniere()
|
|
|
|
# Étapes de test
|
|
etapes = [
|
|
("Backend Disponible", self.verifier_backend_disponible),
|
|
("Composants Executor", self.verifier_composants_executor),
|
|
("Service Exécution VWB", self.tester_service_execution_vwb),
|
|
("Hook Exécution VWB", self.tester_hook_execution_vwb),
|
|
("Intégration Executor", self.tester_integration_executor),
|
|
]
|
|
|
|
for nom_etape, fonction_test in etapes:
|
|
try:
|
|
fonction_test()
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors de {nom_etape}: {e}")
|
|
|
|
# Calcul du score
|
|
score = self.calculer_score_integration()
|
|
|
|
# Rapport final
|
|
self.generer_rapport_final()
|
|
|
|
# Sauvegarde
|
|
self.sauvegarder_resultats()
|
|
|
|
return score >= 4
|
|
|
|
def main():
|
|
"""Fonction principale"""
|
|
print("Test d'Intégration Executor 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 test
|
|
test = TestIntegrationExecutorVWB()
|
|
succes = test.executer_test_complet()
|
|
|
|
sys.exit(0 if succes else 1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |