Files
guide/tests/conftest.py
Travis Vasceannie 5cd1fa3532 Update development server port and enhance documentation
- Changed the default port for the development server from 8000 to 8765 in the documentation.
- Updated testing instructions to reflect the new server port.
- Improved comments and structure in various files for better clarity and maintainability.
- Refactored some logging statements for consistency and readability.
- Added new configuration options for browser host management, including session isolation settings.
- Enhanced type safety and modularity in several components, ensuring better integration and performance.
2025-12-07 13:11:30 +00:00

174 lines
5.0 KiB
Python

"""Pytest configuration and shared fixtures for all tests."""
from __future__ import annotations
from typing import TYPE_CHECKING
from unittest.mock import AsyncMock, MagicMock
import pytest
if TYPE_CHECKING:
from guide.app.core.config import AppSettings, BrowserHostConfig
from guide.app.models.personas.models import DemoPersona
from guide.app.models.personas.store import PersonaStore
@pytest.fixture
def mock_browser_hosts() -> dict[str, BrowserHostConfig]:
"""Provide mock browser host configurations for testing."""
from guide.app.core.config import BrowserHostConfig, HostKind
return {
"demo-extension": BrowserHostConfig(
id="demo-extension",
kind=HostKind.EXTENSION,
port=17373,
),
"support-extension": BrowserHostConfig(
id="support-extension",
kind=HostKind.EXTENSION,
port=17374,
),
"browserless-cdp": BrowserHostConfig(
id="browserless-cdp",
kind=HostKind.CDP,
host="browserless.lab",
port=80,
cdp_url="ws://browserless.lab:80/",
browser="chromium",
),
"headless-local": BrowserHostConfig(
id="headless-local",
kind=HostKind.HEADLESS,
browser="chromium",
),
}
@pytest.fixture
def mock_personas() -> dict[str, DemoPersona]:
"""Provide mock persona configurations for testing."""
from guide.app.models.personas.models import (
DemoPersona,
LoginMethod,
PersonaRole,
)
return {
"buyer": DemoPersona(
id="buyer",
role=PersonaRole.BUYER,
email="travis@raindrop.com",
login_method=LoginMethod.MFA_EMAIL,
browser_host_id="demo-extension",
),
"analyst": DemoPersona(
id="analyst",
role=PersonaRole.ANALYST,
email="rd.daya@sidepiece.rip",
login_method=LoginMethod.MFA_EMAIL,
browser_host_id="support-extension",
),
"supplier": DemoPersona(
id="supplier",
role=PersonaRole.SUPPLIER,
email="supplier.demo@example.com",
login_method=LoginMethod.MFA_EMAIL,
browser_host_id="headless-local",
),
}
@pytest.fixture
def app_settings(
mock_browser_hosts: dict[str, BrowserHostConfig],
mock_personas: dict[str, DemoPersona],
) -> AppSettings:
"""Provide application settings with mock configuration."""
from guide.app.core.config import AppSettings
return AppSettings(
raindrop_base_url="https://app.raindrop.com",
raindrop_graphql_url="https://app.raindrop.com/graphql",
default_browser_host_id="browserless-cdp",
browser_hosts=mock_browser_hosts,
personas=mock_personas,
)
@pytest.fixture
def persona_store(app_settings: AppSettings) -> PersonaStore:
"""Provide PersonaStore instance with mock settings."""
from guide.app.models.personas.store import PersonaStore
return PersonaStore(app_settings)
@pytest.fixture
def action_registry(persona_store: PersonaStore) -> object:
"""Provide ActionRegistry instance with DI context.
Note: Returns object type since ActionRegistry doesn't have public type exports.
"""
from guide.app.actions.registry import ActionRegistry
registry = ActionRegistry(
di_context={
"persona_store": persona_store,
"login_url": "https://app.raindrop.com",
}
)
return registry
@pytest.fixture
def action_context(persona_store: PersonaStore) -> object:
"""Provide ActionContext instance for testing action execution.
Note: Returns object type since ActionContext structure is opaque to fixtures.
Args:
persona_store: Unused, but required for fixture dependency order.
"""
_ = persona_store # Unused but required for fixture dependency
from guide.app.models.domain.models import ActionContext
return ActionContext(
action_id="test-action",
persona_id="buyer",
browser_host_id="demo-extension",
correlation_id="test-correlation-123",
shared_state={},
)
@pytest.fixture
def mock_page() -> AsyncMock:
"""Provide mock Playwright page instance."""
page = AsyncMock()
page.goto = AsyncMock()
page.wait_for_selector = AsyncMock()
page.fill = AsyncMock()
page.click = AsyncMock()
page.screenshot = AsyncMock(return_value=b"fake-image-data")
page.content = AsyncMock(return_value="<html><body>Mock</body></html>")
page.on = MagicMock()
return page
@pytest.fixture
def mock_browser_client() -> AsyncMock:
"""Provide mock BrowserClient instance."""
client = AsyncMock()
client.open_page = AsyncMock()
return client
@pytest.fixture
def mock_browser_pool() -> AsyncMock:
"""Provide mock BrowserPool instance."""
pool = AsyncMock()
pool.initialize = AsyncMock()
pool.close = AsyncMock()
return pool