letsbe-sysadmin/app/playwright_scenarios/echo.py

121 lines
3.7 KiB
Python

"""Echo scenario for testing Playwright executor.
This simple scenario navigates to a URL and verifies the page loads.
Useful for testing the Playwright infrastructure without complex workflows.
"""
from typing import Any
from playwright.async_api import Page
from app.playwright_scenarios import register_scenario
from app.playwright_scenarios.base import BaseScenario, ScenarioOptions, ScenarioResult
@register_scenario
class EchoScenario(BaseScenario):
"""Simple echo scenario for testing Playwright executor.
This scenario navigates to a URL and returns basic page information.
Useful for verifying:
- Playwright is installed and working
- Domain restrictions are enforced
- Screenshots are captured correctly
Required inputs:
url: The URL to navigate to
Optional inputs:
wait_for_selector: CSS selector to wait for (default: body)
expected_title: Expected page title (optional validation)
Result data:
title: Page title after load
url: Final URL after any redirects
content_length: Approximate content length
"""
@property
def name(self) -> str:
return "echo"
@property
def required_inputs(self) -> list[str]:
return ["url"]
@property
def optional_inputs(self) -> list[str]:
return ["wait_for_selector", "expected_title"]
@property
def description(self) -> str:
return "Navigate to URL and return page info (test scenario)"
async def execute(
self,
page: Page,
inputs: dict[str, Any],
options: ScenarioOptions,
) -> ScenarioResult:
"""Navigate to URL and capture page information.
Args:
page: Playwright Page object
inputs: Scenario inputs (url, optional wait_for_selector)
options: Scenario options
Returns:
ScenarioResult with page information
"""
url = inputs["url"]
wait_for_selector = inputs.get("wait_for_selector", "body")
expected_title = inputs.get("expected_title")
screenshots = []
result_data = {}
try:
# Navigate to the URL
response = await page.goto(url, wait_until="networkidle")
# Wait for specified selector
if wait_for_selector:
await page.wait_for_selector(wait_for_selector, timeout=options.timeout_ms)
# Collect page information
result_data = {
"title": await page.title(),
"url": page.url,
"status_code": response.status if response else None,
"content_length": len(await page.content()),
}
# Validate title if expected
if expected_title and result_data["title"] != expected_title:
return ScenarioResult(
success=False,
data=result_data,
screenshots=screenshots,
error=f"Title mismatch: expected '{expected_title}', got '{result_data['title']}'",
)
# Take screenshot if requested
if options.screenshot_on_success and options.artifacts_dir:
screenshot_path = options.artifacts_dir / "echo_result.png"
await page.screenshot(path=str(screenshot_path))
screenshots.append(str(screenshot_path))
return ScenarioResult(
success=True,
data=result_data,
screenshots=screenshots,
)
except Exception as e:
return ScenarioResult(
success=False,
data=result_data,
screenshots=screenshots,
error=f"Echo scenario failed: {str(e)}",
)