allow to ask for remote host profiles and save token on first connection for later use

This commit is contained in:
2026-05-01 19:07:04 +02:00
parent 2f982fa714
commit 5ff340a6d3
11 changed files with 216 additions and 33 deletions
+2 -2
View File
@@ -17,9 +17,9 @@ def browser():
"""Returns a connected send_command callable for the testing profile, or skips the test."""
try:
send_command("tabs.list", profile=TEST_BROWSER_PROFILE)
except BrowserNotConnected:
except (BrowserNotConnected, RuntimeError) as e:
pytest.skip(
"Browser 'testing' not connected — start Brave/Chrome with the extension loaded for that profile"
f"Browser 'testing' not connected — start Brave/Chrome with the extension loaded for that profile ({e})"
)
def _browser(command, args=None):
+32 -1
View File
@@ -149,7 +149,9 @@ def test_clients_remote_uses_remote_endpoint_without_local_registry():
with patch.dict(os.environ, {}, clear=True), patch(
"browser_cli.cli.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")
), patch("browser_cli.cli.send_command", side_effect=fake_send_command) as send_command:
), patch("browser_cli.cli.send_command", side_effect=fake_send_command) as send_command, patch(
"browser_cli.cli.save_remote_token"
):
result = CliRunner().invoke(main, ["--remote", "127.0.0.1:8765", "--token", "test", "clients"])
assert result.exit_code == 0
@@ -551,3 +553,32 @@ def test_convert_html_to_markdown_indents_multiline_list_items():
"- Unternehmensdaten → RAG → KI-Orchestrierung →\n"
" Local LLMs / API Modelle / Spezialmodelle"
) in markdown
def test_remote_token_is_saved_when_passed_on_cli():
endpoint = "browser-host.example:8765"
with patch("browser_cli.cli.save_remote_token") as save_remote_token:
result = CliRunner().invoke(main, ["--remote", endpoint, "--token", "secret", "completion", "bash", "--script"])
assert result.exit_code == 0
save_remote_token.assert_called_once_with(endpoint, "secret")
def test_tabs_list_multi_browser_queries_remote_target():
endpoint = "browser-host.example:8765"
remote_target = BrowserTarget(
"work",
"browser-host.example:work",
"",
remote=endpoint,
token="secret",
)
with patch("browser_cli.commands.tabs.active_browser_targets", return_value=[remote_target, BrowserTarget("local", "local", "/tmp/local.sock")]), patch(
"browser_cli.commands.tabs.send_command",
return_value=[{"id": 1, "windowId": 1, "active": True, "title": "Remote", "url": "https://example.com"}],
) as send_command:
result = CliRunner().invoke(main, ["tabs", "list"])
assert result.exit_code == 0
send_command.assert_any_call("tabs.list", {}, profile="work", remote=endpoint, token="secret")
assert "browser-host.example:work" in result.output
+48 -3
View File
@@ -3,7 +3,14 @@ from pathlib import Path
import pytest
from browser_cli.client import BrowserNotConnected, _resolve_socket, active_browser_targets, display_browser_name
from browser_cli.client import (
BrowserNotConnected,
_resolve_socket,
active_browser_targets,
display_browser_name,
save_remote_token,
token_for_remote,
)
from browser_cli.platform import endpoint_for_alias
def test_resolve_socket_raises_when_registry_missing(monkeypatch):
@@ -63,7 +70,7 @@ def test_active_browser_targets_filters_stale_entries(monkeypatch, tmp_path):
monkeypatch.setattr("browser_cli.client.REGISTRY_PATH", registry_path)
targets = active_browser_targets()
targets = active_browser_targets(include_remotes=False)
assert len(targets) == 1
assert targets[0].profile == "work"
@@ -77,7 +84,45 @@ def test_active_browser_targets_keeps_windows_registry_entries(monkeypatch, tmp_
monkeypatch.setattr("browser_cli.client.REGISTRY_PATH", registry_path)
monkeypatch.setattr("browser_cli.client.is_windows", lambda: True)
targets = active_browser_targets()
targets = active_browser_targets(include_remotes=False)
assert len(targets) == 1
assert targets[0].socket_path == r"\\.\pipe\browser-cli-work"
def test_save_remote_token_persists_per_endpoint(monkeypatch, tmp_path):
remotes_path = tmp_path / "remotes.json"
monkeypatch.setattr("browser_cli.client.REMOTE_REGISTRY_PATH", remotes_path)
endpoint = "browser-host.example:8765"
save_remote_token(endpoint, "secret-token")
assert token_for_remote(endpoint) == "secret-token"
assert json.loads(remotes_path.read_text(encoding="utf-8")) == {
endpoint: {"token": "secret-token"}
}
def test_active_browser_targets_includes_remote_targets(monkeypatch, tmp_path):
remotes_path = tmp_path / "remotes.json"
endpoint = "browser-host.example:8765"
remotes_path.write_text(json.dumps({endpoint: {"token": "secret-token"}}), encoding="utf-8")
monkeypatch.setattr("browser_cli.client.REGISTRY_PATH", tmp_path / "missing-registry.json")
monkeypatch.setattr("browser_cli.client.REMOTE_REGISTRY_PATH", remotes_path)
def fake_send_command(command, args=None, profile=None, remote=None, token=None):
assert command == "browser-cli.targets"
assert remote == endpoint
assert token == "secret-token"
return [{"profile": "work", "displayName": "work"}]
monkeypatch.setattr("browser_cli.client.send_command", fake_send_command)
targets = active_browser_targets()
assert len(targets) == 1
assert targets[0].profile == "work"
assert targets[0].display_name == "browser-host.example:work"
assert targets[0].remote == endpoint
assert targets[0].token == "secret-token"