fix(accounts): keep first login launch in one window
This commit is contained in:
+13
-2
@@ -3,7 +3,7 @@ id: T-633
|
||||
title: ④新账号首次启动登录只打开一个 Chrome 窗口
|
||||
phase: 1
|
||||
deps: [T-105b]
|
||||
status: TODO
|
||||
status: DONE
|
||||
created: 2026-07-14
|
||||
---
|
||||
|
||||
@@ -20,6 +20,7 @@ created: 2026-07-14
|
||||
- `chrome.wait_debug_ready()` 等待 CDP;
|
||||
- `_open_or_activate_login_tab()` 再查找蝦皮页面,未找到时调用 `cdp.create_tab_info(portal_url)`。
|
||||
3. `chrome.build_launch_args()` 当前只传 Chrome 路径、调试端口、`remote-allow-origins` 和账号 `user-data-dir`,没有携带 `https://<region_host>/portal/`。因此新 Chrome 会先按自身启动策略创建空白/新标签页;CDP 就绪后代码又执行一次 `Target.createTarget` 打开卖家中心。部分 Chrome 版本或窗口状态下,这会表现为一个初始窗口加一个卖家中心窗口,而不是同一窗口内唯一页面。
|
||||
- Windows 全新临时 profile 实测进一步确认:Chrome 会先创建独立的 `chrome://intro/` 首次运行窗口并忽略命令行 URL;旧判断不把该页视为安全启动页,随后兜底 `Target.createTarget`,最终稳定复现 2 个 page target 和 2 个 `Chrome_WidgetWin_1` 顶层窗口。
|
||||
4. 现有 `tests/test_accounts.py` 的冷启动测试明确断言 `launch_chrome()` 后还会调用一次 `create_tab_info()`,说明当前自动回归把“双阶段建页”当成了正常行为,未覆盖“首次启动只产生一个可见窗口/页面”的产品要求。
|
||||
5. 本地 `chrome_launch` 运行日志中,最近两次启动记录相隔约 25 秒,各自只有一次 `start -> launched`,并记录不同 PID。该证据不支持“单次 GUI 回调调用两次 `Popen`”,但说明还需要防止用户连续点击或首轮 CDP 消失后再次启动。任务必须同时区分:
|
||||
- 一次启动进程内额外创建页面/窗口;
|
||||
@@ -32,6 +33,7 @@ T-105b 已解决“同账号 Chrome 的 CDP 端口仍在运行时,重复点击
|
||||
### 1. 冷启动直接携带卖家中心 URL
|
||||
|
||||
- 给 `chrome.build_launch_args()` / `chrome.launch_chrome()` 增加可选 `initial_url` 参数;不传时保持现有调用兼容,传入时把规范化 URL 作为唯一启动页面追加到 Chrome 参数末尾。
|
||||
- 传入 `initial_url` 的冷启动登录路径同时追加 `--no-first-run` 和 `--no-default-browser-check`,避免全新 profile 的 `chrome://intro/`/默认浏览器提示抢占独立窗口;不传 `initial_url` 的快捷方式和其他入口不追加这些参数。
|
||||
- `accounts.launch_for_login()` 在确认账号端口未运行后,计算 `https://<region_host>/portal/`,调用:
|
||||
|
||||
```python
|
||||
@@ -47,7 +49,7 @@ chrome.launch_chrome(account, config=config, initial_url=portal_url)
|
||||
- `wait_debug_ready()` 成功后,不立即把“当前没有已完成导航的蝦皮 URL”解释为必须新建 target。
|
||||
- 对本轮刚启动的 Chrome,在一个短且有上限的预算内重新枚举 `/json`,等待命令行携带的初始卖家中心页面出现;建议总预算不超过 2~3 秒、短间隔轮询,不使用无条件固定长 `sleep`。
|
||||
- 如果已经出现卖家中心或 `accounts.shopee.<区域>/seller/login` 页面,直接激活该 target,返回 `created_tab=false` / `startup_target_reused=true`,不得再调用 `Target.createTarget`。
|
||||
- 如果初始 URL 尚未完成,但本轮新 Chrome 已有唯一的普通 page target(如 `about:blank` / `chrome://newtab`),优先通过该 target 导航到卖家中心并激活,避免另建窗口。该行为只适用于“本轮刚启动”的冷启动路径。
|
||||
- 如果初始 URL 尚未完成,但本轮新 Chrome 已有唯一的普通启动 page target(如 `about:blank` / `chrome://newtab` / `chrome://intro/`),优先通过该 target 导航到卖家中心并激活,避免另建窗口。该行为只适用于“本轮刚启动”的冷启动路径;端口启动前已经运行的 Chrome 不得把 `chrome://intro/` 当作可覆盖页面。
|
||||
- 只有在有界等待结束后仍没有任何可复用的 page target 时,才允许兜底创建一个卖家中心 target;返回值和运行日志必须标记 `created_tab=true` 与兜底原因。
|
||||
- 对“端口启动前已经运行”的 Chrome 继续沿用 T-105b:优先激活现有卖家中心/登录页;若没有,新增一个卖家中心 tab。不得为了单窗口目标导航、覆盖或关闭用户已有的普通页面。
|
||||
|
||||
@@ -129,3 +131,12 @@ chrome.launch_chrome(account, config=config, initial_url=portal_url)
|
||||
- 不修改 Shopee 商品详情页 CDP 选择器、采集、标题/封面更新、AI/cmhub、Excel 或自动升级流程。
|
||||
- 不自动登录、不填写或提交密码、不读取 Cookie 值、不绕过验证码、风控或权限校验。
|
||||
- 实现时同步更新 `docs/04-architecture.md`、`docs/api.md` 和必要的 `docs/routes.md`;不修改冻结的 `docs/06-tasks.md`。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-14 完成。`chrome.build_launch_args()` / `launch_chrome()` 已支持经过校验的蝦皮 `initial_url`;冷启动登录同时使用 `--no-first-run`、`--no-default-browser-check`,卖家中心 URL 保持为唯一末尾 URL。未传 `initial_url` 的快捷方式和既有启动调用参数不变。
|
||||
- `accounts.launch_for_login()` 已区分冷启动与已运行 Chrome:冷启动在 2 秒有界预算内复用初始卖家中心/登录 target,唯一 `about:blank`、新标签页或 `chrome://intro/` 可导航复用,完全无安全 target 时才创建一次并返回兜底原因;已运行 Chrome 不改写或关闭用户普通页面。
|
||||
- ④账号管理已增加启动中状态和连续点击保护;启动期间禁用账号列表及增删改/登录操作,底层调用成功或失败后恢复控件。同账号启动中或系统队列紧接着投递的重复点击不会再次调用 `launch_for_login()`,并写 `result=ignored reason=launch_in_progress`。启动日志新增 `created_tab/startup_target_reused/startup_page_navigated/page_target_count/fallback_reason`,且继续统一脱敏。
|
||||
- 已同步 `docs/04-architecture.md`、`docs/api.md`、`docs/routes.md`;测试覆盖启动 URL/首次运行参数校验、初始 target 立即或延迟出现、空白/intro 复用、无 target 单次兜底、运行中普通页保护、新增账号不自动启动、GUI 重入及成功/失败控件恢复。
|
||||
- Windows 全新临时 profile 初次探测复现了 `chrome://intro/` 导致 2 个 page target/2 个顶层窗口,补齐首次运行参数和 intro 复用后复测通过:首次启动为 `launched`、`created_tab=false`、1 个 page target、1 个 `Chrome_WidgetWin_1`;再次调用为 `reused` 且 target 不变;关闭后使用同一 profile 再次冷启动仍为 1 个页面、1 个窗口。验证未读取或填写凭据,临时 Chrome 已通过 CDP 关闭并清理。
|
||||
- 最终干净验证工作树中 `py -3.10 -m unittest discover -s tests` 共 495 项全部通过;`python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check` 全部通过。工作区中用户未提交的提示词、版本号、历史任务归档和 HTML 样本未纳入验证快照或提交。
|
||||
|
||||
Reference in New Issue
Block a user