Files
hermes-agent/tests/tools/test_browser_use_harness.py
2026-10-10 15:20:13 +02:00

68 lines
3.6 KiB
Python

"""Browser Use caller -> browser-harness on Hermes's own interpreter -> actual child."""
import importlib.metadata
import json
import subprocess
import sys
import pytest
from tools import browser_use_cli as bu
@pytest.mark.platforms("posix", "windows")
def test_harness_runs_on_an_interpreter_without_its_own_site_packages(monkeypatch):
"""The Desktop bundle boots its store interpreter with no venv to activate (``-S`` emulates
that); the harness and its daemon must import from the PYTHONPATH the tool env supplies,
never from what the agent process inherited."""
monkeypatch.setattr(bu, "_find_cli", bu._find_cli_unpatched)
monkeypatch.setenv("PYTHONPATH", "/wrong-abi")
monkeypatch.setenv("PYTHONHOME", "/wrong-python")
cmd = bu._find_cli()
assert cmd == [sys.executable, "-m", "browser_harness.run"]
result = subprocess.run([cmd[0], "-S", *cmd[1:], "--version"], env=bu._base_subprocess_env(),
capture_output=True, text=True, timeout=120, check=False)
assert result.returncode == 0, result.stderr
assert result.stdout.strip() == importlib.metadata.version("browser-harness")
@pytest.mark.platforms("posix", "windows")
def test_browser_exec_child_environment(tmp_path, monkeypatch):
from tools import browser_tool_session, browser_supervisor
probe = tmp_path / "probe.py"
probe.write_text("import json, os, sys\n"
"print(json.dumps({'argv': sys.argv, 'stdin': sys.stdin.read(), 'env': dict(os.environ)}))\n",
encoding="utf-8")
monkeypatch.setattr(bu, "_find_cli", lambda: [sys.executable, str(probe)])
monkeypatch.setattr("hermes_cli.config.read_raw_config", lambda: {"browser": {"backend": "browser-use"}})
monkeypatch.setattr("tools.browser_tool_cdp._get_cdp_override", lambda: "")
monkeypatch.setattr("tools.browser_tool_cdp._resolve_cdp_override", lambda url: url)
monkeypatch.setattr("tools.browser_tool_cloud._get_cloud_provider", lambda: None)
monkeypatch.setattr("tools.browser_tool_lightpanda_fallback._using_lightpanda_engine", lambda: False)
def local_browser(task_id, command, args, **kwargs):
assert (task_id, command, args) == ("bu-named-research", "get", ["cdp-url"])
return {"success": True, "data": {"cdpUrl": "ws://127.0.0.1:47000/private"}}
monkeypatch.setattr(browser_tool_session, "_run_browser_command", local_browser)
attached = []
monkeypatch.setattr(browser_supervisor.SUPERVISOR_REGISTRY, "get_or_start",
lambda task_id, cdp_url, **kw: attached.append((task_id, cdp_url)))
monkeypatch.setenv("PYTHONPATH", "/wrong-abi")
monkeypatch.setenv("PYTHONHOME", "/wrong-python")
monkeypatch.setenv("OPENAI_API_KEY", "must-not-leak")
monkeypatch.setenv("BROWSERBASE_API_KEY", "browser-key")
monkeypatch.setenv("KEEP_BROWSER_PROBE", "kept")
monkeypatch.delenv("ANONYMIZED_TELEMETRY", raising=False)
result = json.loads(bu.browser_exec("print('payload')", session="research", task_id="owner"))
assert result["success"], result
child = json.loads(result["output"])
assert child["stdin"] == "print('payload')"
for key in ("PYTHONHOME", "OPENAI_API_KEY", "_HERMES_BU_PRIVATE_BROWSER"):
assert key not in child["env"]
assert child["env"].get("PYTHONPATH") == bu._harness_site_dir()
assert child["env"]["BU_NAME"] == "research"
assert child["env"]["BU_CDP_WS"] == "ws://127.0.0.1:47000/private"
assert child["env"]["ANONYMIZED_TELEMETRY"] == "false"
assert child["env"]["BROWSERBASE_API_KEY"] == "browser-key"
assert child["env"]["KEEP_BROWSER_PROBE"] == "kept"
assert attached == [("owner", "ws://127.0.0.1:47000/private")]