Files
MailUI4Agents/web/test/manual/README.md
JianFeeeee 342282b92c fix: 窄屏实测修复 —— 删抽屉、44px 命中区、触摸设备可见的次要动作
用 playwright 连本机共享 Chromium,在 390px(iPhone 14 Pro)与 320px
(iPhone SE)量真实盒子。之前的窄屏适配是「照着规则写对」,实测发现
一个功能性 bug 加五处可用性问题。

## 抽屉式侧栏遮挡底部导航(真 bug)

抽屉是 `fixed left-0 top-0 bottom-0 z-50`,铺满整个视口高度;底部导航没有
z-index。抽屉打开时点最左那一项「收件」,elementFromPoint 命中的是抽屉里的
SVG,不是导航按钮 —— 按钮在那里、尺寸也够、CSS 规则也没写错,只有命中测试
才能发现。

**删掉抽屉而不是给导航加 z-index**:抽屉装的六项(收件/发件/联系/用户/新建/
管理)与底部导航完全重复,唯一独有的是退出登录。为一个按钮维护一套 fixed
层级加遮罩不划算,而它还附带「Esc 关不掉」「底层未锁滚」两个毛病。

退出登录移到「我的」页 —— 它与密码、密钥同属「账号自身」,而那页此前根本
没有退出入口。`NavToggle` 与 uiStore 的 navOpen/toggleNav/closeNav 一并删除。

## 触摸命中区:新增 .tap

详情页那排工具按钮视觉高度只有 15-16px(实测「标记已读」48x16、「对话树」
54x16、「转发」42x16、「抄送」20x15),移动端下限是 44x44。

直接加 padding 会把本来就挤的头部撑散、320px 下换行,因此用居中的透明伪元素
扩大命中区:**视觉一像素不动**。只在 max-width:767px 生效 —— 桌面用鼠标精度
足够,而扩大后的命中区在密排工具栏里会互相重叠,点一个可能命中隔壁那个。

覆盖 MailView / ContactPanel / WorkCard / ModelScopePanel / AdminUsersPage /
ComposePage / ThreadView / KeyPanel / QuotaPanel / Attachments / BackButton。

## 看不见却按得动的按钮:新增 .reveal

`opacity-0 group-hover:opacity-100` 在没有 hover 的设备上永远是 opacity:0,
**但仍然接收点击** —— 实测联系人列表里 elementFromPoint 命中的就是那个看不见的
「归档」。一个看不见却按得动的破坏性按钮比没有按钮更糟:人以为点的是卡片,
实际归档了一条会话。

改为默认可见,只在 `(hover: hover) and (pointer: fine)` 时隐藏。
单看 hover 会把带触摸板的平板算进去。

## 对话树

- 缩进随屏宽自适应:固定「每级 20px、上限 8 级」= 最多 160px,320px 屏还要
  去掉 px-4 的 32px 与连接线 18px,卡片只剩 110px,发件人一行直接被 truncate
  吃掉。窄屏改为每级 10px、上限 5 级
- 补返回出口:原先只有「关闭」。两者语义不同 —— 返回退出整个详情栏回到列表,
  关闭只收起树、留在这封邮件上

## 把实测脚本留进仓库

`web/test/manual/`(`npm run test:narrow` / `test:wide`),不进 npm test ——
要一个跑着的浏览器加一个活的 Gateway。

留着而不是用完即删,是因为结构性断言守不住「按钮实际多大、点下去命中谁」,
而这次最严重的 bug 恰好只有 elementFromPoint 能发现。helper 里两个函数专门
为此:tapTargets() 量 .tap 的真实命中区(伪元素尺寸,不是 boundingBox),
hitTest() 验每个元素点下去是否命中自己。

## 验证

- 窄屏 13 项 + 宽屏 5 项全通过。宽屏回归特意验了两件只该在窄屏生效的事:
  .tap 伪元素 content 为 none、没有返回按钮
- narrow-layout.test.mjs 从 20 条扩到 28 条,逐条钉住上面每个修复
- 无横向溢出:390px 与 320px 下 scrollWidth === clientWidth
- 生产已部署
2026-09-02 23:53:59 +08:00

59 lines
2.4 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.

# 手工浏览器实测脚本
不进 `npm test` —— 它们需要一个跑着的 Chromium 与一个活的 Gateway。
日常回归靠 `../narrow-layout.test.mjs`(读源码验形态,无外部依赖)。
## 为什么两套都要
结构性断言守住「代码写成了什么形态」,量不出「按钮实际多大、点下去命中谁」。
窄屏那轮修复里最严重的一个 bug 是抽屉式侧栏(`fixed ... z-50` 铺满视口高度)
把底部导航最左那一项盖住 —— 按钮在那里、尺寸也够、`md:hidden` 之类的规则也
没写错,**只有 `elementFromPoint` 才能发现它命中的是抽屉里的 SVG**。
## 用法
```bash
# 窄屏390pxiPhone 14 Pro+ 320pxiPhone SE
ADMIN_PW=<密码> npm run test:narrow
# 宽屏回归:窄屏修复不能把桌面改坏
ADMIN_PW=<密码> npm run test:wide
```
环境变量:
| 变量 | 默认 | 说明 |
|---|---|---|
| `ADMIN_PW` | 无(必填) | 管理员密码 |
| `ADMIN_USER` | `admin` | 登录用户名 |
| `AGENTMAIL_URL` | `https://mail.jianfgit.xyz` | 目标地址 |
| `CDP_URL` | `http://127.0.0.1:9222` | 浏览器 CDP 端点 |
| `PLAYWRIGHT` | `/usr/lib/node_modules/playwright/index.mjs` | playwright 入口 |
浏览器用的是本机 systemd 托管的共享 Chromium`homeagent-browser.service`
通过 CDP 连上去开自己的标签页,用完关掉。没有它时先
`systemctl start homeagent-browser`
## 文件
| 文件 | 作用 |
|---|---|
| `narrow-probe-helper.mjs` | 连浏览器、登录、量盒子/溢出/命中区/命中测试 |
| `narrow-verify.mjs` | 窄屏 13 项验收 |
| `wide-regression.mjs` | 宽屏 5 项回归 |
`narrow-probe-helper.mjs` 里两个函数值得单独知道:
- `tapTargets(page, labels)` —— 量 `.tap` 按钮的**真实**命中区(`::after`
伪元素的尺寸)。`.tap` 刻意不改变视觉尺寸,所以只看 `boundingBox` 会误判成偏小
- `hitTest(page, selector)` —— 每个元素点下去是否命中自己。遮挡类 bug 只能这样查
## 已知限制
headless Chromium 报告 `hover: none`,因此 `.reveal`(只在支持悬停的设备上隐藏)
在这里永远是可见的 —— 脚本只能验「触摸设备上可见」这一半,
「鼠标设备上隐藏」那一半靠 `../narrow-layout.test.mjs` 检查 CSS 规则存在。
没有像素级视觉比对:字体差异下极脆,维护成本高于收益。