171 lines
5.6 KiB
Python
171 lines
5.6 KiB
Python
|
|
"""
|
||
|
|
Browser Test Scenarios for DevLoop
|
||
|
|
Pre-built Playwright scenarios that can be used for dashboard verification.
|
||
|
|
|
||
|
|
These scenarios use the same structure as DashboardTestRunner browser tests
|
||
|
|
but provide ready-made tests for common dashboard operations.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from typing import Dict, List
|
||
|
|
|
||
|
|
|
||
|
|
def get_study_browser_scenarios(study_name: str) -> List[Dict]:
|
||
|
|
"""
|
||
|
|
Get browser test scenarios for a specific study.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
study_name: The study to test
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
List of browser test scenarios
|
||
|
|
"""
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
"id": "browser_home_loads",
|
||
|
|
"name": "Home page loads with studies",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": "/"},
|
||
|
|
{"action": "wait_for", "selector": "text=Studies"},
|
||
|
|
{"action": "wait_for", "selector": "button:has-text('trials')"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 15000,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "browser_canvas_loads",
|
||
|
|
"name": f"Canvas loads for {study_name}",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": f"/canvas/{study_name}"},
|
||
|
|
# Wait for ReactFlow nodes to render
|
||
|
|
{"action": "wait_for", "selector": ".react-flow__node"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 20000,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "browser_dashboard_loads",
|
||
|
|
"name": f"Dashboard loads for {study_name}",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": f"/dashboard"},
|
||
|
|
# Wait for dashboard main element to load
|
||
|
|
{"action": "wait_for", "selector": "main"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 15000,
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def get_ui_verification_scenarios() -> List[Dict]:
|
||
|
|
"""
|
||
|
|
Get scenarios for verifying UI components.
|
||
|
|
|
||
|
|
These are general UI health checks, not study-specific.
|
||
|
|
"""
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
"id": "browser_home_stats",
|
||
|
|
"name": "Home page shows statistics",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": "/"},
|
||
|
|
{"action": "wait_for", "selector": "text=Total Studies"},
|
||
|
|
{"action": "wait_for", "selector": "text=Running"},
|
||
|
|
{"action": "wait_for", "selector": "text=Total Trials"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 10000,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "browser_expand_folder",
|
||
|
|
"name": "Topic folder expands on click",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": "/"},
|
||
|
|
{"action": "wait_for", "selector": "button:has-text('trials')"},
|
||
|
|
{"action": "click", "selector": "button:has-text('trials')"},
|
||
|
|
# After click, should see study status badges
|
||
|
|
{
|
||
|
|
"action": "wait_for",
|
||
|
|
"selector": "span:has-text('completed'), span:has-text('running'), span:has-text('paused')",
|
||
|
|
},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 10000,
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def get_chat_verification_scenarios() -> List[Dict]:
|
||
|
|
"""
|
||
|
|
Get scenarios for verifying chat/Claude integration.
|
||
|
|
"""
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
"id": "browser_chat_panel",
|
||
|
|
"name": "Chat panel opens",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": "/canvas/support_arm"},
|
||
|
|
{"action": "wait_for", "selector": ".react-flow__node"},
|
||
|
|
# Look for chat toggle or chat panel
|
||
|
|
{
|
||
|
|
"action": "click",
|
||
|
|
"selector": "button[aria-label='Chat'], button:has-text('Chat')",
|
||
|
|
},
|
||
|
|
{"action": "wait_for", "selector": "textarea, input[type='text']"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 15000,
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
# Standard scenario sets
|
||
|
|
STANDARD_BROWSER_SCENARIOS: Dict[str, List[Dict]] = {
|
||
|
|
"quick": [
|
||
|
|
{
|
||
|
|
"id": "browser_smoke",
|
||
|
|
"name": "Dashboard smoke test",
|
||
|
|
"type": "browser",
|
||
|
|
"steps": [
|
||
|
|
{"action": "navigate", "url": "/"},
|
||
|
|
{"action": "wait_for", "selector": "text=Studies"},
|
||
|
|
],
|
||
|
|
"expected_outcome": {"status": "pass"},
|
||
|
|
"timeout_ms": 10000,
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"home": get_ui_verification_scenarios(),
|
||
|
|
"full": get_ui_verification_scenarios() + get_study_browser_scenarios("support_arm"),
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def get_browser_scenarios(level: str = "quick", study_name: str = None) -> List[Dict]:
|
||
|
|
"""
|
||
|
|
Get browser scenarios by level.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
level: "quick" (smoke), "home" (home page), "full" (all scenarios)
|
||
|
|
study_name: Optional study name for study-specific tests
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
List of browser test scenarios
|
||
|
|
"""
|
||
|
|
if level == "quick":
|
||
|
|
return STANDARD_BROWSER_SCENARIOS["quick"]
|
||
|
|
elif level == "home":
|
||
|
|
return STANDARD_BROWSER_SCENARIOS["home"]
|
||
|
|
elif level == "full":
|
||
|
|
scenarios = list(STANDARD_BROWSER_SCENARIOS["full"])
|
||
|
|
if study_name:
|
||
|
|
scenarios.extend(get_study_browser_scenarios(study_name))
|
||
|
|
return scenarios
|
||
|
|
elif level == "study" and study_name:
|
||
|
|
return get_study_browser_scenarios(study_name)
|
||
|
|
else:
|
||
|
|
return STANDARD_BROWSER_SCENARIOS["quick"]
|