feat: harden remote serve and reuse connections
Testing / remote-protocol-compat (0.9.5) (push) Successful in 56s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 59s
Testing / test (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 33s
Package Extension / package-extension (push) Successful in 36s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 56s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 59s
Testing / test (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 33s
Package Extension / package-extension (push) Successful in 36s
- Gate TCP serve commands with safe-by-default policies, per-key allow tokens, per-key rate limiting, and audit labels. - Reuse authenticated encrypted remote sessions and parallelize/caches multi-browser fanout to reduce repeated handshake roundtrips. - Increase paged native-host batch size with extension-side byte budgeting to speed large tab listings safely. - Point install output at public Chrome Web Store / Firefox AMO listings by default, with --dev preserving unpacked workflows. - Share search-engine metadata between CLI and SDK and bump the package/extension version to 0.16.0. - Cover the new security, pooling, paging, install, and fanout behavior with expanded Python and extension tests.
This commit is contained in:
+39
-17
@@ -28,8 +28,8 @@ def test_long_version_option():
|
||||
assert result.output.strip() == _expected_version()
|
||||
|
||||
def test_project_version_falls_back_to_installed_package_metadata():
|
||||
with patch("browser_cli.cli.Path.read_text", side_effect=OSError), patch(
|
||||
"browser_cli.cli.package_version", return_value="9.9.9"
|
||||
with patch("browser_cli.version_manager.Path.read_text", side_effect=OSError), patch(
|
||||
"browser_cli.version_manager._pkg_version", return_value="9.9.9"
|
||||
):
|
||||
assert _project_version() == "9.9.9"
|
||||
|
||||
@@ -114,8 +114,8 @@ def test_install_writes_testing_and_webstore_allowed_origins(tmp_path):
|
||||
],
|
||||
}
|
||||
]
|
||||
assert "Testing extension ID" in result.output
|
||||
assert "Chrome Web Store extension ID" in result.output
|
||||
assert "chromewebstore.google.com" in result.output
|
||||
assert "Add to Brave" in result.output
|
||||
|
||||
def test_install_writes_firefox_allowed_extensions(tmp_path):
|
||||
manifests = []
|
||||
@@ -139,12 +139,34 @@ def test_install_writes_firefox_allowed_extensions(tmp_path):
|
||||
"allowed_extensions": ["browser-cli@yiprawr.dev"],
|
||||
}
|
||||
]
|
||||
assert "addons.mozilla.org/firefox/addon/browser-cli" in result.output
|
||||
assert "Add to Firefox" in result.output
|
||||
|
||||
def test_install_dev_flag_prints_unpacked_instructions(tmp_path):
|
||||
with patch("browser_cli.commands.install.native_host_exe", return_value=tmp_path / "browser-cli-native-host"), patch(
|
||||
"browser_cli.commands.install.write_native_host_exe"
|
||||
), patch("browser_cli.commands.install._install_manifest", return_value=[tmp_path / "com.browsercli.host.json"]):
|
||||
result = CliRunner().invoke(main, ["install", "brave", "--dev"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Load unpacked" in result.output
|
||||
assert "Developer mode" in result.output
|
||||
assert "Testing extension ID" in result.output
|
||||
assert "Chrome Web Store extension ID" in result.output
|
||||
assert "chromewebstore.google.com" not in result.output # store path is the non-dev default
|
||||
|
||||
def test_install_dev_flag_prints_firefox_unpacked_instructions(tmp_path):
|
||||
with patch("browser_cli.commands.install.native_host_exe", return_value=tmp_path / "browser-cli-native-host"), patch(
|
||||
"browser_cli.commands.install.write_native_host_exe"
|
||||
), patch("browser_cli.commands.install._install_manifest", return_value=[tmp_path / "com.browsercli.host.json"]):
|
||||
result = CliRunner().invoke(main, ["install", "firefox", "--dev"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "about:debugging#/runtime/this-firefox" in result.output
|
||||
assert "npm run package:extension:firefox" in result.output
|
||||
output_unwrapped = result.output.replace("\n", "")
|
||||
assert "dist/extension-package-firefox/manifest.json" in output_unwrapped
|
||||
assert "Do not select extension/manifest.json" in output_unwrapped
|
||||
assert "Firefox extension ID" in result.output
|
||||
|
||||
def test_install_windows_registers_native_host(tmp_path):
|
||||
writes = []
|
||||
@@ -205,7 +227,7 @@ def test_write_native_host_exe_windows(tmp_path):
|
||||
|
||||
def test_clients_exits_cleanly_when_registry_is_missing():
|
||||
with patch("browser_cli.commands.clients.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")), patch(
|
||||
"browser_cli.commands.clients.active_browser_targets", return_value=[]
|
||||
"browser_cli.client.core.active_browser_targets", return_value=[]
|
||||
):
|
||||
result = CliRunner().invoke(main, ["clients"])
|
||||
|
||||
@@ -239,8 +261,8 @@ def test_clients_without_remote_shows_saved_remotes_without_pq_warning(tmp_path)
|
||||
return [remote_target]
|
||||
|
||||
with patch("browser_cli.commands.clients.REGISTRY_PATH", registry_path), patch(
|
||||
"browser_cli.commands.clients.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.commands.clients.active_browser_targets", side_effect=fake_active_browser_targets) as active_targets:
|
||||
"browser_cli.client.core.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.client.core.active_browser_targets", side_effect=fake_active_browser_targets) as active_targets:
|
||||
result = CliRunner().invoke(main, ["clients"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -263,8 +285,8 @@ def test_clients_reads_registry_with_trailing_garbage(tmp_path):
|
||||
return [{"profile": "main", "name": "Chrome", "version": "1", "extensionVersion": "0.8.2"}]
|
||||
|
||||
with patch("browser_cli.commands.clients.REGISTRY_PATH", registry_path), patch(
|
||||
"browser_cli.commands.clients.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.commands.clients.active_browser_targets", return_value=[]):
|
||||
"browser_cli.client.core.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.client.core.active_browser_targets", return_value=[]):
|
||||
result = CliRunner().invoke(main, ["clients"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -280,7 +302,7 @@ def test_clients_remote_uses_remote_endpoint_without_local_registry():
|
||||
|
||||
with patch.dict(os.environ, {}, clear=True), patch(
|
||||
"browser_cli.commands.clients.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")
|
||||
), patch("browser_cli.commands.clients.send_command", side_effect=fake_send_command) as send_command:
|
||||
), patch("browser_cli.client.core.send_command", side_effect=fake_send_command) as send_command:
|
||||
result = CliRunner().invoke(main, ["--remote", "127.0.0.1:8765", "clients"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -290,7 +312,7 @@ def test_clients_remote_uses_remote_endpoint_without_local_registry():
|
||||
assert "2.3.4" in result.output
|
||||
|
||||
def test_clients_remote_respects_global_browser_route():
|
||||
with patch.dict(os.environ, {}, clear=True), patch("browser_cli.commands.clients.send_command", return_value=[]) as send_command:
|
||||
with patch.dict(os.environ, {}, clear=True), patch("browser_cli.client.core.send_command", return_value=[]) as send_command:
|
||||
result = CliRunner().invoke(main, ["--remote", "127.0.0.1:8765", "--browser", "work", "clients"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
@@ -316,10 +338,10 @@ def test_clients_browser_alias_resolves_to_remote():
|
||||
return [{"name": "Chrome", "version": "147.0.0.0", "extensionVersion": "0.8.5"}]
|
||||
|
||||
with patch.dict(os.environ, {}, clear=True), patch(
|
||||
"browser_cli.commands.clients.remote_target_for_alias", return_value=resolved_target
|
||||
"browser_cli.client.core.remote_target_for_alias", return_value=resolved_target
|
||||
), patch(
|
||||
"browser_cli.commands.clients.remote_browser_targets", return_value=all_remote_targets
|
||||
), patch("browser_cli.commands.clients.send_command", side_effect=fake_send_command) as send_command:
|
||||
"browser_cli.client.core.remote_browser_targets", return_value=all_remote_targets
|
||||
), patch("browser_cli.client.core.send_command", side_effect=fake_send_command) as send_command:
|
||||
result = CliRunner().invoke(main, ["--browser", "browser-host.example", "clients"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -346,8 +368,8 @@ def test_clients_shows_named_profile_and_uses_socket_uuid_for_default(tmp_path):
|
||||
return responses[profile]
|
||||
|
||||
with patch("browser_cli.commands.clients.REGISTRY_PATH", registry_path), patch(
|
||||
"browser_cli.commands.clients.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.commands.clients.active_browser_targets", return_value=[]):
|
||||
"browser_cli.client.core.send_command", side_effect=fake_send_command
|
||||
), patch("browser_cli.client.core.active_browser_targets", return_value=[]):
|
||||
result = CliRunner().invoke(main, ["clients"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
Reference in New Issue
Block a user