fix(accounts): keep first login launch in one window

This commit is contained in:
chengma
2026-07-14 17:22:52 +08:00
parent a4ac3f8ee5
commit 699625ea0e
10 changed files with 608 additions and 60 deletions
+186 -14
View File
@@ -84,18 +84,18 @@ class AccountsTests(TempDirMixin, unittest.TestCase):
class FakeProcess:
pid = 1234
initial_tab = {
"type": "page",
"id": "target-initial",
"url": "https://seller.shopee.tw/portal/",
"webSocketDebuggerUrl": "ws-initial",
}
with mock.patch("app.accounts.chrome.is_running", return_value=False) as is_running, \
mock.patch("app.accounts.chrome.launch_chrome", return_value=FakeProcess()) as launch, \
mock.patch("app.accounts.chrome.wait_debug_ready", return_value=True) as wait_ready, \
mock.patch("app.accounts.cdp.http_get", return_value=[]), \
mock.patch(
"app.accounts.cdp.create_tab_info",
return_value={
"id": "target-new",
"url": "https://seller.shopee.tw/portal/",
"webSocketDebuggerUrl": "ws-new",
},
) as create_tab_info, \
mock.patch("app.accounts.cdp.http_get", return_value=[initial_tab]), \
mock.patch("app.accounts.cdp.create_tab_info") as create_tab_info, \
mock.patch("app.accounts.cdp.activate_tab") as activate_tab:
result = accounts.launch_for_login("alias", config=cfg)
@@ -103,18 +103,190 @@ class AccountsTests(TempDirMixin, unittest.TestCase):
self.assertTrue(result["launched"])
self.assertFalse(result["reused"])
self.assertEqual(1234, result["pid"])
self.assertEqual("target-new", result["target_id"])
self.assertEqual("target-initial", result["target_id"])
self.assertFalse(result["created_tab"])
self.assertTrue(result["startup_target_reused"])
is_running.assert_called_once_with(9222)
launch.assert_called_once_with(account, config=cfg)
launch.assert_called_once_with(
account,
config=cfg,
initial_url="https://seller.shopee.tw/portal/",
)
wait_ready.assert_called_once_with(9222, timeout=60)
create_tab_info.assert_called_once_with(
"https://seller.shopee.tw/portal/",
create_tab_info.assert_not_called()
activate_tab.assert_called_once_with(
"target-initial",
host="127.0.0.1:9222",
)
activate_tab.assert_called_once_with("target-new", host="127.0.0.1:9222")
self.assert_removed(temp_dir)
def test_new_chrome_waits_for_delayed_initial_login_target(self):
account = {
"alias": "alias",
"region_host": "seller.shopee.tw",
"debug_port": 9222,
}
blank_tab = {
"type": "page",
"id": "target-blank",
"url": "about:blank",
"webSocketDebuggerUrl": "ws-blank",
}
portal_tab = {
"type": "page",
"id": "target-portal",
"url": "https://seller.shopee.tw/portal/",
"webSocketDebuggerUrl": "ws-portal",
}
probe_count = 0
def page_targets(*_args, **_kwargs):
nonlocal probe_count
probe_count += 1
return [blank_tab] if probe_count == 1 else [portal_tab]
with mock.patch("app.accounts.cdp.http_get", side_effect=page_targets), \
mock.patch("app.accounts.cdp.create_tab_info") as create_tab_info, \
mock.patch("app.accounts.cdp.activate_tab") as activate_tab:
result = accounts._open_or_activate_login_tab(
account,
newly_launched=True,
startup_wait_timeout=0.3,
)
self.assertGreaterEqual(probe_count, 2)
self.assertEqual("target-portal", result["target_id"])
self.assertTrue(result["startup_target_reused"])
self.assertFalse(result["created_tab"])
create_tab_info.assert_not_called()
activate_tab.assert_called_once_with(
"target-portal",
host="127.0.0.1:9222",
)
def test_new_chrome_navigates_its_only_blank_page(self):
account = {
"alias": "alias",
"region_host": "seller.shopee.tw",
"debug_port": 9222,
}
blank_tab = {
"type": "page",
"id": "target-blank",
"url": "about:blank",
"webSocketDebuggerUrl": "ws-blank",
}
client = mock.Mock()
client.send.return_value = {}
with mock.patch("app.accounts.cdp.http_get", return_value=[blank_tab]), \
mock.patch("app.accounts.cdp.CDP", return_value=client) as cdp_client, \
mock.patch("app.accounts.cdp.create_tab_info") as create_tab_info, \
mock.patch("app.accounts.cdp.activate_tab") as activate_tab:
result = accounts._open_or_activate_login_tab(
account,
newly_launched=True,
startup_wait_timeout=0,
)
cdp_client.assert_called_once_with("ws-blank")
client.send.assert_called_once_with(
"Page.navigate",
{"url": "https://seller.shopee.tw/portal/"},
)
client.close.assert_called_once_with()
self.assertFalse(result["created_tab"])
self.assertTrue(result["startup_target_reused"])
self.assertTrue(result["startup_page_navigated"])
create_tab_info.assert_not_called()
activate_tab.assert_called_once_with(
"target-blank",
host="127.0.0.1:9222",
)
def test_new_chrome_treats_intro_as_reusable_startup_page(self):
intro_tab = {
"type": "page",
"id": "target-intro",
"url": "chrome://intro/",
"webSocketDebuggerUrl": "ws-intro",
}
self.assertEqual(intro_tab, accounts._safe_startup_page([intro_tab]))
def test_new_chrome_without_page_creates_one_fallback_target(self):
account = {
"alias": "alias",
"region_host": "seller.shopee.tw",
"debug_port": 9222,
}
created_tab = {
"type": "page",
"id": "target-fallback",
"url": "https://seller.shopee.tw/portal/",
"webSocketDebuggerUrl": "ws-fallback",
}
with mock.patch("app.accounts.cdp.http_get", return_value=[]), \
mock.patch(
"app.accounts.cdp.create_tab_info",
return_value=created_tab,
) as create_tab_info, \
mock.patch("app.accounts.cdp.activate_tab") as activate_tab:
result = accounts._open_or_activate_login_tab(
account,
newly_launched=True,
startup_wait_timeout=0,
)
self.assertTrue(result["created_tab"])
self.assertEqual("startup_page_missing", result["fallback_reason"])
create_tab_info.assert_called_once_with(
"https://seller.shopee.tw/portal/",
host="127.0.0.1:9222",
)
activate_tab.assert_called_once_with(
"target-fallback",
host="127.0.0.1:9222",
)
def test_running_chrome_preserves_normal_page_and_opens_login_tab(self):
account = {
"alias": "alias",
"region_host": "seller.shopee.tw",
"debug_port": 9222,
}
normal_tab = {
"type": "page",
"id": "target-user",
"url": "https://example.com/",
"webSocketDebuggerUrl": "ws-user",
}
created_tab = {
"type": "page",
"id": "target-login",
"url": "https://seller.shopee.tw/portal/",
"webSocketDebuggerUrl": "ws-login",
}
with mock.patch("app.accounts.cdp.http_get", return_value=[normal_tab]), \
mock.patch("app.accounts.cdp.CDP") as cdp_client, \
mock.patch(
"app.accounts.cdp.create_tab_info",
return_value=created_tab,
) as create_tab_info, \
mock.patch("app.accounts.cdp.activate_tab"):
result = accounts._open_or_activate_login_tab(
account,
newly_launched=False,
)
self.assertTrue(result["created_tab"])
self.assertEqual("existing_chrome_no_login_tab", result["fallback_reason"])
create_tab_info.assert_called_once()
cdp_client.assert_not_called()
def test_launch_for_login_reuses_running_chrome_without_starting_process(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)