Files
rpa_vision_v3/tests/unit/test_vwb_evidence_viewer_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

667 lines
22 KiB
Python

#!/usr/bin/env python3
"""
Tests unitaires pour le composant Evidence Viewer VWB
Auteur : Dom, Alice, Kiro - 10 janvier 2026
"""
import os
import sys
import json
import pytest
from pathlib import Path
# Ajout du répertoire racine au path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
def test_evidence_viewer_structure():
"""Test 1/20 : Vérification de la structure du composant Evidence Viewer"""
# Vérification des fichiers principaux
base_path = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer")
required_files = [
"index.tsx",
"EvidenceList.tsx",
"EvidenceDetail.tsx",
"ScreenshotViewer.tsx",
"EvidenceStats.tsx",
"EvidenceFilters.tsx",
"EvidenceViewer.css"
]
for file_name in required_files:
file_path = base_path / file_name
assert file_path.exists(), f"Fichier manquant : {file_path}"
assert file_path.stat().st_size > 0, f"Fichier vide : {file_path}"
print("✅ Structure du composant Evidence Viewer validée")
def test_evidence_types():
"""Test 2/20 : Vérification des types TypeScript Evidence"""
types_file = Path("visual_workflow_builder/frontend/src/types/evidence.ts")
assert types_file.exists(), "Fichier types/evidence.ts manquant"
content = types_file.read_text()
# Vérification des interfaces principales
required_interfaces = [
"VWBActionError",
"VWBEvidence",
"EvidenceViewerProps",
"EvidenceListProps",
"EvidenceDetailProps",
"ScreenshotViewerProps",
"AnnotationData",
"EvidenceFilters",
"EvidenceStats"
]
for interface in required_interfaces:
assert f"interface {interface}" in content, f"Interface {interface} manquante"
# Vérification des utilitaires
assert "EvidenceUtils" in content, "Utilitaires EvidenceUtils manquants"
assert "filterEvidences" in content, "Méthode filterEvidences manquante"
assert "sortEvidences" in content, "Méthode sortEvidences manquante"
assert "calculateStats" in content, "Méthode calculateStats manquante"
print("✅ Types TypeScript Evidence validés")
def test_evidence_service():
"""Test 3/20 : Vérification du service Evidence"""
service_file = Path("visual_workflow_builder/frontend/src/services/evidenceService.ts")
assert service_file.exists(), "Fichier evidenceService.ts manquant"
content = service_file.read_text()
# Vérification de la classe EvidenceService
assert "class EvidenceService" in content, "Classe EvidenceService manquante"
# Vérification des méthodes principales
required_methods = [
"getEvidences",
"getEvidence",
"saveEvidence",
"deleteEvidence",
"filterEvidences",
"sortEvidences",
"calculateStats",
"exportEvidences",
"healthCheck"
]
for method in required_methods:
assert f"async {method}" in content or f"{method}" in content, f"Méthode {method} manquante"
# Vérification de l'instance singleton
assert "evidenceService = new EvidenceService" in content, "Instance singleton manquante"
print("✅ Service Evidence validé")
def test_evidence_hook():
"""Test 4/20 : Vérification du hook useEvidenceViewer"""
hook_file = Path("visual_workflow_builder/frontend/src/hooks/useEvidenceViewer.ts")
assert hook_file.exists(), "Fichier useEvidenceViewer.ts manquant"
content = hook_file.read_text()
# Vérification de l'export du hook
assert "export const useEvidenceViewer" in content, "Hook useEvidenceViewer manquant"
# Vérification des imports React
assert "import { useState, useEffect, useCallback, useMemo }" in content, "Imports React manquants"
# Vérification des fonctionnalités
required_features = [
"evidences",
"filteredEvidences",
"selectedEvidence",
"stats",
"loading",
"error",
"filters",
"setFilters",
"refreshEvidences",
"exportEvidences"
]
for feature in required_features:
assert feature in content, f"Fonctionnalité {feature} manquante dans le hook"
print("✅ Hook useEvidenceViewer validé")
def test_evidence_viewer_component():
"""Test 5/20 : Vérification du composant principal EvidenceViewer"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/index.tsx")
assert component_file.exists(), "Composant EvidenceViewer manquant"
content = component_file.read_text()
# Vérification des imports Material-UI
mui_imports = [
"Box",
"Paper",
"Typography",
"Divider",
"Alert",
"CircularProgress",
"Fab",
"Tooltip"
]
for import_name in mui_imports:
assert import_name in content, f"Import Material-UI {import_name} manquant"
# Vérification des imports de composants
component_imports = [
"EvidenceList",
"EvidenceDetail",
"EvidenceFilters",
"EvidenceStats"
]
for import_name in component_imports:
assert f"import {import_name}" in content, f"Import composant {import_name} manquant"
# Vérification de l'export par défaut
assert "export default EvidenceViewer" in content, "Export par défaut manquant"
print("✅ Composant principal EvidenceViewer validé")
def test_evidence_list_component():
"""Test 6/20 : Vérification du composant EvidenceList"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceList.tsx")
assert component_file.exists(), "Composant EvidenceList manquant"
content = component_file.read_text()
# Vérification des fonctionnalités de liste
required_features = [
"List",
"ListItem",
"ListItemText",
"Pagination",
"TextField",
"Search",
"Sort"
]
for feature in required_features:
assert feature in content, f"Fonctionnalité {feature} manquante dans EvidenceList"
# Vérification des modes d'affichage
assert "viewMode" in content, "Mode d'affichage manquant"
assert "list" in content and "grid" in content, "Modes liste/grille manquants"
print("✅ Composant EvidenceList validé")
def test_evidence_detail_component():
"""Test 7/20 : Vérification du composant EvidenceDetail"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceDetail.tsx")
assert component_file.exists(), "Composant EvidenceDetail manquant"
content = component_file.read_text()
# Vérification des fonctionnalités de détail
required_features = [
"Accordion",
"AccordionSummary",
"AccordionDetails",
"ScreenshotViewer",
"metadata",
"zoom",
"download"
]
for feature in required_features:
assert feature in content, f"Fonctionnalité {feature} manquante dans EvidenceDetail"
# Vérification de la gestion des erreurs
assert "Alert" in content, "Gestion d'erreurs manquante"
assert "error" in content, "Affichage d'erreurs manquant"
print("✅ Composant EvidenceDetail validé")
def test_screenshot_viewer_component():
"""Test 8/20 : Vérification du composant ScreenshotViewer"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/ScreenshotViewer.tsx")
assert component_file.exists(), "Composant ScreenshotViewer manquant"
content = component_file.read_text()
# Vérification des fonctionnalités de visualisation
required_features = [
"zoom",
"pan",
"annotations",
"bbox",
"clickPoint",
"onWheel",
"onMouseDown",
"onMouseMove"
]
for feature in required_features:
assert feature in content, f"Fonctionnalité {feature} manquante dans ScreenshotViewer"
# Vérification des annotations
assert "evidence-annotation" in content, "Système d'annotations manquant"
assert "click-point" in content, "Annotation point de clic manquante"
print("✅ Composant ScreenshotViewer validé")
def test_evidence_stats_component():
"""Test 9/20 : Vérification du composant EvidenceStats"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceStats.tsx")
assert component_file.exists(), "Composant EvidenceStats manquant"
content = component_file.read_text()
# Vérification des statistiques
required_stats = [
"total",
"successful",
"failed",
"successRate",
"averageExecutionTime",
"averageConfidence",
"actionTypeDistribution",
"timelineData"
]
for stat in required_stats:
assert stat in content, f"Statistique {stat} manquante"
# Vérification des icônes
assert "SuccessIcon" in content, "Icône succès manquante"
assert "ErrorIcon" in content, "Icône erreur manquante"
assert "LinearProgress" in content, "Barre de progression manquante"
print("✅ Composant EvidenceStats validé")
def test_evidence_filters_component():
"""Test 10/20 : Vérification du composant EvidenceFilters"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceFilters.tsx")
assert component_file.exists(), "Composant EvidenceFilters manquant"
content = component_file.read_text()
# Vérification des filtres
required_filters = [
"TextField",
"Select",
"type=\"date\"", # Remplacé DatePicker par TextField avec type date
"Slider",
"searchText",
"actionTypes",
"status",
"dateRange",
"confidenceRange",
"executionTimeRange"
]
for filter_type in required_filters:
assert filter_type in content, f"Filtre {filter_type} manquant"
# Vérification de la localisation française (nous utilisons maintenant des champs date natifs)
assert "fr" in content or "français" in content.lower(), "Localisation française manquante"
print("✅ Composant EvidenceFilters validé")
def test_css_styles():
"""Test 11/20 : Vérification des styles CSS"""
css_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceViewer.css")
assert css_file.exists(), "Fichier CSS manquant"
content = css_file.read_text()
# Vérification des classes principales
required_classes = [
".evidence-viewer",
".evidence-list",
".evidence-list-item",
".evidence-grid",
".evidence-grid-item",
".evidence-detail",
".evidence-screenshot",
".evidence-annotation",
".evidence-stats",
".evidence-filters"
]
for class_name in required_classes:
assert class_name in content, f"Classe CSS {class_name} manquante"
# Vérification des couleurs du design system
design_colors = [
"#1e293b", # Card Background
"#334155", # Border Color
"#e2e8f0", # Text Primary
"#94a3b8", # Text Secondary
"#1976d2", # Primary Blue
"#22c55e", # Success Green
"#ef4444" # Error Red
]
for color in design_colors:
assert color in content, f"Couleur design system {color} manquante"
print("✅ Styles CSS validés")
def test_responsive_design():
"""Test 12/20 : Vérification du design responsive"""
css_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceViewer.css")
content = css_file.read_text()
# Vérification des media queries
assert "@media (max-width: 768px)" in content, "Media query mobile manquante"
# Vérification des adaptations mobiles
mobile_adaptations = [
"grid-template-columns: 1fr",
"flex-direction: column",
"position: fixed"
]
for adaptation in mobile_adaptations:
assert adaptation in content, f"Adaptation mobile {adaptation} manquante"
print("✅ Design responsive validé")
def test_accessibility_features():
"""Test 13/20 : Vérification des fonctionnalités d'accessibilité"""
# Vérification dans le composant principal
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/index.tsx")
content = component_file.read_text()
# Vérification des éléments d'accessibilité
accessibility_features = [
"Tooltip",
"aria-",
"title="
# Supprimé "alt=" car nous l'avons corrigé (n'était pas valide sur Box)
]
for feature in accessibility_features:
assert feature in content, f"Fonctionnalité d'accessibilité {feature} manquante"
# Vérification dans ScreenshotViewer
screenshot_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/ScreenshotViewer.tsx")
screenshot_content = screenshot_file.read_text()
assert 'alt="Screenshot Evidence"' in screenshot_content, "Texte alternatif manquant"
assert "title=" in screenshot_content, "Attributs title manquants"
print("✅ Fonctionnalités d'accessibilité validées")
def test_error_handling():
"""Test 14/20 : Vérification de la gestion d'erreurs"""
# Vérification dans le hook
hook_file = Path("visual_workflow_builder/frontend/src/hooks/useEvidenceViewer.ts")
hook_content = hook_file.read_text()
assert "try {" in hook_content, "Gestion d'erreurs try/catch manquante"
assert "catch" in hook_content, "Bloc catch manquant"
assert "setError" in hook_content, "État d'erreur manquant"
# Vérification dans le service
service_file = Path("visual_workflow_builder/frontend/src/services/evidenceService.ts")
service_content = service_file.read_text()
assert "throw new Error" in service_content, "Propagation d'erreurs manquante"
assert "console.error" in service_content, "Logging d'erreurs manquant"
print("✅ Gestion d'erreurs validée")
def test_performance_optimizations():
"""Test 15/20 : Vérification des optimisations de performance"""
# Vérification dans le hook
hook_file = Path("visual_workflow_builder/frontend/src/hooks/useEvidenceViewer.ts")
hook_content = hook_file.read_text()
# Vérification des hooks d'optimisation
performance_hooks = [
"useMemo",
"useCallback",
"cache",
"cacheTimeout"
]
for hook in performance_hooks:
assert hook in hook_content, f"Optimisation {hook} manquante"
# Vérification de la pagination
list_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceList.tsx")
list_content = list_file.read_text()
assert "Pagination" in list_content, "Pagination manquante"
assert "itemsPerPage" in list_content, "Limitation d'items manquante"
print("✅ Optimisations de performance validées")
def test_internationalization():
"""Test 16/20 : Vérification de l'internationalisation française"""
# Vérification des textes français dans les composants
files_to_check = [
"visual_workflow_builder/frontend/src/components/EvidenceViewer/index.tsx",
"visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceList.tsx",
"visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceDetail.tsx",
"visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceStats.tsx",
"visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceFilters.tsx"
]
french_texts = [
"Chargement",
"Erreur",
"Rechercher",
"Filtres",
"Statistiques",
"Evidence",
"Succès",
"Échouées",
"Total"
]
for file_path in files_to_check:
if Path(file_path).exists():
content = Path(file_path).read_text()
french_found = any(text in content for text in french_texts)
assert french_found, f"Textes français manquants dans {file_path}"
# Vérification de la localisation des dates (nous utilisons maintenant des champs date natifs HTML5)
filters_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceFilters.tsx")
filters_content = filters_file.read_text()
# Vérification que nous avons des champs de date fonctionnels
assert 'type="date"' in filters_content, "Champs de date manquants"
assert "formatDateForInput" in filters_content, "Fonction de formatage de date manquante"
print("✅ Internationalisation française validée")
def test_material_ui_integration():
"""Test 17/20 : Vérification de l'intégration Material-UI"""
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/index.tsx")
content = component_file.read_text()
# Vérification des imports Material-UI selon le design system
required_mui_components = [
"Box",
"Paper",
"Typography",
"Divider",
"Alert",
"CircularProgress",
"Fab",
"Tooltip",
"useTheme",
"useMediaQuery"
]
for component in required_mui_components:
assert component in content, f"Composant Material-UI {component} manquant"
# Vérification de l'utilisation du thème
assert "theme.breakpoints" in content, "Utilisation des breakpoints du thème manquante"
print("✅ Intégration Material-UI validée")
def test_design_system_compliance():
"""Test 18/20 : Vérification de la conformité au design system"""
css_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/EvidenceViewer.css")
content = css_file.read_text()
# Vérification des couleurs du design system
design_system_colors = {
"#1976d2": "Primary Blue",
"#dc004e": "Secondary Pink",
"#22c55e": "Success Green",
"#f59e0b": "Warning Orange",
"#ef4444": "Error Red",
"#0f172a": "Dark Background",
"#1e293b": "Card Background",
"#334155": "Border Color",
"#e2e8f0": "Text Primary",
"#94a3b8": "Text Secondary"
}
colors_found = 0
for color, name in design_system_colors.items():
if color in content:
colors_found += 1
assert colors_found >= 6, f"Seulement {colors_found}/10 couleurs du design system trouvées"
# Vérification des espacements
spacing_values = ["4px", "8px", "12px", "16px", "20px"]
spacing_found = any(spacing in content for spacing in spacing_values)
assert spacing_found, "Espacements du design system manquants"
print("✅ Conformité au design system validée")
def test_export_functionality():
"""Test 19/20 : Vérification des fonctionnalités d'export"""
service_file = Path("visual_workflow_builder/frontend/src/services/evidenceService.ts")
content = service_file.read_text()
# Vérification des méthodes d'export
export_features = [
"exportEvidences",
"exportEvidencesClientSide",
"generateHtmlReport",
"options.format", # Corrigé pour refléter notre implémentation
"includeScreenshots",
"includeMetadata"
]
for feature in export_features:
assert feature in content, f"Fonctionnalité d'export {feature} manquante"
# Vérification de la génération de Blob
assert "new Blob" in content, "Génération de Blob manquante"
assert "URL.createObjectURL" in content, "Création d'URL de téléchargement manquante"
print("✅ Fonctionnalités d'export validées")
def test_integration_readiness():
"""Test 20/20 : Vérification de la préparation à l'intégration"""
# Vérification de l'export du composant principal
component_file = Path("visual_workflow_builder/frontend/src/components/EvidenceViewer/index.tsx")
content = component_file.read_text()
assert "export default EvidenceViewer" in content, "Export par défaut manquant"
# Vérification des props d'intégration
integration_props = [
"evidences: externalEvidences",
"selectedEvidenceId: externalSelectedId",
"onEvidenceSelect",
"onExport",
"showFilters",
"maxHeight",
"className"
]
for prop in integration_props:
assert prop in content, f"Prop d'intégration {prop} manquante"
# Vérification de la compatibilité avec l'écosystème VWB
types_file = Path("visual_workflow_builder/frontend/src/types/evidence.ts")
types_content = types_file.read_text()
assert "VWB" in types_content, "Préfixe VWB manquant dans les types"
assert "contract:" in types_content, "Système de contrats manquant"
print("✅ Préparation à l'intégration validée")
def run_all_tests():
"""Exécute tous les tests unitaires"""
test_functions = [
test_evidence_viewer_structure,
test_evidence_types,
test_evidence_service,
test_evidence_hook,
test_evidence_viewer_component,
test_evidence_list_component,
test_evidence_detail_component,
test_screenshot_viewer_component,
test_evidence_stats_component,
test_evidence_filters_component,
test_css_styles,
test_responsive_design,
test_accessibility_features,
test_error_handling,
test_performance_optimizations,
test_internationalization,
test_material_ui_integration,
test_design_system_compliance,
test_export_functionality,
test_integration_readiness
]
print("🧪 TESTS UNITAIRES - EVIDENCE VIEWER VWB")
print("=" * 50)
passed = 0
failed = 0
for i, test_func in enumerate(test_functions, 1):
try:
test_func()
passed += 1
except Exception as e:
print(f"❌ Test {i}/20 échoué : {e}")
failed += 1
print("=" * 50)
print(f"📊 RÉSULTATS : {passed}/{len(test_functions)} tests réussis")
if failed == 0:
print("🎉 TOUS LES TESTS UNITAIRES RÉUSSIS !")
return True
else:
print(f"⚠️ {failed} test(s) échoué(s)")
return False
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)