Files
rpa_vision_v3/scripts/test_etats_visuels_canvas_vwb_10jan2026.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

426 lines
18 KiB
Python

#!/usr/bin/env python3
"""
Test des États Visuels Canvas VWB - Validation des animations et indicateurs
Auteur : Dom, Alice, Kiro - 10 janvier 2026
Ce script teste l'implémentation des états visuels sur le Canvas pour les actions VWB,
vérifiant les animations, indicateurs de progression et feedback en temps réel.
"""
import os
import sys
import json
import time
from pathlib import Path
from typing import Dict, List, Any, Optional
class TestEtatsVisuelsCanvasVWB:
"""Test des états visuels Canvas VWB"""
def __init__(self):
self.resultats_test = {
'composants_canvas': {},
'animations_css': {},
'etats_visuels': {},
'integration_vwb': {},
'performance': {},
'score_global': 0
}
def afficher_banniere(self):
"""Afficher la bannière de test"""
print("🎨" + "="*70 + "🎨")
print("🚀 TEST DES ÉTATS VISUELS CANVAS VWB")
print("="*74)
print("📅 Date : 10 janvier 2026")
print("👥 Auteur : Dom, Alice, Kiro")
print("🎯 Objectif : Valider les animations et états visuels VWB")
print("="*74)
print()
def verifier_composants_canvas(self) -> bool:
"""Vérifier les composants Canvas VWB"""
print("🔍 Vérification des composants Canvas...")
composants_requis = {
'StepNode Principal': {
'path': 'visual_workflow_builder/frontend/src/components/Canvas/StepNode.tsx',
'checks': ['VWBStepNodeExtension', 'useVWBExecutionService', 'isVWBAction']
},
'Extension VWB StepNode': {
'path': 'visual_workflow_builder/frontend/src/components/Canvas/VWBStepNodeExtension.tsx',
'checks': ['VWBStepNodeExtension', 'pulseAnimation', 'glowAnimation', 'successPulse']
},
}
composants_valides = 0
for nom, config in composants_requis.items():
chemin = Path(config['path'])
if not chemin.exists():
print(f"{nom} manquant: {chemin}")
self.resultats_test['composants_canvas'][nom] = False
continue
try:
with open(chemin, 'r', encoding='utf-8') as f:
contenu = f.read()
checks_reussis = 0
for check in config['checks']:
if check in contenu:
checks_reussis += 1
else:
print(f"{check} manquant dans {nom}")
if checks_reussis == len(config['checks']):
print(f"{nom} validé ({checks_reussis}/{len(config['checks'])})")
self.resultats_test['composants_canvas'][nom] = True
composants_valides += 1
else:
print(f"{nom} incomplet ({checks_reussis}/{len(config['checks'])})")
self.resultats_test['composants_canvas'][nom] = False
except Exception as e:
print(f"❌ Erreur lecture {nom}: {e}")
self.resultats_test['composants_canvas'][nom] = False
return composants_valides == len(composants_requis)
def verifier_animations_css(self) -> bool:
"""Vérifier les animations CSS-in-JS"""
print("\n🔍 Vérification des animations CSS...")
extension_file = Path("visual_workflow_builder/frontend/src/components/Canvas/VWBStepNodeExtension.tsx")
if not extension_file.exists():
print("❌ Extension VWB StepNode manquante")
return False
try:
with open(extension_file, 'r', encoding='utf-8') as f:
contenu = f.read()
# Vérifications des animations
animations_requises = [
('pulseAnimation', 'Animation de pulsation'),
('glowAnimation', 'Animation de lueur'),
('successPulse', 'Animation de succès'),
('errorShake', 'Animation d\'erreur'),
('keyframes', 'Définitions keyframes'),
('LinearProgress', 'Barre de progression'),
('CircularProgress', 'Indicateur circulaire'),
('Fade', 'Animation de fondu'),
('Zoom', 'Animation de zoom'),
]
animations_trouvees = 0
for animation, description in animations_requises:
if animation in contenu:
print(f"{description}")
animations_trouvees += 1
else:
print(f"{description} manquante")
self.resultats_test['animations_css']['total'] = len(animations_requises)
self.resultats_test['animations_css']['trouvees'] = animations_trouvees
self.resultats_test['animations_css']['valide'] = animations_trouvees >= len(animations_requises) * 0.8
if animations_trouvees >= len(animations_requises) * 0.8:
print(f"✅ Animations CSS validées ({animations_trouvees}/{len(animations_requises)})")
return True
else:
print(f"❌ Animations incomplètes ({animations_trouvees}/{len(animations_requises)})")
return False
except Exception as e:
print(f"❌ Erreur vérification animations: {e}")
return False
def verifier_etats_visuels(self) -> bool:
"""Vérifier les états visuels"""
print("\n🔍 Vérification des états visuels...")
extension_file = Path("visual_workflow_builder/frontend/src/components/Canvas/VWBStepNodeExtension.tsx")
if not extension_file.exists():
print("❌ Extension VWB StepNode manquante")
return False
try:
with open(extension_file, 'r', encoding='utf-8') as f:
contenu = f.read()
# Vérifications des états visuels
etats_requis = [
('StepExecutionState.IDLE', 'État inactif'),
('StepExecutionState.RUNNING', 'État en cours'),
('StepExecutionState.SUCCESS', 'État succès'),
('StepExecutionState.ERROR', 'État erreur'),
('StepExecutionState.PAUSED', 'État en pause'),
('vwbExecutionStateColors', 'Couleurs d\'état'),
('vwbExecutionStateIcons', 'Icônes d\'état'),
('getBorderColor', 'Couleur de bordure dynamique'),
('getBackgroundColor', 'Couleur de fond dynamique'),
('getAnimationStyles', 'Styles d\'animation'),
]
etats_trouves = 0
for etat, description in etats_requis:
if etat in contenu:
print(f"{description}")
etats_trouves += 1
else:
print(f"{description} manquant")
self.resultats_test['etats_visuels']['total'] = len(etats_requis)
self.resultats_test['etats_visuels']['trouves'] = etats_trouves
self.resultats_test['etats_visuels']['valide'] = etats_trouves >= len(etats_requis) * 0.8
if etats_trouves >= len(etats_requis) * 0.8:
print(f"✅ États visuels validés ({etats_trouves}/{len(etats_requis)})")
return True
else:
print(f"❌ États visuels incomplets ({etats_trouves}/{len(etats_requis)})")
return False
except Exception as e:
print(f"❌ Erreur vérification états: {e}")
return False
def verifier_integration_vwb(self) -> bool:
"""Vérifier l'intégration VWB"""
print("\n🔍 Vérification de l'intégration VWB...")
stepnode_file = Path("visual_workflow_builder/frontend/src/components/Canvas/StepNode.tsx")
if not stepnode_file.exists():
print("❌ StepNode principal manquant")
return False
try:
with open(stepnode_file, 'r', encoding='utf-8') as f:
contenu = f.read()
# Vérifications d'intégration
integrations_requises = [
('VWBStepNodeExtension', 'Import extension VWB'),
('useVWBExecutionService', 'Service VWB'),
('isVWBStep', 'Détection étapes VWB'),
('isVWBAction', 'Variable de détection'),
('tempStep', 'Objet Step temporaire'),
('StandardStepNode', 'Composant standard'),
]
integrations_trouvees = 0
for integration, description in integrations_requises:
if integration in contenu:
print(f"{description}")
integrations_trouvees += 1
else:
print(f"{description} manquant")
self.resultats_test['integration_vwb']['total'] = len(integrations_requises)
self.resultats_test['integration_vwb']['trouvees'] = integrations_trouvees
self.resultats_test['integration_vwb']['valide'] = integrations_trouvees >= len(integrations_requises) * 0.7
if integrations_trouvees >= len(integrations_requises) * 0.7:
print(f"✅ Intégration VWB validée ({integrations_trouvees}/{len(integrations_requises)})")
return True
else:
print(f"❌ Intégration VWB incomplète ({integrations_trouvees}/{len(integrations_requises)})")
return False
except Exception as e:
print(f"❌ Erreur vérification intégration: {e}")
return False
def verifier_performance(self) -> bool:
"""Vérifier les optimisations de performance"""
print("\n🔍 Vérification des optimisations de performance...")
# Vérifier les mémorisations et optimisations
fichiers_a_verifier = [
'visual_workflow_builder/frontend/src/components/Canvas/StepNode.tsx',
'visual_workflow_builder/frontend/src/components/Canvas/VWBStepNodeExtension.tsx'
]
optimisations_trouvees = 0
optimisations_totales = 0
for fichier in fichiers_a_verifier:
if not Path(fichier).exists():
continue
try:
with open(fichier, 'r', encoding='utf-8') as f:
contenu = f.read()
# Vérifications de performance
checks_performance = [
('memo', 'Mémorisation React'),
('useCallback', 'Callbacks mémorisés'),
('useMemo', 'Valeurs mémorisées'),
('transition', 'Transitions CSS optimisées'),
]
for check, description in checks_performance:
optimisations_totales += 1
if check in contenu:
print(f"{description} dans {Path(fichier).name}")
optimisations_trouvees += 1
else:
print(f"{description} manquant dans {Path(fichier).name}")
except Exception as e:
print(f"❌ Erreur lecture {fichier}: {e}")
self.resultats_test['performance']['total'] = optimisations_totales
self.resultats_test['performance']['trouvees'] = optimisations_trouvees
self.resultats_test['performance']['valide'] = optimisations_trouvees >= optimisations_totales * 0.6
if optimisations_trouvees >= optimisations_totales * 0.6:
print(f"✅ Optimisations de performance validées ({optimisations_trouvees}/{optimisations_totales})")
return True
else:
print(f"❌ Optimisations insuffisantes ({optimisations_trouvees}/{optimisations_totales})")
return False
def calculer_score_global(self) -> int:
"""Calculer le score global"""
score = 0
total = 5
if self.resultats_test['composants_canvas'].get('StepNode Principal', False) and \
self.resultats_test['composants_canvas'].get('Extension VWB StepNode', False):
score += 1
if self.resultats_test['animations_css'].get('valide', False):
score += 1
if self.resultats_test['etats_visuels'].get('valide', False):
score += 1
if self.resultats_test['integration_vwb'].get('valide', False):
score += 1
if self.resultats_test['performance'].get('valide', False):
score += 1
self.resultats_test['score_global'] = score
return score
def generer_rapport_final(self):
"""Générer le rapport final"""
print("\n" + "🎯" + "="*70 + "🎯")
print("📊 RAPPORT FINAL - ÉTATS VISUELS CANVAS VWB")
print("="*74)
score = self.resultats_test['score_global']
total = 5
pourcentage = (score / total) * 100
print(f"\n🎯 SCORE GLOBAL: {score}/{total} ({pourcentage:.1f}%)")
if score == total:
print("🎉 ÉTATS VISUELS COMPLÈTEMENT IMPLÉMENTÉS!")
print("✅ Toutes les animations et indicateurs VWB sont opérationnels")
elif score >= 4:
print("✅ ÉTATS VISUELS MAJORITAIREMENT IMPLÉMENTÉS")
print("⚠️ Quelques ajustements mineurs possibles")
else:
print("❌ IMPLÉMENTATION INCOMPLÈTE")
print("🔧 Des corrections importantes sont nécessaires")
print(f"\n📋 DÉTAILS DE L'IMPLÉMENTATION:")
composants_valides = sum(1 for v in self.resultats_test['composants_canvas'].values() if v)
print(f" Composants Canvas: {composants_valides}/2")
animations_score = self.resultats_test['animations_css'].get('trouvees', 0)
animations_total = self.resultats_test['animations_css'].get('total', 9)
print(f" Animations CSS: {animations_score}/{animations_total}")
etats_score = self.resultats_test['etats_visuels'].get('trouves', 0)
etats_total = self.resultats_test['etats_visuels'].get('total', 10)
print(f" États Visuels: {etats_score}/{etats_total}")
integration_score = self.resultats_test['integration_vwb'].get('trouvees', 0)
integration_total = self.resultats_test['integration_vwb'].get('total', 6)
print(f" Intégration VWB: {integration_score}/{integration_total}")
perf_score = self.resultats_test['performance'].get('trouvees', 0)
perf_total = self.resultats_test['performance'].get('total', 8)
print(f" Optimisations: {perf_score}/{perf_total}")
print(f"\n🎯 PROCHAINES ÉTAPES:")
if score == total:
print(" 🚀 Continuer avec la Tâche 3.1.3 : Intégration Evidence Viewer")
print(" 📋 Implémenter l'affichage des Evidence pendant l'exécution")
else:
print(" 🔧 Corriger les composants manquants ou incomplets")
print(" 🎨 Améliorer les animations et états visuels")
print(f"\n📄 Rapport sauvegardé dans: tests/results/etats_visuels_canvas_vwb_10jan2026.json")
def sauvegarder_resultats(self):
"""Sauvegarder les résultats"""
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_global'] >= 4 else 'PARTIEL'
}
os.makedirs('tests/results', exist_ok=True)
with open('tests/results/etats_visuels_canvas_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"""
self.afficher_banniere()
# Étapes de test
etapes = [
("Composants Canvas", self.verifier_composants_canvas),
("Animations CSS", self.verifier_animations_css),
("États Visuels", self.verifier_etats_visuels),
("Intégration VWB", self.verifier_integration_vwb),
("Performance", self.verifier_performance),
]
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_global()
# Rapport final
self.generer_rapport_final()
# Sauvegarde
self.sauvegarder_resultats()
return score >= 4
def main():
"""Fonction principale"""
print("Test des États Visuels Canvas 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 = TestEtatsVisuelsCanvasVWB()
succes = test.executer_test_complet()
sys.exit(0 if succes else 1)
if __name__ == "__main__":
main()