feat: improve remote browser tree routing
Testing / remote-protocol-compat (0.9.3) (push) Successful in 43s
Testing / test (push) Successful in 1m1s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 39s
Build & Publish Package / publish (push) Successful in 58s
Package Extension / package-extension (push) Successful in 1m15s

- Allow remote host aliases passed via --browser to fan out for read-only
  multi-browser SDK paths while preserving strict routing for mutating commands.
- Add remote host grouping and scoped profile labels to tabs tree output so
  global views avoid repeated host prefixes.
- Carry browser family metadata through remote targets, tabs, and groups and
  style tree browser labels by family.
- Split CLI rendering helpers into a typed rendering package with dedicated
  common, label, tabs-tree, and windows-tree modules.
- Bump browser-cli and extension versions to 0.15.5.
- Cover the new routing and rendering behavior with unit and CLI tests.
This commit is contained in:
2026-06-18 00:12:17 +02:00
parent 371b794170
commit 479a0f1964
22 changed files with 672 additions and 221 deletions
+24 -2
View File
@@ -470,7 +470,7 @@ class TestTabs:
tabs = b.tabs.list()
tabs[0].close()
assert [tab.browser for tab in tabs] == ["host:work"]
assert [tab.browser for tab in tabs] == ["work"]
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="work", remote="host:8765", key=None),
call("tabs.close", {"tabId": 10}, profile="work", remote="host:8765", key=None),
@@ -491,6 +491,28 @@ class TestTabs:
call("tabs.close", {"tabId": 10}, profile="work", remote="browser-host.example", key="agent"),
]
def test_tabs_list_browser_host_alias_fans_out_to_remote_targets(self, mock_send):
b = BrowserCLI(browser="browser-host.example", key="agent")
with patch(
"browser_cli.remote_targets_for_alias",
return_value=[
BrowserTarget("main", "browser-host.example:main", "", remote="browser-host.example:8765", browser_name="Chrome"),
BrowserTarget("work", "browser-host.example:work", "", remote="browser-host.example:8765", browser_name="Firefox"),
],
):
mock_send.side_effect = [[TAB_DATA], [{**TAB_DATA, "id": 11}], None]
tabs = b.tabs.list()
tabs[1].close()
assert [tab.browser for tab in tabs] == ["main", "work"]
assert [tab.browser_name for tab in tabs] == ["Chrome", "Firefox"]
assert [tab.browser_group for tab in tabs] == [None, None]
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="main", remote="browser-host.example:8765", key="agent"),
call("tabs.list", {}, profile="work", remote="browser-host.example:8765", key="agent"),
call("tabs.close", {"tabId": 11}, profile="work", remote="browser-host.example:8765", key="agent"),
]
def test_tabs_active_returns_active_tab(self, b, mock_send):
mock_send.side_effect = [[TAB_DATA], TAB_DATA]
@@ -659,7 +681,7 @@ class TestGroups:
groups = b.groups.list()
groups[0].close()
assert [group.browser for group in groups] == ["host:work"]
assert [group.browser for group in groups] == ["work"]
assert mock_send.call_args_list == [
call("group.list", {}, profile="work", remote="host:8765", key=None),
call("group.close", {"groupId": 42}, profile="work", remote="host:8765", key=None),