fix(monitor): 已登录时点「同步登录态为 Cookie」要干等 30 秒
Deploy VitePress site to Pages / build (push) Waiting to run
Deploy VitePress site to Pages / Deploy (push) Blocked by required conditions

顺序反了:原先先开页面、读二维码,读完才发现「已经登录、没有二维码」。而读二维码内部
会 wait_for_selector 等满 30 秒才放弃 —— 用户点一下按钮要干等半分钟,还白开一个标签页。
实测日志里就是 `Page.wait_for_selector: Timeout 30000ms exceeded`。

改成先问登录状态(那是一次接口调用,很快),已登录就直接返回,根本不碰页面。
新增测试守住这个顺序:已登录时 context.new_page 不得被调用。
This commit is contained in:
2026-10-09 13:49:11 +08:00
parent de9ff58371
commit 44cbe8e2aa
2 changed files with 33 additions and 12 deletions
+18 -12
View File
@@ -331,6 +331,23 @@ async def start(platform: str = PLATFORM_XHS) -> Dict[str, Any]:
async with _lock: async with _lock:
await _discard_current_locked() await _discard_current_locked()
# **先问状态,再决定要不要开页面。** 顺序反过来是有代价的:读二维码内部会
# wait_for_selector 等满 30 秒才放弃,而已经登录时页面上根本没有二维码 ——
# 用户点一下按钮要干等半分钟,还白开一个标签页。
state = await check_login_state(force=True)
if state.get("logged_in"):
# 已经是登录状态时站点不显示二维码 —— 这本身就是成功,不是失败。
# 顺带把 cookie 取出来,让调用方可以存进库。
session = QrLoginSession(platform, None)
session.cookie = await _current_cookie()
session.status = STATUS_SUCCESS
session.logged_in = True
session.nickname = state.get("nickname")
who = f"({session.nickname})" if session.nickname else ""
session.message = f"浏览器已经是登录状态{who},无需扫码"
_current = session
return session.snapshot()
page = await _ensure_page(platform) page = await _ensure_page(platform)
try: try:
await page.goto( await page.goto(
@@ -342,18 +359,7 @@ async def start(platform: str = PLATFORM_XHS) -> Dict[str, Any]:
session = QrLoginSession(platform, page) session = QrLoginSession(platform, page)
session.image = image session.image = image
if not image:
state = await check_login_state()
if state.get("logged_in"):
# 已经是登录状态时站点不显示二维码——这本身就是成功,不是失败。
# 顺带把 cookie 取出来,让调用方可以存进库。
session.cookie = await _current_cookie()
session.status = STATUS_SUCCESS
session.logged_in = True
session.nickname = state.get("nickname")
who = f"({session.nickname})" if session.nickname else ""
session.message = f"浏览器已经是登录状态{who},无需扫码"
elif not image:
session.status = STATUS_ERROR session.status = STATUS_ERROR
session.message = "页面上没找到二维码,请确认站点结构没有变化" session.message = "页面上没找到二维码,请确认站点结构没有变化"
+15
View File
@@ -140,6 +140,21 @@ async def test_an_already_signed_in_profile_needs_no_scan(monkeypatch):
assert snapshot["nickname"] == "老王" assert snapshot["nickname"] == "老王"
@pytest.mark.asyncio
async def test_an_already_signed_in_profile_never_opens_a_page(monkeypatch):
"""已登录时**根本不该去开页面**。
读二维码内部会 wait_for_selector 等满 30 秒才放弃,而已经登录时页面上没有二维码 ——
顺序反了的话,用户点一下按钮要干等半分钟,还白开一个标签页。
"""
manager, _pw, _browser, context, _page, _qr = _fake_stack()
_patch(monkeypatch, manager, resolver=lambda _c: {"user_id": "u1", "nickname": "小明"})
await qrlogin.start(qrlogin.PLATFORM_XHS)
context.new_page.assert_not_called()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_no_qr_and_not_signed_in_is_an_error(monkeypatch): async def test_no_qr_and_not_signed_in_is_an_error(monkeypatch):
manager, *_rest = _fake_stack() manager, *_rest = _fake_stack()