- 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>
258 lines
9.5 KiB
Python
258 lines
9.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Tests d'intégration pour l'API de capture d'écran et d'embedding visuel du VWB.
|
|
|
|
Auteur : Dom, Alice, Kiro - 09 janvier 2026
|
|
|
|
Ces tests vérifient que les endpoints /api/screen-capture et /api/visual-embedding
|
|
fonctionnent correctement avec le système de capture réel.
|
|
"""
|
|
|
|
import pytest
|
|
import sys
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# Ajouter le répertoire racine au path
|
|
ROOT_DIR = Path(__file__).parent.parent.parent
|
|
sys.path.insert(0, str(ROOT_DIR))
|
|
|
|
|
|
class TestScreenCaptureService:
|
|
"""Tests pour le service de capture d'écran."""
|
|
|
|
def test_screen_capturer_import(self):
|
|
"""Vérifie que le ScreenCapturer peut être importé."""
|
|
try:
|
|
from core.capture import ScreenCapturer
|
|
assert ScreenCapturer is not None
|
|
except ImportError as e:
|
|
pytest.skip(f"ScreenCapturer non disponible: {e}")
|
|
|
|
def test_screen_capturer_initialization(self):
|
|
"""Vérifie que le ScreenCapturer peut être initialisé."""
|
|
try:
|
|
from core.capture import ScreenCapturer
|
|
capturer = ScreenCapturer(buffer_size=2, detect_changes=False)
|
|
assert capturer is not None
|
|
assert capturer.method in ["mss", "pyautogui"]
|
|
except ImportError as e:
|
|
pytest.skip(f"ScreenCapturer non disponible: {e}")
|
|
except Exception as e:
|
|
# Peut échouer sur un serveur sans écran
|
|
pytest.skip(f"Capture d'écran non disponible: {e}")
|
|
|
|
def test_screen_capture_returns_array(self):
|
|
"""Vérifie que la capture retourne un tableau numpy valide."""
|
|
try:
|
|
from core.capture import ScreenCapturer
|
|
import numpy as np
|
|
|
|
capturer = ScreenCapturer(buffer_size=2, detect_changes=False)
|
|
img = capturer.capture()
|
|
|
|
if img is None:
|
|
pytest.skip("Capture d'écran non disponible (pas d'écran)")
|
|
|
|
assert isinstance(img, np.ndarray)
|
|
assert len(img.shape) == 3 # (H, W, C)
|
|
assert img.shape[2] == 3 # RGB
|
|
assert img.shape[0] > 0 # Hauteur > 0
|
|
assert img.shape[1] > 0 # Largeur > 0
|
|
|
|
except ImportError as e:
|
|
pytest.skip(f"Dépendances non disponibles: {e}")
|
|
except Exception as e:
|
|
pytest.skip(f"Capture d'écran non disponible: {e}")
|
|
|
|
|
|
class TestCLIPEmbedderService:
|
|
"""Tests pour le service d'embedding CLIP."""
|
|
|
|
def test_clip_embedder_import(self):
|
|
"""Vérifie que le CLIPEmbedder peut être importé."""
|
|
try:
|
|
from core.embedding import create_clip_embedder
|
|
assert create_clip_embedder is not None
|
|
except ImportError as e:
|
|
pytest.skip(f"CLIPEmbedder non disponible: {e}")
|
|
|
|
def test_clip_embedder_initialization(self):
|
|
"""Vérifie que le CLIPEmbedder peut être initialisé."""
|
|
try:
|
|
from core.embedding import create_clip_embedder
|
|
embedder = create_clip_embedder(device="cpu")
|
|
assert embedder is not None
|
|
assert embedder.get_dimension() > 0
|
|
except ImportError as e:
|
|
pytest.skip(f"CLIPEmbedder non disponible: {e}")
|
|
except Exception as e:
|
|
pytest.skip(f"Initialisation CLIP échouée: {e}")
|
|
|
|
def test_clip_embedding_dimension(self):
|
|
"""Vérifie que les embeddings ont la bonne dimension."""
|
|
try:
|
|
from core.embedding import create_clip_embedder
|
|
from PIL import Image
|
|
import numpy as np
|
|
|
|
embedder = create_clip_embedder(device="cpu")
|
|
|
|
# Créer une image de test
|
|
test_image = Image.fromarray(
|
|
np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
|
|
)
|
|
|
|
embedding = embedder.embed_image(test_image)
|
|
|
|
assert isinstance(embedding, np.ndarray)
|
|
assert len(embedding.shape) == 1
|
|
assert embedding.shape[0] == embedder.get_dimension()
|
|
|
|
except ImportError as e:
|
|
pytest.skip(f"Dépendances non disponibles: {e}")
|
|
except Exception as e:
|
|
pytest.skip(f"Embedding échoué: {e}")
|
|
|
|
|
|
class TestBackendFunctions:
|
|
"""Tests pour les fonctions du backend VWB."""
|
|
|
|
def test_capture_screen_to_base64_function(self):
|
|
"""Vérifie la fonction capture_screen_to_base64."""
|
|
try:
|
|
sys.path.insert(0, str(ROOT_DIR / "visual_workflow_builder" / "backend"))
|
|
from app_lightweight import capture_screen_to_base64
|
|
|
|
result = capture_screen_to_base64()
|
|
|
|
assert isinstance(result, dict)
|
|
assert 'success' in result
|
|
|
|
if result['success']:
|
|
assert 'screenshot' in result
|
|
assert 'width' in result
|
|
assert 'height' in result
|
|
assert isinstance(result['screenshot'], str)
|
|
assert len(result['screenshot']) > 0
|
|
else:
|
|
# Peut échouer si pas d'écran disponible
|
|
assert 'error' in result
|
|
|
|
except ImportError as e:
|
|
pytest.skip(f"Backend non disponible: {e}")
|
|
except Exception as e:
|
|
pytest.skip(f"Test échoué: {e}")
|
|
|
|
def test_create_visual_embedding_function(self):
|
|
"""Vérifie la fonction create_visual_embedding."""
|
|
try:
|
|
import base64
|
|
from PIL import Image
|
|
import numpy as np
|
|
import io
|
|
|
|
sys.path.insert(0, str(ROOT_DIR / "visual_workflow_builder" / "backend"))
|
|
from app_lightweight import create_visual_embedding
|
|
|
|
# Créer une image de test en base64
|
|
test_image = Image.fromarray(
|
|
np.random.randint(0, 255, (200, 200, 3), dtype=np.uint8)
|
|
)
|
|
buffer = io.BytesIO()
|
|
test_image.save(buffer, format='PNG')
|
|
buffer.seek(0)
|
|
screenshot_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
|
|
|
# Zone de sélection
|
|
bounding_box = {
|
|
'x': 50,
|
|
'y': 50,
|
|
'width': 100,
|
|
'height': 100
|
|
}
|
|
|
|
result = create_visual_embedding(screenshot_base64, bounding_box, "test_step")
|
|
|
|
assert isinstance(result, dict)
|
|
assert 'success' in result
|
|
|
|
if result['success']:
|
|
assert 'embedding' in result
|
|
assert 'embedding_id' in result
|
|
assert 'dimension' in result
|
|
assert isinstance(result['embedding'], list)
|
|
assert len(result['embedding']) > 0
|
|
else:
|
|
# Peut échouer si CLIP non disponible
|
|
assert 'error' in result
|
|
|
|
except ImportError as e:
|
|
pytest.skip(f"Dépendances non disponibles: {e}")
|
|
except Exception as e:
|
|
pytest.skip(f"Test échoué: {e}")
|
|
|
|
|
|
class TestAPIEndpointsStructure:
|
|
"""Tests pour la structure des endpoints API."""
|
|
|
|
def test_backend_module_loads(self):
|
|
"""Vérifie que le module backend peut être chargé."""
|
|
try:
|
|
sys.path.insert(0, str(ROOT_DIR / "visual_workflow_builder" / "backend"))
|
|
import app_lightweight
|
|
assert app_lightweight is not None
|
|
except ImportError as e:
|
|
pytest.fail(f"Impossible de charger le backend: {e}")
|
|
|
|
def test_workflow_database_class_exists(self):
|
|
"""Vérifie que la classe WorkflowDatabase existe."""
|
|
try:
|
|
sys.path.insert(0, str(ROOT_DIR / "visual_workflow_builder" / "backend"))
|
|
from app_lightweight import WorkflowDatabase
|
|
assert WorkflowDatabase is not None
|
|
|
|
db = WorkflowDatabase()
|
|
assert db is not None
|
|
except ImportError as e:
|
|
pytest.fail(f"WorkflowDatabase non disponible: {e}")
|
|
|
|
def test_simple_workflow_class_exists(self):
|
|
"""Vérifie que la classe SimpleWorkflow existe."""
|
|
try:
|
|
sys.path.insert(0, str(ROOT_DIR / "visual_workflow_builder" / "backend"))
|
|
from app_lightweight import SimpleWorkflow
|
|
assert SimpleWorkflow is not None
|
|
|
|
workflow = SimpleWorkflow(
|
|
id="test_wf",
|
|
name="Test Workflow",
|
|
description="Description de test"
|
|
)
|
|
assert workflow.id == "test_wf"
|
|
assert workflow.name == "Test Workflow"
|
|
except ImportError as e:
|
|
pytest.fail(f"SimpleWorkflow non disponible: {e}")
|
|
|
|
|
|
class TestDataDirectory:
|
|
"""Tests pour la structure des répertoires de données."""
|
|
|
|
def test_visual_embeddings_directory_creation(self):
|
|
"""Vérifie que le répertoire visual_embeddings peut être créé."""
|
|
embeddings_dir = ROOT_DIR / "data" / "visual_embeddings"
|
|
embeddings_dir.mkdir(parents=True, exist_ok=True)
|
|
assert embeddings_dir.exists()
|
|
assert embeddings_dir.is_dir()
|
|
|
|
def test_workflows_directory_creation(self):
|
|
"""Vérifie que le répertoire workflows peut être créé."""
|
|
workflows_dir = ROOT_DIR / "data" / "workflows"
|
|
workflows_dir.mkdir(parents=True, exist_ok=True)
|
|
assert workflows_dir.exists()
|
|
assert workflows_dir.is_dir()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v', '--tb=short'])
|