fix(monitor): 已登录时点「同步登录态为 Cookie」要干等 30 秒
顺序反了:原先先开页面、读二维码,读完才发现「已经登录、没有二维码」。而读二维码内部 会 wait_for_selector 等满 30 秒才放弃 —— 用户点一下按钮要干等半分钟,还白开一个标签页。 实测日志里就是 `Page.wait_for_selector: Timeout 30000ms exceeded`。 改成先问登录状态(那是一次接口调用,很快),已登录就直接返回,根本不碰页面。 新增测试守住这个顺序:已登录时 context.new_page 不得被调用。
This commit is contained in:
+18
-12
@@ -331,6 +331,23 @@ async def start(platform: str = PLATFORM_XHS) -> Dict[str, Any]:
|
||||
async with _lock:
|
||||
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)
|
||||
try:
|
||||
await page.goto(
|
||||
@@ -342,18 +359,7 @@ async def start(platform: str = PLATFORM_XHS) -> Dict[str, Any]:
|
||||
|
||||
session = QrLoginSession(platform, page)
|
||||
session.image = 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:
|
||||
if not image:
|
||||
session.status = STATUS_ERROR
|
||||
session.message = "页面上没找到二维码,请确认站点结构没有变化"
|
||||
|
||||
|
||||
@@ -140,6 +140,21 @@ async def test_an_already_signed_in_profile_needs_no_scan(monkeypatch):
|
||||
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
|
||||
async def test_no_qr_and_not_signed_in_is_an_error(monkeypatch):
|
||||
manager, *_rest = _fake_stack()
|
||||
|
||||
Reference in New Issue
Block a user