""" Playwright E2E test configuration for ITSulu Blog Publisher. Runs on ITSulu K8s cluster (itsulu-testing namespace). Handles cold-start polling, authentication, and fixture setup. """ import os import time import requests import pytest BASE_URL = os.environ.get('ODOO_BASE_URL', 'http://localhost:8069') K8S_TIMEOUT = 300 # seconds (Odoo startup + addon install can take time) def wait_for_odoo(url, timeout=K8S_TIMEOUT): """ Poll Odoo login page until it responds (K8s container cold-start handling). K8s pod startup + Odoo initialization + addon installation can take 60-120s. """ deadline = time.time() + timeout last_error = None while time.time() < deadline: try: response = requests.get(f"{url}/web/login", timeout=5) if response.status_code == 200: return except Exception as e: last_error = e pass time.sleep(2) raise TimeoutError( f"Odoo at {url} did not respond after {timeout}s. " f"Running on ITSulu K8s cluster (itsulu-testing namespace). " f"Last error: {last_error}" ) @pytest.fixture(scope='session') def browser_context_args(browser_context_args): """ Poll Runboat instance and set base URL for all tests. Runs once per test session before any browser is created. """ print(f"\nšŸ“” Waiting for Odoo at {BASE_URL}...") wait_for_odoo(BASE_URL) print("āœ… Odoo is ready") return {**browser_context_args, 'base_url': BASE_URL} @pytest.fixture(scope='session') def auth_state(browser, browser_context_args): """ Log in as admin and save authentication state. Reused across all tests to avoid repeated login (30s+ per test). """ print("\nšŸ” Authenticating as admin...") ctx = browser.new_context(**browser_context_args) page = ctx.new_page() page.set_default_timeout(30_000) try: page.goto('/web/login') page.get_by_label('Email').fill('admin') page.get_by_label('Password').fill('admin') page.get_by_role('button', name='Log in').click() page.wait_for_url('**/odoo/**', timeout=30_000) state = ctx.storage_state() print("āœ… Authentication successful") ctx.close() return state except Exception as e: ctx.close() raise RuntimeError(f"Login failed: {e}") @pytest.fixture def page(browser, browser_context_args, auth_state): """ Authenticated Playwright page fixture. Each test gets a fresh context with saved auth state. """ ctx = browser.new_context(**browser_context_args, storage_state=auth_state) pg = ctx.new_page() pg.set_default_timeout(30_000) # Odoo JS rendering is slow yield pg ctx.close() @pytest.fixture def admin_user(page): """ Helper to get admin user record (via API call within page context). Useful for setting up test data that requires user relationships. """ # In a real Runboat instance, we'd fetch this via the web services # For now, return a simple dict with admin info return { 'id': 2, # Odoo default admin user ID 'name': 'Administrator', 'email': 'admin@example.com', 'login': 'admin', } @pytest.fixture(scope='session') def blog_name(): """Pre-configured test blog name (must exist in template DB).""" return 'ITSulu Insights' @pytest.fixture(scope='session') def notification_email(): """Email address for testing notifications.""" return 'test@itsulu.com'