a275539c17
task-9 让内容页黄金从 47 涨到 53(通讯设置页六态),本笔只做**当前态陈述**的同步;真值全部本轮实测: `simulator/tests/ref/*.bin` = **53**;`git diff 31ca4a1f..HEAD` 对该目录 = ** 6 个新增、零修改** ⇒ 存量 47 张 逐字节未变(这条是关键:新增页不该让旧页重生成,否则回归基线就失去意义)。 **四类命中各走各路,这是本笔的全部难点**(分类比替换重要得多): · 当前态 → 改,25 处页数,落在 16 只文件(AGENTS、钩子显示名、导航器 docstring、`lvgl-simulator` s kill、 门禁索引与 `ui-golden` 详解、UI 自动化流程、内容页架构、页面补齐规划与扩充方案、数据供给、自动化测 试流程、覆盖率口径、测试开发标准流程、模拟器两份 README); · 变更记录历史行 → **一条不动**,另在其下一行插入当日「47 → 53」新行 6 条(含判据与零漂移证据); · **同数不同义 → 不动**:覆盖率口径里的「47 个 .c」「47 = 13+5+29」、ram_report 的表行号 47、`#47-D` 诊断号、LSI 47kHz、47,360 栈字数、像素哈希 3476/3474 —— 一并替换就会毁掉六个不相干的事实; · 带日期戳 / 自declare 冻结的快照 → 不臆改(数据供给篇那句上一笔已加「当时」,页面补齐规划里那张 「2026-10-25 复核…剩 21 叶」的表自带「完成即冻结不回改」声明)。 复扫残留当前态 47 = **0**。⚠ 顺手纠一条**会教错方法**的陈旧:naive 计数 `grep -c '#page='` 上一笔写的是 22,现在真值是 **23**(文件头示例行也算一次)——旧文档里那个 22 **恰好等于新的正确 bound 数**,不改的话, 下一个人用错算法还能碰巧对上,比错更糟。 ⚠ `AGENTS.md` 里本次有两件事同行相邻(本笔的内容页 53 页 + 批次三那句 `TC-*` 停发),**分两句说明**: 前者是计数同步,后者是昨天那条「批次三不坐」裁定的入口文案,二者不是同一件事。 钩子显示名改在 `.pre-commit-config.yaml`(47 → 53)。**这条必须与代码同批入库**:配置脏而未 stage 时 pre-commit 会直接报错挡住全仓任何提交(今天已实测两次),所以本笔先落它,把后面几笔的路清开。 自查:`check_doc_links --all` rc=0(203 篇)、`check_ids --strict` rc=0 且不可判定绝对 数 **979 未变**(新增 文本里的提交号与 `#page=comm` 没推高它)、`gen_task_table --check` 0、`check_bom_drift` 0、18 只文件 noBOM / LF / U+FFFD=0;行数变动 +49/−47 全部可归属(插 6、删 2、并 1),其余为 1:1 等行替换。登记簿销项与叶数 (`UI补齐.md` + `docs/任务规划/README.md`)**不在本笔** —— 那是口径变更不是计数同步。
226 lines
23 KiB
Markdown
226 lines
23 KiB
Markdown
# UI 自动化测试流程(模拟器回归)
|
||
|
||
> **用途**:所有涉及 UI 的改动(菜单结构 / 内容页 / 字体 / 样式 / 几何)改完代码后,按本文跑一遍全部门禁再提交。脚本已入库,直接调用即可,无需临时重写。
|
||
> **定位**:`UI_界面制作流程.md` P2/P3 门禁的可执行版本;设计阶段(P0 规格 / P1 编码)走 `UI_界面制作流程.md`。
|
||
|
||
---
|
||
|
||
## 一、前置条件
|
||
|
||
| 项 | 说明 |
|
||
|---|---|
|
||
| 模拟器已构建 | 仓库根目录:`& "simulator\build_sim.bat"`(自动探测本机 VS2019/2022/2026 生成器,见 `simulator/README.md` §3.2) |
|
||
| Python | 统一入口 `.venv\Scripts\python.exe`(AGENTS.md「Python 环境」);两个回归脚本纯标准库,任意 python3 均可,为保持一致一律用 .venv |
|
||
|
||
## 二、流程总览
|
||
|
||
```powershell
|
||
# 仓库根目录执行(python 统一用 .venv,见 AGENTS.md「Python 环境」)
|
||
cmake --build simulator/build --config Debug # 0) 构建模拟器(须 0 警告)
|
||
.venv\Scripts\python.exe simulator/tests/check_menu_rows.py # 1) 菜单 8 状态像素回归 + 池基线门禁
|
||
.venv\Scripts\python.exe simulator/tests/check_content_pages.py # 2) 内容页黄金参考回归 + 往返池门禁
|
||
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py # 3) Keil 构建(BUILD_OK,0 错 0 警)
|
||
.venv\Scripts\python.exe scripts/check_coding_standard.py # 4) 代码规范机械检查(PASS)
|
||
```
|
||
|
||
| 步 | 脚本/命令 | 门禁内容 | 预期输出 |
|
||
|---|---|---|---|
|
||
| 1 | `simulator/tests/check_menu_rows.py` | 菜单 8 状态:选中行白带 / 非选行黑底白字 / 框体 1px 边框 / 往返像素一致(MENU-STATE-03==MENU-STATE-01、MENU-STATE-06==MENU-STATE-01、MENU-STATE-07==MENU-STATE-02)+ MENU-STATE-00 池基线 | `PASS: 8 状态全部断言通过(8 图,池基线 5368 B)` |
|
||
| 2 | `simulator/tests/check_content_pages.py` | ① 文本级断言(字形模板匹配,310 条,独立于 `ref/`)→ ② 53 页截图与 `ref/` 黄金参考**逐字节**比对 + 开页-关页往返池水位 | `PASS: 53 内容页 + 往返池水位全部通过`(文本断言先于像素比对,失败即中止) |
|
||
| 3 | `keil-build` skill(`keil_build.py`) | MCU 端编译(UI 源码双端共用,改一端必须过另一端) | 退出码 0 = BUILD_OK |
|
||
| 4 | `scripts/check_coding_standard.py` | 代码规范 V1.0 机械检查 | PASS |
|
||
|
||
> **文本级断言层**(2026-09-10 新增):`check_content_pages.py` 内置字形模板匹配——直接解析
|
||
> `ui_font_cn_12.c` 的 cmap/glyph_dsc/bitmap,把期望字符串(标题/标签/值/页脚,含新增易缺字文案)
|
||
> 渲染成墨点集合,在截图对应 y 带内做精确匹配(LVGL 基线对齐)。价值:**缺字显示空白 / 标签写错**
|
||
> 这类回归不再只靠像素位图(那需要刷参考,且无视觉后端时难以判读);文本断言不依赖 `ref/`,且
|
||
> **先于**像素比对运行,失败即中止(不误刷参考)。文本断言覆盖确定文案,像素参考仍负责几何/样式/
|
||
> 光标反显等其余视觉。规模与覆盖面(2026-10-26 实跑 `check_content_pages.py` 取数):文本断言 **310 条**、覆盖当时 40 页中的
|
||
> **37 页**——`pwd` / `pwe` / `pwc` 三张密码态只进像素比对、未登记文本断言,改这几页的文案没有文本层兜底。
|
||
|
||
**退出码约定**:两个脚本均为 0=PASS / 1=断言失败 / 2=环境错误(exe 缺失、参考缺失)。
|
||
失败时脚本打印差异明细(文本断言未命中项 / ink runs 对照 / 像素差数),内容页脚本保留现场截图于临时目录并提示路径。
|
||
|
||
## 三、内存水位门禁常量
|
||
|
||
| 常量 | 所在脚本 | 当前值 | 含义 |
|
||
|---|---|---|---|
|
||
| `MENU_POOL_BASELINE` | check_menu_rows.py | **5368 B** | 菜单根框建完的 LVGL 池 used(x64 模拟器) |
|
||
| `POOL_AFTER_ROUNDTRIP` | check_content_pages.py | **5448 B** | 开页-关页往返后水位 = 基线 + 一次性残留 80 B |
|
||
|
||
> 水位历史:4784 →(2026-09-14 待机模块常驻 +656)5440 / 5520 →(2026-10-11 裁剪 LVGL 控件类 −72)5368 / 5448。
|
||
> 后一次漂移已核实为**有意且更优**:像素逐字节未变(**裁剪当时黄金参考只有 11 页**,在裁剪**前**生成、裁剪后全部一致;该集合现已扩至 53 页),
|
||
> 且一次性残留仍是 80 B(5448 − 5368)→ 泄漏特征未变,只是 `lv_theme_apply` 不再为已不存在的控件类登记样式条目。
|
||
|
||
**漂移处理**:菜单/页面结构或样式变更导致门禁失败时,先确认新值合理(残留分解见
|
||
`菜单页面设计.md` §9.5),再更新脚本常量并在本文变更记录登记。**禁止为过门禁盲目改常量**——
|
||
无法解释的漂移 = 内存回归 bug。
|
||
|
||
## 四、黄金参考(入库)与目检 PNG(本地产物)
|
||
|
||
`simulator/tests/ref/*.bin`(像素黄金参考,53 页 × 3200 B)**随仓库入库**;派生的 `.png`
|
||
目检图仍是本地产物(`.gitignore`)。入库的理由:比对是**逐字节**的,基线不入库时任何新克隆
|
||
或新工作树跑 `ui-golden` 都必然 FAIL(缺基准),这条门禁就只在"有老副本的机器"上真实存在。
|
||
可复现性实测(2026-10-22):两份各自独立构建的 `lvgl_sim`(不同构建目录、相隔 11 天的代码)
|
||
对同一批 11 个 `.bin` **SHA-256 全部一致** → 渲染是 CPU 侧确定性输出,基线可以进仓库。
|
||
|
||
换机后**不需要**再生成基准;只有有意改视觉时才 `--update`(改动会进 `git diff`):
|
||
|
||
```powershell
|
||
.venv\Scripts\python.exe simulator/tests/check_content_pages.py --update # 生成 ref/*.bin
|
||
.venv\Scripts\python.exe simulator/tests/regen_ref_png.py # 生成 ref/*.png(--scale 6 --invert)
|
||
```
|
||
|
||
有意改视觉时的流程:
|
||
|
||
1. **先肉眼确认新效果正确**:窗口模式运行 `simulator\build\Debug\lvgl_sim.exe`,或刷新后跑
|
||
`regen_ref_png.py` 看图对照 mockup;
|
||
2. 刷新参考:`.venv\Scripts\python.exe simulator/tests/check_content_pages.py --update`(重写 `ref/*.bin`);
|
||
3. **重生成目检 PNG**:`.venv\Scripts\python.exe simulator/tests/regen_ref_png.py`。
|
||
`.png` 是本地调试产物、**不会**随 `.bin` 自动更新——不重跑则 PNG 仍是旧渲染(缺字/错位,看似"乱码")。
|
||
默认 `--scale 6 --invert`(深字白底便于目检);`--no-invert` = 白字黑底(与设备一致);
|
||
4. **提交 `ref/*.bin` 的改动**(它已入库,等于改基准):`git diff --stat simulator/tests/ref` 必须
|
||
|
||
**误刷保护**:`--update` 会**先跑文本级断言**,断言失败即中止,避免把缺字/错标签的渲染"刷成"新基准。
|
||
|
||
**何时不该更新**:未有意改视觉而某页 FAIL → 是 bug(缺字、几何漂移、样式回归),修代码而不是刷参考。
|
||
菜单状态无黄金参考文件——其断言是结构性的(白带占比/边框/往返一致),不依赖入库位图。
|
||
|
||
## 五、误报排查
|
||
|
||
| 现象 | 常见原因与处置 |
|
||
|---|---|
|
||
| 多页大面积像素差异 | 字体重生成(`ui_font_cn_12.c` 变化)→ 确认字形正确后 `--update` 刷参考 |
|
||
| 单行/单字差异 | 几何或文案变更 → 先判断是否有意修改;无意 = bug |
|
||
| 池水位门禁失败但像素一致 | 样式/结构变更(如动态样式转常量、增删框体)→ 确认新值合理后更新常量并登记 |
|
||
| **只有 `netcfg_save` 一页失败**(保存行值列是 `ERR` 而非 `OK`),其余 26 页全过 | **不是代码回归,是工作目录被污染**:模拟器按**当前工作目录**读写 `sim_config.ini`,而 `--cfgtest` 超长守卫的场景 2 会伪造一份 4000 B 纯注释"雷"文件、并断言"拒写后原文件不动"——**连通过路径也会把它留在原地**。之后每次运行都加载它 → 外科手术保存要在 4000 B 注释后补写受管段 → 输出必超 `CFG_FILE_MAX_LEN` → 引擎**按设计拒写** → 保存行显示 ERR,与"工厂默认态"的黄金参考对不上。处置:两套回归已改为**在空临时目录里跑**(传 `cwd=tmp`),`--cfgtest` 已加外壳无论成败一律删除伪造档;手工跑 `lvgl_sim` 时删掉当前目录的 `sim_config.ini` 即恢复。**禁止为此刷黄金参考**(参考是对的) |
|
||
| `找不到 lvgl_sim.exe` | 模拟器未构建或 build/ 被删 → 先按 §一 重建 |
|
||
| 终端输出中文乱码 | PowerShell 代码页渲染问题,不影响判定(看 PASS/FAIL 与退出码) |
|
||
|
||
## 六、与其他文档的关系
|
||
|
||
- `UI_界面制作流程.md`:P0 需求录入 + 设计规格 → P1 规格→代码 → **P2 本文回归** → P3 MCU 上机目检 → P4 归档
|
||
- `菜单页面设计.md` §9:内容页对象树 / 几何表 / 内存预算(本文数字的来源)
|
||
- `simulator/README.md` §3.5/§3.6:无头模式(`--keys`/`--screenshot`)与回归脚本说明
|
||
|
||
## 七、板端有状态导航判据(真机侧,`scripts/board_ui_nav.py`)
|
||
|
||
> 前五节都在模拟器里跑;模拟器与固件同一份 UI 源码,像素判据在 PC 上就成立。本节管另外
|
||
> 一半:**真机上把页面走到、并证明走对了**——这一步只有真机需要(模拟器侧把键序直接喂给
|
||
> 无头进程,状态是确定的)。
|
||
|
||
### 7.1 为什么必须闭环(实测 2026-10-25 大窗)
|
||
|
||
- RemoDispBus 的 **KEY 应答是空帧、不携带任何状态**:发了 5 个键不等于到了第 5 层。
|
||
- 靠预置键序盲走,9 个「应当到达」的态里只有 3 个真是那个态:
|
||
|
||
| 留档帧 | 文件名声称 | 实际是 | 墨量 | 证据 |
|
||
|---|---|---|---|---|
|
||
| 00 / 01 / 02 | 根菜单 / 装置信息 / 交流量 | 名副其实 | 3226 / 3476 / 3346 | 认屏一致 |
|
||
| 03_dc | 直流量 | 菜单级联(整屏无页标题) | 4961 | [blindwalk_cascade](../测试说明/boot_log_data/20261025_uinav_blindwalk_cascade.png) |
|
||
| 04_yx / 05_yxp2 / 06_soe | 遥信量两页 / SOE记录 | **密码输入页** | 512 / 515 / 512 | [blindwalk_pwd512](../测试说明/boot_log_data/20261025_uinav_blindwalk_pwd512.png) |
|
||
| 07_vparam | 参数查看页 | 网口设置页 | 3774 | 标题带命中「网口设置」 |
|
||
| 08_vset | 定值查看页 | 装置信息页 | 3474 | 标题带命中「装置信息」 |
|
||
|
||
那三帧的 512 墨量曾被记成「神秘空白态」;与黄金参考 `shot_pwd.bin`、`shot_pwe.bin`(墨量
|
||
同为 512)逐字对得上之后可以定性:**走带 `#P` 注记的叶子时,第一屏是要密码,不是内容页**
|
||
——写路径判据(批 5)因此必须把「过密码」当显式状态处理,口径见 §7.5。
|
||
- 结论:判据脚本只能信画面。脚本因此**每按一键重新认屏**再决定下一个键,且「到达」只由
|
||
**页面身份**裁定;中途任何假设都写进轨迹,绝不当成结论。
|
||
|
||
### 7.2 认屏的三条判据(精确字形匹配,复用同一份 `ui_font_cn_12`)
|
||
|
||
| 态 | 判据 | 为什么这样判 |
|
||
|---|---|---|
|
||
| 内容页 | 标题带命中 + 该页黄金行文本至少一条 + 页码行「第 N 页,共 M 页」 | 只认标题会把两屏认成一屏(「参数」既是菜单项也是页名);页码让「遥信量第 2 页 / 共 5 页」成为可比对的事实 |
|
||
| 菜单 | 在白底横条(反白选中行)覆盖的行范围内、**整幅宽度**找反白标签;长标签优先,命中框被包住者丢 | 选中行是黑字白底,只按正常极性永远读不出选中项;「参数定值」那行必然同时落进子串「参数」「定值」,不去重就凭空多两列 |
|
||
| 密码页 | 「用户密码」四个字里中三个 | 整串匹配实测差约 1 px 打不中;数字格随输入变,不参与判定 |
|
||
|
||
另两条实测纪律(理由写死在代码注释里,此处不重述):
|
||
|
||
- **收级联列按 `l`、不按 `s`**:菜单态按 `s` 不收列,用 `ssssssss` 回根正是深页错位的来源之一;
|
||
- 菜单树的 `#P` 注记可能写在 `#page=` **之前**(`网口设置 #P #page=net_cfg`),解析顺序错了就
|
||
剥不掉,那一叶的页面 id 也永远认不出来。
|
||
|
||
### 7.3 用法与门禁档位
|
||
|
||
```powershell
|
||
# 认屏快检:53 张黄金参考(+ 若有台架留档帧),秒级,不需要构建产物
|
||
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --selftest-quick
|
||
# 完整自检:再加全绑定页闭环导航(需模拟器可执行文件,约 30 s)
|
||
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --selftest
|
||
# 台架窗口:一条命令走完全部绑定页并逐页存证
|
||
# ⚠ 真机动作必须显式确认已持 bench 锁,否则脚本直接拒绝(不碰网络,退出码 3)
|
||
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --walk --i-hold-bench-lock
|
||
# 只走一页并抓图;--trace 落步迹、--dump-fail 落「认错的那一屏」,--outdir 改存证目录
|
||
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --board --to yx --grab D:/tmp/yx \
|
||
--i-hold-bench-lock --trace D:/tmp/uinav_trace.json
|
||
```
|
||
|
||
- 提交钩子 `uinav-selftest` 跑的是**快检档**(`--selftest-quick`)。为什么不挂完整档:闭环
|
||
那一段要模拟器可执行文件——它是构建产物,新工作树里没有,正是同一天 `mem-numbers` 缺
|
||
`.map` 那课的形状。脚本对「缺可执行文件」报 FAIL 并给可执行提示,不「跳过当通过」;
|
||
合入前 / 上板前请手工跑一次完整档(快检 ≠ 闭环,两者结论不同,别互相顶替)。
|
||
- 板端后端只连 7003 取图注键,**不含串口、烧录、复位**;`--board` / `--walk` 必须另加
|
||
`--i-hold-bench-lock` 才会去连——没给就直接拒绝(退出码 3,不碰网络)。这条不是防御性
|
||
设计,是**同一天踩出来的**:跑 `--walk` 想看一眼默认存证目录打印成什么,脚本就照着连上
|
||
板子注入了按键,而那时台架属于验收窗的准备方。「必须持锁」写在文档里防不住「我只是跑
|
||
一下」,所以把确认做成命令行参数:要动真机,就得在命令行里留下字面证据(脚本不代取锁,
|
||
也不替人判断「应该没人在用」)。
|
||
- **存证不进工作树**:`--walk` 的帧默认落 `ci-artifacts/uinav/walk/`(版本控制之外),
|
||
`--outdir` 可改;给的路径若落在版本控制内(且不在 `ci-artifacts` 之下),脚本**直接拒绝
|
||
执行**并退出 3。理由与提交门禁同一条:产物一旦写进工作树,`git status` 就不再是判据,
|
||
而「记得删」只防得住记得的人。
|
||
- 步迹只在 `--trace <路径>` 给出时落盘;认错那一屏只在 `--dump-fail <目录>` 给出时留存——
|
||
两者都指到 `ci-artifacts/` 下,窗口结束把工作目录交回来时工作树仍是干净的。
|
||
- 台架留档帧目录在 gitignore 内、不入库:缺就整段跳过,不算失败——但脚本把「没跑」与
|
||
「跑过且通过」分开打印,不把前者写成后者。
|
||
|
||
### 7.4 已知限度(别把它当万能闸)
|
||
|
||
1. **根列选中落在最后两行时,子菜单弹框会被屏幕裁掉**:选带不在可扫窗口里,列数会漏计。
|
||
脚本对策是「枚举 + 验终点」——末列先盲按 N 次下移再进(第 N 次尝试),成败仍只由页面
|
||
身份裁定,所以它会大声报错而不是静默走错页。实测 `自检记录` / `运行记录` 两页在模拟器
|
||
上 5 次枚举内没吃到,现场帧见
|
||
[popup_clipped](../测试说明/boot_log_data/20261025_uinav_popup_clipped.png);
|
||
**真机上那层弹框究竟画在哪,留台架窗口取证后再定修法**——这是取证题,不是编码题。
|
||
2. 同一标题的多个显示态(网口设置的 只读 / 编辑 / 保存)在分类里都是同一个页面 id
|
||
`net_cfg`;要区分得看行内文本,写路径判据需要时再加。
|
||
3. 认屏复用黄金参考的文案:改了页面文案而没同步 `simulator/tests/` 的文本断言表,本节脚本
|
||
会一起红。那是**有意的耦合**(两处必须同时改),不是脚本脆弱。
|
||
4. 快检档只证「认屏认得对」,不证「导航走得对」;后者只有完整档的闭环那一段会响。
|
||
|
||
### 7.5 过密码的口径(与黄金回归同源,只有一套走法)
|
||
|
||
查看密码 = 出厂 `000`(直接 `e` 确认);修改密码 = `123`,键序 `u,r,u,r,u,r,e`,与
|
||
`simulator/tests/check_content_pages.py` 的 `netcfg_edit` 态**完全一致**——刻意不另发明一套走法
|
||
(两套走法迟早分叉,而分叉的那一边往往是真机)。导航器**默认只过查看密码**:判据需要写
|
||
路径权限时必须显式传 `modify=True`,**不因「能进去」就自动升格成可写**——只读判据偷偷拿到
|
||
修改权限,等于把判据的边界让给了实现。
|
||
|
||
---
|
||
## 变更记录
|
||
|
||
| 日期 | 变更 |
|
||
|---|---|
|
||
| 2026-09-09 | Python 解释器统一为仓库 `.venv`(新增 `requirements.txt`,`.gitignore` 忽略 `.venv/`);§1/§2/§4 命令同步改用 `.venv\Scripts\python.exe` |
|
||
| 2026-09-09 | 初版:菜单 8 状态像素回归 + 内容页黄金参考回归(ref/ 3 图,I1 原始位图入库)+ 池水位门禁(4784/4864 B)。脚本自会话临时目录整理入 `simulator/tests/`(相对路径定位 exe、输出改临时目录),替代每次重写 |
|
||
| 2026-09-10 | `check_content_pages.py` 新增**文本级断言层**(字形模板匹配 50 条,独立于 `ref/`,先于像素比对运行、失败即中止防误刷参考);内容页扩至 11 页(+网口设置 4 态);§二/§四同步 |
|
||
| 2026-09-10 | 新增 `simulator/tests/regen_ref_png.py`(由 `ref/*.bin` 批量重生成目检 PNG,默认 `--scale 6 --invert`);`ref/*.png` 加入 `.gitignore`(本地调试产物不入库);§四 补"重生成目检 PNG"步骤(修复"刷了 `.bin` 参考但 `.png` 仍是旧渲染 → 看似乱码") |
|
||
| 2026-09-10 | `simulator/tests/ref/` **整目录不入库**(`.bin` 黄金参考 + `.png` 目检图均为本地生成物):`git rm --cached` 原有 3 个 `.bin`,`.gitignore` 改为忽略整目录;首次/换机后先 `--update` 生成参考;`--update` 先跑文本断言防误刷;§四 重写 |
|
||
| 2026-09-13 | 管线同步:`UI_界面制作流程.md` 移除 HTML 样机阶段(五阶段 → 四阶段 P0~P4),本文定位改为"P2/P3 门禁的可执行版本";§六 关系描述更新为 P0 规格 → P1 编码 → P2 本文回归 → P3 上机目检 → P4 归档;移除 `tools/ui_mock/` 引用 |
|
||
| 2026-10-11 | **裁剪 LVGL 死代码(F-1/F-2/F-3)时的门禁记录**:先用**未裁剪**配置 `--update` 生成 11 页黄金参考,再切到裁剪配置重编重跑 → **逐字节全部一致**(菜单 8 状态像素一致),证明裁剪零视觉影响。池水位门禁随之 5440/5520 → **5368/5448**(−72 B;一次性残留仍 80 B,故非泄漏变化,见 §三 水位历史)。顺带揪出并修掉 `Lib/lv_conf.h` 与 `simulator/lv_conf.h` 的**长期漂移**(模拟器早已 I1-only、MCU 端未裁)→ 规则见 `UI_设计架构.md` §1.4 第 10 条,量化见 `../内存管理/RAM使用分析与优化方案.md` §2.6.4 |
|
||
| 2026-10-15 | **回归改为自洽运行(修 `netcfg_save` 假失败)**:`check_menu_rows.py` / `check_content_pages.py` 一律以**空临时目录当工作目录**跑 `lvgl_sim`(模拟器按 CWD 读写 `sim_config.ini`,残留档会改变页面内容);`simulator/main.c` 的 `--cfgtest` 加外壳,**无论成败一律删除伪造的 4000 B 配置档**——旧行为连 PASS 路径也会留雷,之后每次 UI 回归的保存行都从 `OK` 变 `ERR`(引擎拒写超长文档,属正确行为)。脚本里"删 `sim_netcfg.bin` 残留"的旧兼容清理随之作废(旧档迁移 2026-10-10 已删),改为**只提示不删除**。修后 11 页 + 往返池水位 5,448 B 全过,**未刷任何黄金参考**;排查口径见 §五 |
|
||
| 2026-10-25 | 第七节同日修订:`--walk` 的存证默认落 `ci-artifacts/uinav/walk/`(第一版写进
|
||
`scripts/walk/`,污染工作树);路径落在版本控制内直接拒绝;`--board` / `--walk` 需显式
|
||
`--i-hold-bench-lock`(实测过一次未持锁就注入按键,故把确认做成参数而非文字纪律)|
|
||
| 2026-10-25 | 新增第七节「板端有状态导航判据」(`scripts/board_ui_nav.py`):真机侧闭环导航、
|
||
盲走 9 帧仅 3 帧名副其实的实测表、认屏三判据、`uinav-selftest` 钩子档位、四条已知限度与
|
||
过密码口径;三张证据 PNG 落 `boot_log_data/` |
|
||
| 2026-10-22 | **`ref/*.bin` 像素黄金参考改为入库**(撤销 2026-09-10 的"整目录不入库"):`.gitignore` 由忽略整目录收窄为只忽略 `ref/*.png`。动因是这条门禁不可移植——新克隆/新工作树里基准必然缺失,`ui-golden` 报「缺黄金参考」而不是回归结论;本仓实测两次同类踩坑(并行工作树里第一次跑必失败,只能现场 `--update` 造基准,而"现场造的基准"恰好失去意义)。入库前做了可复现性验证:主树(`ref/` 生成于 2026-10-11)与新工作树各自独立构建 `lvgl_sim`,11 个 `.bin` SHA-256 全部一致。§四 与"何时不该更新"随之改写:`--update` = 改基准,会进 `git diff`,须逐页过目并在提交正文说明 |
|
||
| 2026-10-27 | 内容页黄金参考 **40 → 47 页**(遥测死区与系数 2 页落地,`simulator/tests/ref/` 实测 47 张:7 张新增、存量 40 张逐字节零漂移);本文件的当前态计数同步改 47,历史行 27 → 40 原样保留 |
|
||
| 2026-10-27 | 内容页黄金参考 **47 → 53 页**(通讯设置页落地并绑 `#page=comm`;判据 = `simulator/tests/ref/` 入库 `shot_*.bin` 实数 53 张,`git diff --name-status 31ca4a1f HEAD -- simulator/tests/ref` 实测只有 6 个 `A`、零 `M` ⇒ 存量 47 张逐字节零漂移);本文件的当前态计数已同步 |
|
||
| 2026-10-26 | **内容页页数口径统一为 27**:正文里残留的「11 页 / 其余 10 页 / 18 张」按现状改正(判据本体 = `simulator/tests/ref/shot_*.bin` 入库实数 27 个、`check_content_pages.py` 的 `PAGES` 27 项,含整定 9 态);下方变更记录里的「11 页」是当时事实,按历史冻结不动。同类陈述同步在 `测试开发标准流程.md`、`自动化测试流程.md`、`主机单测覆盖率口径.md`、`内容页架构.md`、`simulator/tests/README.md`、`scripts/board_ui_nav.py` 改正 |
|
||
| 2026-10-26 | **文本级断言规模口径修正**:门禁表里的「50 条」是 2026-09-10 首版数字,现值 **242 条 / 覆盖 27 页中的 24 页**(`pwd` `pwe` `pwc` 三张密码态只进像素比对、未登记文本断言);正文的文本层说明补写了覆盖面与这条盲区。下方变更记录里的 50 条属历史,不动 |
|
||
| 2026-10-26 | **内容页黄金参考下限 27 → 40 页**(UI 三页落地,机器实测:`simulator/tests/ref/` 入库 `shot_*.bin` 40 个、`check_content_pages.py` 的 `PAGES` 40 项);文本断言随之 **242 → 310 条**、覆盖 **40 页中的 37 页**(`pwd` `pwe` `pwc` 三张密码态仍只进像素比对、无文本断言);27 张旧参考逐字节未变,往返池 5448 B 与菜单常驻堆 5368 B 均未变,字库仍 183 字。本文其余各处与 `AGENTS.md`、`docs/门禁说明/`、`simulator/tests/README.md`、`docs/测试说明/` 三篇同批改齐;**历史行里的 27 / 11 一律保留**(当时下限就是那个数,不改数造连续性)|
|