from playwright.sync_api import Page def do_login(page: Page, webui_base: str, username: str, password: str): """Navigate to /login, fill credentials, submit, and wait until we leave /login.""" page.goto(f"{webui_base}/login") page.wait_for_load_state('networkidle') page.fill('input[autocomplete="username"]', username) page.fill('input[autocomplete="current-password"]', password) page.click('button[type="submit"]') page.wait_for_url(lambda url: '/login' not in url, timeout=10000) def do_logout(page: Page, webui_base: str): """Click the 'Sign out' button in the desktop sidebar and wait for redirect to /login.""" # The desktop sidebar renders a button with text "Sign out"; the mobile sidebar # also has one. Use first() to avoid a strict-mode error when both are mounted. page.locator('button:has-text("Sign out")').first.click() page.wait_for_url(lambda url: '/login' in url, timeout=5000)