Files
pocketpaw/tests/e2e/conftest.py
Amritesh 828469b64b feat(memory): Implement knowledge graph features in memory management
- Added UI components for memory graph, stats, and facts in memory modal.
- Enhanced FileMemoryStore with graph indexing, entity extraction, and relationship management.
- Introduced methods for updating memory entries and retrieving graph snapshots.
- Implemented pruning of old daily memories and cleanup of orphan records.
- Added tests for graph functionality, memory updates, and pruning logic.
2026-03-24 17:52:29 +05:30

113 lines
3.4 KiB
Python

# E2E Test Configuration for Playwright
# Created: 2026-02-05
#
# Provides fixtures for E2E tests:
# - Dashboard server startup/shutdown
# - Browser configuration
# - Test isolation
#
# IMPORTANT: Before running E2E tests, install Playwright browsers (one-time setup):
# Linux/Mac: uv run playwright install
# Windows: .venv\Scripts\python -m playwright install
#
# Run with: pytest tests/e2e/ -v
# Run headed (see browser): pytest tests/e2e/ -v --headed
#
# If you see "fixture 'page' not found", it means Playwright browsers are not installed.
import os
import pathlib
import socket
import time
from contextlib import closing
from multiprocessing import Process
import pytest
def _playwright_browsers_installed() -> bool:
"""Check if Playwright browsers are installed."""
try:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser_path = p.chromium.executable_path
return pathlib.Path(browser_path).exists()
except Exception:
return False
@pytest.fixture(scope="session", autouse=True)
def require_playwright_browsers():
"""Skip all e2e tests if Playwright browsers are not installed."""
if not _playwright_browsers_installed():
pytest.skip("Playwright Chromium not installed, skipping e2e tests")
def find_free_port() -> int:
"""Find a free port on localhost."""
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind(("", 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
def run_dashboard(port: int):
"""Run the dashboard server in a subprocess."""
import uvicorn # noqa: I001
from pocketpaw.dashboard import app
uvicorn.run(app, host="127.0.0.1", port=port, log_level="warning")
def wait_for_server(port: int, timeout: float = 10.0) -> bool:
"""Wait for the server to be ready."""
start = time.time()
while time.time() - start < timeout:
try:
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.settimeout(1)
s.connect(("127.0.0.1", port))
return True
except (OSError, ConnectionRefusedError):
time.sleep(0.1)
return False
@pytest.fixture(scope="session")
def dashboard_port() -> int:
"""Get a free port for the dashboard."""
return find_free_port()
@pytest.fixture(scope="session")
def dashboard_server(dashboard_port: int):
"""Start the dashboard server for the test session."""
os.environ["POCKETPAW_TEST_MODE"] = "1"
process = Process(target=run_dashboard, args=(dashboard_port,))
process.start()
if not wait_for_server(dashboard_port):
process.terminate()
process.join(timeout=5)
pytest.fail(f"Dashboard server failed to start on port {dashboard_port}")
yield f"http://127.0.0.1:{dashboard_port}"
process.terminate()
process.join(timeout=5)
if process.is_alive():
process.kill()
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
"""Configure browser context for tests."""
return {
**browser_context_args,
"viewport": {"width": 1280, "height": 720},
"ignore_https_errors": True,
}
@pytest.fixture
def dashboard_url(dashboard_server: str) -> str:
"""Alias for dashboard_server URL."""
return dashboard_server