"""Selenium smoke tests — need a running app (see README).""" from __future__ import annotations import os import urllib.error import urllib.request import pytest from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.ui import WebDriverWait pytest.importorskip("selenium.webdriver") def _server_reachable(base_url: str, timeout: float = 2.0) -> bool: try: urllib.request.urlopen(f"{base_url.rstrip('/')}/", timeout=timeout) return True except (urllib.error.URLError, OSError): return False @pytest.fixture def driver(): from selenium import webdriver from selenium.webdriver.chrome.options import Options opts = Options() opts.add_argument("--headless=new") opts.add_argument("--no-sandbox") opts.add_argument("--disable-dev-shm-usage") try: browser = webdriver.Chrome(options=opts) except Exception as exc: # pragma: no cover pytest.skip(f"Chrome / ChromeDriver not available: {exc}") yield browser browser.quit() @pytest.mark.selenium def test_home_page_title(driver): base = os.environ.get("SELENIUM_BASE_URL", "http://127.0.0.1:8080").rstrip("/") if not _server_reachable(base): pytest.skip( f"No server at {base}. In another terminal run: " "pipenv run dev (then re-run this test, or set SELENIUM_BASE_URL)." ) driver.get(f"{base}/") assert "Python Editor" in driver.title @pytest.mark.selenium def test_editor_page_loads_core_controls(driver): base = os.environ.get("SELENIUM_BASE_URL", "http://127.0.0.1:8080").rstrip("/") if not _server_reachable(base): pytest.skip( f"No server at {base}. In another terminal run: " "pipenv run dev (then re-run this test, or set SELENIUM_BASE_URL)." ) driver.get(f"{base}/editor") # If the app is configured with AUTH_ENABLED=true, unauthenticated requests redirect to /login. if "/login" in (driver.current_url or ""): pytest.skip("Editor requires login; set AUTH_ENABLED=false for this Selenium smoke test.") wait = WebDriverWait(driver, 10) wait.until(ec.presence_of_element_located((By.ID, "run-btn"))) wait.until(ec.presence_of_element_located((By.ID, "stop-btn"))) wait.until(ec.presence_of_element_located((By.ID, "file-tree")))