tester fully decoupled

This commit is contained in:
2026-04-12 05:50:08 -03:00
parent 85a856b7ac
commit 3e625c2a27
10 changed files with 63 additions and 208 deletions

View File

@@ -29,7 +29,7 @@ templates = Jinja2Templates(directory=Path(__file__).parent / "templates")
@app.get("/", response_class=HTMLResponse)
def index(request: Request):
"""Mock configuration UI."""
return templates.TemplateResponse("index.html", {"request": request})
return templates.TemplateResponse(request, "index.html")
# Include router at root (matches real MercadoPago API structure)
app.include_router(router)

View File

@@ -512,9 +512,17 @@ def station_index(request: Request):
)
# Mount station tool routers
try:
from station.tools.tester.api import router as tester_router
app.include_router(tester_router, prefix="/station")
except ImportError as e:
print(f"Warning: Could not load tester router: {e}")
@app.get("/station/{path:path}")
def station_route(path: str):
"""Station sub-routes."""
"""Station sub-routes (fallback)."""
return {"system": "station", "path": path}

View File

@@ -2,6 +2,7 @@
FastAPI router for tester tool.
"""
import os
from pathlib import Path
from typing import Optional
from pydantic import BaseModel
@@ -69,8 +70,7 @@ def index(request: Request):
tests_tree = get_tests_tree()
tests_list = discover_tests()
return templates.TemplateResponse("index.html", {
"request": request,
return templates.TemplateResponse(request, "index.html", context={
"config": config,
"tests_tree": tests_tree,
"total_tests": len(tests_list),
@@ -86,8 +86,7 @@ def health():
@router.get("/filters", response_class=HTMLResponse)
def test_filters(request: Request):
"""Show filterable test view with multiple filter options."""
return templates.TemplateResponse("filters.html", {
"request": request,
return templates.TemplateResponse(request, "filters.html", context={
"config": config,
})
@@ -95,8 +94,7 @@ def test_filters(request: Request):
@router.get("/filters_v2", response_class=HTMLResponse)
def test_filters_v2(request: Request):
"""Show Gherkin-driven filter view (v2 with pulse variables)."""
return templates.TemplateResponse("filters_v2.html", {
"request": request,
return templates.TemplateResponse(request, "filters_v2.html", context={
"config": config,
})
@@ -140,10 +138,18 @@ def select_environment(env_id: str):
if not env:
raise HTTPException(status_code=404, detail=f"Environment {env_id} not found")
# Update config (in memory for this session)
# Update config and env vars (tests read from os.environ)
config["CONTRACT_TEST_URL"] = env["url"]
config["CONTRACT_TEST_API_KEY"] = env.get("api_key", "")
os.environ["CONTRACT_TEST_URL"] = env["url"]
if env.get("api_key"):
os.environ["CONTRACT_TEST_API_KEY"] = env["api_key"]
os.environ["CONTRACT_TEST_AUTH_TYPE"] = "api-key"
else:
os.environ.pop("CONTRACT_TEST_API_KEY", None)
os.environ["CONTRACT_TEST_AUTH_TYPE"] = "bearer"
return {
"success": True,
"environment": {

View File

@@ -4,7 +4,7 @@
"name": "Local",
"url": "http://localhost:8000",
"api_key": "",
"description": "Local development server",
"description": "Local development server (bare-metal)",
"default": true
}
]

View File

@@ -340,8 +340,8 @@
<div>
<h1>Contract HTTP Tests - Filters</h1>
<div class="nav-links">
<a href="/tools/tester/">Runner</a>
<a href="/tools/tester/filters" class="active">Filters</a>
<a href="/station/tools/tester/">Runner</a>
<a href="/station/tools/tester/filters" class="active">Filters</a>
</div>
</div>
<div style="display: flex; align-items: center; gap: 12px; font-size: 0.875rem; color: #9ca3af;">
@@ -450,7 +450,7 @@
// Load tests on page load
async function loadTests() {
try {
const response = await fetch('/tools/tester/api/tests');
const response = await fetch('/station/tools/tester/api/tests');
const data = await response.json();
allTests = data.tests;
@@ -505,12 +505,12 @@
async function loadLastRunResults() {
try {
const response = await fetch('/tools/tester/api/runs');
const response = await fetch('/station/tools/tester/api/runs');
const data = await response.json();
if (data.runs && data.runs.length > 0) {
const lastRunId = data.runs[0];
const runResponse = await fetch(`/tools/tester/api/run/${lastRunId}`);
const runResponse = await fetch(`/station/tools/tester/api/run/${lastRunId}`);
const runData = await runResponse.json();
runData.results.forEach(result => {
@@ -774,7 +774,7 @@
const testIds = Array.from(selectedTests);
try {
const response = await fetch('/tools/tester/api/run', {
const response = await fetch('/station/tools/tester/api/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test_ids: testIds }),
@@ -798,7 +798,7 @@
}
// Redirect to main runner with filters applied
window.location.href = `/tools/tester/?${params.toString()}`;
window.location.href = `/station/tools/tester/?${params.toString()}`;
} catch (error) {
console.error('Failed to start run:', error);
alert('Failed to start test run');
@@ -814,7 +814,7 @@
// Load environments
async function loadEnvironments() {
try {
const response = await fetch('/tools/tester/api/environments');
const response = await fetch('/station/tools/tester/api/environments');
const data = await response.json();
const selector = document.getElementById('environmentSelector');
const currentUrl = document.getElementById('currentUrl');
@@ -835,7 +835,7 @@
selector.addEventListener('change', async (e) => {
const envId = e.target.value;
try {
const response = await fetch(`/tools/tester/api/environment/select?env_id=${envId}`, {
const response = await fetch(`/station/tools/tester/api/environment/select?env_id=${envId}`, {
method: 'POST'
});
const data = await response.json();

View File

@@ -464,9 +464,9 @@
<span class="version-badge">Beta</span>
</h1>
<div class="nav-links" style="margin-top: 8px;">
<a href="/tools/tester/">Runner</a>
<a href="/tools/tester/filters">Filters v1</a>
<a href="/tools/tester/filters_v2" class="active">Filters v2</a>
<a href="/station/tools/tester/">Runner</a>
<a href="/station/tools/tester/filters">Filters v1</a>
<a href="/station/tools/tester/filters_v2" class="active">Filters v2</a>
</div>
</div>
<div style="display: flex; align-items: center; gap: 12px; font-size: 0.875rem; color: #9ca3af;">
@@ -704,7 +704,7 @@
// Load environments
async function loadEnvironments() {
try {
const response = await fetch('/tools/tester/api/environments');
const response = await fetch('/station/tools/tester/api/environments');
const data = await response.json();
const selector = document.getElementById('environmentSelector');
const currentUrl = document.getElementById('currentUrl');
@@ -725,7 +725,7 @@
selector.addEventListener('change', async (e) => {
const envId = e.target.value;
try {
const response = await fetch(`/tools/tester/api/environment/select?env_id=${envId}`, {
const response = await fetch(`/station/tools/tester/api/environment/select?env_id=${envId}`, {
method: 'POST'
});
const data = await response.json();
@@ -747,10 +747,10 @@
async function loadFeatures() {
try {
// First sync features
await fetch('/tools/tester/api/features/sync', { method: 'POST' });
await fetch('/station/tools/tester/api/features/sync', { method: 'POST' });
// Then load them
const response = await fetch('/tools/tester/api/features');
const response = await fetch('/station/tools/tester/api/features');
const data = await response.json();
allFeatures = data.features;
@@ -766,7 +766,7 @@
});
// Load tags
const tagsResponse = await fetch('/tools/tester/api/features/tags');
const tagsResponse = await fetch('/station/tools/tester/api/features/tags');
const tagsData = await tagsResponse.json();
const tagFilters = document.getElementById('tagFilters');
@@ -787,7 +787,7 @@
// Load tests
async function loadTests() {
try {
const response = await fetch('/tools/tester/api/tests');
const response = await fetch('/station/tools/tester/api/tests');
const data = await response.json();
// For now, all tests are backend (until we integrate Playwright discovery)
@@ -1109,7 +1109,7 @@
const testIds = Array.from(selectedTests);
try {
const response = await fetch('/tools/tester/api/run', {
const response = await fetch('/station/tools/tester/api/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test_ids: testIds }),
@@ -1117,7 +1117,7 @@
const data = await response.json();
// Redirect to runner
window.location.href = `/tools/tester/?run=${data.run_id}`;
window.location.href = `/station/tools/tester/?run=${data.run_id}`;
} catch (error) {
console.error('Failed to start run:', error);
alert('Failed to start test run');

View File

@@ -402,8 +402,8 @@
<div>
<h1>Contract HTTP Tests</h1>
<div style="display: flex; gap: 12px; margin-top: 8px; font-size: 0.875rem;">
<a href="/tools/tester/" style="color: #60a5fa; text-decoration: none; font-weight: 600;">Runner</a>
<a href="/tools/tester/filters" style="color: #60a5fa; text-decoration: none;">Filters</a>
<a href="/station/tools/tester/" style="color: #60a5fa; text-decoration: none; font-weight: 600;">Runner</a>
<a href="/station/tools/tester/filters" style="color: #60a5fa; text-decoration: none;">Filters</a>
</div>
</div>
<div class="config-info">
@@ -602,7 +602,7 @@
// Load environments
async function loadEnvironments() {
try {
const response = await fetch('/tools/tester/api/environments');
const response = await fetch('/station/tools/tester/api/environments');
const data = await response.json();
const selector = document.getElementById('environmentSelector');
const currentUrl = document.getElementById('currentUrl');
@@ -627,7 +627,7 @@
selector.addEventListener('change', async (e) => {
const envId = e.target.value;
try {
const response = await fetch(`/tools/tester/api/environment/select?env_id=${envId}`, {
const response = await fetch(`/station/tools/tester/api/environment/select?env_id=${envId}`, {
method: 'POST'
});
const data = await response.json();
@@ -709,7 +709,7 @@
document.getElementById('resultsList').innerHTML = '';
try {
const response = await fetch('/tools/tester/api/run', {
const response = await fetch('/station/tools/tester/api/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test_ids: testIds }),
@@ -731,7 +731,7 @@
if (!currentRunId) return;
try {
const response = await fetch(`/tools/tester/api/run/${currentRunId}`);
const response = await fetch(`/station/tools/tester/api/run/${currentRunId}`);
const data = await response.json();
updateUI(data);