AutoRpa/rpa_selection/tests/test_chrome_profile.py

123 lines
4.0 KiB
Python

from pathlib import Path
import playwright.sync_api as playwright_sync
import auth_login
from auth_login import BrowserRuntime, resolve_selection_chrome_profile
REPO_ROOT = Path(__file__).resolve().parents[2]
def _is_relative_to(path: Path, root: Path) -> bool:
try:
path.resolve().relative_to(root.resolve())
except ValueError:
return False
return True
def test_default_chrome_profile_is_outside_repo_selection_subdir(monkeypatch):
monkeypatch.delenv("RPA_SELECTION_CHROME_PROFILE", raising=False)
monkeypatch.delenv("RPA_CHROME_PROFILE", raising=False)
profile = resolve_selection_chrome_profile(repo_root=REPO_ROOT)
assert profile == (REPO_ROOT.parent / "rpa-chrome-profile" / "selection").resolve()
assert not _is_relative_to(profile, REPO_ROOT)
def test_env_path_inside_repo_is_rejected(monkeypatch):
inside = REPO_ROOT / "rpa_selection" / "data" / "chrome-profile"
monkeypatch.delenv("RPA_CHROME_PROFILE", raising=False)
profile = resolve_selection_chrome_profile(requested=str(inside), repo_root=REPO_ROOT)
assert profile == (REPO_ROOT.parent / "rpa-chrome-profile" / "selection").resolve()
assert not _is_relative_to(profile, REPO_ROOT)
def test_env_path_outside_repo_is_kept(tmp_path):
outside = tmp_path / "custom-chrome"
outside.mkdir()
profile = resolve_selection_chrome_profile(requested=str(outside), repo_root=REPO_ROOT)
assert profile == outside.resolve()
def test_rpa_chrome_profile_uses_selection_subdir(monkeypatch, tmp_path):
base = tmp_path / "work-profile"
monkeypatch.delenv("RPA_SELECTION_CHROME_PROFILE", raising=False)
monkeypatch.setenv("RPA_CHROME_PROFILE", str(base))
profile = resolve_selection_chrome_profile(repo_root=REPO_ROOT)
assert profile == (base / "selection").resolve()
class _FakePage:
url = "about:blank"
def bring_to_front(self) -> None:
return None
class _FakeContext:
def __init__(self) -> None:
self.pages = [_FakePage()]
self.closed = False
self.new_page_calls = 0
def new_page(self) -> _FakePage:
self.new_page_calls += 1
page = _FakePage()
self.pages.append(page)
return page
def close(self) -> None:
self.closed = True
class _FakeChromium:
def __init__(self) -> None:
self.persistent_calls: list[tuple[str, dict]] = []
self.launch_calls: list[dict] = []
self.context = _FakeContext()
def launch_persistent_context(self, user_data_dir: str, **kwargs):
self.persistent_calls.append((user_data_dir, kwargs))
return self.context
def launch(self, **kwargs):
self.launch_calls.append(kwargs)
raise AssertionError("选品登录必须复用用户目录,禁止 launch 空 Chrome")
class _FakePlaywright:
def __init__(self, chromium: _FakeChromium) -> None:
self.chromium = chromium
def start(self) -> "_FakePlaywright":
return self
def stop(self) -> None:
return None
def test_browser_runtime_reuses_persistent_profile(monkeypatch, tmp_path):
profile = tmp_path / "selection-profile"
monkeypatch.setenv("RPA_SELECTION_CHROME_PROFILE", str(profile))
chromium = _FakeChromium()
fake = _FakePlaywright(chromium)
monkeypatch.setattr(playwright_sync, "sync_playwright", lambda: fake)
runtime = BrowserRuntime(keep=False)
ctx1, page1 = runtime.new_page()
ctx2, page2 = runtime.new_page()
assert chromium.launch_calls == []
assert len(chromium.persistent_calls) == 1
user_data_dir, kwargs = chromium.persistent_calls[0]
assert user_data_dir == str(profile.resolve())
assert kwargs.get("channel") == "chrome"
assert "--disable-blink-features=AutomationControlled" in kwargs.get("args", [])
assert ctx1 is ctx2 is chromium.context
assert page1 is not page2
assert chromium.context.new_page_calls == 1
runtime.close()
assert chromium.context.closed
assert auth_login.resolve_selection_chrome_profile() == profile.resolve()