feat(tabs): batch-close tabs by id list
Testing / remote-protocol-compat (0.9.5) (push) Successful in 44s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 45s
Testing / test (push) Successful in 52s
Build & Publish Package / publish (push) Successful in 32s
Package Extension / package-extension (push) Successful in 35s

Closing many tabs previously meant one IPC round-trip per tab
(tab.close() in a loop). Add a single batched path so callers can
close N tabs in one command, reusing the existing large-operation
throttle so the browser UI stays responsive.

- extension: tabs.close accepts tabIds: number[]; new branch feeds
  the array through processInBatches/chrome.tabs.remove
- sdk: tabs_close(tab_ids=...) takes tab IDs or Tab objects; the
  payload always carries "tabIds" (null when unused)
- tests: cover id-list and Tab-object batch close in test_api.py
- bump 0.10.3 -> 0.10.4 (pyproject.toml, manifest.json)
This commit is contained in:
2026-06-11 10:31:53 +02:00
parent 6c90837414
commit 0813ae2de9
6 changed files with 51 additions and 10 deletions
+22 -3
View File
@@ -305,7 +305,26 @@ class TestTabs:
b.tabs_close(tab_id=10)
mock_send.assert_called_once_with(
"tabs.close",
{"tabId": 10, "inactive": False, "duplicates": False},
{"tabId": 10, "tabIds": None, "inactive": False, "duplicates": False},
profile=None, remote=None, key=None,
)
def test_tabs_close_by_ids(self, b, mock_send):
mock_send.return_value = {"closed": 3}
assert b.tabs_close(tab_ids=[10, 20, 30]) == 3
mock_send.assert_called_once_with(
"tabs.close",
{"tabId": None, "tabIds": [10, 20, 30], "inactive": False, "duplicates": False},
profile=None, remote=None, key=None,
)
def test_tabs_close_by_ids_accepts_tab_objects(self, b, mock_send):
tabs = [b._make_tab({**TAB_DATA, "id": 10}), b._make_tab({**TAB_DATA, "id": 20})]
mock_send.return_value = {"closed": 2}
assert b.tabs_close(tab_ids=tabs) == 2
mock_send.assert_called_once_with(
"tabs.close",
{"tabId": None, "tabIds": [10, 20], "inactive": False, "duplicates": False},
profile=None, remote=None, key=None,
)
@@ -446,8 +465,8 @@ class TestTabs:
call("tabs.status", {"tabId": 10}, profile=None, remote=None, key=None),
call("tabs.query", {"search": "Example"}, profile=None, remote=None, key=None),
call("tabs.query", {"search": "Missing"}, profile=None, remote=None, key=None),
call("tabs.close", {"tabId": 10, "inactive": False, "duplicates": False}, profile=None, remote=None, key=None),
call("tabs.close", {"tabId": 10, "inactive": False, "duplicates": False}, profile=None, remote=None, key=None),
call("tabs.close", {"tabId": 10, "tabIds": None, "inactive": False, "duplicates": False}, profile=None, remote=None, key=None),
call("tabs.close", {"tabId": 10, "tabIds": None, "inactive": False, "duplicates": False}, profile=None, remote=None, key=None),
]
def test_find_tabs_alias(self, b, mock_send):