Files
UHD_Media_Tool/docs/plan/09-visual-qa.md
T
2026-09-28 15:24:49 +08:00

147 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# v0.2 浏览器视觉与交互检查
2026-09-28。Playwright(chromium headless)逐页截图 + 走业务链。截图在 `apps/web/test/screenshots/qa-v02/`(不进 git),共 310 张。
## 环境
- 独立 QA 栈:`docker compose -p umtqa`,127.0.0.1:4381,独立 `.env`(随机密钥)与 override;`/media`、`/downloads` 挂 `/opt/umt-qa/*`(属主 10001),
放 18 个假样片(电影 / 剧集 / 整季包目录 / 综艺 / 字幕随行 / 无关文件),视频用 `truncate` 做成 400 MB 稀疏文件(主视频下限 50 MB)。
用户的 `umt` 栈(4380)全程未动。
- mock:testkit 的 qB / NexusPHP(观众,自定 5 条 + 默认 fixture)/ RSS / TMDB / Emby,跑在同一 compose 网络里的 `denoland/deno` 容器(`umtqa-mocks`)。
宿主 ufw 的 INPUT 策略是 drop,容器经 `host.docker.internal` / docker0 访问宿主端口不通,所以没按原计划把 mock 放宿主。
- 镜像:先用 `uhd-media-tool:v0.2.0-rc` 检查;修复后以 `83498f9 + 本轮改动` 构建 `uhd-media-tool:qa` 替换 app 复测(见"CI 与并行开发")。
- 视口:桌面 1440×900 明(d)/ 暗(dd),手机 390×844(m)。每页记录 console.error/warn、pageerror、失败请求、横向溢出(`scrollWidth` + 越界元素扫描)。
## 走过的流程
| 流程 | 结果 |
| --- | --- |
| 首次初始化(空提交 / 口令过短 / 两次密码不一致 / 口令错误)→ 登录 → 改密 → 登出 → 再登录 | 通过;**改密时旧密码错误被踢回登录页**(#1,已修) |
| 错误密码限速(另一 `X-Real-IP` 连续 6 次) | 第 5 次起 429「失败次数过多,15 分钟后再试」 |
| 设置 9 分区:自动化改检查间隔、库根 `/media`(哨兵)、路径映射 `/downloads`(校验)、qB 测试、Emby 测试、观众登记 + 改地址 + Cookie、TMDB key + Base URL、API Key 创建 / 撤销 | 全部成功 |
| Agent 上游:fake 设默认 + 测试 + 最小补全;自定义兼容端点指向不存在地址;fake 订阅登录 browser(粘回 URL)与 device(自动批准)、退出登录 | 成功;错误提示问题见 #13、U2 |
| 定时任务:立即执行、停用 / 启用、运行记录 | 成功 |
| Feed 新建 → 立即抓取 → 识别(5 条:4 条识别、1 条待识别)→ 站点工作台库存叠加 → 快照 | 成功;抓取后列表不自动刷新(U3) |
| 收录策略草案(1080p 模板 + 新作品收录)→ 发布 → 订阅沙丘2 → 下载计划 / qB 任务 → mock 完成 → 自动整理 | 首次因样片 1 MB 被 `too_small` 拦下(测试数据问题);改 400 MB 后手动整理成功入库 |
| 待处理:待识别事项「手动指定 TMDB ID」(842675) | 资源变为已识别 |
| 文件管理:浏览、重命名、新建目录、移动(预览 → 执行)、移入回收站、还原、批量整理向导(3 组 5 文件) | 成功 |
| Agent 会话:execute、plan_only、spawn 子会话 + await;抽屉 Ctrl+J 开关、Esc 关闭、焦点落输入框、FAB 状态 | 成功(自定义 fake 脚本后未匹配目标失败,见 U11) |
| 引擎面板 runs / 详情;业务任务失败项重试 | 成功;引擎里没有失败 run,重跑按钮只看了详情页 |
| 审计列表 | 成功;动作名缺中文(#11,已修) |
| SSE 断线:页面打开时 `docker restart umtqa-app-1` | EventSource 3 次内重连,页面无报错;期间 `/dashboard` 一次 CONNECTION_RESET 属预期 |
## 检查矩阵
38 个路由 × 3 视口 = 114 张(文件名 `M-<路由>-<d|dd|m>.png`),修复后复测截图 `V*`。无横向溢出、无 pageerror、无非预期 4xx/5xx。
"问题"列指下方清单编号,✓ 为该视口未发现问题。
| 页面 | d | dd | m | 问题 |
| --- | --- | --- | --- | --- |
| 登录 / 初始化 | ✓ | ✓ | ✓ | — |
| 首页 | 问题 | 问题 | ✓ | #6 #17 |
| 待处理 | 问题 | 问题 | 问题 | #5 #12 U15 U16 |
| 站点工作台 / 详情(整理视图、快照与 Feed、账号) | 问题 | ✓ | 问题 | #3 #15 U8 |
| 来源健康 | 问题 | 问题 | 问题 | #3 U3 |
| 订阅 / 新建订阅 | 问题 | ✓ | ✓ | #5 |
| 收录策略(草案 / 发布) | 问题 | 问题 | 问题 | #4 #5 U4 |
| 偏好标签 | ✓ | ✓ | ✓ | — |
| 下载队列 / 详情 | 问题 | 问题 | 问题 | #2 #6 #9 #14 U7 |
| 下载计划 | 问题 | 问题 | 问题 | #10 |
| 业务任务 / 详情 | 问题 | 问题 | 问题 | #5 |
| 媒体库 / 详情 | 问题 | 问题 | 问题 | #8 U1 U9 |
| 整理记录 / 详情 | 问题 | 问题 | 问题 | #5 #7 |
| 文件管理 / 回收站 / 向导 | 问题 | ✓ | 问题 | #5 U6 U12 U13 |
| 身份与元数据 | ✓ | ✓ | ✓ | — |
| Agent 会话 / 详情 / 抽屉 | ✓ | ✓ | ✓ | U10 |
| 定时任务 | ✓ | ✓ | ✓ | 文案清单 |
| 设置·自动化 / 站点与账号 / 下载器 / 媒体库与目录 / 媒体服务器 / 元数据 | ✓ | ✓ | 问题 | U5 U6 |
| 设置·Agent | 问题 | 问题 | 问题 | #13 U2 U6 |
| 设置·API Key | ✓ | ✓ | ✓ | 文案清单 |
| 设置·账户与安全 | 问题 | ✓ | ✓ | #1 U14 |
| 引擎面板 / 详情 | ✓ | ✓ | ✓ | — |
| 审计日志 | 问题 | 问题 | 问题 | #11 |
| 404 | ✓ | ✓ | ✓ | — |
## 问题清单
共 34 项:已修 17、未修 17(另有文案清单 13 条,其中 3 条已随 #9/#5/#13 修掉)。
### 已修
| # | 严重度 | 页面 | 截图 | 现象 | 提交 |
| --- | --- | --- | --- | --- | --- |
| 1 | 高 | 设置·账户与安全 | `02-pwd-wrong-current-d.png` → `V01-pwd-wrong-current-d.png` | 改密时旧密码填错,服务端回 401,全局 401 处理当成会话失效直接跳登录页;开启二次验证填错验证码同样 | `0c0907a` |
| 2 | 中 | 下载详情·手动整理 | `45-dl-organize-preview-d.png`、`45-dl-organize-exec-d.png` | 预览显示「无法生成计划:source_size_mismatch」时「执行」仍可点,执行后生成一条「未关联作品 0/0」的失败整理记录 | `d7eb6a4` |
| 3 | 中 | 来源健康 / 站点详情(手机) | `M-sources-m.png` → `V12-sources-m.png` | Feed 表名称列 320px,健康、启停、立即抓取被挤出屏幕,只能横滑发现 | `d7eb6a4` |
| 4 | 中 | 收录策略·新建草案 | `40-policy-new-d.png`、`40-rules-err.png` | 策略键只有占位符 `default`,看起来像已填;保存只弹「表单有错误」 | `46d37d8`(预填 default) |
| 5 | 中 | 策略版本、订阅、待处理、业务任务、整理记录、回收站 | `40-policy-published-d.png`、`87-task-retried-d.png`、`64-trash-d.png` | 操作者显示 `admin_session:<uuid>`、`user:<uuid>`、`system` | `46d37d8` |
| 6 | 中 | 下载队列、首页缓存水位 | `42-downloads-d.png` → `V04-downloads-volume-d.png` | 没填缓存卷标识时显示 `instance:<uuid>` | `46d37d8`(显示下载器名) |
| 7 | 中 | 整理记录详情 | `43-organize_4bedfb53-…-d.png` → `V03-organize-reason-d.png` | 失败原因 `blocked:no_main_video(blocked)` | `46d37d8`(取冲突说明「没有可入库的主视频」) |
| 8 | 中 | 媒体库详情·版本目标 | `47-library_…-d.png` | 原因显示 `blocked:no_main_video`、`deferred:slot_busy;inflight:<uuid>` | `46d37d8` |
| 9 | 低 | 下载详情 | `44-downloads_…-d.png` | 时间线「提交下载:succeeded」「复制:failed」,用途 `upgrade`,说明 `added` | `46d37d8` |
| 10 | 低 | 下载计划 | `M-downloads_plans-m.png` → `V07-plans-d.png` | 「优先级 new_work / upgrade」,说明 `organize:succeeded` | `46d37d8` |
| 11 | 低 | 审计日志 | `M-audit-m.png` → `V08-audit-d.png` | `capability.invoke`、`files.*`、`site.*`、`feed_source.created` 等无中文 | `46d37d8` |
| 12 | 低 | 待处理·待识别 | `42-inbox-d.png` | 摘要「没有匹配的作品(no_viable_candidate)」 | `46d37d8`(新开事项生效) |
| 13 | 低 | 设置·Agent 上游测试 | `72-custom-completion-fail-d.png` | 端点不存在时显示「失败 · Connection error.」,没归到「网络错误」也没说怎么办;凭证来源 `stored credential` | `46d37d8` |
| 14 | 低 | 手动整理预览 | `46-dl-organize-preview-ok-d.png` | 徽章 `copy` / `transfer`、文件类型 `video` | `d7eb6a4` |
| 15 | 低 | 站点详情·库存叠加 | `M-sites_…-m.png` | 候选标签 `1080p:deferred` | `46d37d8` |
| 16 | 低 | 全站弹窗 / 抽屉 | — | 关闭按钮读屏文本 `Close`、面包屑 `More` | `46d37d8` |
| 17 | 低 | 首页·最近产出 | `92-home-after-restart-3s-d.png` | 无作品的记录显示「未命名」,与整理记录页「未关联作品」不一致 | `46d37d8` |
### 未修
| # | 严重度 | 页面 | 截图 | 现象 | 原因 |
| --- | --- | --- | --- | --- | --- |
| U1 | 中 | 媒体库详情 | `47-library_f020597a-…-d.png`、`V09-library-slot-d.png` | 自动整理被拦(版本目标进 attention)后,从下载详情手动整理成功入库、资产已核验,版本目标仍「需处理」、当前资产「无」 | 设计取舍:`transitionWithInflight` 对静止态 attention 拒绝 `verify_passed`("可能已被人工处理")。要么放行 attention→verify_passed,要么手动整理成功时自动解决对应「整理冲突」事项,需要定 |
| U2 | 中 | 设置·Agent 上游 | `V11-pi-test-network-hint-d.png` | Base URL 不存在,「测试」仍「通过」并把状态改成「可用」;只有「最小补全」会连端点 | 测试语义设计(只查凭证和模型,不产生费用);建议测试结果不改写可用状态,或给自定义端点做一次 `/models` 探测 |
| U3 | 中 | 来源健康 / 站点详情 | `90-sse-after-event-d.png` | 点「立即抓取」后,抓取任务完成不发 SSE 事件,列表只在请求返回那一刻刷新一次;worker 慢时一直显示旧的「最后成功」 | 需要新事件(如 `source.feed_fetched`)+ 前端失效,超出本轮 |
| U4 | 低 | 收录策略草案 | `40-policy-saved-d.png` | 保存失败只弹「表单有错误」,不指明字段、不滚动到错误处(长表单里看不到) | 需要表单级错误定位,改动面大 |
| U5 | 低 | 设置各分区表单 | `10-empty-settings_agent-d.png` | 带说明文字的字段,说明与下一个字段标签只隔 4px,节奏不齐 | `FormField` 间距属设计取舍 |
| U6 | 低 | 全站(手机更明显) | `M-settings_agent-m.png`、`60-files-d.png` | 右下 Agent FAB 盖住右对齐开关、文件管理页脚「剩余空间」 | FAB 定位设计取舍 |
| U7 | 低 | 下载计划 / 详情 | `44-downloads_…-d.png` | 新作品首次下载的计划用途是「升级」、时间线写「创建下载计划(升级)」 | 业务逻辑待查 |
| U8 | 低 | 站点详情 | `32-site-detail-d.png` | 所有资源都是「H&R 未知」,fixture 里标了 H&R 的也一样 | 适配器 / mock 选择器待查 |
| U9 | 低 | 媒体库详情·元数据 | `47-library_…-d.png` | TMDB 已识别,元数据各字段仍「未提供」;别名重复(沙丘2 ×2、Dune: Part Two ×3) | 数据层待查 |
| U10 | 低 | Agent | `83-agent-run-execute-d.png` | 配了自定义 fake 脚本后,不匹配的目标直接失败「assistant_error: no fake script matched」,内置演示脚本不再兜底 | fake 仅用于演示,行为与 runbook 一致 |
| U11 | 低 | 全站说明文字 | 多处 | 中文句子里混用半角 `,;:` 与全角 `。`(如「停用后不再访问该站点,也不产生新候选;…」「账号:未验证」) | 全站文案规范问题,留给文案轮 |
| U12 | 低 | 文件管理 | `61-files-incoming-d.png` | 单击目录只选中,双击才进入;手机上不便 | 交互设计取舍 |
| U13 | 低 | 文件管理·移动到… | `63-move-preview-d.png` | 目标树点到源所在目录即自动预览,返回 400 并在控制台报错 | 预期校验,但应在前端先拦 |
| U14 | 低 | 账户弹层 | `02-account-menu-d.png` | 浮层透明度高,底下的「实时」「暂停自动化」透出 | 材质设计取舍 |
| U15 | 低 | 待处理(手机) | `M-inbox-m.png` | 指标卡说明「待处理 + 调查中 + 等你决定」被截断 | 文案可缩短 |
| U16 | 低 | 身份指定弹窗 | `50-inbox-assign-dialog-d.png` | 类型用原生 `<select>`,输入框只有占位符没有标签 | 组件统一待做 |
| U17 | 低 | 健康检查 | — | `v0.2.0-rc` 镜像 `/health` 报 `version: 0.1.0` | 当前 main 已有 `chore(release): v0.2.0`,下次构建复核 |
## 文案问题清单
| 位置 | 现状 | 建议 |
| --- | --- | --- |
| 下载详情·计划 | 用途 `upgrade`、说明 `added` | 已修:升级 / 已添加到下载器 |
| 业务任务·触发 | `user:<uuid>` | 已修:管理员 |
| 上游测试 | `Connection error.` | 已修:「连不上上游,检查 Base URL、端口和网络。原始错误:…」 |
| 元数据保存 toast | 「TMDB已保存」 | 「TMDB 已保存」(中英文之间空格) |
| 设置·API Key | 分区标题「API Key / 签发给外部程序的 Key」下小节又是「API Key / 签发给外部程序(…)的 Key」 | 删掉一处 |
| 定时任务 | 「每 168 小时」 | 「每 7 天」 |
| 定时任务·备份 | 「目前由 scripts/backup.sh 在宿主机执行」 | 与 runbook 的 `umt backup` 对齐 |
| 初始化页 | 字段叫「初始化口令」,服务端报错「setup token 无效」 | 统一一个词 |
| 待处理指标 | 「最高 提示」 | 「最高级别:提示」 |
| 版本目标 | 「延后(单元在途)」 | 「延后:已有计划在途」 |
| 整理记录详情 | 「整理后 · 库根相对 / 未知或未授权」 | 失败记录直接写「未生成目标路径」 |
| Agent 上游列表 | 模型列「provider 默认」 | 「默认模型」 |
| 全站 | 半角 `,;:` 混在中文句子里 | 见 U11 |
## CI 与并行开发
- 检查期间 main 上有另一路开发在提交(W9 站点中心、命名模板等),工作区还有大量未提交改动。当前 main 的 `deno task ci` 在本轮之前就是红的:
`instances-routes.ts` 的 `SiteCredentialsPut` 类型错误、`release-fields.ts` 缺 `challenge`、`api-registry` 端点未实现等,都不在本轮改动里。
- 本轮只提交自己的改动,用临时 index 按块提交(`organize.ts` 里只含本轮 7 行,对方未提交的命名改动未带入),提交后把真实 index 对应路径同步到新 HEAD。
- 验证:在 `83498f9`(本轮开始时的 HEAD)+ 本轮改动的独立 worktree 跑 `deno task ci`:typecheck、lint、check:tokens、build 全过;
测试 server 275 通过,2 个文件因与并行开发共用开发库(55433)的 schema 被对方删掉而失败,单独重跑通过;tasks 的崩溃恢复用例同理重跑通过。
用这份代码构建的 `uhd-media-tool:qa` 在 QA 栈复测了 #1–#17。
## 值得一看的 5 张截图
1. `apps/web/test/screenshots/qa-v02/47-library_f020597a-d1f5-4ca0-8d16-81b974ad1960-d.png`:手动整理成功后版本目标仍「需处理」(U1)
2. `apps/web/test/screenshots/qa-v02/83-agent-run-spawn-d.png`:fake 模型派生子会话 + await,会话树合计与系统核实
3. `apps/web/test/screenshots/qa-v02/66-organize-wizard-1-d.png`:批量整理向导识别步骤(整季包 + 电影 + 待选作品)
4. `apps/web/test/screenshots/qa-v02/45-dl-organize-exec-d.png`:预览失败仍能执行产生的失败记录(#2,已修)
5. `apps/web/test/screenshots/qa-v02/V11-pi-test-network-hint-d.png`:不存在的端点「测试」通过、状态变「可用」(U2)