1
0
This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/tests/functional/test_cascade_router_e2e.py
Alexander Payne d8d976aa60 feat: complete Event Log, Ledger, Memory, Cascade Router, Upgrade Queue, Activity Feed
This commit implements six major features:

1. Event Log System (src/swarm/event_log.py)
   - SQLite-based audit trail for all swarm events
   - Task lifecycle tracking (created, assigned, completed, failed)
   - Agent lifecycle tracking (joined, left, status changes)
   - Integrated with coordinator for automatic logging
   - Dashboard page at /swarm/events

2. Lightning Ledger (src/lightning/ledger.py)
   - Transaction tracking for Lightning Network payments
   - Balance calculations (incoming, outgoing, net, available)
   - Integrated with payment_handler for automatic logging
   - Dashboard page at /lightning/ledger

3. Semantic Memory / Vector Store (src/memory/vector_store.py)
   - Embedding-based similarity search for Echo agent
   - Fallback to keyword matching if sentence-transformers unavailable
   - Personal facts storage and retrieval
   - Dashboard page at /memory

4. Cascade Router Integration (src/timmy/cascade_adapter.py)
   - Automatic LLM failover between providers (Ollama → AirLLM → API)
   - Circuit breaker pattern for failing providers
   - Metrics tracking per provider (latency, error rates)
   - Dashboard status page at /router/status

5. Self-Upgrade Approval Queue (src/upgrades/)
   - State machine for self-modifications: proposed → approved/rejected → applied/failed
   - Human approval required before applying changes
   - Git integration for branch management
   - Dashboard queue at /self-modify/queue

6. Real-Time Activity Feed (src/events/broadcaster.py)
   - WebSocket-based live activity streaming
   - Bridges event_log to dashboard clients
   - Activity panel on /swarm/live

Tests:
- 101 unit tests passing
- 4 new E2E test files for Selenium testing
- Run with: SELENIUM_UI=1 pytest tests/functional/ -v --headed

Documentation:
- 6 ADRs (017-022) documenting architecture decisions
- Implementation summary in docs/IMPLEMENTATION_SUMMARY.md
- Architecture diagram in docs/architecture-v2.md
2026-02-26 08:01:01 -05:00

134 lines
4.8 KiB
Python

"""E2E tests for Cascade Router Integration.
RUN: pytest tests/functional/test_cascade_router_e2e.py -v --headed
"""
import os
import time
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from .conftest import DASHBOARD_URL
@pytest.fixture
def driver():
"""Non-headless Chrome so you can watch."""
opts = Options()
# NO --headless - you will see the browser!
opts.add_argument("--no-sandbox")
opts.add_argument("--disable-dev-shm-usage")
opts.add_argument("--window-size=1400,900")
d = webdriver.Chrome(options=opts)
d.implicitly_wait(5)
yield d
d.quit()
class TestCascadeRouterUI:
"""Cascade Router dashboard and failover behavior."""
def test_router_status_page_exists(self, driver):
"""Router status page loads at /router/status."""
driver.get(f"{DASHBOARD_URL}/router/status")
header = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)
assert "router" in header.text.lower() or "provider" in header.text.lower()
# Should show provider list
providers = driver.find_elements(By.CSS_SELECTOR, ".provider-card, .provider-row")
assert len(providers) >= 1, "Should show at least one provider"
def test_router_shows_ollama_provider(self, driver):
"""Ollama provider is listed as priority 1."""
driver.get(f"{DASHBOARD_URL}/router/status")
# Look for Ollama
page_text = driver.find_element(By.TAG_NAME, "body").text.lower()
assert "ollama" in page_text, "Should show Ollama provider"
def test_router_shows_provider_health(self, driver):
"""Each provider shows health status (healthy/degraded/unhealthy)."""
driver.get(f"{DASHBOARD_URL}/router/status")
# Look for health indicators
health_badges = driver.find_elements(
By.CSS_SELECTOR, ".health-badge, .status-healthy, .status-degraded, .status-unhealthy"
)
assert len(health_badges) >= 1, "Should show health status"
def test_router_shows_metrics(self, driver):
"""Providers show request counts, latency, error rates."""
driver.get(f"{DASHBOARD_URL}/router/status")
# Look for metrics
page_text = driver.find_element(By.TAG_NAME, "body").text
# Should show some metrics
has_requests = "request" in page_text.lower()
has_latency = "ms" in page_text.lower() or "latency" in page_text.lower()
assert has_requests or has_latency, "Should show provider metrics"
def test_chat_uses_cascade_router(self, driver):
"""Sending chat message routes through cascade (may show provider used)."""
driver.get(DASHBOARD_URL)
# Wait for chat to load
chat_input = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='message']"))
)
# Send a message
chat_input.send_keys("test cascade routing")
chat_input.send_keys(Keys.RETURN)
# Wait for response
time.sleep(5)
# Should get some response (even if error)
messages = driver.find_elements(By.CSS_SELECTOR, ".chat-message")
assert len(messages) >= 2, "Should have user message and response"
def test_nav_link_to_router(self, driver):
"""Navigation menu has link to router status."""
driver.get(DASHBOARD_URL)
# Look for router link
router_link = driver.find_elements(
By.XPATH, "//a[contains(@href, '/router') or contains(text(), 'Router')]"
)
if router_link:
router_link[0].click()
time.sleep(1)
assert "/router" in driver.current_url
class TestCascadeFailover:
"""Router failover behavior (if we can simulate failures)."""
def test_fallback_to_next_provider_on_failure(self, driver):
"""If primary fails, automatically uses secondary."""
# This is hard to test in E2E without actually breaking Ollama
# We'll just verify the router has multiple providers configured
driver.get(f"{DASHBOARD_URL}/router/status")
# Count providers
providers = driver.find_elements(By.CSS_SELECTOR, ".provider-card, .provider-row")
# If multiple providers, failover is possible
if len(providers) >= 2:
# Look for priority numbers
page_text = driver.find_element(By.TAG_NAME, "body").text
assert "priority" in page_text.lower() or "1" in page_text or "2" in page_text