Files
browser-cli/tests/test_cli.py
T

230 lines
9.0 KiB
Python

from pathlib import Path
from click.testing import CliRunner
from unittest.mock import patch
from browser_cli.cli import main, _project_version
from browser_cli.client import BrowserTarget
def _expected_version() -> str:
pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
for line in pyproject.read_text(encoding="utf-8").splitlines():
if line.startswith("version = "):
return line.split('"')[1]
raise AssertionError("version not found in pyproject.toml")
def test_short_version_option():
result = CliRunner().invoke(main, ["-V"])
assert result.exit_code == 0
assert result.output.strip() == _expected_version()
def test_long_version_option():
result = CliRunner().invoke(main, ["--version"])
assert result.exit_code == 0
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"
):
assert _project_version() == "9.9.9"
def test_rename_profile_uses_command_level_browser_target():
with patch("browser_cli.cli.send_command") as send_command:
result = CliRunner().invoke(main, ["rename-profile", "--browser", "old-id", "work"])
assert result.exit_code == 0
send_command.assert_called_once_with("clients.rename_profile", {"alias": "work"}, profile="old-id")
def test_rename_profile_uses_global_browser_target_when_set():
with patch("browser_cli.cli.send_command") as send_command:
result = CliRunner().invoke(main, ["--browser", "old-id", "rename-profile", "work"])
assert result.exit_code == 0
send_command.assert_called_once_with("clients.rename_profile", {"alias": "work"}, profile=None)
assert "Restart the browser" not in result.output
def test_install_help_lists_supported_browsers():
result = CliRunner().invoke(main, ["install", "--help"])
assert result.exit_code == 0
assert "[chrome|chromium|brave|edge|vivaldi]" in result.output
def test_clients_exits_cleanly_when_registry_is_missing():
with patch("browser_cli.cli.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")):
result = CliRunner().invoke(main, ["clients"])
assert result.exit_code == 1
assert "No browser clients found" in result.output
def test_clients_shows_named_profile_and_uses_socket_uuid_for_default(tmp_path):
registry_path = tmp_path / "registry.json"
default_socket = tmp_path / "550e8400-e29b-41d4-a716-446655440000.sock"
work_socket = tmp_path / "work.sock"
registry_path.write_text(
'{"default": "%s", "work": "%s"}' % (default_socket, work_socket),
encoding="utf-8",
)
responses = {
"default": [{"profile": "default", "name": "Chrome", "version": "1", "extensionVersion": "2.3.4"}],
"work": [{"profile": "default", "name": "Chrome", "version": "1", "extensionVersion": "2.3.4"}],
}
def fake_send_command(command, args=None, profile=None):
assert command == "clients.list"
return responses[profile]
with patch("browser_cli.cli.REGISTRY_PATH", registry_path), patch(
"browser_cli.cli.send_command", side_effect=fake_send_command
):
result = CliRunner().invoke(main, ["clients"])
assert result.exit_code == 0
assert "550e8400-e29b-41d4-a716-446655440000" in result.output
assert "work" in result.output
assert "Extension Version" in result.output
assert "2.3.4" in result.output
def test_tabs_list_multi_browser_shows_browser_column():
def fake_send_command(command, args=None, profile=None):
assert command == "tabs.list"
return [{"id": 1 if profile == "default" else 2, "windowId": 1, "active": True, "title": profile, "url": "https://example.com"}]
with patch(
"browser_cli.commands.tabs.active_browser_targets",
return_value=[
BrowserTarget("default", "550e8400-e29b-41d4-a716-446655440000", "/tmp/default.sock"),
BrowserTarget("work", "work", "/tmp/work.sock"),
],
), patch("browser_cli.commands.tabs.send_command", side_effect=fake_send_command):
result = CliRunner().invoke(main, ["tabs", "list"])
assert result.exit_code == 0
assert "Browser" in result.output
assert "550e8400-e29b-41d4-a716-446655440000" in result.output
assert "work" in result.output
def test_tabs_list_with_explicit_browser_does_not_show_browser_column():
with patch(
"browser_cli.commands.tabs.active_browser_targets",
return_value=[
BrowserTarget("default", "uuid-1", "/tmp/default.sock"),
BrowserTarget("work", "work", "/tmp/work.sock"),
],
), patch(
"browser_cli.commands.tabs.send_command",
return_value=[{"id": 1, "windowId": 1, "active": True, "title": "Example", "url": "https://example.com"}],
) as send_command:
result = CliRunner().invoke(main, ["--browser", "work", "tabs", "list"])
assert result.exit_code == 0
assert "Browser" not in result.output
send_command.assert_called_once_with("tabs.list", {}, profile=None)
def test_tabs_count_multi_browser_shows_total():
counts = {"default": 3, "work": 4}
def fake_send_command(command, args=None, profile=None):
assert command == "tabs.count"
assert args == {"pattern": "github"}
return counts[profile]
with patch(
"browser_cli.commands.tabs.active_browser_targets",
return_value=[
BrowserTarget("default", "uuid-1", "/tmp/default.sock"),
BrowserTarget("work", "work", "/tmp/work.sock"),
],
), patch("browser_cli.commands.tabs.send_command", side_effect=fake_send_command):
result = CliRunner().invoke(main, ["tabs", "count", "github"])
assert result.exit_code == 0
assert "Browser" in result.output
assert "Total" in result.output
assert "7" in result.output
def test_group_count_multi_browser_shows_total():
counts = {"default": 1, "work": 2}
def fake_send_command(command, args=None, profile=None):
assert command == "group.count"
return counts[profile]
with patch(
"browser_cli.commands.groups.active_browser_targets",
return_value=[
BrowserTarget("default", "uuid-1", "/tmp/default.sock"),
BrowserTarget("work", "work", "/tmp/work.sock"),
],
), patch("browser_cli.commands.groups.send_command", side_effect=fake_send_command):
result = CliRunner().invoke(main, ["group", "count"])
assert result.exit_code == 0
assert "Browser" in result.output
assert "Total" in result.output
assert "3" in result.output
def test_group_list_leaves_unnamed_group_cell_empty():
with patch(
"browser_cli.commands.groups.send_command",
return_value=[{"id": 42, "title": "", "color": "grey", "collapsed": False, "tabCount": 1}],
):
result = CliRunner().invoke(main, ["group", "list"])
assert result.exit_code == 0
assert "(unnamed)" not in result.output
assert "42" in result.output
assert "grey" in result.output
def test_windows_list_multi_browser_shows_browser_column():
def fake_send_command(command, args=None, profile=None):
assert command == "windows.list"
return [{"id": 1, "alias": profile, "focused": True, "tabCount": 2, "state": "normal"}]
with patch(
"browser_cli.commands.windows.active_browser_targets",
return_value=[
BrowserTarget("default", "uuid-1", "/tmp/default.sock"),
BrowserTarget("work", "work", "/tmp/work.sock"),
],
), patch("browser_cli.commands.windows.send_command", side_effect=fake_send_command):
result = CliRunner().invoke(main, ["windows", "list"])
assert result.exit_code == 0
assert "Browser" in result.output
assert "Focused" not in result.output
assert "uuid-1" in result.output
assert "work" in result.output
def test_windows_open_passes_url():
with patch("browser_cli.commands.windows.send_command", return_value={"id": 7}) as send_command:
result = CliRunner().invoke(main, ["windows", "open", "https://example.com"])
assert result.exit_code == 0
assert "https://example.com" in result.output
send_command.assert_called_once_with("windows.open", {"url": "https://example.com"}, profile=None)
def test_extract_markdown_command():
with patch("browser_cli.commands.extract.send_command", return_value="# Title\n") as send_command:
result = CliRunner().invoke(main, ["extract", "markdown"])
assert result.exit_code == 0
assert result.output == "# Title\n"
send_command.assert_called_once_with("extract.markdown", {"selector": None})
def test_extract_markdown_command_with_selector():
with patch("browser_cli.commands.extract.send_command", return_value="## Post\n") as send_command:
result = CliRunner().invoke(main, ["extract", "markdown", "--selector", "article"])
assert result.exit_code == 0
assert result.output == "## Post\n"
send_command.assert_called_once_with("extract.markdown", {"selector": "article"})