Spaces:
Running
Running
| """ | |
| Visual verification using browser. | |
| Browser is installed in project: .local-browsers/ | |
| Uses full chromium (requires --enable=playwright-chrome in safehouse) | |
| """ | |
| # ruff: noqa: T201 | |
| import os | |
| def get_browser_path(): | |
| """Find browser executable in project.""" | |
| project_root = os.path.dirname(os.path.abspath(__file__)).replace("/tests", "") | |
| # Try full chromium first | |
| chromium_full = os.path.join( | |
| project_root, | |
| ".local-browsers", | |
| "chromium-1217", | |
| "chrome-mac-arm64", | |
| "Google Chrome for Testing.app", | |
| "Contents", | |
| "MacOS", | |
| "Google Chrome for Testing", | |
| ) | |
| # Fall back to headless shell | |
| chromium_headless = os.path.join( | |
| project_root, | |
| ".local-browsers", | |
| "chromium_headless_shell-1217", | |
| "chrome-headless-shell-mac-arm64", | |
| "chrome-headless-shell", | |
| ) | |
| if os.path.exists(chromium_full): | |
| return chromium_full | |
| elif os.path.exists(chromium_headless): | |
| return chromium_headless | |
| return None | |
| def get_element_styles(css: str, selector: str) -> dict: | |
| """Extract styles from CSS.""" | |
| import re | |
| pattern = re.escape(selector) + r"\s*\{([^}]+)\}" | |
| match = re.search(pattern, css) | |
| if not match: | |
| return {"error": "Selector not found"} | |
| styles = {} | |
| for line in match.group(1).split(";"): | |
| if ":" not in line: | |
| continue | |
| key, value = line.split(":", 1) | |
| styles[key.strip()] = value.strip() | |
| return { | |
| "fontSize": styles.get("font-size", ""), | |
| "lineHeight": styles.get("line-height", ""), | |
| } | |
| def verify_with_browser() -> bool: | |
| """Verify using browser (installed in project).""" | |
| from playwright.sync_api import sync_playwright | |
| browser_path = get_browser_path() | |
| if not browser_path: | |
| print("No browser found in .local-browsers/") | |
| return False | |
| print(f"Using browser: {browser_path}") | |
| with sync_playwright() as p: | |
| browser = p.chromium.launch( | |
| headless=True, | |
| executable_path=browser_path, | |
| args=["--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu"], | |
| timeout=15000, | |
| ) | |
| page = browser.new_page() | |
| page.goto("http://localhost:8080/static/scan.html") | |
| page.wait_for_load_state("networkidle") | |
| # Wait for AnalyzeModal and open | |
| page.wait_for_function("typeof AnalyzeModal !== 'undefined'", timeout=10000) | |
| page.evaluate("() => AnalyzeModal.open()") | |
| page.wait_for_selector("#analyze-modal:not(.hidden)", timeout=5000) | |
| # Load FRMM | |
| page.fill("#analyze-modal-input", "FRMM") | |
| page.keyboard.press("Enter") | |
| page.wait_for_selector(".analyze-company-desc", timeout=30000) | |
| # Get company desc styles | |
| desc_el = page.locator(".analyze-company-desc") | |
| desc_fs = desc_el.evaluate("e => getComputedStyle(e).fontSize") | |
| desc_lh = desc_el.evaluate("e => getComputedStyle(e).lineHeight") | |
| print("\n=== COMPANY DESC (rendered) ===") | |
| print(f" font-size: {desc_fs}") | |
| print(f" line-height: {desc_lh}") | |
| # Get catalyst summary styles if exists | |
| summary_el = page.locator(".analyze-catalyst-summary") | |
| if summary_el.count() > 0: | |
| summary_fs = summary_el.first.evaluate("e => getComputedStyle(e).fontSize") | |
| summary_lh = summary_el.first.evaluate("e => getComputedStyle(e).lineHeight") | |
| print("\n=== CATALYST SUMMARY (rendered) ===") | |
| print(f" font-size: {summary_fs}") | |
| print(f" line-height: {summary_lh}") | |
| match = desc_fs == summary_fs and desc_lh == summary_lh | |
| else: | |
| print("\n=== CATALYST SUMMARY ===") | |
| print(" Not found (no catalyst data)") | |
| # Pass if company desc loaded | |
| match = bool(desc_fs) | |
| print(f"\nRESULT: {'PASS' if match else 'FAIL'}") | |
| browser.close() | |
| return match | |
| def verify_static() -> bool: | |
| """Verify CSS via static analysis.""" | |
| import urllib.request | |
| print("Using static CSS analysis...") | |
| try: | |
| with urllib.request.urlopen("http://localhost:8080/static/css/analyze.css") as resp: | |
| css = resp.read().decode("utf-8") | |
| except Exception as e: | |
| print(f"ERROR: {e}") | |
| return False | |
| desc = get_element_styles(css, ".analyze-company-desc") | |
| summary = get_element_styles(css, ".analyze-catalyst-summary") | |
| print(f"\n=== COMPANY DESC (CSS) === {desc}") | |
| print(f"\n=== CATALYST SUMMARY (CSS) === {summary}") | |
| match = desc.get("fontSize") == summary.get("fontSize") and desc.get("lineHeight") == summary.get("lineHeight") | |
| print(f"RESULT: {'PASS' if match else 'FAIL'}") | |
| return match | |
| if __name__ == "__main__": | |
| browser_path = get_browser_path() | |
| has_browser = browser_path and os.path.exists(browser_path) | |
| if has_browser: | |
| print("Attempting browser-based verification...") | |
| try: | |
| success = verify_with_browser() | |
| except Exception as e: | |
| print(f"Browser error: {e}") | |
| success = verify_static() | |
| else: | |
| success = verify_static() | |
| exit(0 if success else 1) | |