litellm/tests/e2e/management/conftest.py
Yassin Kortam 08fa25042c
test(e2e): rename Gateway to ProxyClient and expose it as a session-scoped fixture (#33750)
The shared proxy wrapper in tests/e2e/e2e_gateway.py was misnamed: Gateway is
not a gateway server, it is the client every suite uses to talk to the proxy
(keys, models, chat/embed/ocr, spend read-backs, poll helpers). Rename the
module to proxy_client.py and the class to ProxyClient, with build_gateway
becoming build_proxy_client and the GatewayProvider protocol becoming
ProxyClientProvider. The .gateway attribute suites held is now .proxy. Only
identifiers changed; prose and string literals that use the word gateway for the
proxy-server concept were left alone.

Each suite previously built its own instance through a per-suite build_client()
that called build_gateway() inside, duplicating the proxy wiring across suites.
There is now one session-scoped proxy fixture in tests/e2e/conftest.py; every
suite's client fixture depends on it and injects it, so the wiring lives in one
place. claude_code keeps building its own client directly since it has its own
harness and does not use the shared fixtures.

Behavior is unchanged: shared transport, data-plane/control-plane split routing,
poll budget, typed request/response models, and resource cleanup all go through
the same object.
2026-07-18 18:41:18 +00:00

64 lines
2.3 KiB
Python

"""Management suite fixtures: the client plus a logged-in dashboard page.
Lifecycle/liveness gate/marker live in the parent conftest. The browser fixtures drive
the dashboard the proxy serves at /ui, so browser tests exercise exactly what an
end user sees. playwright is an optional dependency loaded behind importorskip
inside the fixture, so the API tests in this suite collect and run without it:
uv pip install playwright && uv run playwright install chromium
"""
from typing import TYPE_CHECKING, Iterator
import pytest
from e2e_config import UI_BASE_URL, UI_PASSWORD, UI_USERNAME
from management_client import ManagementClient, build_client
from proxy_client import ProxyClient
if TYPE_CHECKING:
from playwright.sync_api import Browser, Page
def pytest_configure(config: pytest.Config) -> None:
config.addinivalue_line(
"markers",
"covers: registry cell a test covers, e.g. mgmt.key.generate.persists",
)
@pytest.fixture(scope="session")
def client(proxy: ProxyClient) -> ManagementClient:
return build_client(proxy)
@pytest.fixture(scope="session")
def browser() -> "Iterator[Browser]":
pytest.importorskip("playwright.sync_api", reason="playwright not installed")
from playwright.sync_api import sync_playwright
with sync_playwright() as playwright:
launched = playwright.chromium.launch()
yield launched
launched.close()
@pytest.fixture
def ui_page(browser: "Browser") -> "Iterator[Page]":
context = browser.new_context()
try:
page = context.new_page()
# Split deploys serve the Next.js dashboard on the UI service, not the
# data-plane gateway (which 404s /ui). Login is a client-rendered form
# that appears after LoadingScreen; wait on the placeholder, not #id
# (Ant Design Input does not always set id="username").
page.goto(f"{UI_BASE_URL}/ui/login")
username = page.get_by_placeholder("Enter your username")
username.wait_for(state="visible", timeout=30_000)
username.fill(UI_USERNAME)
page.get_by_placeholder("Enter your password").fill(UI_PASSWORD)
page.get_by_role("button", name="Login", exact=True).click()
page.wait_for_function("() => document.cookie.includes('token=')")
yield page
finally:
context.close()