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:
|
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 = "页面上没找到二维码,请确认站点结构没有变化"
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user