pupilometer/tests/test_e2e.py
Tempest 40b9b2c8d2 feat: Add pupil detection and camera stream to UI
- Add a new section to the web UI to display pupil detection data and a live camera stream with YOLO segmentation.
- Add a /video_feed endpoint to stream the annotated camera feed.
- Update the VisionSystem to support onnxruntime-gpu with a fallback to CPU.
- Add logging to indicate which backend is being used.
- Refactor the test suite to accommodate the new features and fix existing tests.
2025-11-28 08:29:17 +07:00

134 lines
4.1 KiB
Python

import pytest
import subprocess
import time
import requests
import os
import sys
from playwright.sync_api import Page, expect
# Define the host and port for the application
HOST = "127.0.0.1"
PORT = 5000
BASE_URL = f"http://{HOST}:{PORT}"
STDOUT_FILE = "app_stdout.log"
STDERR_FILE = "app_stderr.log"
@pytest.fixture(scope="module")
def run_app():
"""
Fixture to run the Flask application in a test environment.
"""
# Set the environment variable for the subprocess
env = os.environ.copy()
env["PUPILOMETER_ENV"] = "test"
command = [sys.executable, "-u", "app.py"]
with open(STDOUT_FILE, "w") as stdout_f, open(STDERR_FILE, "w") as stderr_f:
process = subprocess.Popen(
command,
cwd="src/controllerSoftware",
stdout=stdout_f,
stderr=stderr_f,
text=True,
env=env
)
# Wait for the app to start
start_time = time.time()
while True:
if os.path.exists(STDERR_FILE):
with open(STDERR_FILE, "r") as f:
if "* Running on http" in f.read():
break
if time.time() - start_time > 15:
raise TimeoutError("Flask app failed to start in time.")
time.sleep(0.5)
yield process
process.terminate()
process.wait()
# Read stdout and stderr for debugging
with open(STDOUT_FILE, "r") as f:
print("App STDOUT:\n", f.read())
with open(STDERR_FILE, "r") as f:
print("App STDERR:\n", f.read())
if os.path.exists(STDOUT_FILE):
os.remove(STDOUT_FILE)
if os.path.exists(STDERR_FILE):
os.remove(STDERR_FILE)
def test_program_output(run_app):
"""
Tests that the mock backend is initialized.
"""
with open(STDERR_FILE, "r") as f:
stderr = f.read()
assert "Initializing Mock backend" in stderr
assert "MockBackend initialized." in stderr
def test_curl_output(run_app):
"""
Tests the API endpoints using requests (similar to curl).
"""
# Test the /ble_status endpoint
response_ble = requests.get(f"{BASE_URL}/ble_status")
assert response_ble.status_code == 200
assert response_ble.json() == {"connected": True} # In DEBUG_MODE
# Test the /vision/pupil_data endpoint
response_vision = requests.get(f"{BASE_URL}/vision/pupil_data")
assert response_vision.status_code == 200
assert "data" in response_vision.json()
assert "success" in response_vision.json()
def test_playwright_checks(page: Page, run_app):
"""
Performs basic and visual checks using Playwright.
"""
page.goto(BASE_URL)
# Basic output check: Title and heading
expect(page).to_have_title("Lamp Matrix Control")
heading = page.locator("h1")
expect(heading).to_have_text("Lamp Matrix Control")
# Pupil detection UI check
pupil_detection_section = page.locator("#pupil-detection")
expect(pupil_detection_section).to_be_visible()
expect(pupil_detection_section.locator("h2")).to_have_text("Pupil Detection")
pupil_canvas = page.locator("#pupil-canvas")
expect(pupil_canvas).to_be_visible()
pupil_center = page.locator("#pupil-center")
pupil_area = page.locator("#pupil-area")
expect(pupil_center).to_be_visible()
expect(pupil_area).to_be_visible()
# Wait for the pupil data to be updated
time.sleep(1)
expect(pupil_center).not_to_have_text("(x, y)")
expect(pupil_area).not_to_have_text("0")
# Camera stream UI check
camera_feed_section = page.locator("#video-feed")
expect(camera_feed_section).to_be_visible()
expect(camera_feed_section.locator("h2")).to_have_text("Camera Feed")
video_feed_img = page.locator("#video-feed img")
expect(video_feed_img).to_be_visible()
expect(video_feed_img).to_have_attribute("src", "/video_feed")
# Visual check: Screenshot
os.makedirs("screenshots", exist_ok=True)
screenshot_path = "screenshots/homepage.png"
page.screenshot(path=screenshot_path)
assert os.path.exists(screenshot_path)