- 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>
262 lines
9.6 KiB
Python
262 lines
9.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Test de Localisation du Composant RealDemo
|
|
Auteur : Dom, Alice, Kiro - 8 janvier 2026
|
|
|
|
Script pour valider l'implémentation de la localisation du composant RealDemo.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict, List
|
|
|
|
class RealDemoLocalizationTester:
|
|
"""
|
|
Testeur pour la localisation du composant RealDemo
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.i18n_dir = Path("i18n")
|
|
self.component_path = Path("visual_workflow_builder/frontend/src/components/RealDemo/index.tsx")
|
|
self.expected_keys = [
|
|
"realDemo.component.title",
|
|
"realDemo.component.description",
|
|
"realDemo.component.startButton"
|
|
]
|
|
self.languages = ["fr", "en", "es", "de"]
|
|
self.results = []
|
|
|
|
def test_translation_files(self) -> bool:
|
|
"""Teste que toutes les clés sont présentes dans tous les fichiers"""
|
|
print("🔍 Test des fichiers de traduction...")
|
|
|
|
all_passed = True
|
|
|
|
for lang in self.languages:
|
|
lang_file = self.i18n_dir / f"{lang}.json"
|
|
|
|
try:
|
|
with open(lang_file, 'r', encoding='utf-8') as f:
|
|
translations = json.load(f)
|
|
|
|
# Vérifier la présence des clés
|
|
component_translations = translations.get("realDemo", {}).get("component", {})
|
|
|
|
missing_keys = []
|
|
for key in ["title", "description", "startButton"]:
|
|
if key not in component_translations:
|
|
missing_keys.append(key)
|
|
|
|
if missing_keys:
|
|
print(f"❌ {lang}.json - Clés manquantes: {missing_keys}")
|
|
all_passed = False
|
|
else:
|
|
print(f"✅ {lang}.json - Toutes les clés présentes")
|
|
|
|
# Vérifier que les valeurs ne sont pas vides
|
|
empty_values = []
|
|
for key, value in component_translations.items():
|
|
if not value or not value.strip():
|
|
empty_values.append(key)
|
|
|
|
if empty_values:
|
|
print(f"⚠️ {lang}.json - Valeurs vides: {empty_values}")
|
|
|
|
except FileNotFoundError:
|
|
print(f"❌ Fichier manquant: {lang}.json")
|
|
all_passed = False
|
|
except json.JSONDecodeError as e:
|
|
print(f"❌ JSON invalide dans {lang}.json: {e}")
|
|
all_passed = False
|
|
|
|
return all_passed
|
|
|
|
def test_component_integration(self) -> bool:
|
|
"""Teste que le composant utilise bien la localisation"""
|
|
print("\n🔍 Test de l'intégration du composant...")
|
|
|
|
if not self.component_path.exists():
|
|
print(f"❌ Composant non trouvé: {self.component_path}")
|
|
return False
|
|
|
|
try:
|
|
with open(self.component_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Vérifier l'import du service de localisation
|
|
if "useLocalization" not in content:
|
|
print("❌ Import useLocalization manquant")
|
|
return False
|
|
|
|
if "from '../../services/LocalizationService'" not in content:
|
|
print("❌ Import du LocalizationService incorrect")
|
|
return False
|
|
|
|
# Vérifier l'utilisation du hook
|
|
if "const { t } = useLocalization();" not in content:
|
|
print("❌ Hook useLocalization non utilisé")
|
|
return False
|
|
|
|
# Vérifier que les clés sont utilisées
|
|
expected_calls = [
|
|
"t('realDemo.component.title')",
|
|
"t('realDemo.component.description')",
|
|
"t('realDemo.component.startButton')"
|
|
]
|
|
|
|
missing_calls = []
|
|
for call in expected_calls:
|
|
if call not in content:
|
|
missing_calls.append(call)
|
|
|
|
if missing_calls:
|
|
print(f"❌ Appels de traduction manquants: {missing_calls}")
|
|
return False
|
|
|
|
# Vérifier qu'il n'y a plus de texte codé en dur
|
|
hardcoded_texts = [
|
|
"Démonstration Réelle - RPA Vision V3",
|
|
"Ce composant permettra de tester le système RPA en temps réel",
|
|
"Démarrer la Démonstration"
|
|
]
|
|
|
|
found_hardcoded = []
|
|
for text in hardcoded_texts:
|
|
if text in content:
|
|
found_hardcoded.append(text)
|
|
|
|
if found_hardcoded:
|
|
print(f"⚠️ Texte codé en dur trouvé: {found_hardcoded}")
|
|
|
|
print("✅ Composant correctement intégré")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors de la lecture du composant: {e}")
|
|
return False
|
|
|
|
def test_translation_quality(self) -> bool:
|
|
"""Teste la qualité des traductions"""
|
|
print("\n🔍 Test de la qualité des traductions...")
|
|
|
|
quality_passed = True
|
|
|
|
# Vérifier les longueurs des traductions
|
|
max_lengths = {
|
|
"title": 50, # Titre pas trop long
|
|
"description": 100, # Description raisonnable
|
|
"startButton": 30 # Bouton compact
|
|
}
|
|
|
|
for lang in self.languages:
|
|
lang_file = self.i18n_dir / f"{lang}.json"
|
|
|
|
try:
|
|
with open(lang_file, 'r', encoding='utf-8') as f:
|
|
translations = json.load(f)
|
|
|
|
component_translations = translations.get("realDemo", {}).get("component", {})
|
|
|
|
for key, max_length in max_lengths.items():
|
|
if key in component_translations:
|
|
text = component_translations[key]
|
|
if len(text) > max_length:
|
|
print(f"⚠️ {lang}.{key} trop long ({len(text)} > {max_length}): {text[:30]}...")
|
|
quality_passed = False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors de la vérification de {lang}: {e}")
|
|
quality_passed = False
|
|
|
|
if quality_passed:
|
|
print("✅ Qualité des traductions validée")
|
|
|
|
return quality_passed
|
|
|
|
def test_consistency(self) -> bool:
|
|
"""Teste la cohérence terminologique"""
|
|
print("\n🔍 Test de la cohérence terminologique...")
|
|
|
|
consistency_passed = True
|
|
|
|
# Vérifier que "RPA Vision V3" est identique partout
|
|
for lang in self.languages:
|
|
lang_file = self.i18n_dir / f"{lang}.json"
|
|
|
|
try:
|
|
with open(lang_file, 'r', encoding='utf-8') as f:
|
|
translations = json.load(f)
|
|
|
|
title = translations.get("realDemo", {}).get("component", {}).get("title", "")
|
|
|
|
if "RPA Vision V3" not in title:
|
|
print(f"⚠️ {lang}: Nom du produit 'RPA Vision V3' manquant dans le titre")
|
|
consistency_passed = False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors de la vérification de cohérence pour {lang}: {e}")
|
|
consistency_passed = False
|
|
|
|
if consistency_passed:
|
|
print("✅ Cohérence terminologique validée")
|
|
|
|
return consistency_passed
|
|
|
|
def run_all_tests(self) -> bool:
|
|
"""Exécute tous les tests"""
|
|
print("🚀 Démarrage des tests de localisation RealDemo...")
|
|
print("=" * 60)
|
|
|
|
tests = [
|
|
("Fichiers de traduction", self.test_translation_files),
|
|
("Intégration du composant", self.test_component_integration),
|
|
("Qualité des traductions", self.test_translation_quality),
|
|
("Cohérence terminologique", self.test_consistency)
|
|
]
|
|
|
|
all_passed = True
|
|
results = []
|
|
|
|
for test_name, test_func in tests:
|
|
try:
|
|
result = test_func()
|
|
results.append((test_name, result))
|
|
if not result:
|
|
all_passed = False
|
|
except Exception as e:
|
|
print(f"❌ Erreur dans le test '{test_name}': {e}")
|
|
results.append((test_name, False))
|
|
all_passed = False
|
|
|
|
# Rapport final
|
|
print("\n" + "=" * 60)
|
|
print("📊 RAPPORT FINAL DES TESTS")
|
|
print("=" * 60)
|
|
|
|
for test_name, result in results:
|
|
status = "✅ RÉUSSI" if result else "❌ ÉCHOUÉ"
|
|
print(f" {test_name}: {status}")
|
|
|
|
print()
|
|
if all_passed:
|
|
print("🎉 TOUS LES TESTS RÉUSSIS!")
|
|
print(" La localisation du composant RealDemo est correctement implémentée.")
|
|
else:
|
|
print("⚠️ CERTAINS TESTS ONT ÉCHOUÉ")
|
|
print(" Veuillez corriger les problèmes identifiés.")
|
|
|
|
print("=" * 60)
|
|
|
|
return all_passed
|
|
|
|
def main():
|
|
"""Point d'entrée principal"""
|
|
tester = RealDemoLocalizationTester()
|
|
success = tester.run_all_tests()
|
|
|
|
return 0 if success else 1
|
|
|
|
if __name__ == "__main__":
|
|
exit(main()) |