from __future__ import annotations import shutil import time from pathlib import Path from playwright.sync_api import Error, Playwright IGNORE_PATTERNS = shutil.ignore_patterns( "Singleton*", "LOCK", "lockfile", "Crashpad*", "BrowserMetrics*", ) def launch_browser_context( playwright: Playwright, user_data_dir: str, channel: str, headless: bool, ): launch_kwargs = { "channel": channel, "headless": headless, "args": ["--start-maximized"], "no_viewport": True, } source_dir = Path(user_data_dir) try: return playwright.chromium.launch_persistent_context( user_data_dir=str(source_dir), **launch_kwargs, ) except Error as exc: message = str(exc) if "Target page, context or browser has been closed" not in message: raise fallback_dir = source_dir.parent / f"{source_dir.name}-runtime-{int(time.time())}" if fallback_dir.exists(): shutil.rmtree(fallback_dir, ignore_errors=True) fallback_dir.mkdir(parents=True, exist_ok=True) if source_dir.exists(): shutil.copytree( source_dir, fallback_dir, dirs_exist_ok=True, ignore=IGNORE_PATTERNS, ) return playwright.chromium.launch_persistent_context( user_data_dir=str(fallback_dir), **launch_kwargs, )