- 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>
481 lines
17 KiB
Python
481 lines
17 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script de Test - Interface Propriétés d'Étapes Complète
|
|
Auteur : Dom, Alice, Kiro - 12 janvier 2026
|
|
|
|
Ce script teste l'interface complète des propriétés d'étapes pour s'assurer
|
|
que tous les composants fonctionnent correctement avec les vrais contrôles.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import subprocess
|
|
import requests
|
|
from pathlib import Path
|
|
|
|
# Configuration
|
|
VWB_BACKEND_URL = "http://localhost:5003"
|
|
VWB_FRONTEND_URL = "http://localhost:3000"
|
|
TEST_TIMEOUT = 30
|
|
|
|
def print_header(title: str):
|
|
"""Affiche un en-tête de section"""
|
|
print(f"\n{'='*60}")
|
|
print(f" {title}")
|
|
print(f"{'='*60}")
|
|
|
|
def print_step(step: str):
|
|
"""Affiche une étape de test"""
|
|
print(f"\n🔧 {step}")
|
|
|
|
def print_success(message: str):
|
|
"""Affiche un message de succès"""
|
|
print(f"✅ {message}")
|
|
|
|
def print_error(message: str):
|
|
"""Affiche un message d'erreur"""
|
|
print(f"❌ {message}")
|
|
|
|
def print_warning(message: str):
|
|
"""Affiche un message d'avertissement"""
|
|
print(f"⚠️ {message}")
|
|
|
|
def check_backend_status():
|
|
"""Vérifie que le backend VWB est démarré"""
|
|
print_step("Vérification du backend VWB...")
|
|
|
|
try:
|
|
response = requests.get(f"{VWB_BACKEND_URL}/api/health", timeout=5)
|
|
if response.status_code == 200:
|
|
print_success("Backend VWB accessible")
|
|
return True
|
|
else:
|
|
print_error(f"Backend VWB retourne le code {response.status_code}")
|
|
return False
|
|
except requests.exceptions.RequestException as e:
|
|
print_error(f"Backend VWB inaccessible: {e}")
|
|
return False
|
|
|
|
def check_frontend_status():
|
|
"""Vérifie que le frontend VWB est démarré"""
|
|
print_step("Vérification du frontend VWB...")
|
|
|
|
try:
|
|
response = requests.get(VWB_FRONTEND_URL, timeout=5)
|
|
if response.status_code == 200:
|
|
print_success("Frontend VWB accessible")
|
|
return True
|
|
else:
|
|
print_error(f"Frontend VWB retourne le code {response.status_code}")
|
|
return False
|
|
except requests.exceptions.RequestException as e:
|
|
print_error(f"Frontend VWB inaccessible: {e}")
|
|
return False
|
|
|
|
def test_step_type_resolver():
|
|
"""Teste le service StepTypeResolver"""
|
|
print_step("Test du StepTypeResolver...")
|
|
|
|
try:
|
|
# Test avec une étape standard
|
|
test_data = {
|
|
"step": {
|
|
"id": "test_step_1",
|
|
"type": "click",
|
|
"data": {
|
|
"parameters": {}
|
|
}
|
|
}
|
|
}
|
|
|
|
response = requests.post(
|
|
f"{VWB_BACKEND_URL}/api/step-type-resolver/resolve",
|
|
json=test_data,
|
|
timeout=10
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
if result.get("success") and result.get("parameterConfig"):
|
|
print_success(f"Résolution étape standard réussie - {len(result['parameterConfig'])} paramètres")
|
|
return True
|
|
else:
|
|
print_error("Résolution étape standard échouée")
|
|
return False
|
|
else:
|
|
print_error(f"Erreur API StepTypeResolver: {response.status_code}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur test StepTypeResolver: {e}")
|
|
return False
|
|
|
|
def test_catalog_service():
|
|
"""Teste le service de catalogue VWB"""
|
|
print_step("Test du service de catalogue...")
|
|
|
|
try:
|
|
response = requests.get(f"{VWB_BACKEND_URL}/api/catalog/actions", timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
actions = response.json()
|
|
if isinstance(actions, list) and len(actions) > 0:
|
|
print_success(f"Catalogue accessible - {len(actions)} actions disponibles")
|
|
return True
|
|
else:
|
|
print_warning("Catalogue vide ou format incorrect")
|
|
return False
|
|
else:
|
|
print_error(f"Erreur API catalogue: {response.status_code}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur test catalogue: {e}")
|
|
return False
|
|
|
|
def test_screen_capture_service():
|
|
"""Teste le service de capture d'écran"""
|
|
print_step("Test du service de capture d'écran...")
|
|
|
|
try:
|
|
response = requests.get(f"{VWB_BACKEND_URL}/api/real-screen-capture/status", timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
status = response.json()
|
|
if status.get("success"):
|
|
print_success("Service de capture d'écran disponible")
|
|
return True
|
|
else:
|
|
print_warning("Service de capture d'écran indisponible")
|
|
return False
|
|
else:
|
|
print_error(f"Erreur API capture d'écran: {response.status_code}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur test capture d'écran: {e}")
|
|
return False
|
|
|
|
def check_typescript_compilation():
|
|
"""Vérifie la compilation TypeScript"""
|
|
print_step("Vérification de la compilation TypeScript...")
|
|
|
|
frontend_dir = Path("visual_workflow_builder/frontend")
|
|
if not frontend_dir.exists():
|
|
print_error("Répertoire frontend non trouvé")
|
|
return False
|
|
|
|
try:
|
|
# Vérifier la compilation TypeScript
|
|
result = subprocess.run(
|
|
["npm", "run", "type-check"],
|
|
cwd=frontend_dir,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
print_success("Compilation TypeScript réussie")
|
|
return True
|
|
else:
|
|
print_error("Erreurs de compilation TypeScript:")
|
|
print(result.stderr)
|
|
return False
|
|
|
|
except subprocess.TimeoutExpired:
|
|
print_error("Timeout lors de la compilation TypeScript")
|
|
return False
|
|
except Exception as e:
|
|
print_error(f"Erreur compilation TypeScript: {e}")
|
|
return False
|
|
|
|
def test_properties_panel_components():
|
|
"""Teste les composants du panneau de propriétés"""
|
|
print_step("Test des composants du panneau de propriétés...")
|
|
|
|
components_to_check = [
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/StandardParametersEditor.tsx",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/ParameterFieldRenderer.tsx",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/EmptyStateMessage.tsx",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/LoadingState.tsx",
|
|
"visual_workflow_builder/frontend/src/components/RealScreenCapture/index.tsx",
|
|
"visual_workflow_builder/frontend/src/services/StepTypeResolver.ts",
|
|
"visual_workflow_builder/frontend/src/hooks/useStepTypeResolver.ts"
|
|
]
|
|
|
|
missing_components = []
|
|
for component_path in components_to_check:
|
|
if not Path(component_path).exists():
|
|
missing_components.append(component_path)
|
|
|
|
if missing_components:
|
|
print_error("Composants manquants:")
|
|
for component in missing_components:
|
|
print(f" - {component}")
|
|
return False
|
|
else:
|
|
print_success("Tous les composants requis sont présents")
|
|
return True
|
|
|
|
def create_test_workflow():
|
|
"""Crée un workflow de test avec différents types d'étapes"""
|
|
print_step("Création d'un workflow de test...")
|
|
|
|
test_workflow = {
|
|
"id": "test_workflow_properties",
|
|
"name": "Test Interface Propriétés",
|
|
"description": "Workflow de test pour l'interface des propriétés d'étapes",
|
|
"steps": [
|
|
{
|
|
"id": "step_1",
|
|
"type": "click",
|
|
"name": "Clic de test",
|
|
"data": {
|
|
"parameters": {
|
|
"target": None,
|
|
"clickType": "left"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "step_2",
|
|
"type": "type",
|
|
"name": "Saisie de test",
|
|
"data": {
|
|
"parameters": {
|
|
"target": None,
|
|
"text": "Texte de test",
|
|
"clearFirst": True
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "step_3",
|
|
"type": "wait",
|
|
"name": "Attente de test",
|
|
"data": {
|
|
"parameters": {
|
|
"duration": 2
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "step_4",
|
|
"type": "click_anchor",
|
|
"name": "Action VWB de test",
|
|
"data": {
|
|
"isVWBCatalogAction": True,
|
|
"vwbActionId": "click_anchor",
|
|
"parameters": {}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
try:
|
|
response = requests.post(
|
|
f"{VWB_BACKEND_URL}/api/workflows",
|
|
json=test_workflow,
|
|
timeout=10
|
|
)
|
|
|
|
if response.status_code in [200, 201]:
|
|
print_success("Workflow de test créé")
|
|
return test_workflow["id"]
|
|
else:
|
|
print_error(f"Erreur création workflow: {response.status_code}")
|
|
return None
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur création workflow: {e}")
|
|
return None
|
|
|
|
def test_properties_interface_functionality():
|
|
"""Teste la fonctionnalité de l'interface des propriétés"""
|
|
print_step("Test de la fonctionnalité de l'interface des propriétés...")
|
|
|
|
# Créer un workflow de test
|
|
workflow_id = create_test_workflow()
|
|
if not workflow_id:
|
|
return False
|
|
|
|
try:
|
|
# Tester la résolution des propriétés pour chaque type d'étape
|
|
step_types = ["click", "type", "wait", "click_anchor"]
|
|
|
|
for step_type in step_types:
|
|
test_step = {
|
|
"id": f"test_{step_type}",
|
|
"type": step_type,
|
|
"data": {
|
|
"parameters": {},
|
|
"isVWBCatalogAction": step_type.startswith("click_anchor")
|
|
}
|
|
}
|
|
|
|
response = requests.post(
|
|
f"{VWB_BACKEND_URL}/api/step-type-resolver/resolve",
|
|
json={"step": test_step},
|
|
timeout=10
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
if result.get("success"):
|
|
print_success(f"Résolution réussie pour {step_type}")
|
|
else:
|
|
print_warning(f"Résolution échouée pour {step_type}")
|
|
else:
|
|
print_error(f"Erreur API pour {step_type}: {response.status_code}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur test fonctionnalité: {e}")
|
|
return False
|
|
|
|
def run_integration_tests():
|
|
"""Lance les tests d'intégration"""
|
|
print_step("Lancement des tests d'intégration...")
|
|
|
|
try:
|
|
# Lancer les tests d'intégration spécifiques
|
|
test_files = [
|
|
"tests/integration/test_correction_proprietes_etapes_finale_12jan2026.py",
|
|
"tests/property/test_parameter_field_renderer_properties_12jan2026.py",
|
|
"tests/property/test_standard_parameters_editor_properties_12jan2026.py"
|
|
]
|
|
|
|
success_count = 0
|
|
for test_file in test_files:
|
|
if Path(test_file).exists():
|
|
try:
|
|
result = subprocess.run(
|
|
["python", "-m", "pytest", test_file, "-v"],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
print_success(f"Test réussi: {test_file}")
|
|
success_count += 1
|
|
else:
|
|
print_error(f"Test échoué: {test_file}")
|
|
print(result.stdout)
|
|
|
|
except subprocess.TimeoutExpired:
|
|
print_error(f"Timeout test: {test_file}")
|
|
except Exception as e:
|
|
print_error(f"Erreur test {test_file}: {e}")
|
|
else:
|
|
print_warning(f"Test non trouvé: {test_file}")
|
|
|
|
return success_count > 0
|
|
|
|
except Exception as e:
|
|
print_error(f"Erreur tests d'intégration: {e}")
|
|
return False
|
|
|
|
def generate_test_report():
|
|
"""Génère un rapport de test"""
|
|
print_step("Génération du rapport de test...")
|
|
|
|
report = {
|
|
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
"test_name": "Interface Propriétés d'Étapes Complète",
|
|
"version": "12 janvier 2026",
|
|
"results": {
|
|
"backend_status": check_backend_status(),
|
|
"frontend_status": check_frontend_status(),
|
|
"typescript_compilation": check_typescript_compilation(),
|
|
"components_present": test_properties_panel_components(),
|
|
"step_type_resolver": test_step_type_resolver(),
|
|
"catalog_service": test_catalog_service(),
|
|
"screen_capture_service": test_screen_capture_service(),
|
|
"properties_functionality": test_properties_interface_functionality(),
|
|
"integration_tests": run_integration_tests()
|
|
}
|
|
}
|
|
|
|
# Calculer le score global
|
|
total_tests = len(report["results"])
|
|
passed_tests = sum(1 for result in report["results"].values() if result)
|
|
report["score"] = f"{passed_tests}/{total_tests}"
|
|
report["success_rate"] = f"{(passed_tests/total_tests)*100:.1f}%"
|
|
|
|
# Sauvegarder le rapport
|
|
report_file = f"validation_interface_proprietes_etapes_complete_{time.strftime('%Y%m%d_%H%M%S')}.json"
|
|
with open(report_file, 'w', encoding='utf-8') as f:
|
|
json.dump(report, f, indent=2, ensure_ascii=False)
|
|
|
|
print_success(f"Rapport sauvegardé: {report_file}")
|
|
return report
|
|
|
|
def main():
|
|
"""Fonction principale"""
|
|
print_header("TEST INTERFACE PROPRIÉTÉS D'ÉTAPES COMPLÈTE")
|
|
print("Auteur : Dom, Alice, Kiro - 12 janvier 2026")
|
|
print("Test de l'interface complète des propriétés d'étapes avec vrais contrôles")
|
|
|
|
# Générer le rapport de test
|
|
report = generate_test_report()
|
|
|
|
# Afficher le résumé
|
|
print_header("RÉSUMÉ DES TESTS")
|
|
print(f"Score global: {report['score']} ({report['success_rate']})")
|
|
|
|
for test_name, result in report["results"].items():
|
|
status = "✅ RÉUSSI" if result else "❌ ÉCHOUÉ"
|
|
print(f" {test_name}: {status}")
|
|
|
|
# Recommandations
|
|
print_header("RECOMMANDATIONS")
|
|
|
|
failed_tests = [name for name, result in report["results"].items() if not result]
|
|
|
|
if not failed_tests:
|
|
print_success("Tous les tests sont réussis ! L'interface des propriétés est fonctionnelle.")
|
|
print("🎯 L'interface des propriétés d'étapes est maintenant complète avec :")
|
|
print(" - Bouton de capture d'écran fonctionnel")
|
|
print(" - Champs de configuration pour tous les types d'étapes")
|
|
print(" - Validation en temps réel")
|
|
print(" - Support des actions VWB")
|
|
print(" - Messages d'état informatifs")
|
|
else:
|
|
print_warning("Certains tests ont échoué. Actions recommandées :")
|
|
|
|
if "backend_status" in failed_tests:
|
|
print(" - Démarrer le backend VWB: cd visual_workflow_builder/backend && python app.py")
|
|
|
|
if "frontend_status" in failed_tests:
|
|
print(" - Démarrer le frontend VWB: cd visual_workflow_builder/frontend && npm start")
|
|
|
|
if "typescript_compilation" in failed_tests:
|
|
print(" - Corriger les erreurs TypeScript dans le frontend")
|
|
|
|
if "components_present" in failed_tests:
|
|
print(" - Vérifier que tous les composants sont implémentés")
|
|
|
|
if "step_type_resolver" in failed_tests:
|
|
print(" - Vérifier l'implémentation du StepTypeResolver")
|
|
|
|
if "screen_capture_service" in failed_tests:
|
|
print(" - Vérifier le service de capture d'écran réelle")
|
|
|
|
print_header("TEST TERMINÉ")
|
|
|
|
# Code de sortie
|
|
if len(failed_tests) == 0:
|
|
print_success("Interface des propriétés d'étapes complètement fonctionnelle !")
|
|
return 0
|
|
else:
|
|
print_error(f"{len(failed_tests)} test(s) échoué(s)")
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |