Restore default template binding across browser sessions
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# 默认画面保存绑定修复
|
||||
|
||||
本轮只补齐设备网页的保存绑定与保存选项,正式版本保持 1.1.3,功能更新时间为 `2026-10-10T10:18+08:00`。用户静态模板可以覆盖;演示静态图和演示动图第一帧的“保存到当前模板”为黑色受限态,只能另存。新设备开机会话载入默认画面,同次开机刷新保留草稿、原修订与保存基线;用户动图仍使用原逐帧流程。
|
||||
|
||||
## 验证证据
|
||||
|
||||
- 原工作区完整本机 `all` 套件通过,包括 Python、Node、静态 JavaScript 语法和文案目录校验;新增模板保存模型行为测试 6 项通过。
|
||||
- 实际浏览器验证了另存、覆盖、取消、刷新绑定、默认引用不变、新开机会话、两个演示案例的黑色受限按钮、`409` 冲突、删除后的 `404`、读取失败、未来版本草稿、初始化期间编辑和多标签外部草稿绑定。用户动图实际保存帧返回 `200`,退出后恢复普通画布绑定。桌面和手机保存弹窗截图为隔离 mock 数据,见本目录 PNG。
|
||||
- 初次隔离副本缺少内核依赖及内核源码材料,依赖完整性测试失败;补齐这些离线材料后重新验证。不复制、检查或重建历史 IMG。
|
||||
- 初次隔离测试还出现一次 `app/persistence.py` 原子替换的 `PermissionError / WinError 5`,导致动图 API 错误响应;独立定向重测及下一轮完整测试均未复现该项。没有足够证据确定其系统根因,没有为此修改动画或生产写入保护。
|
||||
- 补齐材料后的隔离全量 Python 结果为 505 通过、10 跳过、1 失败;失败项为 OTA 故障注入测试的目录 rename,同样返回 `WinError 5`,定向重测 1 项通过。隔离前端 84 项全部通过,全部静态 JavaScript 语法及文案目录校验通过。隔离环境从文档入口重新创建 venv 和安装依赖,没有复用原工作区环境;本轮 Windows 间歇性文件访问失败的根因仍未确认,不把这一轮全量运行写成零失败。
|
||||
- 板端通过现有 `update_walnutpi.sh` 原子更新:全部依赖离线安装,原生 bitplane 与 fake safeoff 测试通过,Python 509 项通过、7 项按平台/应用载荷边界跳过;生产切换和服务 restart 健康检查通过,真实驱动为 `walnutpi-h618-hub75`。9 个安装后的实现/版本文件与本机源码摘要一致。
|
||||
- 生产网页临时模板覆盖返回 `200`,保留 ID、名称和创建时间,刷新后恢复保存绑定;用户默认引用不变,临时模板删除返回 `200`。当前设备默认为用户动图,沿用现有逐帧流程;两个演示案例的黑色受限状态在隔离 mock 中验证,没有为此切换设备默认或实际画面。
|
||||
- 部署前后全部 430 个持久文件数量和 SHA-256 一致,用户配置、模板、动图、字体等内容未被修改。汇总证据见 `验收结果.json`,未保存实际凭据或设备标识。
|
||||
- 远端 `/var/tmp/qms-default-save-20261010` 已清理,更新脚本的 staging、候选数据、回滚数据和测试运行目录均不存在;当前正式运行程序及其 venv 保留。本轮本机 mock 服务、SSH 验收隧道和专用浏览器已停止。本机临时目录的递归删除被工具安全策略拒绝(`blocked by policy`),未换手段绕过。
|
||||
- 可手动删除 `测试相关资料/如何测试/本机测试环境/.local/work/default-save-20261010/`:仅含本轮测试副本及其重建 venv、mock 数据、专用浏览器状态、上传包、中间日志和摘要;交付证据已保存到本归档。该目录不包含生产数据或长期复用的 SSH/本机测试环境,不要连带删除上级 `.local/`。
|
||||
|
||||
## 可重复经验
|
||||
|
||||
稳定验收条目和保存交互经验已加入 `测试相关资料/如何测试/核桃派点阵屏控制服务测试流程.md` 的默认画面保存绑定小节;隔离依赖边界及 Windows 文件替换诊断记录在本机测试环境 README。跨端兼容登记说明 REST、BLE、scene v2、配置和驱动契约不变,无需 App 更新。
|
||||
|
||||
本次实屏视觉验收不适用,没有摄像头、接线、调压或测试图案操作。真实断电开机的行为通过 mock 开机会话验证;板端采用服务重启验收,不将其写成物理断电验证。
|
||||
@@ -0,0 +1,19 @@
|
||||
# Windows 隔离测试失败证据摘要
|
||||
|
||||
以下调用和错误类型来自本轮实际测试日志;省略本机绝对路径及无关依赖安装日志,完整结果计数见验收结果 JSON。
|
||||
|
||||
## 首轮
|
||||
|
||||
测试:`tests/test_animations.py::test_default_animation_delete_and_last_frame_delete_fall_back`。
|
||||
|
||||
第二个用户动图添加帧时,`app/animations/store.py::_write_at` 调用 `app/persistence.py::atomic_write_many_bytes`,`os.replace(temporaries[target], target)` 返回 `PermissionError: [WinError 5]`。API 返回错误响应后,测试访问 `second["id"]` 产生 `KeyError: 'id'`。独立定向运行和下一轮全量运行未复现该项;没有确认其系统根因。
|
||||
|
||||
同轮另有内核依赖完整性测试失败,原因是隔离副本没有复制该测试要求的内核载荷和源码归档;补齐项目内登记的原材料后该项通过。
|
||||
|
||||
## 补齐材料后的全量运行
|
||||
|
||||
测试:`tests/test_ota_checkpoints.py::test_power_loss_between_data_renames_recovers_original`。
|
||||
|
||||
测试中的 `c.DATA.rename(backup)` 经 `pathlib.Path.rename` 调用 `os.rename`,返回 `PermissionError: [WinError 5]`,尚未进入恢复断言。该轮为 505 通过、10 跳过、1 失败;使用独立测试目录定向重测该项,结果 `1 passed in 0.06s`。没有修改 OTA、动画、文件写入保护或测试断言来掩盖失败。
|
||||
|
||||
上述现象仍保留为本机间歇性文件访问边界,不能仅凭重测通过推断具体原因。板端 Linux 原子部署验证为 509 通过、7 跳过,生产保存接口和数据保留验证通过。
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"staticOverwrite": true,
|
||||
"refreshBinding": true,
|
||||
"defaultReferencePreserved": true,
|
||||
"demoStaticBlack": true,
|
||||
"demoAnimationBlack": true,
|
||||
"conflict409": true,
|
||||
"deleted404": true,
|
||||
"readFailurePreservesDraft": true,
|
||||
"futureDraftUntouched": true,
|
||||
"initializationEditRace": true,
|
||||
"newBootReload": true,
|
||||
"mobileNoOverflow": true,
|
||||
"externalDraftBinding": true,
|
||||
"animationFrameSaveAndRestore": true
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"deployment": {
|
||||
"result": "success",
|
||||
"native_unit": "passed",
|
||||
"python_passed": 509,
|
||||
"python_skipped": 7,
|
||||
"restart_health": "passed"
|
||||
},
|
||||
"production_browser": {
|
||||
"featureUpdated": "2026-10-10T10:18+08:00",
|
||||
"version": "1.1.3",
|
||||
"bootMarkerPresent": true,
|
||||
"defaultType": "animation",
|
||||
"defaultIsDemo": false,
|
||||
"overwriteStatus": 200,
|
||||
"refreshRestoresBinding": true,
|
||||
"keepsTemplateIdentity": true,
|
||||
"defaultUnchanged": true,
|
||||
"temporaryDeleted": true
|
||||
},
|
||||
"persistent_files": 430,
|
||||
"persistent_contents_unchanged": true,
|
||||
"installed_source_matches": true,
|
||||
"local_original_all": "passed",
|
||||
"isolated_python_full": {
|
||||
"passed": 505,
|
||||
"skipped": 10,
|
||||
"failed": 1,
|
||||
"failed_case": "test_power_loss_between_data_renames_recovers_original",
|
||||
"failure": "Windows WinError 5 directory rename",
|
||||
"targeted_retest": "1 passed"
|
||||
},
|
||||
"isolated_frontend": {
|
||||
"passed": 84,
|
||||
"failed": 0
|
||||
},
|
||||
"payload_sha256": "84527ee7b383c6bacdc22e3b4ab74ef05ad3fa7b95582c07d0a24efb277e9385"
|
||||
}
|
||||
Reference in New Issue
Block a user