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.""" # Desktop sidebar button has title="Sign out"; mobile button has no title. # This avoids clicking the hidden mobile sidebar button when both are in the DOM. page.locator('button[title="Sign out"]').click() page.wait_for_url(lambda url: '/login' in url, timeout=5000)