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>
This commit is contained in:
262
test_realdemo_localization.py
Normal file
262
test_realdemo_localization.py
Normal file
@@ -0,0 +1,262 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user