diff --git a/tests/test_qr_login.py b/tests/test_qr_login.py index 4f397b9..74c54d9 100644 --- a/tests/test_qr_login.py +++ b/tests/test_qr_login.py @@ -4,7 +4,12 @@ from xhs_cli.command_normalizers import normalize_xhs_user_payload from xhs_cli.exceptions import XhsApiError -from xhs_cli.qr_login import BrowserQrLoginUnavailable, _normalize_browser_cookies, qrcode_login +from xhs_cli.qr_login import ( + BrowserQrLoginUnavailable, + _camoufox_launch_options, + _normalize_browser_cookies, + qrcode_login, +) class _FakeQrClient: @@ -219,6 +224,15 @@ def test_qrcode_login_falls_back_when_browser_backend_unavailable(monkeypatch): } +def test_browser_assisted_login_excludes_default_addons(): + from camoufox import DefaultAddons + + options = _camoufox_launch_options() + + assert options["headless"] is False + assert options["exclude_addons"] == [DefaultAddons.UBO] + + def test_normalize_browser_cookies_uses_allowlist(): cookies = _normalize_browser_cookies([ {"name": "a1", "value": "a1-value", "domain": ".xiaohongshu.com"}, diff --git a/xhs_cli/qr_login.py b/xhs_cli/qr_login.py index e7b189a..e1e3f4f 100644 --- a/xhs_cli/qr_login.py +++ b/xhs_cli/qr_login.py @@ -337,6 +337,16 @@ def _ensure_camoufox_ready() -> None: ) +def _camoufox_launch_options() -> dict[str, Any]: + """Return Camoufox launch options for browser-assisted QR login.""" + from camoufox import DefaultAddons + + return { + "headless": False, + "exclude_addons": [DefaultAddons.UBO], + } + + def _browser_assisted_qrcode_login( *, on_status: callable[[str], None] | None = None, @@ -347,6 +357,7 @@ def _browser_assisted_qrcode_login( try: from camoufox.sync_api import Camoufox + launch_options = _camoufox_launch_options() except ImportError as exc: raise BrowserQrLoginUnavailable( "Camoufox sync API is unavailable in the current environment." @@ -356,7 +367,7 @@ def _browser_assisted_qrcode_login( _emit_status(on_status, "🔑 Starting browser-assisted QR login...") - with Camoufox(headless=False) as browser: + with Camoufox(**launch_options) as browser: page = browser.new_page() def _handle_response(response) -> None: