自动放映联调与验收计划
状态:M0 已验收(2026-10-17,WP01–WP12);M1 已验收(2026-10-17,WP13–WP21),Backend capabilities 已声明 timer 与单窗口自动放映;M2 已验收(2026-10-18,WP22–WP30),已开放 schema 2、media_end、媒体超时与演讲者自动放映,捕获仍禁播;M3 已验收(2026-10-18,WP31–WP33),本地构建产物完成 61 分钟多页循环与恢复演练,未开放产品级远端无人值守。A01–A08 的真实预览/构建、双库迁移、模板与 Chromium 动画证据见 WP12 实施记录;A09/A11/A14/A15 的 M1 真实浏览器证据见 WP16 实施记录;A15/A16 的静态捕获真实 PNG 证据见 WP17 实施记录;A16 的 PDF/PPTX/打印真实产物与取消隔离证据见 WP18 实施记录;A10/A12/A13 的真实过渡后计时、手动/快速/浏览器导航、末页/单页循环与隐藏页证据见 WP21 实施记录;A17 的 CLI/MCP 证据见 WP19/WP20。M2 的 A18–A24 真实浏览器、CLI/MCP 与 Renderer 生命周期证据统一见 WP30 实施记录。字段以统一契约为准,工作包以总计划为准。
执行分工见工作包清单。阶段出口分别为 WP12、WP21、WP30、WP33,负责汇总本阶段场景与真实产物证据。
1. 验证层次与数据
- Backend 单测/API 测试验证配置合法性、事务、权限、迁移、幂等和模板往返;共享样例约束 API 与 Runtime 数据转换。
- Editor 测试验证草稿、继承/null、生成类型、提交与错误反馈;Runtime 虚拟时钟验证调度和旧回调失效。
- 真实浏览器验证 CSS 过渡、媒体、全屏、双窗口和可见性;远程截图必须检查实际 PNG,导出必须检查实际文件。
- 准备独立 fixture:可见封面、分组子页、隐藏页、同一页面重复引用、末页;另有无视频、单视频、多视频、循环背景、失效资源和延迟加载页。
- 验证使用不可变 artifact/snapshot,记录项目默认与路由原始覆盖;E2E 使用技能规定的隔离库和 mock 环境,不重置开发数据。
2. M0:Backend 与动画配置
| 编号 | 场景 | 通过条件 |
|---|---|---|
| A01 | 旧库升级、新建项目、旧模板导入 | 默认淡入淡出 400ms、手动翻页;没有意外自动开始 |
| A02 | 项目默认与两组路由覆盖 | 查询值、原始覆盖、生效值、Runtime 下发符合统一契约 |
| A03 | null、字段省略、分组非法覆盖与越界参数 | 省略/清除语义正确,非法写入整体失败且旧树不变 |
| A04 | 旧客户端整树保存、路由移动/重命名、重复引用 | 匹配的旧节点保留覆盖;新版客户端移动后不丢设置;重复引用互不影响 |
| A05 | API、External、权限和幂等 | 同输入同结果;无权读取/写入失败;省略与 null 使用不同语义指纹 |
| A06 | 预览、历史、下载构建、模板 1/2/3 | 当前快照一致;历史不变;三版本模板可导入,新包往返等价 |
| A07 | none/fade/push、反向翻页和快速导航 | 效果及方向正确,最多两层,结束无残留;减少动态效果立即稳定 |
| A08 | 应用样式、另存为样式、复制页面 | 放映参数归属正确,不被样式应用或页面资源复制隐式改变 |
3. M1:单窗口定时自动放映
| 编号 | 场景 | 通过条件 |
|---|---|---|
| A09 | 从首页/当前页开始,进入后自动开始 | 起点正确,初始化只启动一次,手动模式页面等待操作 |
| A10 | 延迟挂载、资源就绪、动画耗时 | 停留计时从就绪且过渡结束后开始;失败可见且不无限等待 |
| A11 | 暂停、继续、停止和重复点击 | 剩余时间保持;停止保留当前页;只有一个调度句柄 |
| A12 | 播放中/暂停中手动跳页、连跳及浏览器导航 | 旧回调失效,新页按当前播放状态处理,不重复翻页 |
| A13 | 末页结束/循环、单页循环、隐藏页 | 自动边界符合配置;手动边界不绕回;每轮有完整停留周期 |
| A14 | 后台隐藏、切回、切换卡片/演讲模式 | 状态按 Runtime 计划暂停,切回不连跳,旧模式计时清理 |
| A15 | 缩略图、控制台小窗、单页/组件/资源预览 | 自动开始不生效,预览不抢播,不创建后台推进器 |
| A16 | 自动放映配置下截图、PDF/PPTX/打印 | 真实产物路由、顺序、尺寸正确,无离场层;取消不污染主放映 |
| A17 | CLI/MCP 读改写和旧服务兼容 | 显式覆盖/null 不丢失;只读字段不回写;旧服务明确不支持 |
WP13 的虚拟时钟用例已覆盖 A09、A11、A12、A13 的纯调度层(就绪前后计时、暂停剩余时间、旧回调失效、末页/循环/单页循环);WP14 的宿主与媒体守卫用例已覆盖 A14–A16 的执行上下文优先级、缩略图/预览禁自动播放和暂停媒体记录;WP15 的宿主集成用例覆盖 A09/A10/A12/A13 的 Router 绑定、延迟就绪、旧 settled、导航错误和捕获禁推进。WP16 已在真实 Chromium 中验证 A09/A11/A14/A15:1200ms/3000ms 不可变快照自动计时、暂停/继续、后台隐藏不补跳、全屏空格不双触发、卡片模式清理、停止保留当前页,以及 Editor 三档宽度入口。 WP21 在 Chromium 中补充 A10/A12/A13:600ms 过渡 + 1200ms 停留的过渡后计时(1806ms/1866ms)、播放与暂停中手动跳页/连跳、history.back 后旧计时失效、末页循环(1756/1831/1867ms)、单页循环和隐藏页跳过,21 项检查全部通过。WP17 验证 A15 的远程截图真实 PNG;WP18 验证 A16:暂停状态下 PDF/PPTX/打印顺序与内容正确,导出取消不下载且不改变主画布页码、剩余时间与路由。A12 的真实手动连跳仍以 WP21 为准。
虚拟时钟对业务剩余毫秒进行确定性断言。真实浏览器测试记录导航提交、过渡结束和下一次导航时间,运行前声明前台计时容差及设备环境,不能用宽泛 sleep 代替行为判定。
4. M2:媒体与双窗口
| 编号 | 场景 | 通过条件 |
|---|---|---|
| A18 | 单/多非循环媒体、无媒体、循环背景 | 等待全部目标结束;无目标走停留时间;循环背景不阻塞 |
| A19 | 静音、有声、播放受阻、错误和超时 | 状态基于真实播放结果;受阻/错误有重试、下一页和停止入口 |
| A20 | 媒体播放中暂停、跳页、替换或卸载 | 恢复原进度和正确媒体;旧页事件不能推进新页;无残留声音 |
| A21 | 控制台导航/键盘和观众自动翻页 | 双方状态一致且只有观众窗口调度,不重复推进;控制台空格切换自动/手动 |
| A22 | 窗口先后加载、关闭重开、重复/旧消息 | 新快照能恢复,旧 owner 失效;断开后暂停并显式继续 |
| A23 | 控制台隐藏、观众隐藏和退出全屏 | 按实际观众可见性处理;观众退出全屏暂停并提示,重新全屏后才能继续 |
| A24 | 媒体模式下远程截图与取消/期限 | 捕获禁播、PNG 正确、槽位和浏览器进程/临时产物释放 |
桌面 Chromium 必测;Firefox/WebKit 的媒体与全屏差异记录为支持矩阵,未验证浏览器不列为已支持。跨域 iframe 授权使用真实预览拓扑,不能只在同源测试页上验收。
WP26 在独立 Runtime(7373,同源 standalone,4s timer)用两个真实 Chromium 窗口验证 A21–A23:控制台先加载时保持未连接且不接管推进,观众后加载后显式开始;自动翻页间隔 3947ms/8016ms、控制台跟随且无双重计时;控制台/观众键盘与页面按钮导航一致。控制台隐藏时观众继续自动翻页;观众隐藏后暂停、4.5s 内不翻页,重新可见保持暂停且剩余时间未重置,显式继续后完成翻页。全屏进入/退出剩余时间 0:04→0:03→0:03→0:02。关闭观众窗口后回显“已关闭”并暂停,重开未显式开始 4.5s 内不翻页;重复、旧 owner 与旧 revision 注入不改变路径。
WP30 在真实预览 artifact(127.0.0.1:8000 桥接 iframe)和 4.2 秒有声 WebM 上完成 A18–A24:媒体结束后 3839ms 翻页(素材 4200ms);无媒体回退 1590ms;有声非静音实际播放(audioTracks=1);注入受阻后显示重试/下一页/停止并可恢复;失效资源返回真实错误、超时进入暂停、下一页可回放;暂停后跳页保持暂停且离开页无残留播放。演讲者模式下观众窗口唯一调度,媒体结束推进到下一页,控制台隐藏不影响观众,观众隐藏暂停并需显式继续,关闭观众后控制台回显已关闭并暂停。A24 截图成功(1280×720、36740 字节,画面为媒体暂停首帧),槽位在任务期间 busy 且出现 5 个 Chromium/Node 后代进程,取消与期限任务结束后恢复 idle、后代进程和临时产物清零;期限失败为 RENDER_ASSET_NOT_READY。CLI(wp)与 MCP(生产 binding/AsyncApiClient)均在能力开放后的真实 Backend 完成项目默认值与路由覆盖的 media_end 读改写回滚,未回写只读生效值。Firefox/WebKit、移动端行内播放与真实远端无人值守仍不在已支持范围。
5. M3:本地构建产物长稳
| 编号 | 场景 | 通过条件 |
|---|---|---|
| L01 | 真实构建产物与本地入口 | 普通用户鉴权下载 ZIP,SHA-256 与构建记录一致;按产物 base_url 启动本机静态服务,入口、路由、资源、字体和放映配置可达;不使用预览 artifact、Runtime 开发服务器或远端代理 |
| L02 | 至少 60 分钟多页循环 | 可见页面按配置顺序循环,无旧事件推进、重复调度或持续资源增长;记录 JS 堆、DOM、监听器、媒体元素、计时器和浏览器进程 |
| L03 | 防休眠与恢复 | Screen Wake Lock 获得或权限拒绝时普通放映;隐藏、freeze/pageshow、本地服务中断重试和浏览器重载后按显式步骤恢复,不连跳、不无限重试;退出释放锁与媒体 |
| L04 | 支持边界与证据 | 记录代码版本、设备/浏览器/服务形态、实际命令、通过项和未运行项;一次演练不扩展为所有设备全天承诺 |
具体长稳数据、支持矩阵和未覆盖项见 WP33 实施记录。2026-10-18 的最终演练使用构建任务 13(SHA-256 73580772e85a0f75aa3f783f9ae2b4c7b0c5894d6fd2285ead8d6eadb12807de),在有头 Chromium 148.0.7778.96(Playwright 1.60.0,1280×720,Windows 10.0.26300 x64)和本机静态服务上连续运行 61.08 分钟:61 次采样、553 次自动翻页(约 138 轮);JS 堆 8.4→8.4MB、浏览器进程树 RSS 704.2→703.5MB、DOM 139–141、监听器低水位 66→66、活动计时器最大 3、媒体元素最大 2,外部点击/按键 0;隐藏 15 秒、冻结/pageshow 20 秒、本地服务中断重试和浏览器重载均按显式步骤恢复,全部检查通过。M3 只关闭本地验证门槛,不开放产品级远端无人值守、构建访问代理或公开发布能力。
5.1 全屏放映统一模型补充(2026-10-18)
| 编号 | 场景 | 通过条件 |
|---|---|---|
| F01 | 预览与进入/退出全屏 | 预览无控制器、无控制条、无自动计时;进入全屏即开始放映;退出全屏停止计时和媒体并回到预览;全屏失败留在预览并提示 |
| F02 | 自动/手动切换 | auto_start 决定初始模式;自动切手动取消计时但媒体继续;手动切自动按当前页重新计时/等待媒体;manual 页不自动推进;手动末页不绕回 |
| F03 | 全屏控制条与键盘 | 控制条提供上一页/自动手动/下一页/页码/状态/剩余时间/演讲/退出,默认收起、指针进入底部区域显示、移开隐藏,暂停/错误/结束态保持显示;预览与放映均支持 →/↓/PageDown/空格下一页、←/↑/PageUp 上一页、Home/End 首末页、数字键跳页;预览另有 O 卡片模式、F 进入放映、Shift+P 演讲,放映保留 Shift+P;无双重触发;不拦截 F11,F11/浏览器菜单全屏不进入放映 |
| F04 | 演讲者模式 | 观众窗口唯一调度;预览工具栏或放映控制条均可进入,预览入口按项目 auto_start 起步、放映入口继承当前模式;必须全屏后才开始;观众只读;控制台传输栏切换自动/手动并同步;退出全屏暂停并提示;控制台键盘不受观众全屏门禁限制,重开观众窗口按项目 auto_start 初始化 |
自动化证据:Runtime 全量 143 个测试文件、1121 通过、3 跳过(pnpm --dir runtime test),pnpm --dir runtime check 与改动文件 ESLint 通过;覆盖虚拟时钟自动/手动语义、媒体继续、控制条命令、预览/全屏布局归属、工具栏按钮聚焦时方向键翻页、协议 v3 与观众全屏门禁。
真实桌面 Chromium 证据(2026-10-18,有头 Chromium 148.0.7778.96 / Playwright 1.60.0 / Windows 10.0.26300 x64 / 1280×720):node .tmp/fullscreen-playback/verify.mjs 通过 38/38 项,覆盖 F01–F04。关键结果:预览无控制条且 1.8s 内不推进;进入全屏即开始会话并显示自动剩余时间;自动切手动停住、切回自动按当前页重新计时后翻页;手动配置页显示“本页手动”且会话仍为自动;空格在自动/手动间切换,方向键翻页,工具栏按钮聚焦后方向键仍有效;退出全屏控制条消失且无后台推进,重新进入从当前页开始;演讲者模式观众窗口唯一调度,继承手动模式,控制台切换自动后观众按 1500ms 推进,切回手动后停住,观众键盘不翻页;观众退出全屏后控制台等待重新全屏、播放保持暂停,重新全屏后“继续”恢复;退出演讲回预览且无残留控制条。证据为 .tmp/fullscreen-playback/evidence.json 与截图 01–09。未验证:观众窗口 getScreenDetails 多屏授权(使用“当前窗口全屏”回退)、Firefox/WebKit、移动端;旧 M3 长稳不作为全屏入口证据。
键盘口径更新(2026-10-18,晚于上方浏览器证据):放映态空格改为下一页,新增 Home/End、数字键跳页、↑/↓ 翻页、O 卡片模式与 F 进入放映;键位集中在 runtime/src/runtime-shell/keyboard/keyboard-map.ts,usePlaybackHost 不再注册键盘监听。该变更由 keyboard-map、ResponsiveLayout、usePlaybackHost 单测与组件测试覆盖,未重跑上方真实浏览器脚本;“空格在自动/手动间切换”一条为变更前记录。
文档口径与已知行为(2026-10-18 复核):F11/浏览器菜单全屏不写 document.fullscreenElement,不进入放映,也不被页面拦截;页面内元素全屏期间放映继续,退出该元素全屏后 Chromium 不恢复根全屏,按退出全屏结束并回预览。这两项属于实现行为,本轮未单列浏览器用例;观众窗口重开不继承临时模式、控制台键盘不受观众全屏门禁限制为设计意图,详见全屏放映统一模型规划 §12。控制条悬停唤出由组件测试覆盖(PlaybackHostBridge.test.ts 5 项通过),未重跑上方真实浏览器 38 项。
6. 兼容与发布
| 组合 | 预期 |
|---|---|
| 新 Runtime + 旧 artifact/旧配置 | 不启动自动推进、不误启动;全屏时控制条只显示“当前项目未启用放映配置”和退出,不渲染翻页与自动/手动按钮,翻页依赖方向键/PageUp/PageDown |
| 新 Backend + 旧客户端 | 可读取新增字段;匹配节点整树更新保留覆盖;新模式需能力检测 |
| 新客户端 + 旧 Backend | 新参数返回明确不支持或校验失败,不能伪装保存成功 |
| 新 Backend 配置 + 旧 Runtime 执行池 | 不验收为支持;发布前升级配套 Runtime 或阻止开放新能力 |
| 新模板导入器 + schema 1/2/3 | 三版本均接受,旧包补默认;schema 3 保留原始覆盖 |
| 旧模板导入器 + schema 3 | 明确拒绝,不静默丢失放映字段 |
配置快照、Runtime 构建身份和能力版本一起记录;已有历史 artifact 不重写。发布前完成迁移备份、同版部署验证和回滚说明,旧应用回滚不等于新模板/新配置可被旧版本完整编辑。
7. 证据与检查清单
- [x] M0:接口正反例、SQLite/PostgreSQL 迁移、类型生成、预览/构建配置对拍和模板往返报告(2026-10-17,证据见 WP12 实施记录 与
.tmp/wp12/)。 - [x] M1:控制器单测、Editor 表单验证、真实浏览器计时记录、实际 PNG/PDF/PPTX 与客户端往返证据(2026-10-17,WP13–WP21;证据见
.tmp/wp16/、.tmp/wp17/、.tmp/wp18/、.tmp/wp19/、.tmp/wp20/、.tmp/wp21/)。 - [x] M2:媒体播放结果、权限失败、双窗口消息/状态记录与 Renderer 生命周期清理报告(2026-10-18,WP22–WP30;证据见 WP30 实施记录 与
.tmp/wp30/)。 - [x] M3:通过普通用户鉴权下载真实构建产物 ZIP,本地解压并按产物 base 启动静态服务,至少一次持续 60 分钟的多页循环;记录防休眠、休眠/唤醒、本地服务或浏览器恢复与资源占用;不使用预览 artifact 或 Runtime 开发服务器;远端构建访问入口、票据/Cookie 与代理不在 M3 范围,由独立代理服务另行验收;完成前不承诺产品级无人值守。(2026-10-18,WP31–WP33;证据见 WP33 实施记录 与
.tmp/wp31/、.tmp/wp32/browser/、.tmp/wp33/soak/)
证据写入专属 .tmp/ 或 test-results/ 子目录,不提交可再生成的大文件。报告记录提交版本、浏览器/运行环境组合、实际命令、通过/失败数量、失败原因与未运行项。
测试选择、服务复用、E2E 准备、全量门禁和真实渲染命令统一使用 dev-start-test及其测试矩阵。实现阶段按模块逐步验证,跨端发布前执行主全量门禁并补齐对应专项;本次纯文档变更仅执行仓库文档/边界检查。