| @@ -0,0 +1,4 @@ | |||||
| # These generated reports attest exact artifact bytes with SHA-256. Preserve | |||||
| # their original line endings on Windows and Linux, including embedded bundles. | |||||
| reports/model-editor-closure-20260906/** -text -whitespace | |||||
| reports/scene-editor-closure-20260906/** -text -whitespace | |||||
| @@ -0,0 +1,19 @@ | |||||
| import { defineConfig } from '@playwright/test' | |||||
| export default defineConfig({ | |||||
| testDir: './tests', testMatch: 'model-editor-*closure.spec.ts', | |||||
| outputDir: './reports/model-editor-closure-20260906/test-results', | |||||
| workers: 1, fullyParallel: false, retries: 0, timeout: 180_000, | |||||
| expect: { timeout: 25_000 }, | |||||
| reporter: [ | |||||
| ['list'], | |||||
| ['html', { outputFolder: 'reports/model-editor-closure-20260906/playwright', open: 'never' }], | |||||
| ['json', { outputFile: 'reports/model-editor-closure-20260906/results.json' }], | |||||
| ], | |||||
| use: { | |||||
| baseURL: 'http://127.0.0.1:6180', browserName: 'chromium', channel: 'msedge', headless: true, | |||||
| locale: 'zh-CN', timezoneId: 'Asia/Shanghai', viewport: { width: 1920, height: 1080 }, | |||||
| navigationTimeout: 60_000, actionTimeout: 25_000, | |||||
| screenshot: 'only-on-failure', trace: 'off', video: 'off', | |||||
| }, | |||||
| }) | |||||
| @@ -0,0 +1,48 @@ | |||||
| # 装备模型编辑器闭环验收报告 | |||||
| 打开 [index.html](index.html)。本报告区分源码实现、单元/合同测试、真实接口、浏览器 UI 与脚本调用运行时,不把截图或套件总通过数替代逐功能验证。 | |||||
| 从 `ute2e` 目录生成: | |||||
| ```sh | |||||
| node tools/build-model-editor-closure-report.mjs | |||||
| ``` | |||||
| - `feature-catalog.json`:103 个实际可达功能的源码位置、边界、修复和验收要求。 | |||||
| - `coverage.json`:生成时逐项关联当前证据的矩阵。 | |||||
| - `results.json`:最终 Playwright JSON 原始结果。 | |||||
| - `run-history.json`:首轮失败和定向重跑的安全摘要;只含次数、标题、时间与源文件哈希,保留失败事实,不用定向重跑替换全量结果。 | |||||
| - `validation.json`:最终构建、单元测试等验证记录;`e2eComplete: true` 标记最终轮已完成。 | |||||
| - `evidence/*.json`:经过脱敏的真实 API、运行时及界面断言记录。 | |||||
| - `screenshots/*`:真实截图,报告自动枚举全部 PNG/JPEG/WebP。 | |||||
| - `screenshot-captions.json`:以文件名或不含后缀文件名为键,值为 `{ "title": "图名", "description": "实际证明的范围" }`。 | |||||
| - `screenshot-verification.json`:每张图片与当前 `results.json` 正式附件的 SHA256 比对;同名重拍或预跑图不自动计当前轮通过。 | |||||
| - `cleanup.json`:临时测试数据的清理或保留记录。 | |||||
| - `artifact-checks.json`:四仓库变动及本轮报告的凭据/令牌、ZIP内元数据和图片文本元数据扫描;`finalArtifactScan: true` 才表示最终文件已扫描,初查不替代最终验收。 | |||||
| - `data/inventory-main.md`:修复前只读基线及本轮源码实现记录。 | |||||
| - `data/final-corrections.json`:只读查看交互与连接健康检查补修的解释和边界;`data/kingbase-validation-probe-result.json` 只含脱敏探针结果,不含连接信息或凭据。 | |||||
| 证据推荐格式(仅示例,不是实际通过声明): | |||||
| ```json | |||||
| { | |||||
| "time": "真实执行时间", | |||||
| "data": { | |||||
| "title": "当前曲线编辑与刷新", | |||||
| "status": "PASS", | |||||
| "kind": "e2e", | |||||
| "testTitle": "与 results.json 完全对应的真实用例名称", | |||||
| "featureIds": ["timeline.curve", "curve.time", "curve.value", "curve.easing"], | |||||
| "details": "记录真正执行和断言的内容,不按同类功能推测覆盖", | |||||
| "screenshots": ["screenshots/实际文件.png"] | |||||
| } | |||||
| } | |||||
| ``` | |||||
| `kind` 应明确使用 `e2e`、`api`、`runtime` 或 `unit`,不要把通过脚本调用编辑器方法说成纯 UI 操作。带 `testTitle` 的证据会与当前 Playwright 结果按完整标题及执行时间交叉核对;对应用例不存在、失败,或证据来自不同时段时,不能标为本轮通过。未关联证据的功能保持待验证。 | |||||
| 全量首轮的 17/19 和随后仅两条定向重跑的 2/2 不可相加后改写成“全量19/19通过”。必须另跑完整套件,保留新的完整 `results.json` 以及匹配时段证据;历史503的诊断判断和已证明的因果关系要分开陈述。 | |||||
| 总状态只有在结果最终完成、最终验证通过、无失败、全矩阵都有证据且最终交付物扫描通过时才为 PASS;已执行用例通过但仍有未覆盖功能时,会如实显示待验证范围。组件运行系统、完整三维离线包、下游自动执行模型动作属于三项另行确认的范围,不应虚构完成证据。 | |||||
| 此目录不得存入账号文件、密码、令牌、cookie、私有 fixtures、原始服务日志或数据库备份。原始 PDF 只相对链接至工作区 `文档`,不复制全文。 | |||||
| @@ -0,0 +1,81 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:34:43.610816+00:00", | |||||
| "status": "PASS", | |||||
| "secretScan": "PASS", | |||||
| "phase": "final", | |||||
| "finalArtifactScan": true, | |||||
| "scope": "四个仓库相对 HEAD 的变动/新增文件与本轮完整报告;真实本地账号密码精确匹配、可解码 JWT、ZIP/Playwright 内嵌报告逐项解压扫描及 PNG 文本元数据。输出不包含任何命中值或附近正文。", | |||||
| "baselinePolicy": "只排除 HEAD 已存在且邻近至少64字符完全一致的普通源码/固定库字符串(统一CRLF/LF);新哈希模型bundle另允许至少25个邻近词元在仅归一化压缩变量名后完全一致,且命中须为更长固定常量的子串、不能是完整密码值。唯一经本轮复核的配置例外是 ut_auth/src/main/resources/application.yml 的 bootstrap-admin-password 环境变量默认项:文件、键、整行须与 HEAD 完全相同,且新旧文件各只出现一次;改值、改变量名、复制到其他文件或新增同一行均仍失败。其他真实凭据赋值与ZIP内元数据不作排除。Playwright静态库对比HEAD上一轮报告壳。", | |||||
| "limitations": [ | |||||
| "图片仅扫描可读元数据,不执行OCR;图像正文由浏览器报告视觉QA核对。", | |||||
| "只扫描本轮交付范围,不声称已审计整个历史仓库。", | |||||
| "初查通过不代表最终结果文件已完成,最终需 --final 再执行。" | |||||
| ], | |||||
| "selfChecks": { | |||||
| "status": "PASS", | |||||
| "tests": 15 | |||||
| }, | |||||
| "repositoryHeads": { | |||||
| "unreal_tran": "d16184acf1686bb4a6ad44949d0587c5373ffbde", | |||||
| "unreal_tran_web": "3f39e2c94df9cdadf3545ae14bf0df41f2c37bf1", | |||||
| "unreal_tran_api": "71df00dffa39a8f49a4f0654969a3014c2f78f67", | |||||
| "ute2e": "b3d4ce8ffd8144090c18c8a28f5ca824170042c8" | |||||
| }, | |||||
| "changedFileCounts": { | |||||
| "unreal_tran": 14, | |||||
| "unreal_tran_web": 8, | |||||
| "unreal_tran_api": 15, | |||||
| "ute2e": 184 | |||||
| }, | |||||
| "deletedFileCounts": { | |||||
| "unreal_tran": 0, | |||||
| "unreal_tran_web": 2, | |||||
| "unreal_tran_api": 0, | |||||
| "ute2e": 0 | |||||
| }, | |||||
| "textArtifactsScanned": 104, | |||||
| "pngMetadataFilesScanned": 122, | |||||
| "archives": [ | |||||
| { | |||||
| "file": "ute2e/reports/model-editor-closure-20260906/playwright/index.html!embedded-report-1.zip", | |||||
| "entries": 7, | |||||
| "textEntries": 7 | |||||
| } | |||||
| ], | |||||
| "finalInputs": { | |||||
| "results.json": true, | |||||
| "validation.json": true, | |||||
| "cleanup.json": true, | |||||
| "playwright/index.html": true | |||||
| }, | |||||
| "finalInputSha256": { | |||||
| "results.json": "f37013658c8c38a5ec5993e636a30ad57eee9d3bcc119650c929952de8d556e9", | |||||
| "validation.json": "6e0e87d0df73061bc8549d3405f03731fecf077d7425f52eeed45008f7d09959", | |||||
| "cleanup.json": "ab2776afa143d9937651daa8fa18b531a3fb84c703f5f5b0918930e78c76eb26", | |||||
| "playwright/index.html": "92dcca3fe570530bde973b9e09199c064fc2b343bb6f8a21b67fb3c72b8949ed" | |||||
| }, | |||||
| "unchangedBaselineExclusions": [ | |||||
| { | |||||
| "file": "unreal_tran_api/ut_auth/src/main/resources/application.yml", | |||||
| "baseline": "unreal_tran_api/HEAD:ut_auth/src/main/resources/application.yml", | |||||
| "occurrences": 1 | |||||
| }, | |||||
| { | |||||
| "file": "unreal_tran_api/wiki/11-内容制作模块.md", | |||||
| "baseline": "unreal_tran_api/HEAD:wiki/11-内容制作模块.md", | |||||
| "occurrences": 17 | |||||
| }, | |||||
| { | |||||
| "file": "unreal_tran_web/public/legacy-model-editor/assets/editor-BAqfQ3VC.js", | |||||
| "baseline": "unreal_tran_web/HEAD:public/legacy-model-editor/assets/editor-CunHwJSa.js", | |||||
| "occurrences": 1 | |||||
| }, | |||||
| { | |||||
| "file": "ute2e/reports/model-editor-closure-20260906/playwright/index.html", | |||||
| "baseline": "ute2e/HEAD:reports/role-permissions-20260906/playwright/index.html", | |||||
| "occurrences": 1 | |||||
| } | |||||
| ], | |||||
| "unscannedBinaryFiles": [], | |||||
| "findings": [] | |||||
| } | |||||
| @@ -0,0 +1,428 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:27:13.581Z", | |||||
| "status": "PASS", | |||||
| "originals": [ | |||||
| { | |||||
| "id": "157", | |||||
| "name": "实测模型-狐狸动画-已验证-20260905", | |||||
| "version": 15, | |||||
| "unchanged": true | |||||
| }, | |||||
| { | |||||
| "id": "156", | |||||
| "name": "实测模型-牛奶卡车-已验证-20260905", | |||||
| "version": 20, | |||||
| "unchanged": true | |||||
| }, | |||||
| { | |||||
| "id": "94", | |||||
| "name": "桥梁架设装备整机模型", | |||||
| "version": 253, | |||||
| "unchanged": true | |||||
| } | |||||
| ], | |||||
| "projects": [ | |||||
| { | |||||
| "id": "168", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "169", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "170", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "171", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "172", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "173", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "174", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "175", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "176", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "177", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "178", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "179", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "180", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "181", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "182", | |||||
| "alreadyAbsent": true | |||||
| }, | |||||
| { | |||||
| "id": "183", | |||||
| "name": "闭环导航名称-183", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "184", | |||||
| "name": "闭环验收-资源往返-mtph19ll", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "185", | |||||
| "name": "闭环验收-三维手柄-1788678747289", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "186", | |||||
| "name": "闭环验收-离开保护-1788678780620", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "187", | |||||
| "name": "闭环验收-恢复副本-mtph6hw8", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "188", | |||||
| "name": "闭环验收-加载与预检-mtph6ubj", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "189", | |||||
| "name": "闭环验收-三维手柄-1788678838243", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "190", | |||||
| "name": "闭环验收-离开保护-1788678850196", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "191", | |||||
| "name": "闭环工具补充-卡车控件-mtpha049", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "192", | |||||
| "name": "闭环工具补充-卡车控件-mtphbg8t", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "193", | |||||
| "name": "闭环工具补充-基准匹配-mtphbpqq", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "194", | |||||
| "name": "闭环工具补充-卡车控件-mtphfk1m", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "195", | |||||
| "name": "闭环工具补充-基准匹配-mtphfu32", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "196", | |||||
| "name": "闭环验收-资源往返-mtphjhoi", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "197", | |||||
| "name": "闭环验收-拒绝非法资源-mtphjv5x", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "198", | |||||
| "name": "闭环验收-保存失败恢复-mtphk0kk", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "199", | |||||
| "name": "闭环验收-发布封面版本-mtphk960", | |||||
| "withdrawn": true, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "200", | |||||
| "name": "闭环工具补充-卡车控件-mtphkrbz", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "201", | |||||
| "name": "闭环工具补充-基准匹配-mtphkzlj", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "202", | |||||
| "name": "闭环新建-1788679561949", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "203", | |||||
| "name": "闭环验收-三维手柄-1788679613072", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "204", | |||||
| "name": "闭环验收-离开保护-1788679623529", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "205", | |||||
| "name": "闭环补充-资源库-mtphobxb", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "206", | |||||
| "name": "闭环补充-内置环境-mtphomov", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "207", | |||||
| "name": "闭环导航名称-207", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "208", | |||||
| "name": "闭环验收-恢复副本-mtphpz7v", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "209", | |||||
| "name": "闭环验收-加载与预检-mtphq9y1", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "210", | |||||
| "name": "闭环验收-离开保护-1788681347476", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "211", | |||||
| "name": "闭环补充-内置环境-mtpip60q", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "212", | |||||
| "name": "闭环验收-资源往返-mtpjbnl2", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "213", | |||||
| "name": "闭环验收-拒绝非法资源-mtpjbyqo", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "214", | |||||
| "name": "闭环验收-保存失败恢复-mtpjc2vu", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "215", | |||||
| "name": "闭环验收-发布封面版本-mtpjcafv", | |||||
| "withdrawn": true, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "216", | |||||
| "name": "闭环工具补充-卡车控件-mtpjcof8", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "217", | |||||
| "name": "闭环工具补充-基准匹配-mtpjcvxe", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "218", | |||||
| "name": "闭环新建-1788682528069", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "219", | |||||
| "name": "闭环验收-三维手柄-1788682536810", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "220", | |||||
| "name": "闭环验收-离开保护-1788682545004", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "221", | |||||
| "name": "闭环补充-资源库-mtpjesgj", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "222", | |||||
| "name": "闭环补充-内置环境-mtpjezfi", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "223", | |||||
| "name": "闭环导航名称-223", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "224", | |||||
| "name": "闭环验收-恢复副本-mtpjg6y2", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "225", | |||||
| "name": "闭环验收-加载与预检-mtpjgfnd", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "226", | |||||
| "name": "闭环验收-资源往返-mtpjkcpq", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "227", | |||||
| "name": "闭环验收-拒绝非法资源-mtpjko7g", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "228", | |||||
| "name": "闭环验收-保存失败恢复-mtpjkshn", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "229", | |||||
| "name": "闭环验收-发布封面版本-mtpjkzt1", | |||||
| "withdrawn": true, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "230", | |||||
| "name": "闭环工具补充-卡车控件-mtpjlf69", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "231", | |||||
| "name": "闭环工具补充-基准匹配-mtpjlmiy", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "232", | |||||
| "name": "闭环新建-1788682938712", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "233", | |||||
| "name": "闭环验收-三维手柄-1788682951454", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "234", | |||||
| "name": "闭环验收-离开保护-1788682960426", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "235", | |||||
| "name": "闭环补充-资源库-mtpjnoh9", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "236", | |||||
| "name": "闭环补充-内置环境-mtpjnv0t", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "237", | |||||
| "name": "闭环导航名称-237", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "238", | |||||
| "name": "闭环验收-恢复副本-mtpjp3nr", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| }, | |||||
| { | |||||
| "id": "239", | |||||
| "name": "闭环验收-加载与预检-mtpjpdaj", | |||||
| "withdrawn": false, | |||||
| "removed": true | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,55 @@ | |||||
| # 全功能证据映射与未覆盖规划 | |||||
| 本文件是测试设计与源码断言核对,不是执行通过证据。最终结果由 `results.json`、`validation.json`、`evidence/*.json` 与 `coverage.json` 决定。 | |||||
| ## 已校准的浏览器脚本 | |||||
| |脚本|实际范围|证据边界| | |||||
| |---|---|---| | |||||
| |model-editor-closure.spec.ts|属性数值、PBR首槽、扩展标记、保存重开、撤销重做、视图开关/原生片段、新建/权限|已删除不存在的 object.* / viewport.* / permissions.* ID;变换模式按钮不等同真实 gizmo 拖拽,不能代填 view.move/rotate/scale| | |||||
| |model-editor-assets-closure.spec.ts|主模型/外部环境真实上传、JSON往返、无效导入、保存失败和重试、发布封面/固定版本/离线步骤HTML|异常通过定向请求中断注入;恢复副本“存在”不等于恢复/隔离/下载全部UI已测;固定版本可取得不等于下游自动运行| | |||||
| |model-editor-blueprint-closure.spec.ts|真实轨道/帧/曲线/蓝图库/接线/剪贴板/执行控制、真实点击/双击/auto事件;另有刻度/按键/录帧/分量、基准动作匹配/不匹配、搜索拖入/工具栏添加/画布操作专项|条件真假出口的补充检查标记为 runtime;第4专项才覆盖搜索/拖入和曲线分量路径断言,不把第1例仅切换选择器当成已验| | |||||
| |model-editor-navigation-closure.spec.ts|独立原模型157副本;资源搜索/卡片切换、三内置环境保存重开、折叠树、鼠标镜头/聚焦、页签/分割条/Tab、预览±2秒/Esc、日志/统计、名称保存/真实30秒自动保存|三项真实用例已在私有预跑通过,截图41~47;此预跑不替代最终results,最终统一结果仍须核对| | |||||
| |model-editor-interaction-closure.spec.ts|真实三维 gizmo 平移/旋转/缩放,撤销重做、保存重开;离开时关闭确认、保存失败保留、重试成功再离开|独立副本;只读投影定位手柄,不脚本改变模型姿态;注入503验证失败分支| | |||||
| |model-editor-recovery-closure.spec.ts|同版本真实未存恢复→显式保存、旧版本下载隔离;受控GLB下载失败→UI重试、预检开关无写入和错误资源导入拒绝|恢复稿来自真实beforeunload,不预注入localStorage;较新服务端内容不被旧稿覆盖;服务端发布严格合同另由API测试验证| | |||||
| 首批四份脚本显式计划关联 **88/103** 个功能 ID;随后新增交互/恢复两份脚本补上其中 7 项,时间轴/蓝图专项补 7 项,最终六份脚本显式关联 **102/103** 个功能 ID,多轨计算以明确 unit 证据关联。全部 ID 与 catalog 对齐,未发现未知 ID。这里记录的是“已写断言计划”,不是最终通过数;最终结果以 coverage.json 为准。 | |||||
| 后续并行补测分工:时间轴/蓝图专项负责 `timeline.seek/record/baseline`、`curve.axis`、`blueprint.palette/add/canvas`;资产专项负责恢复稿/加载失败/发布预检;宿主专项负责真实 gizmo 拖拽与离开确认。`timeline.multitrack` 以真实计算方法单元测试作独立证据,映射在 [unit-coverage-plan.json](data/unit-coverage-plan.json),该计划文件本身不代表通过。最终生成器按实际证据动态计算,下面保留补测前的差距,便于对照补测来源。 | |||||
| ## 补测前的15项差距(追溯记录) | |||||
| |功能 ID|补测前已有的验证|据此安排的补测范围| | |||||
| |---|---|---| | |||||
| |project.recovery|本轮 API 指纹回归与真实 beforeunload 方法回归:键顺序相同内容不写假稿;真实变化仍保留;现有 API 恢复合同|用户明确恢复/放弃/隔离/下载的真实对话框;同版本真实修改与旧版本分叉| | |||||
| |project.leave|上一轮角色/权限回归及宿主聚焦合同|本轮模型编辑器脏状态取消、放弃、保存失败与上传忙时离开;不能用干净页面切路由代替| | |||||
| |resource.loading|启动后readyFrame状态;本轮renderAssets真实DOM空目录/卡片回归|GLB下载或解析失败后中性失败状态、重试成功;不能把未加载空白当成功| | |||||
| |view.move|属性XYZ保存重开;多轨中性基值单测|真实TransformControls平移手柄拖动、保存重开;当前只点击W模式| | |||||
| |view.rotate|旋转数值输入保存;多轨旋转单测|真实旋转环拖动及撤销重做;当前只点击E模式| | |||||
| |view.scale|缩放数值输入保存重开|真实缩放手柄拖动及保存;当前只点击R模式| | |||||
| |timeline.seek|时间轴拖帧触发timechange合同;键盘/seek运行时已有回归|真实播放头/刻度点击、左右/Shift按键、时间码与视口同步| | |||||
| |timeline.record|主类addKeyframeFromSelection源码已接;中性姿态单测|真实“记录关键帧”按钮捕获当前帧偏移,保存后回放一致| | |||||
| |timeline.multitrack|本轮main实际capture/apply方法单测:最后有效轨道、静音/删除/重绑、保存基值|可用unit证据明确覆盖计算合同;需要多轨真实视口可见性截图时另加UI,不能冒称已拍| | |||||
| |timeline.baseline|既有装备profile/动作生成合同|有匹配实际载入并保存;无匹配保留数据;当前没有单独确认框,不能写“取消验证通过”| | |||||
| |curve.axis|现有UI只选Y再选X;向量其他分量保持的unit回归|修改不同轴数值后切显示轴,断言曲线变化且不改其他数据| | |||||
| |blueprint.palette|当前点选创建七类型节点|搜索/清空、HTML5拖入节点,不能用脚本addNode冒充拖放| | |||||
| |blueprint.add|当前节点库点选与节点新增unit|工具栏“添加节点”确实新增默认提示节点并进入历史/JSON| | |||||
| |blueprint.canvas|现有用例点击“适应画布”;节点自身拖动|蓝图画布滚轮缩放、Space平移/适应,并验证节点图数据未意外变化| | |||||
| |publish.preflight|发布API拒绝非法资源/固定版本合同;当前面板打开并真实发布|界面校验清单和服务端阻断对应,打开/关闭不改变工程;不能仅凭绿标判定有效| | |||||
| ## 已有测试中的局部限制 | |||||
| - `property.identity` 新增可见性/阴影真实DOM回归;补充UI目前检查只读标识与流程绑定字段。权限注入的“只读”标签需由宿主最终用例确认。 | |||||
| - `timeline.drag-key` 已有真实拖动与碰撞合同,Alt取消吸附尚未单独通过浏览器验证。 | |||||
| - `blueprint.move` 有单节点真实拖动与全选剪贴板;多选框选拖移并未单独截图。 | |||||
| - `blueprint.highlight` 有真实执行与缺目标/隐藏目标/临时材质单测;呼吸幅度当前不是像素级曲线验收。 | |||||
| - `publish.cover` 的真实成功上传、版本、封面URI已测;503/409失败保旧图由独立API合同补充,不能称该真实服务自然出现503。 | |||||
| - `selection.scope` 补充用例增加明确整机根/部件对象断言;仍需避免把仅点击按钮当成三维目标操作。 | |||||
| ## 本轮新增阻断回归 | |||||
| 1. 资源库启动:真实DOM复现两处单节点选择器误用后修复,覆盖卡片绑定/空目录。 | |||||
| 2. 保存后刷新假恢复稿:真实175快照逐字段无差异,仅environment键顺序不同;指纹统一递归排序对象键,保留数组顺序和真实值变化;beforeunload假稿/真稿均有回归。 | |||||
| 3. 状态标签:真实DOM验证隐藏祖先及castShadow;宿主通过span[data-model-editability]显示会话权限。 | |||||
| 以上属于修复和证据分层,不新增 solo,也不把组件运行系统、完整离线三维包、下游自动运行三项待确认范围伪装成已实现。 | |||||
| @@ -0,0 +1,43 @@ | |||||
| { | |||||
| "kind": "implementation-notes", | |||||
| "scope": "补修说明与已确认的聚焦验证;不替代最终完整浏览器结果、后端构建或最终验证记录。", | |||||
| "items": [ | |||||
| { | |||||
| "title": "只读模型的搜索、原生动画选择与键盘预览", | |||||
| "problem": "权限桥误把查看控件的键盘交互当成内容编辑,导致只读用户不能在搜索框输入、切换原生动画或按 Enter 进入预览。", | |||||
| "change": "按实际查看控件放行键盘输入/选择/激活;模型编辑、内容上传/保存/发布仍依对应权限阻断。", | |||||
| "validation": "真实 DOM 权限桥 14/14 通过;最终完整19条E2E全部通过,其中管理员用例验证真实键盘搜索、原生动画切换与Enter播放/暂停,期间没有内容写请求,直接创建接口返回403。", | |||||
| "featureIds": [ | |||||
| "project.permissions", | |||||
| "resource.search", | |||||
| "tree.search", | |||||
| "timeline.native", | |||||
| "view.preview" | |||||
| ], | |||||
| "source": "../../../unreal_tran_web/src/features/editors/model/legacy-iframe-permissions.ts", | |||||
| "testSource": "../../tools/content-permissions.test.mjs" | |||||
| }, | |||||
| { | |||||
| "title": "Auth / Tran 连接有效性检查增加时限与空闲保活", | |||||
| "problem": "数据库连接健康检查可能在驱动网络读取上长时间阻塞,拖住借用连接的请求;不能据此把每个历史503都逐条归因为此缺陷。", | |||||
| "change": "两个模块统一使用有时限的 SELECT 1 健康检查,默认临时网络时限 2 秒;检查结束恢复原连接超时,开启空闲检查和保活。已有普通业务 SQL 超时策略不变。", | |||||
| "validation": "实际 Kingbase 驱动隔离探针:正常检查 12ms,原0ms和原7000ms网络超时均恢复;隔离网络黑洞约2010ms抛出 SocketTimeoutException 并关闭连接。探针不是整个平台可用性测试,后端打包和全量E2E结果另记。", | |||||
| "source": "../../../unreal_tran_api/ut_auth/src/main/java/com/unrealtran/auth/config/BoundedConnectionValidator.java", | |||||
| "secondSource": "../../../unreal_tran_api/ut_tran/src/main/java/com/unrealtran/tran/config/BoundedConnectionValidator.java", | |||||
| "evidence": "data/kingbase-validation-probe-result.json" | |||||
| }, | |||||
| { | |||||
| "title": "曲线轨道与分量控件的可读性", | |||||
| "problem": "曲线轨道改为按钮后遗漏背景和边框样式,显示为灰底灰字;分量下拉沿用浏览器默认样式并与数值标签重叠。", | |||||
| "change": "补齐整宽暗色轨道按钮、主副文字与选中/悬停/键盘焦点样式;分量下拉使用暗色样式并定位右上。仅修改曲线面板CSS。", | |||||
| "validation": "最终浏览器轮次重新操作轨道、关键帧、五种插值和分量选择并截图;可视效果以最终22与28号截图核对。", | |||||
| "featureIds": [ | |||||
| "timeline.curve", | |||||
| "curve.easing", | |||||
| "curve.value" | |||||
| ], | |||||
| "source": "../../../unreal_tran/src/style.css", | |||||
| "evidence": "screenshots/22-truck-curve-value-five.png" | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,115 @@ | |||||
| # 装备模型编辑器闭环清单(2026-09-06) | |||||
| 本清单为只读审查基线,后续修复/验收须单独记录结果,不把源码已接通当作 E2E 已通过。 | |||||
| ## 实际入口 | |||||
| Web config/content.ts:101 默认 legacy-demo;LegacyModelEditorView.vue 使用同源 iframe 并注入权限;stage 脚本从 unreal_tran/src/main.js 打包。公开产物为 editor-CunHwJSa.js,原清单生成于 2026-09-05T10:06:01Z。正式备用 features/editors/model/DigitalTwinEditor.js 不是当前默认执行入口。 | |||||
| ## 功能逐项 | |||||
| |功能|原路径|审查基线| | |||||
| |---|---|---| | |||||
| |新建|main.js:2984|重置并 PUT 当前工程,无新增 ID;由主代理宿主改造| | |||||
| |导入 GLB|1273|受控上传、解析、最终保存,单文件 GLB| | |||||
| |导入 JSON|2829|恢复并覆盖当前工程,非服务端副本| | |||||
| |保存/Ctrl+S|2714|恢复副本、截图、队列 PUT/乐观锁| | |||||
| |自动保存|2177|30秒自动 PUT,不更新封面| | |||||
| |工程名|2134|失焦保存| | |||||
| |另存|2846|JSON 下载,不包含 GLB 字节| | |||||
| |撤销重做|158|35 个快照,缺异步互斥/失败索引回滚| | |||||
| |移动旋转缩放|2010/2215|可回存,动画基值计算有漂移| | |||||
| |聚焦|2242|相机可存| | |||||
| |网格/PBR/线框/轮廓|2217/2253|当前视图;关闭轮廓后重选泄漏| | |||||
| |透视|2217|固定透视重置,无菜单| | |||||
| |截图|3037|当前 canvas PNG| | |||||
| |预览|2254|真实三维;前后步实际跳时间轴2秒| | |||||
| |运行蓝图|1061/2189|有执行器,分支/触发有bug| | |||||
| |生成发布|2923|预检只做存在性/数量| | |||||
| |场景资源发布|2860|固定服务端版本;未直接捕获封面| | |||||
| |离线HTML|2956/io:432|截图+CSS示意+固定节拍,不是真实三维运行| | |||||
| |场景树/展开/搜索|1939|最多220行,计数为全部| | |||||
| |显示隐藏|1949|能回存;拾取未排除隐藏祖先| | |||||
| |整体部件选择|1952|可序列化| | |||||
| |装备资源切换|1440|自动保存,模板可覆盖时间轴/蓝图| | |||||
| |资源搜索|1474|多词/简称,重绘保持| | |||||
| |内置环境|775/972|可恢复车间/野外/车库| | |||||
| |外部环境GLB|1014/1802/1896|仅会话字节,重开需重选;本轮评估受控资源闭环| | |||||
| |训练场景JSON|816|无明确可达按钮,通用localStorage,不进入工程| | |||||
| |名称/变换属性|1972/2010|可回存| | |||||
| |PBR材质|1972/2010|可回存,多槽仅编辑第一槽| | |||||
| |资源编码/运行状态|1984|控件无回写,重选即丢| | |||||
| |流程绑定|1984|只读模板名称,非真实业务绑定| | |||||
| |组件|1989/2111|派生说明+持久化名称标签,无运行行为| | |||||
| |时间轴播放暂停停止循环|timeline:369|实际执行;循环可存| | |||||
| |前后关键帧/播放头|timeline:261/555|已接通| | |||||
| |轨道增删/目标/属性|timeline:444|可存,仅位置XYZ/旋转XYZ| | |||||
| |关键帧增删拖动|timeline:491|可存,默认1/30秒吸附、Alt取消| | |||||
| |记录关键帧|main:2246|从目标相对基值取值| | |||||
| |静音|timeline:239|忽略轨道但宿主不复位,保存仍扣值| | |||||
| |时间轴缩放|timeline:427|可存| | |||||
| |关键帧数值/插值|timeline:518|方法存在,曲线面板未连接| | |||||
| |基准动作|main:3003|匹配部件,替换时间轴/蓝图| | |||||
| |原生GLB动画|1709|选择播放,保存片段编号| | |||||
| |蓝图库/参数|blueprint:274/418/710|可存| | |||||
| |连线移动缩放框选删除|blueprint:522/728|可存,输入端口来源被覆盖| | |||||
| |复制粘贴|blueprint:669|只复制节点,不复制内部连线| | |||||
| |蓝图运行停止重置|blueprint:835|实际执行、200步上限| | |||||
| |点击双击自动|blueprint:898/main:2237|未匹配目标,无双击独立派发| | |||||
| |时间轴节点|main:2037|唯一当前时间轴,clip仅名称| | |||||
| |条件节点|main:2076/blueprint:867|缺truthy、布尔字符串解析,false出口缺失走任意出口| | |||||
| |高亮|main:2062|无匹配回退整机,pulse只有不同等待时长| | |||||
| |提示|main:2083|1.8/2.5秒自动继续或人工关闭| | |||||
| |曲线编辑器|1090|固定轨道/SVG/参数,无数据写回| | |||||
| |日志|3061|内存160行,非服务端审计| | |||||
| ## 已做只读原方法探针 | |||||
| - condition 返回 false,仅 true 连线:仍执行 true-only 完成节点并返回 true。 | |||||
| - trigger('click',{object:'B'}):A/B 两个目标节点时仍选择 A。 | |||||
| - 相同目标 rotation.z 两轨值 1/2:可见旋转 2,序列化基值 -1,应为0。 | |||||
| - 静音后 seek:可见姿态1、序列化基值-1,说明显示与重开存在漂移。 | |||||
| ## 本轮已授权修复与边界 | |||||
| main 负责真实曲线输入/插值、自定义属性、动画基值与静音、条件值解析、准确高亮、点击/双击/进入预览auto、隐藏拾取、轮廓、历史互斥及环境受控资源集成。新建由主代理宿主负责。Blueprint/Timeline 和内容 API/IO 各由其他代理负责。真正离线三维包与完整组件系统属于较大调整,最终确认;现有入口应明确“步骤演示 HTML(不含三维模型)”及“扩展标记,仅保存标签”。 | |||||
| 快捷键:全局 Ctrl+S/Z/Y、W/E/R、F、Tab、Esc;时间轴 Space/Delete/Backspace/左右键及Shift快进;蓝图 Ctrl/Cmd+A/C/V、Delete、Space平移、Esc、F5。当前没有模型对象的删除/复制上下文菜单。 | |||||
| ## 本轮 main 实施完成(2026-09-06,源码检查与聚焦测试,非真实 UI 验收结论) | |||||
| 上表保留修复前定位和基线;以下为实际实施后状态。源码目录 `unreal_tran/unreal_tran/src`,由正式 Web 的 stage 脚本复制并构建。未在子任务提交、推送、生成 bundle 或执行业务 E2E。 | |||||
| - 新增 `model-curve-editor.js`,曲线轨道名、关键帧点、时间、标量/向量值及插值均读取/修改当前 TimelineEditor;实际调用 updateKeyframe/selectKeyframe,随工程 JSON 重开。画面不再呈现与时间轴脱节的假控制点;本轮没有新增 Bezier 切线或 solo。 | |||||
| - 自定义资源编码、NORMAL/SERVICE 状态写入对象 customProperties;环境/模型捕获、恢复及撤销均保留明确的修改或清空。扩展标记只存名称,文案如实说明不提供运行行为。多材质对象明确显示“材质槽 1/N”。 | |||||
| - 新增 `model-editor-state.js` 统一时间轴有效偏移:同一目标同一属性采用最后一个有效轨道;静音、删轨、重绑复原此前作用对象;保存和手工变换基值只扣除实际应用偏移一次。 | |||||
| - 蓝图条件支持 truthy、布尔/数值字符串和嵌套路径比较;高亮不再找不到对象就回退整机,隐藏或重名目标反馈错误,pulse 实际调节亮度,停止恢复材质。预览临时高亮不会被自动保存为永久材质。 | |||||
| - 点击携带命中对象及祖先别名;双击单独派发 double-click;进入预览仅显式派发 auto。时间轴节点保留 clip 数据键,标签改“动作名称(播放当前时间轴)”,没有虚构原生片段选择功能。 | |||||
| - 轮廓关闭状态在重新选择/进出预览后保持;射线拾取排除隐藏祖先下面的子对象。 | |||||
| - History 保存 60 个快照,异步恢复互斥,恢复失败不移动索引;托管 GLB 历史恢复通过当前项目资产重新 materialize,避免 blob 被 JSON 清掉后撤销失败。 | |||||
| - 外部 GLB 环境调用 uploadEnvironment,保存稳定 assetCode/storageUri;刷新/JSON/恢复稿重新下载受控资源。导入最终工程提交前保持 busy;上传已登记但解析/绑定失败时阻断保存/发布,防止旧文档误覆盖新资源。 | |||||
| - 发布时捕获当前真实视口封面,使用 API 队列保存后发布;封面上传/截图失败提示保留旧封面,版本冲突阻断发布;保存/发布封面期间阻止重入。 | |||||
| - 生成面板、按钮和完成提示明确为“步骤演示 HTML(不含三维模型)”;真实离线三维包、下游自动执行蓝图、完整组件运行系统仍属于较大调整待确认。 | |||||
| ## 聚焦验证与真实 UI 待验入口 | |||||
| 1. `node --test tests/model-main-closure.test.mjs`:13/13,包含实际 TimelineEditor + happy-dom 曲线交互、工程 JSON 往返、真实主类方法提取、材质/历史/发布失败分支。 | |||||
| 2. `node --test tests/blueprint-timeline-closure.test.mjs tests/model-content-api-integrity.test.mjs`:本轮同批 32/32(各16),与 main 首次12项联合44/44;main补托管历史后单跑13/13。 | |||||
| 3. `node --test tests/model-editor-import.test.mjs tests/editor-timeline-playback.test.mjs tests/editor-delivery.test.mjs tests/model-content-api.test.mjs`:4/4脚本通过。脚本内旧“离线HTML均通过”仅说明现有步骤演示输出合同,不代表完整离线三维。 | |||||
| 4. main.js、model-curve-editor.js、model-editor-state.js 的 node --check 均通过;git diff --check 通过(仅 Git LF/CRLF 通知)。 | |||||
| 真实 E2E 由主代理执行:底部曲线页点关键帧后编辑右栏 `data-curve-field=time/value/easing`;对象属性栏 `#custom-resource-code`/`#custom-operating-status`;资源库外部 GLB 入口;顶部撤销/重做、发布面板及刷新。不得将上述单元/合同测试记作真实 API 或三维可见性截图验收。 | |||||
| ### 真实浏览器预跑暴露的启动阻断补充 | |||||
| 初次 13 项聚焦测试没有覆盖完整资源库 DOM 初始化。真实浏览器发现 renderAssets 两处误用单节点 `$` 后调用 `forEach`,使资源目录初始化抛错、整个模型启动中断。已修为节点集合 `$$`,并新增真实 DOM 回归先复现相同 TypeError,再验证两模型/五环境卡片都渲染、事件都绑定、导入忙时阻断、空目录也可启动。现在 `tests/model-main-closure.test.mjs` 为 **14/14 通过**;此回归不能替代随后正式浏览器重载验收。同类单节点选择器误用复扫无新增匹配。 | |||||
| ### 保存后刷新假恢复稿与状态标签补充 | |||||
| 真实 175 号测试副本快照逐字段比较没有语义差异,但 normalize 调整了 environment 对象的键顺序。原始 JSON.stringify 指纹因此误认为内容改变,beforeunload 在已保存页面刷新时写出同版本恢复稿。`model-content-api.js` 指纹现统一递归排序对象键,保留数组顺序和所有真实值变化;saveNow 与 dirty 比较共用该算法。新增 API 合同先复现再通过,并对真实 beforeunload 恢复方法断言“仅键顺序不写稿、真实名称变动仍写稿”。没有通过测试自动丢弃恢复稿来掩盖故障。 | |||||
| 属性状态从硬编码“可见/投射阴影”改为真实祖先可见性和 castShadow;`span[data-model-editability]` 供正式宿主按权限显示可编辑/只读。最新 main 聚焦测试 **16/16**,API integrity **17/17**;这些是阶段结果,最终统计仍以报告 validation.json 为准。 | |||||
| ### 独立补充浏览器预跑 | |||||
| 新增 `model-editor-navigation-closure.spec.ts`,每例从原狐狸模型 157 创建独立副本并登记清理 ID,不修改原始工程或共享测试狐狸。三个用例完成真实资源搜索与卡片切换、三种内置环境保存重开、树折叠/计数、实际鼠标镜头、面板切换/拖动、预览前后步与 Escape、实际 30 秒自动保存和刷新核对;私有预跑 **3/3** 通过,截图 41~47。此结果不替代最终统一 E2E,最终报告只按 results.json 及匹配 testTitle 的证据计算。更细的播放头/录帧、蓝图画布、恢复/离开和 gizmo 补测由团队分工执行。 | |||||
| @@ -0,0 +1,24 @@ | |||||
| { | |||||
| "exitCode": 0, | |||||
| "checks": [ | |||||
| { | |||||
| "case": "actual-driver-check", | |||||
| "valid": true, | |||||
| "beforeMs": 0, | |||||
| "afterMs": 0, | |||||
| "elapsedMs": 12 | |||||
| }, | |||||
| { | |||||
| "case": "actual-driver-nonzero-restore", | |||||
| "beforeMs": 7000, | |||||
| "afterMs": 7000 | |||||
| }, | |||||
| { | |||||
| "case": "actual-driver-blackhole", | |||||
| "elapsedMs": 2010, | |||||
| "closed": true, | |||||
| "exceptionType": "KSQLException", | |||||
| "causeType": "SocketTimeoutException" | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| { | |||||
| "kind": "unit-coverage-plan", | |||||
| "status": "PENDING", | |||||
| "note": "本文件只说明真实测试与功能的对应关系,不声明执行成功。最终通过状态须由 validation.json 中对应命令的退出码与测试结果确认;单元测试不等同浏览器操作。", | |||||
| "sourceFile": "../../../../unreal_tran/tests/model-main-closure.test.mjs", | |||||
| "command": "node --test tests/model-main-closure.test.mjs", | |||||
| "cwd": "unreal_tran/unreal_tran", | |||||
| "tests": [ | |||||
| { "title": "resource catalog startup renders all model/environment cards and binds every action with a real DOM", "featureIds": ["resource.catalog"], "scope": "真实 DOM 渲染、卡片绑定、空目录及 busy 保护;不包含 GLB 网络加载。" }, | |||||
| { "title": "curve edits real scalar key values, time and interpolation, persisting through document reload", "featureIds": ["timeline.curve", "curve.time", "curve.value", "curve.easing"], "scope": "真实曲线控件与 TimelineEditor,标量编辑与文档往返。" }, | |||||
| { "title": "curve vector editing preserves other components and selected track; invalid values do not mutate", "featureIds": ["curve.value"], "scope": "向量其它分量保留,当前轨道、非法值保护;不包含显示轴切换或可视像素验收。" }, | |||||
| { "title": "multiple tracks on one property use last effective value; capture subtracts it only once", "featureIds": ["timeline.multitrack"], "scope": "调用实际 apply/capture/update 基值方法;验证同属性最后有效轨道、静音/删除后中性姿态,偏移只扣一次。" }, | |||||
| { "title": "changing a binding resets the former target and keeps manual transform edits as base", "featureIds": ["timeline.multitrack", "timeline.target"], "scope": "轨道重绑后旧目标复位,手动变换成为新基值;不假称鼠标拖动已验。" }, | |||||
| { "title": "custom properties and extension labels survive actual capture, project JSON and object restore", "featureIds": ["property.code", "property.status", "component.tag"], "scope": "真实对象 capture、normalization、JSON 与 restore 往返;清空和撤销到未存在字段状态。" }, | |||||
| { "title": "boolean, numeric and nested blueprint conditions select their true/false branches", "featureIds": ["blueprint.condition"], "scope": "布尔、数字、truthy 与嵌套路径值解析。" }, | |||||
| { "title": "visible child under a hidden ancestor cannot be picked or highlighted; trigger aliases include ancestors", "featureIds": ["tree.visibility", "blueprint.highlight"], "scope": "共用可见性和祖先别名函数;鼠标事件另由 E2E 验证。" }, | |||||
| { "title": "inspector state tags reflect ancestor visibility and actual shadow flags, with a host editability hook", "featureIds": ["property.identity"], "scope": "真实属性 DOM 显示隐藏/阴影状态,并提供宿主权限标签 hook;不伪称此单测完成会话鉴权。" }, | |||||
| { "title": "history retains 60 states, truncates redo after edits and ignores duplicate snapshots", "featureIds": ["project.undo", "project.redo"], "scope": "60 个快照上限、重复状态忽略及新编辑截断 redo 分支。" }, | |||||
| { "title": "history serializes async restores and leaves index unchanged when restoration fails", "featureIds": ["project.undo", "project.redo"], "scope": "异步互斥、下载失败不移动索引,解除锁后可继续操作。" }, | |||||
| { "title": "managed-GLB history downloads the snapshot stable reference before restoring, without rewriting it", "featureIds": ["project.undo", "project.redo"], "scope": "受控 GLB 快照先物化再恢复,不把临时 URL 写回快照。" }, | |||||
| { "title": "beforeunload recovery does not create a draft for key order alone, but preserves real unsaved changes", "featureIds": ["project.recovery"], "scope": "同语义对象键顺序不产生假恢复稿;真正修改仍保留。不包含全部恢复/隔离/下载 UI 分支。" }, | |||||
| { "title": "highlight rejects missing/hidden targets and transient colors never enter a saved project", "featureIds": ["blueprint.highlight"], "scope": "目标不存在/隐藏报错,执行时暂态发光颜色不进入保存文档,结束恢复原材质。" }, | |||||
| { "title": "API publish supplies current cover, blocks duplicate publication and reports preserved old cover once", "featureIds": ["publish.api", "publish.cover", "feedback.toast"], "scope": "实际发布宿主方法传封面、重入阻断和上传失败只提示一次;模拟 API,不是实际服务响应。" }, | |||||
| { "title": "API conflict leaves publication failed and releases the cover guard", "featureIds": ["project.conflict", "publish.api", "publish.cover"], "scope": "409 分支不误报已发布并释放 busy 标记;模拟 API。" } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,154 @@ | |||||
| { | |||||
| "recordedAt": "2026-09-06T08:24:22Z", | |||||
| "kind": "manual-visual-review", | |||||
| "status": "PASS_WITH_NOTES", | |||||
| "scope": "逐张只读查看报告 screenshots 目录当前 41 张原始 PNG,并核对各自图注;没有运行业务接口、E2E,没有创建、修改或重拍图片。此记录仅说明视觉复核,不替代最终 E2E、附件一致性或凭据扫描。", | |||||
| "imageCount": 41, | |||||
| "missingCaptions": [], | |||||
| "findings": [ | |||||
| { | |||||
| "topic": "真实模型可见性", | |||||
| "result": "狐狸在属性重开、预览、受控环境导入重开和下载重试成功等图中清楚可辨;牛奶卡车在时间轴零秒、蓝图运行和点击/双击/自动触发预览图中完整可辨。没有将树节点名称或成功提示单独作为模型可见的证据。", | |||||
| "examples": [ | |||||
| "02-properties-reopened.png", | |||||
| "03-fox-preview.png", | |||||
| "21-truck-timeline-controls.png", | |||||
| "27-truck-preview-click.png", | |||||
| "27-truck-preview-double-click.png", | |||||
| "27-truck-preview-auto.png", | |||||
| "30-assets-environment-reopened.png", | |||||
| "64-controlled-glb-retry-loaded.png" | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "topic": "故意改变的测试姿态", | |||||
| "result": "22 的车身 X=5、28 的 X=5/Y=-2,以及 29/30 延续的录制偏移导致车身与轮子分离;51 中狐狸侧立和 X 轴压缩用于真实手柄测试。已按对应图注理解为测试姿态,没有误判为模型丢失或加载变形。", | |||||
| "examples": [ | |||||
| "22-truck-curve-value-five.png", | |||||
| "28-curve-axis-y-negative.png", | |||||
| "29-timeline-seek-record.png", | |||||
| "30-blueprint-palette-canvas.png", | |||||
| "51-transform-gizmos.png" | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "topic": "失败与恢复证据", | |||||
| "result": "04、31、32、52、63 的失败提示与故障注入/非法输入图注相符;60/62 的模态遮罩用于真实恢复保护。63 空视口明确标为加载失败且保留重试,不作为成功加载证据。64 显示重试后真实狐狸。", | |||||
| "examples": [ | |||||
| "04-new-retry-dialog.png", | |||||
| "31-invalid-import-keeps-model.png", | |||||
| "32-save-conflict-keeps-recovery.png", | |||||
| "52-leave-save-failure.png", | |||||
| "60-same-version-real-recovery.png", | |||||
| "62-stale-version-recovery-protection.png", | |||||
| "63-controlled-glb-download-failed.png", | |||||
| "64-controlled-glb-retry-loaded.png" | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "topic": "环境全景的边界", | |||||
| "result": "43/44 以环境全景为主,狐狸较小;45 中狐狸被车库外墙遮挡。45 图注只声称车库 GLB 加载和保存重开,未声称该图证明狐狸可见。35 为真实导出的静态步骤演示 HTML,图注没有将它称为完整三维离线运行包。", | |||||
| "examples": [ | |||||
| "35-offline-step-demo-actual-file.png", | |||||
| "43-builtin-workshop-reopened.png", | |||||
| "44-builtin-outdoor-reopened.png", | |||||
| "45-builtin-depot-reopened.png" | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "topic": "可见敏感信息", | |||||
| "result": "在本次逐图目视范围内未发现密码、令牌、JWT 或登录凭据。画面中的角色显示名、测试模型名称/编号及故障注入请求标识属于测试上下文;此结论不覆盖文件内嵌元数据,元数据由独立 artifact-checks 扫描。" | |||||
| } | |||||
| ], | |||||
| "notes": [ | |||||
| { | |||||
| "image": "05-new-separate-project.png", | |||||
| "observation": "本次较早读取的成功图仍留有前一故障注入的红色提示。主代理已在最终用例中增加等待其自然消失后重拍;最终新版图片需由主代理再次核对。" | |||||
| }, | |||||
| { | |||||
| "image": "33-save-retry-success.png", | |||||
| "observation": "截图同时显示上一轮注入的 409 红色提示与当前重试保存成功提示,属于提示自动消退周期重叠。已补充图注,明确当前成功由 PUT 响应及刷新断言验证;没有重拍或覆盖已关联附件。" | |||||
| }, | |||||
| { | |||||
| "images": [ | |||||
| "22-truck-curve-value-five.png", | |||||
| "28-curve-axis-y-negative.png" | |||||
| ], | |||||
| "observation": "本次较早读取的曲线图存在已知低对比/分量选择器布局问题,随后读取的 28 文件中文字与选择器已清楚。主代理正在最后 CSS 修复后的完整重拍,需以最终 22/28 原图复核为准。" | |||||
| } | |||||
| ], | |||||
| "finalRetakeCaveat": "截图目录会在最终全量用例运行时原路径重拍。本记录说明实际读取时的 41 张图,不推定覆盖之后的新图已逐张复核;主代理最终重点复核 05、22、28、33,并用最终结果与附件校验确认报告关联。", | |||||
| "images": [ | |||||
| "01-components-saved.png", | |||||
| "02-properties-reopened.png", | |||||
| "03-fox-preview.png", | |||||
| "04-new-retry-dialog.png", | |||||
| "05-new-separate-project.png", | |||||
| "06-readonly-permissions.png", | |||||
| "21-truck-timeline-controls.png", | |||||
| "22-truck-curve-value-five.png", | |||||
| "23-truck-blueprint-seven-nodes.png", | |||||
| "24-truck-blueprint-real-message.png", | |||||
| "25-truck-blueprint-completed-log.png", | |||||
| "26-truck-condition-branches-runtime.png", | |||||
| "27-truck-preview-auto.png", | |||||
| "27-truck-preview-click.png", | |||||
| "27-truck-preview-double-click.png", | |||||
| "28-curve-axis-y-negative.png", | |||||
| "29-timeline-seek-record.png", | |||||
| "30-assets-environment-reopened.png", | |||||
| "30-blueprint-palette-canvas.png", | |||||
| "31-bridge-baseline-reopened.png", | |||||
| "31-invalid-import-keeps-model.png", | |||||
| "32-save-conflict-keeps-recovery.png", | |||||
| "33-save-retry-success.png", | |||||
| "34-published-current-cover.png", | |||||
| "35-offline-step-demo-actual-file.png", | |||||
| "41-resource-search-restored.png", | |||||
| "42-resource-card-switch-reopened.png", | |||||
| "43-builtin-workshop-reopened.png", | |||||
| "44-builtin-outdoor-reopened.png", | |||||
| "45-builtin-depot-reopened.png", | |||||
| "46-preview-navigation.png", | |||||
| "47-navigation-autosave-log.png", | |||||
| "51-transform-gizmos.png", | |||||
| "52-leave-save-failure.png", | |||||
| "60-same-version-real-recovery.png", | |||||
| "61-recovered-draft-explicitly-saved.png", | |||||
| "62-stale-version-recovery-protection.png", | |||||
| "63-controlled-glb-download-failed.png", | |||||
| "64-controlled-glb-retry-loaded.png", | |||||
| "65-publish-preflight-readonly.png", | |||||
| "66-depot-saved-return-list.png" | |||||
| ], | |||||
| "finalRecheck": { | |||||
| "time": "2026-09-06T08:28:08.093Z", | |||||
| "reviewer": "主代理逐张查看最终PNG", | |||||
| "items": [ | |||||
| { | |||||
| "file": "screenshots/05-new-separate-project.png", | |||||
| "sha256": "bdcdff92c9ea09f4a8d0d477de7f23c4628823f98030b7f631ae2d28b8f70899", | |||||
| "note": "新建成功画面已无上一轮注入失败提示;独立新工程可见。", | |||||
| "status": "PASS" | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/22-truck-curve-value-five.png", | |||||
| "sha256": "9dc49ad7aac39f0c5119a3dfb3d19130c5ae323fd71c95396697726a0b736af1", | |||||
| "note": "轨道文字与暗色背景清晰,分量下拉位于右上不重叠;车身X=5为测试姿态。", | |||||
| "status": "PASS" | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/28-curve-axis-y-negative.png", | |||||
| "sha256": "afa1ced1f79603933e04b59462507903c1bbc9be70a1c374a6636f41fc1c3686", | |||||
| "note": "已选轨道、负数曲线和Y分量清晰可读;部件分离与图注一致。", | |||||
| "status": "PASS" | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/33-save-retry-success.png", | |||||
| "sha256": "a04c75c96960a149781ab3274c52b75ce64c1e7f7f1501736bdcaddf7f3ee09f", | |||||
| "note": "狐狸真实可见;旧409提示与当前成功提示短暂并存,图注已解释,以成功PUT和刷新断言为准。", | |||||
| "status": "PASS" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:20:27.495Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "受控模型与外部环境 GLB 上传、JSON 往返和刷新重开", | |||||
| "featureIds": [ | |||||
| "project.import-glb", | |||||
| "environment.external", | |||||
| "project.import-json", | |||||
| "project.export-json", | |||||
| "project.save" | |||||
| ], | |||||
| "projectId": "226", | |||||
| "mainCode": "MODEL_MTPJKFPW_09-FOX", | |||||
| "environmentCode": "ENV_MODEL_MTPJKH7H_01-BOX", | |||||
| "mainUri": "fsvc://unreal-tran/model/2026/09/06/b85bd2722c4e133e61469c9f413380f0.glb", | |||||
| "environmentUri": "fsvc://unreal-tran/model/2026/09/06/9bd7351f3ee917431354690f44a449b5.glb", | |||||
| "modelMeshes": 1, | |||||
| "environmentMeshes": 1, | |||||
| "nativeClips": 3, | |||||
| "environmentPosition": [ | |||||
| 6, | |||||
| 0, | |||||
| -7 | |||||
| ], | |||||
| "environmentScale": [ | |||||
| 0.15, | |||||
| 0.15, | |||||
| 0.15 | |||||
| ], | |||||
| "result": "PASS", | |||||
| "scope": "真实上传、注册、保存、JSON重导入、刷新后的实际网格和原生动画目录;未断言下游场景执行动画。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:20:33.535Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "非法 JSON 与未登记 blob 引用导入失败时保留当前文档", | |||||
| "featureIds": [ | |||||
| "project.import-json" | |||||
| ], | |||||
| "projectId": "227", | |||||
| "result": "PASS", | |||||
| "cases": [ | |||||
| "JSON语法错误", | |||||
| "无受控资源编号/地址的跨页面blob引用" | |||||
| ], | |||||
| "retainedVersion": 1 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:20:43.214Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "保存请求超时和 409 保留恢复副本,解除故障后可重试", | |||||
| "featureIds": [ | |||||
| "project.conflict", | |||||
| "project.save", | |||||
| "feedback.toast" | |||||
| ], | |||||
| "projectId": "228", | |||||
| "result": "PASS", | |||||
| "intercepted": [ | |||||
| { | |||||
| "mode": "timedout", | |||||
| "method": "PUT", | |||||
| "projectId": "228" | |||||
| }, | |||||
| { | |||||
| "mode": "409", | |||||
| "method": "PUT", | |||||
| "projectId": "228" | |||||
| } | |||||
| ], | |||||
| "scope": "真实页面保存及真实服务端重试;失败由浏览器定向注入 timedout/409,非宣称自然发生的服务故障。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,21 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:20:51.047Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML", | |||||
| "featureIds": [ | |||||
| "publish.api", | |||||
| "publish.cover", | |||||
| "publish.html", | |||||
| "publish.downstream" | |||||
| ], | |||||
| "projectId": "229", | |||||
| "result": "PASS", | |||||
| "versionId": "283", | |||||
| "coverUri": "fsvc://unreal-tran/image/2026/09/06/14ab7b4e1e7a9d21f13f3504cb8b89ae.jpg", | |||||
| "priorCoverUri": "fsvc://unreal-tran/image/2026/09/05/c09a49efd4423dcf8ccbc46b46d1e209.jpg", | |||||
| "mainCode": "MODEL_MTO6V5W6_09-FOX", | |||||
| "scope": "目录可取得固定发布版本及同版封面;HTML已真实打开并确认演示边界,未声明下游动画执行或完整离线三维运行。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:56.960Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "补充资源库:搜索清空、真实卡片切换与刷新保留", | |||||
| "featureIds": [ | |||||
| "resource.search", | |||||
| "resource.catalog" | |||||
| ], | |||||
| "projectId": "235", | |||||
| "original": { | |||||
| "id": "imported-model_mto6v5w6_09-fox", | |||||
| "name": "09-Fox", | |||||
| "code": "MODEL_MTO6V5W6_09-FOX" | |||||
| }, | |||||
| "boxId": "imported-model_mtpjnqqk_01-box", | |||||
| "restored": { | |||||
| "id": "imported-model_mto6v5w6_09-fox", | |||||
| "code": "MODEL_MTO6V5W6_09-FOX", | |||||
| "meshes": 1 | |||||
| }, | |||||
| "scope": "真实搜索与资源卡片点击、服务端保存、刷新后原模型网格;副本独立登记待清理。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,52 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:23:19.759Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "featureIds": [ | |||||
| "environment.builtin", | |||||
| "tree.browse", | |||||
| "tree.expand", | |||||
| "project.leave" | |||||
| ], | |||||
| "projectId": "236", | |||||
| "snapshots": [ | |||||
| { | |||||
| "type": "workshop", | |||||
| "mode": "placeholder", | |||||
| "sourceKind": "placeholder", | |||||
| "nodes": 48, | |||||
| "meshes": 45, | |||||
| "id": "ee302132-152c-4575-a2ec-0a56b4820079", | |||||
| "shownRows": 76, | |||||
| "totalNodes": 76 | |||||
| }, | |||||
| { | |||||
| "type": "outdoor", | |||||
| "mode": "placeholder", | |||||
| "sourceKind": "placeholder", | |||||
| "nodes": 70, | |||||
| "meshes": 65, | |||||
| "id": "bf88db35-635d-4012-8df6-dd41382e624f", | |||||
| "shownRows": 98, | |||||
| "totalNodes": 98 | |||||
| }, | |||||
| { | |||||
| "type": "depot", | |||||
| "mode": "placeholder", | |||||
| "sourceKind": "builtin-gltf", | |||||
| "nodes": 41, | |||||
| "meshes": 32, | |||||
| "id": "cebab0bb-6910-4dff-b846-9978adcb3450", | |||||
| "shownRows": 69, | |||||
| "totalNodes": 69 | |||||
| } | |||||
| ], | |||||
| "depotSavedLeave": { | |||||
| "promptedForUnsavedChanges": false, | |||||
| "version": 5 | |||||
| }, | |||||
| "scope": "真实切换、保存和刷新三种环境;树计数与展开折叠;装备车库保存后返回列表不误报未保存。树220行上限仍属已说明边界。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,80 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:23:54.656Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存", | |||||
| "featureIds": [ | |||||
| "project.name", | |||||
| "project.autosave", | |||||
| "view.orbit", | |||||
| "view.focus", | |||||
| "view.panels", | |||||
| "view.preview-step", | |||||
| "feedback.log", | |||||
| "feedback.stats", | |||||
| "property.identity", | |||||
| "property.binding", | |||||
| "selection.scope", | |||||
| "component.inspect" | |||||
| ], | |||||
| "projectId": "237", | |||||
| "focused": { | |||||
| "position": [ | |||||
| 11.153569378931522, | |||||
| 8.526809324389628, | |||||
| 13.922975975299929 | |||||
| ], | |||||
| "target": [ | |||||
| 0.01518877997232826, | |||||
| 2.4006999949620704, | |||||
| 2.266009371254541e-7 | |||||
| ], | |||||
| "distance": 18.853169271563605 | |||||
| }, | |||||
| "rotated": { | |||||
| "position": [ | |||||
| 1.7511663652214757, | |||||
| 6.181727848275404, | |||||
| 18.38837160033089 | |||||
| ], | |||||
| "target": [ | |||||
| 0.01518877997232826, | |||||
| 2.4006999949620704, | |||||
| 2.266009371254541e-7 | |||||
| ], | |||||
| "distance": 18.853169271563594 | |||||
| }, | |||||
| "panned": { | |||||
| "position": [ | |||||
| -5.273341581654527, | |||||
| 5.082450786888863, | |||||
| 17.990688935160133 | |||||
| ], | |||||
| "target": [ | |||||
| -0.5866856170824521, | |||||
| 2.73698783970429, | |||||
| -0.11942014831462 | |||||
| ], | |||||
| "distance": 18.85316927156359 | |||||
| }, | |||||
| "focusTargetScreen": [ | |||||
| -5.177525136316571e-19, | |||||
| -1.227265217497261e-16, | |||||
| 0.9980999049952497 | |||||
| ], | |||||
| "panelModes": [ | |||||
| "timeline", | |||||
| "blueprint", | |||||
| "curve", | |||||
| "console" | |||||
| ], | |||||
| "logCount": 8, | |||||
| "stats": { | |||||
| "objects": "98 节点 / 66 网格", | |||||
| "triangles": "1,438", | |||||
| "fps": "54" | |||||
| }, | |||||
| "scope": "真实鼠标镜头操作;聚焦只验证相机目标;真实30秒自动保存,无测试加速定时器;统计内存估值未当作性能结论。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,72 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:38.815Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+runtime-readback", | |||||
| "testTitle": "真实三维移动、旋转、缩放手柄拖动及撤销重做保存重开", | |||||
| "featureIds": [ | |||||
| "view.move", | |||||
| "view.rotate", | |||||
| "view.scale" | |||||
| ], | |||||
| "projectId": "233", | |||||
| "changes": [ | |||||
| { | |||||
| "mode": "translate", | |||||
| "before": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "after": [ | |||||
| 0.7257266613731312, | |||||
| 0, | |||||
| 0 | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "mode": "rotate", | |||||
| "before": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "after": [ | |||||
| -1.194547194225429, | |||||
| 0, | |||||
| 0 | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "mode": "scale", | |||||
| "before": [ | |||||
| 1, | |||||
| 1, | |||||
| 1 | |||||
| ], | |||||
| "after": [ | |||||
| 0.30167729043770014, | |||||
| 1, | |||||
| 1 | |||||
| ] | |||||
| } | |||||
| ], | |||||
| "reopened": { | |||||
| "position": [ | |||||
| 0.7257266613731312, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "rotation": [ | |||||
| -1.194547194225429, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "scale": [ | |||||
| 0.30167729043770014, | |||||
| 1, | |||||
| 1 | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:48.155Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开", | |||||
| "featureIds": [ | |||||
| "project.leave" | |||||
| ], | |||||
| "projectId": "234", | |||||
| "closeKeptDraft": true, | |||||
| "failureKeptDraft": true, | |||||
| "retriedSavePersisted": true | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:24:07.184Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留", | |||||
| "featureIds": [ | |||||
| "project.recovery" | |||||
| ], | |||||
| "projectId": "238", | |||||
| "sameVersion": 1, | |||||
| "explicitSaveVersion": 2, | |||||
| "concurrentVersion": 3, | |||||
| "retainedFilename": "recovery-238-isolated.json", | |||||
| "scope": "通过真实beforeunload创建未保存稿;同版恢复后仅显式保存落库;旧版只下载隔离,不自动覆盖服务端。丢弃/跨标签竞态另由既有恢复合同测试覆盖。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:24:17.025Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON", | |||||
| "featureIds": [ | |||||
| "resource.loading", | |||||
| "publish.preflight" | |||||
| ], | |||||
| "projectId": "239", | |||||
| "failedDownloads": 1, | |||||
| "retainedVersion": 1, | |||||
| "scope": "真实受控下载定向503→中性失败与禁止编辑→解除故障后UI重试成功;预检面板开关不写项目,错误资源JSON在替换当前模型之前被拒绝。服务端发布时code/URI一致性拒绝由ContentProjectServiceTest合同回归覆盖,未把面板绿标代替服务端校验。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:24.723Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型", | |||||
| "featureIds": [ | |||||
| "project.new" | |||||
| ], | |||||
| "oldId": "168", | |||||
| "newId": "232", | |||||
| "cancelPreserved": true, | |||||
| "failureRetainedName": true, | |||||
| "originalVersion": 17, | |||||
| "sourceUnchanged": true | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:29.489Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "管理员只读权限:编辑、新建、导入、保存发布均不可越权", | |||||
| "featureIds": [ | |||||
| "project.permissions" | |||||
| ], | |||||
| "scope": "管理员只读UI、真实键盘搜索、原生片段切换与Enter播放/暂停、预览无内容写请求及创建403;纯publisher无需update的发布流程由独立权限合同回归补充。", | |||||
| "readonlyUi": true, | |||||
| "readonlySearch": true, | |||||
| "nativeClipChanged": true, | |||||
| "keyboardPreview": true, | |||||
| "previewWriteRequests": 0, | |||||
| "createStatus": 403 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,56 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:21:58.738Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+api", | |||||
| "testTitle": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做", | |||||
| "featureIds": [ | |||||
| "property.name", | |||||
| "property.position", | |||||
| "property.rotation", | |||||
| "property.scale", | |||||
| "property.color", | |||||
| "property.metalness", | |||||
| "property.roughness", | |||||
| "property.opacity", | |||||
| "property.code", | |||||
| "property.status", | |||||
| "component.tag", | |||||
| "project.undo", | |||||
| "project.redo", | |||||
| "project.save" | |||||
| ], | |||||
| "scope": "真实属性输入/材质参数/标签、保存与刷新;变换只验数值输入,不代替三维 gizmo 拖动。", | |||||
| "state": { | |||||
| "id": "model-imported-model_mto6v5w6_09-fox-26", | |||||
| "position": [ | |||||
| 1.25, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "rotation": [ | |||||
| 0, | |||||
| 0.2617993877991494, | |||||
| 0 | |||||
| ], | |||||
| "scale": [ | |||||
| 1, | |||||
| 1, | |||||
| 1.1 | |||||
| ], | |||||
| "customProperties": { | |||||
| "resourceCode": "CLOSURE-FOX-001", | |||||
| "operatingStatus": "SERVICE" | |||||
| }, | |||||
| "customComponents": [ | |||||
| "扩展标记 1", | |||||
| "扩展标记 2", | |||||
| "扩展标记 3", | |||||
| "扩展标记 4", | |||||
| "扩展标记 5" | |||||
| ] | |||||
| }, | |||||
| "serverVersion": 15, | |||||
| "persisted": true | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,327 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:21:50.227Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e", | |||||
| "testTitle": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发", | |||||
| "featureIds": [ | |||||
| "blueprint.click", | |||||
| "blueprint.double-click", | |||||
| "blueprint.auto", | |||||
| "view.preview" | |||||
| ], | |||||
| "projectId": "169", | |||||
| "runtimeSupplement": { | |||||
| "status": "PASS", | |||||
| "kind": "runtime", | |||||
| "featureIds": [ | |||||
| "blueprint.condition" | |||||
| ], | |||||
| "branches": { | |||||
| "falseBranch": { | |||||
| "result": true, | |||||
| "visitedFinish": false, | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "开始执行 · 闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "条件结果:否 / FALSE", | |||||
| "level": "warning", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "节点“闭环-条件判断”没有后续连线,流程结束", | |||||
| "level": "warning", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "蓝图执行完成 · 1 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| }, | |||||
| "trueBranch": { | |||||
| "result": true, | |||||
| "visitedFinish": true, | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "开始执行 · 闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "条件结果:是 / TRUE", | |||||
| "level": "success", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "执行节点:闭环-流程完成", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlznf-cxlzk" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:41", | |||||
| "message": "蓝图执行完成 · 2 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| } | |||||
| }, | |||||
| "mismatch": { | |||||
| "result": false, | |||||
| "started": false | |||||
| } | |||||
| }, | |||||
| "browserEvents": [ | |||||
| { | |||||
| "event": "click", | |||||
| "starts": 1, | |||||
| "finished": true, | |||||
| "source": "真实 renderer canvas 指针事件", | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "运行状态已重置", | |||||
| "level": "system", | |||||
| "nodeId": null | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "开始执行 · 闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "执行节点:闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "执行节点:闭环-播放时间轴", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxj9-y3g3v" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "执行节点:闭环-等待", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxxe-ond97" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "执行节点:闭环-高亮部件", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyci-4c5oi" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:42", | |||||
| "message": "执行节点:闭环-操作提示", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyuw-164xj" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:43", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:43", | |||||
| "message": "条件结果:是 / TRUE", | |||||
| "level": "success", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:43", | |||||
| "message": "执行节点:闭环-流程完成", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlznf-cxlzk" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:43", | |||||
| "message": "蓝图执行完成 · 7 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "event": "double-click", | |||||
| "starts": 1, | |||||
| "finished": true, | |||||
| "source": "真实 renderer canvas 指针事件", | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:43", | |||||
| "message": "运行状态已重置", | |||||
| "level": "system", | |||||
| "nodeId": null | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "开始执行 · 闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "执行节点:闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "执行节点:闭环-播放时间轴", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxj9-y3g3v" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "执行节点:闭环-等待", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxxe-ond97" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "执行节点:闭环-高亮部件", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyci-4c5oi" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:44", | |||||
| "message": "执行节点:闭环-操作提示", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyuw-164xj" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "条件结果:是 / TRUE", | |||||
| "level": "success", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-流程完成", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlznf-cxlzk" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "蓝图执行完成 · 7 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "event": "auto", | |||||
| "starts": 1, | |||||
| "finished": true, | |||||
| "source": "真实点击进入预览", | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "运行状态已重置", | |||||
| "level": "system", | |||||
| "nodeId": null | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "开始执行 · 闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-播放时间轴", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxj9-y3g3v" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-等待", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxxe-ond97" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:45", | |||||
| "message": "执行节点:闭环-高亮部件", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyci-4c5oi" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:46", | |||||
| "message": "执行节点:闭环-操作提示", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyuw-164xj" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:46", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:46", | |||||
| "message": "条件结果:是 / TRUE", | |||||
| "level": "success", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:46", | |||||
| "message": "执行节点:闭环-流程完成", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlznf-cxlzk" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:46", | |||||
| "message": "蓝图执行完成 · 7 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| } | |||||
| ], | |||||
| "persistedNodeCount": 7, | |||||
| "persistedEdgeCount": 6, | |||||
| "scope": "执行使用正式模型编辑器的真实模型/时间轴/高亮/提示 handler;不等同于学员端任务下发。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,697 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:21:23.003Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+runtime-read", | |||||
| "testTitle": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移", | |||||
| "featureIds": [ | |||||
| "timeline.seek", | |||||
| "timeline.record", | |||||
| "timeline.baseline", | |||||
| "curve.axis", | |||||
| "blueprint.palette", | |||||
| "blueprint.add", | |||||
| "blueprint.canvas" | |||||
| ], | |||||
| "projectIds": [ | |||||
| "230", | |||||
| "231" | |||||
| ], | |||||
| "pose": { | |||||
| "time": 0.9666666666666666, | |||||
| "value": [ | |||||
| 2.4166666666666665, | |||||
| -0.9666666666666666, | |||||
| 0 | |||||
| ], | |||||
| "actual": [ | |||||
| 2.4166666666666665, | |||||
| -0.9666666666666666, | |||||
| 0 | |||||
| ], | |||||
| "base": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ] | |||||
| }, | |||||
| "recorded": { | |||||
| "id": "key-u60x1lh", | |||||
| "time": 0.9666666666666666, | |||||
| "value": [ | |||||
| 2.4166666666666665, | |||||
| -0.9666666666666666, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| "curveAxis": { | |||||
| "xAndYPathsDiffer": true, | |||||
| "values": [ | |||||
| 5, | |||||
| -2, | |||||
| 0 | |||||
| ] | |||||
| }, | |||||
| "noMatchPreserved": true, | |||||
| "baseline": { | |||||
| "name": "闭环工具补充-基准匹配-mtpjlmiy", | |||||
| "timeline": { | |||||
| "version": 1, | |||||
| "duration": 12, | |||||
| "currentTime": 0, | |||||
| "loop": true, | |||||
| "zoom": 1, | |||||
| "tracks": [ | |||||
| { | |||||
| "id": "bridge-front-outrigger-drop", | |||||
| "name": "前支腿下落支撑", | |||||
| "targetId": "bridge-front-outrigger", | |||||
| "property": "position", | |||||
| "color": "#ffd166", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bfo-k0", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfo-k1", | |||||
| "time": 2.4, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.45, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfo-k2", | |||||
| "time": 10, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.45, | |||||
| 0 | |||||
| ], | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfo-k3", | |||||
| "time": 12, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-rear-outrigger-drop", | |||||
| "name": "后支腿下落支撑", | |||||
| "targetId": "bridge-rear-outrigger", | |||||
| "property": "position", | |||||
| "color": "#f4a261", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bro-k0", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bro-k1", | |||||
| "time": 2.2, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.19, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bro-k2", | |||||
| "time": 10, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.19, | |||||
| 0 | |||||
| ], | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bro-k3", | |||||
| "time": 12, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-rear-support-drop", | |||||
| "name": "后支座下落支撑", | |||||
| "targetId": "bridge-rear-support", | |||||
| "property": "position", | |||||
| "color": "#e76f51", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "brs-k0", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "brs-k1", | |||||
| "time": 0.4, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "brs-k2", | |||||
| "time": 2.6, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.25, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "brs-k3", | |||||
| "time": 10.2, | |||||
| "value": [ | |||||
| 0, | |||||
| -0.25, | |||||
| 0 | |||||
| ], | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "brs-k4", | |||||
| "time": 12, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-gantry-slew", | |||||
| "name": "回转门架回转", | |||||
| "targetId": "bridge-gantry", | |||||
| "property": "rotation.y", | |||||
| "color": "#2a9d8f", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bgs-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgs-k1", | |||||
| "time": 2.2, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgs-k2", | |||||
| "time": 4.8, | |||||
| "value": 0.24, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgs-k3", | |||||
| "time": 8.6, | |||||
| "value": 0.24, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bgs-k4", | |||||
| "time": 11.4, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgs-k5", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-gantry-upper-luffing", | |||||
| "name": "门架上臂变幅", | |||||
| "targetId": "bridge-gantry-upper", | |||||
| "property": "rotation.x", | |||||
| "color": "#8a68e8", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bgu-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgu-k1", | |||||
| "time": 3, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgu-k2", | |||||
| "time": 5.4, | |||||
| "value": -0.22, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgu-k3", | |||||
| "time": 8.8, | |||||
| "value": -0.22, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bgu-k4", | |||||
| "time": 11.2, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bgu-k5", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-erection-frame-luffing", | |||||
| "name": "后架设架起落(抬头 → 落桥)", | |||||
| "targetId": "bridge-erection-frame", | |||||
| "property": "rotation.x", | |||||
| "color": "#4cc9f0", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bef-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k1", | |||||
| "time": 3.6, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k2", | |||||
| "time": 5, | |||||
| "value": -0.07, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k3", | |||||
| "time": 7.8, | |||||
| "value": 0.2, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k4", | |||||
| "time": 9.8, | |||||
| "value": 0.2, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k5", | |||||
| "time": 11.6, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bef-k6", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-luffing-cylinder-follow", | |||||
| "name": "变幅缸随动", | |||||
| "targetId": "bridge-luffing-cylinder", | |||||
| "property": "rotation.x", | |||||
| "color": "#90be6d", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "blc-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k1", | |||||
| "time": 3.6, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k2", | |||||
| "time": 5, | |||||
| "value": -0.03, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k3", | |||||
| "time": 7.8, | |||||
| "value": 0.09, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k4", | |||||
| "time": 9.8, | |||||
| "value": 0.09, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k5", | |||||
| "time": 11.6, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "blc-k6", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-carriage-travel", | |||||
| "name": "移动架沿滑道后行", | |||||
| "targetId": "bridge-carriage", | |||||
| "property": "position", | |||||
| "color": "#32b8e6", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bct-k0", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bct-k1", | |||||
| "time": 5.4, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bct-k2", | |||||
| "time": 8.4, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| -0.42 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bct-k3", | |||||
| "time": 10, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| -0.42 | |||||
| ], | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bct-k4", | |||||
| "time": 12, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-launch-pinion-drive", | |||||
| "name": "导梁销齿轮驱动", | |||||
| "targetId": "bridge-launch-pinion", | |||||
| "property": "rotation.x", | |||||
| "color": "#f9c74f", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "blp-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "blp-k1", | |||||
| "time": 5.4, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "blp-k2", | |||||
| "time": 8.4, | |||||
| "value": 5.2, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "blp-k3", | |||||
| "time": 10, | |||||
| "value": 5.2, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "blp-k4", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-front-cradle-luffing", | |||||
| "name": "前托架抬头", | |||||
| "targetId": "bridge-front-cradle", | |||||
| "property": "rotation.x", | |||||
| "color": "#ff9f2f", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bfc-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfc-k1", | |||||
| "time": 6.8, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfc-k2", | |||||
| "time": 9, | |||||
| "value": 0.12, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfc-k3", | |||||
| "time": 10.4, | |||||
| "value": 0.12, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfc-k4", | |||||
| "time": 11.8, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfc-k5", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-front-pusher-extend", | |||||
| "name": "前推送装置送桥", | |||||
| "targetId": "bridge-front-pusher", | |||||
| "property": "position", | |||||
| "color": "#ef476f", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bfp-k0", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfp-k1", | |||||
| "time": 7.2, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfp-k2", | |||||
| "time": 9.4, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0.34 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "bfp-k3", | |||||
| "time": 10.6, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0.34 | |||||
| ], | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfp-k4", | |||||
| "time": 12, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "id": "bridge-feed-pinion-drive", | |||||
| "name": "前推送销齿轮驱动", | |||||
| "targetId": "bridge-feed-pinion", | |||||
| "property": "rotation.x", | |||||
| "color": "#c77dff", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "bfd-k0", | |||||
| "time": 0, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfd-k1", | |||||
| "time": 7.2, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfd-k2", | |||||
| "time": 9.4, | |||||
| "value": 4, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfd-k3", | |||||
| "time": 10.6, | |||||
| "value": 4, | |||||
| "easing": "linear" | |||||
| }, | |||||
| { | |||||
| "id": "bfd-k4", | |||||
| "time": 12, | |||||
| "value": 0, | |||||
| "easing": "linear" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ] | |||||
| }, | |||||
| "resolved": true | |||||
| }, | |||||
| "addedNode": { | |||||
| "id": "node-mtpjlj3c-n13gc", | |||||
| "type": "message", | |||||
| "title": "操作提示", | |||||
| "x": 440, | |||||
| "y": 160, | |||||
| "params": { | |||||
| "title": "操作提示", | |||||
| "text": "请观察铲斗与动臂的联动过程", | |||||
| "level": "info" | |||||
| } | |||||
| }, | |||||
| "draggedNode": { | |||||
| "id": "node-mtpjlj9e-sko2s", | |||||
| "type": "wait", | |||||
| "title": "等待", | |||||
| "x": -40, | |||||
| "y": -170, | |||||
| "params": { | |||||
| "duration": 600 | |||||
| } | |||||
| }, | |||||
| "canvasPreservedGraph": true, | |||||
| "scope": "真实模型编辑参数/基准轨道生成验收,不构成装备操作或维修指导。桥梁原工程94仅GET和copy。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,259 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:21:37.144Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+runtime-read", | |||||
| "testTitle": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存", | |||||
| "featureIds": [ | |||||
| "blueprint.parameters", | |||||
| "blueprint.move", | |||||
| "blueprint.connect", | |||||
| "blueprint.delete", | |||||
| "blueprint.copy", | |||||
| "blueprint.run", | |||||
| "blueprint.stop", | |||||
| "blueprint.reset", | |||||
| "blueprint.timeline", | |||||
| "blueprint.wait", | |||||
| "blueprint.highlight", | |||||
| "blueprint.message", | |||||
| "blueprint.finish", | |||||
| "project.undo", | |||||
| "project.redo" | |||||
| ], | |||||
| "scope": "节点库点选添加及实际拖动/接线/执行;不把点选当成节点拖入,不把适应画布当成鼠标平移缩放全部已验。", | |||||
| "projectId": "169", | |||||
| "graph": { | |||||
| "nodes": [ | |||||
| { | |||||
| "id": "node-mtpjlx7c-sgcyx", | |||||
| "type": "trigger-click", | |||||
| "title": "闭环-点击触发", | |||||
| "x": 160, | |||||
| "y": -120, | |||||
| "params": { | |||||
| "event": "click", | |||||
| "target": "model-imported-model_mto6wi6k_08-cesiummilktruck-3" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlxj9-y3g3v", | |||||
| "type": "play-timeline", | |||||
| "title": "闭环-播放时间轴", | |||||
| "x": 420, | |||||
| "y": -120, | |||||
| "params": { | |||||
| "clip": "牛奶卡车曲线联动", | |||||
| "from": 8, | |||||
| "speed": 2, | |||||
| "waitForEnd": true | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlxxe-ond97", | |||||
| "type": "wait", | |||||
| "title": "闭环-等待", | |||||
| "x": 680, | |||||
| "y": -120, | |||||
| "params": { | |||||
| "duration": 100 | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlyci-4c5oi", | |||||
| "type": "highlight", | |||||
| "title": "闭环-高亮部件", | |||||
| "x": 160, | |||||
| "y": 70, | |||||
| "params": { | |||||
| "target": "model-imported-model_mto6wi6k_08-cesiummilktruck-3", | |||||
| "color": "#ff8800", | |||||
| "pulse": false | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlyuw-164xj", | |||||
| "type": "message", | |||||
| "title": "闭环-操作提示", | |||||
| "x": 420, | |||||
| "y": 70, | |||||
| "params": { | |||||
| "title": "卡车模型闭环提示", | |||||
| "text": "检查真实目标高亮、时间轴完成和条件出口。", | |||||
| "level": "success" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlz9t-p124m", | |||||
| "type": "condition", | |||||
| "title": "闭环-条件判断", | |||||
| "x": 680, | |||||
| "y": 70, | |||||
| "params": { | |||||
| "variable": "timelineComplete", | |||||
| "operator": "==", | |||||
| "value": true | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "node-mtpjlznf-cxlzk", | |||||
| "type": "finish", | |||||
| "title": "闭环-流程完成", | |||||
| "x": 420, | |||||
| "y": 260, | |||||
| "params": { | |||||
| "result": "success", | |||||
| "text": "牛奶卡车蓝图验证完成" | |||||
| } | |||||
| } | |||||
| ], | |||||
| "edges": [ | |||||
| { | |||||
| "id": "edge-mtpjm04u-tt0qb", | |||||
| "from": { | |||||
| "node": "node-mtpjlx7c-sgcyx", | |||||
| "port": "then" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlxj9-y3g3v", | |||||
| "port": "in" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "edge-mtpjm0bc-mnf7c", | |||||
| "from": { | |||||
| "node": "node-mtpjlxj9-y3g3v", | |||||
| "port": "then" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlxxe-ond97", | |||||
| "port": "in" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "edge-mtpjm0gx-mu6ys", | |||||
| "from": { | |||||
| "node": "node-mtpjlxxe-ond97", | |||||
| "port": "then" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlyci-4c5oi", | |||||
| "port": "in" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "edge-mtpjm0nr-y06n7", | |||||
| "from": { | |||||
| "node": "node-mtpjlyci-4c5oi", | |||||
| "port": "then" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlyuw-164xj", | |||||
| "port": "in" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "edge-mtpjm0ts-px732", | |||||
| "from": { | |||||
| "node": "node-mtpjlyuw-164xj", | |||||
| "port": "then" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlz9t-p124m", | |||||
| "port": "in" | |||||
| } | |||||
| }, | |||||
| { | |||||
| "id": "edge-mtpjm0zf-sa3h2", | |||||
| "from": { | |||||
| "node": "node-mtpjlz9t-p124m", | |||||
| "port": "true" | |||||
| }, | |||||
| "to": { | |||||
| "node": "node-mtpjlznf-cxlzk", | |||||
| "port": "in" | |||||
| } | |||||
| } | |||||
| ], | |||||
| "running": false, | |||||
| "logs": [ | |||||
| { | |||||
| "time": "16:21:35", | |||||
| "message": "运行状态已重置", | |||||
| "level": "system", | |||||
| "nodeId": null | |||||
| } | |||||
| ] | |||||
| }, | |||||
| "completedLog": [ | |||||
| { | |||||
| "time": "16:21:25", | |||||
| "message": "蓝图编辑器就绪 · 7 类节点已加载", | |||||
| "level": "system", | |||||
| "nodeId": null | |||||
| }, | |||||
| { | |||||
| "time": "16:21:33", | |||||
| "message": "开始执行 · 闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:33", | |||||
| "message": "执行节点:闭环-点击触发", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlx7c-sgcyx" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:33", | |||||
| "message": "执行节点:闭环-播放时间轴", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxj9-y3g3v" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:33", | |||||
| "message": "执行节点:闭环-等待", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlxxe-ond97" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:33", | |||||
| "message": "执行节点:闭环-高亮部件", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyci-4c5oi" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:34", | |||||
| "message": "执行节点:闭环-操作提示", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlyuw-164xj" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:35", | |||||
| "message": "执行节点:闭环-条件判断", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:35", | |||||
| "message": "条件结果:是 / TRUE", | |||||
| "level": "success", | |||||
| "nodeId": "node-mtpjlz9t-p124m" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:35", | |||||
| "message": "执行节点:闭环-流程完成", | |||||
| "level": "run", | |||||
| "nodeId": "node-mtpjlznf-cxlzk" | |||||
| }, | |||||
| { | |||||
| "time": "16:21:35", | |||||
| "message": "蓝图执行完成 · 7 个节点", | |||||
| "level": "success", | |||||
| "nodeId": null | |||||
| } | |||||
| ], | |||||
| "actions": "真实节点库/参数控件/端口拖线/复制剪切粘贴/删除/撤销重做/运行停止重置/保存", | |||||
| "boundaries": "200 步循环保护由独立 Node 回归覆盖;本浏览器流程不注入假图或替换执行 handler。" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,81 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:21:02.898Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e+runtime-read", | |||||
| "testTitle": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致", | |||||
| "featureIds": [ | |||||
| "timeline.play", | |||||
| "timeline.stop", | |||||
| "timeline.loop", | |||||
| "timeline.key-nav", | |||||
| "timeline.add-track", | |||||
| "timeline.remove-track", | |||||
| "timeline.target", | |||||
| "timeline.property", | |||||
| "timeline.mute", | |||||
| "timeline.add-key", | |||||
| "timeline.delete-key", | |||||
| "timeline.drag-key", | |||||
| "timeline.zoom", | |||||
| "timeline.curve", | |||||
| "curve.time", | |||||
| "curve.value", | |||||
| "curve.easing" | |||||
| ], | |||||
| "scope": "真实控件和指针操作,运行时读取数值校验;curve.axis仅切换无数值独立断言,timeline.seek播放头与Alt吸附未在本例覆盖。", | |||||
| "projectId": "169", | |||||
| "actions": "真实 DOM 轨道/帧增删、关键帧指针拖移、播放控件、曲线输入和保存重开", | |||||
| "restored": { | |||||
| "id": "track-0-che4ljm", | |||||
| "name": "新轨道 6", | |||||
| "targetId": "interaction-5f7e4bee", | |||||
| "property": "position", | |||||
| "color": "#ffb22e", | |||||
| "muted": false, | |||||
| "keyframes": [ | |||||
| { | |||||
| "id": "key-0-0-mi1ztwf", | |||||
| "time": 0, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "key-zi8i3f7", | |||||
| "time": 2, | |||||
| "value": [ | |||||
| 5, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| }, | |||||
| { | |||||
| "id": "key-0-1-2lnk2wi", | |||||
| "time": 8, | |||||
| "value": [ | |||||
| 0, | |||||
| 0, | |||||
| 0 | |||||
| ], | |||||
| "easing": "easeInOut" | |||||
| } | |||||
| ] | |||||
| }, | |||||
| "interpolationSamples": { | |||||
| "linear": 1.25, | |||||
| "easeInOut": 0.625, | |||||
| "easeIn": 0.3125, | |||||
| "easeOut": 2.1875, | |||||
| "step": 0 | |||||
| }, | |||||
| "excluded": [ | |||||
| "未新增 solo 能力", | |||||
| "未将原生 GLB 动画片段当成多条编辑时间轴" | |||||
| ] | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:22:14.169Z", | |||||
| "data": { | |||||
| "status": "PASS", | |||||
| "kind": "e2e", | |||||
| "testTitle": "场景树搜索、可见性、选择、视口工具、原生动画与截图", | |||||
| "featureIds": [ | |||||
| "tree.search", | |||||
| "tree.visibility", | |||||
| "selection.sync", | |||||
| "view.grid", | |||||
| "view.pbr", | |||||
| "view.wireframe", | |||||
| "view.outline", | |||||
| "view.perspective", | |||||
| "view.preview", | |||||
| "view.snapshot", | |||||
| "timeline.native" | |||||
| ], | |||||
| "scope": "树搜索、对象隐藏刷新、轮廓及视图开关、原生动画和PNG下载。移动/旋转/缩放只切换模式,真实gizmo拖动仍需补验;聚焦未做几何断言。", | |||||
| "clips": 3, | |||||
| "nativeClipPersisted": true, | |||||
| "hiddenObjectPersisted": true, | |||||
| "snapshot": "装备模型编辑工具_1788682931740.png" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,100 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:13:36.256Z", | |||||
| "kind": "historical-runs", | |||||
| "scope": "仅保留安全的次数、名称、时间及源文件哈希;不复制请求正文、会话、错误上下文或私有运行日志。历史轮次不替代当前 results.json,定向2/2不等同全量19/19。", | |||||
| "runs": [ | |||||
| { | |||||
| "name": "全量首轮", | |||||
| "outcome": "FAIL", | |||||
| "startedAt": "2026-09-06T07:23:31.420Z", | |||||
| "tests": 19, | |||||
| "passed": 17, | |||||
| "failed": 2, | |||||
| "skipped": 0, | |||||
| "sourceSha256": "21e9e8a824ba988682ee2eb5edcbb35f2b3a97be4f86ad63353c535922aac22b", | |||||
| "sourceDescription": "私有归档的首轮 Playwright JSON", | |||||
| "cases": [ | |||||
| { | |||||
| "title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开", | |||||
| "outcome": "FAIL", | |||||
| "startTime": "2026-09-06T07:27:01.902Z", | |||||
| "httpStatus": 503, | |||||
| "sourceLocation": { | |||||
| "file": "tests/model-editor-interaction-closure.spec.ts", | |||||
| "line": 114, | |||||
| "column": 41 | |||||
| }, | |||||
| "request": { | |||||
| "method": "GET", | |||||
| "route": "/api/tran/v1/content/projects/{id}" | |||||
| }, | |||||
| "stage": "保存完成并返回模型列表后,由测试辅助函数读取项目详情核验", | |||||
| "note": "界面已返回列表;失败发生于末尾GET详情的状态码断言,不是进入用例登录失败,也不是测试有意注入的保存503。" | |||||
| }, | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "outcome": "FAIL", | |||||
| "startTime": "2026-09-06T07:27:31.096Z", | |||||
| "httpStatus": 503, | |||||
| "sourceLocation": { | |||||
| "file": "tests/model-editor-navigation-closure.spec.ts", | |||||
| "line": 142, | |||||
| "column": 49 | |||||
| }, | |||||
| "request": { | |||||
| "method": "GET", | |||||
| "route": "/api/tran/v1/content/projects/{id}" | |||||
| }, | |||||
| "stage": "保存完成并返回模型列表后,由测试辅助函数读取项目详情核验", | |||||
| "note": "界面已返回列表;失败发生于末尾GET详情的状态码断言,不是进入用例登录失败,也不是测试有意注入的保存503。" | |||||
| } | |||||
| ], | |||||
| "note": "两例均已完成保存并返回列表,末尾测试辅助GET项目详情返回503;分别定位 interaction:114 与 navigation:142。" | |||||
| }, | |||||
| { | |||||
| "name": "首次鉴权诊断定向重跑", | |||||
| "outcome": "FAIL", | |||||
| "tests": 2, | |||||
| "passed": 0, | |||||
| "failed": 2, | |||||
| "sourceSha256": "2c66d00995fa4c69ad12b7fb2e3f367b9d7216eb4a2f283e883c560ac38fc573", | |||||
| "sourceDescription": "私有定向运行日志,仅提取计数及调用阶段", | |||||
| "stage": "测试signIn→login请求达到30秒超时", | |||||
| "note": "此轮才在登录阶段超时,业务操作未开始;不与首轮末尾GET详情503混为同一发生阶段。" | |||||
| }, | |||||
| { | |||||
| "name": "后续定向重跑", | |||||
| "outcome": "PASS", | |||||
| "tests": 2, | |||||
| "passed": 2, | |||||
| "failed": 0, | |||||
| "sourceSha256": "58711f5c450de4fd85845ec7e2a698fbb5faf01ad3258654ca74964b9e0462b1", | |||||
| "sourceDescription": "私有定向运行日志,匹配原两个失败标题", | |||||
| "cases": [ | |||||
| { | |||||
| "title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开", | |||||
| "outcome": "PASS" | |||||
| }, | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "outcome": "PASS" | |||||
| } | |||||
| ], | |||||
| "note": "只证明这两条在此次运行通过,不能把首轮17/19改写为19/19。" | |||||
| }, | |||||
| { | |||||
| "name": "修复与曲线配色更新后的最终完整轮", | |||||
| "outcome": "PASS", | |||||
| "startedAt": "2026-09-06T08:20:11.525Z", | |||||
| "tests": 19, | |||||
| "passed": 19, | |||||
| "failed": 0, | |||||
| "skipped": 0, | |||||
| "durationMs": 246742.013, | |||||
| "sourceSha256": "f37013658c8c38a5ec5993e636a30ad57eee9d3bcc119650c929952de8d556e9", | |||||
| "sourceDescription": "当前完整 Playwright JSON;重试次数0,未拼接定向结果" | |||||
| } | |||||
| ], | |||||
| "investigation": "已修复 Auth/Tran 数据库连接健康检查可能无界阻塞的问题,并完成实际 Kingbase 驱动隔离黑洞探针(约2010ms释放关闭);最终双模块构建和完整E2E另行记录。该探针不能证明历史每一次503均已逐条与该原因建立因果关联。", | |||||
| "finalAcceptance": "完成修复后另跑完整19条,使用新的完整results.json、对应时段证据/附件、最终validation及artifact检查;旧失败保留在本历史记录。" | |||||
| } | |||||
| @@ -0,0 +1,43 @@ | |||||
| { | |||||
| "01-components-saved": { "title": "对象属性与扩展标记保存", "description": "通过真实属性控件编辑并保存;新增内容是可持久化的名称标记,不代表组件运行行为已经实现。" }, | |||||
| "02-properties-reopened": { "title": "刷新后的模型属性", "description": "重新加载服务端工程后核对对象名称、变换、首个材质槽、自定义字段和扩展标记;不是仅核对保存提示。" }, | |||||
| "03-fox-preview": { "title": "狐狸模型运行预览", "description": "真实狐狸模型在编辑器预览视口显示。临时网格、线框、透视等视图选项与模型数据保存分开验收。" }, | |||||
| "04-new-retry-dialog": { "title": "新建失败后的重试界面", "description": "定向注入创建请求失败,核对原工程保留及新建表单可重试;该画面不表示开发服务自然发生故障。" }, | |||||
| "05-new-separate-project": { "title": "新建独立模型工程", "description": "新建走真实创建接口并进入新项目 ID,原模型工程没有被清空覆盖。" }, | |||||
| "06-readonly-permissions": { "title": "只读模型入口", "description": "使用本轮实际权限会话检查只读控件及接口拒绝;平台角色名称本身不授予内容写权限。" }, | |||||
| "21-truck-timeline-controls": { "title": "卡车时间轴与部件轨道", "description": "真实轨道增删、目标绑定、播放停止、静音和关键帧操作。当前截图停在零秒;它不表示原生 GLB 动画已经变成多条可编辑时间轴。" }, | |||||
| "22-truck-curve-value-five": { "title": "曲线编辑:部件 X=5 的测试姿态", "description": "将卡车车身部件关键帧 X 改为 5 验证曲线与真实视口联动,因此车身与轮子暂时分离;这是测试姿态,不是模型加载丢失。" }, | |||||
| "23-truck-blueprint-seven-nodes": { "title": "七种蓝图节点与真实端口连线", "description": "节点通过节点库创建,参数使用实际控件编辑,端口通过指针拖线连接;蓝图图数据随后保存重开核对。" }, | |||||
| "24-truck-blueprint-real-message": { "title": "蓝图执行到操作提示", "description": "编辑器真实 handler 驱动时间轴、等待、高亮与提示节点;不是替换 handler 的演示截图。" }, | |||||
| "25-truck-blueprint-completed-log": { "title": "蓝图完成与本次运行日志", "description": "用例检查节点顺序、条件出口和完成事件;右侧日志只记录当前运行,不等同服务端审计或教学成绩。" }, | |||||
| "26-truck-condition-branches-runtime": { "title": "条件真假出口的运行时补充检查", "description": "对已由 UI 创建的图调用运行时接口检查 true/false 与不匹配目标;这张图标记为运行时证据,不能当成纯鼠标 UI 覆盖。" }, | |||||
| "27-truck-preview-click": { "title": "真实单击卡车触发蓝图", "description": "在真实可见网格像素上单击,校验只启动一次且流程完成;没有伪造 trigger 事件。" }, | |||||
| "27-truck-preview-double-click": { "title": "真实双击卡车触发蓝图", "description": "通过 renderer canvas 双击命中真实模型,校验事件匹配与单次执行;避免单击误启动双击/自动触发器。" }, | |||||
| "27-truck-preview-auto": { "title": "进入预览自动触发蓝图", "description": "真实点击进入预览后派发 auto,校验只启动一次;不代表下游场景或训练会自动运行模型蓝图。" }, | |||||
| "28-curve-axis-y-negative": { "title": "曲线分量切换与负值", "description": "在独立卡车副本中设置关键帧 X=5、Y=-2,切换曲线显示分量并比较曲线路径,确认切换视图不修改关键帧数据。车身偏移是特意设置的测试姿态。" }, | |||||
| "29-timeline-seek-record": { "title": "真实刻度定位、方向键与关键帧记录", "description": "通过时间刻度点击/拖动、左右与 Shift 按键定位时间,再用实际关键帧按钮记录当前偏移,核对时间码、关键帧和持久化内容。" }, | |||||
| "30-blueprint-palette-canvas": { "title": "蓝图库搜索、真实拖入与画布操作", "description": "搜索并清空节点库,通过 HTML5 拖放添加节点,核对工具栏默认添加、画布滚轮缩放/平移/适应操作没有意外改变节点图。" }, | |||||
| "31-bridge-baseline-reopened": { "title": "匹配模型的基准时间轴保存重开", "description": "在独立匹配装备副本载入基准动作,核对轨道目标存在、项目名称保留、保存刷新后时间轴一致;不匹配卡车分支另外验证原时间轴未被覆盖。仅验证通用编辑数据,不制作实际维修流程。" }, | |||||
| "30-assets-environment-reopened": { "title": "主狐狸与外部方盒环境同时重开", "description": "狐狸是主模型,旁边方盒是轻量环境 GLB;两者使用独立受控资产引用,刷新后均有真实网格。当前镜头较远,资产身份以随附 API 断言核对。" }, | |||||
| "31-invalid-import-keeps-model": { "title": "无效工程导入保留原模型", "description": "非法 JSON 或无有效受控引用的导入被拒绝;核对原模型与工程内容仍在,没有以默认模型静默替换。" }, | |||||
| "32-save-conflict-keeps-recovery": { "title": "版本冲突阻断保存并保留恢复稿", "description": "通过定向注入 409 验证保存失败分支及恢复数据,不将失败提示本身当成成功保存。" }, | |||||
| "33-save-retry-success": { "title": "保存失败后再次保存成功", "description": "恢复正常请求后点击真实保存。右上红色 409 提示来自上一故障注入步骤,截图时尚在自动消退周期内;本次重试成功由当前 PUT 响应和保存后的刷新断言确认。失败后的旧上传票据不得被误复用。" }, | |||||
| "34-published-current-cover": { "title": "发布版本与当前视口封面", "description": "发布接口、保存版本和受控封面资产一起核对;封面来自当前三维视口。下载后的下游资源验证不等于下游自动执行蓝图。" }, | |||||
| "35-offline-step-demo-actual-file": { "title": "实际下载的步骤演示 HTML", "description": "打开真实导出文件检查步骤演示内容。此文件不含完整三维模型和资源,完整三维离线包列为待确认范围。" }, | |||||
| "41-resource-search-restored": { "title": "资源搜索清空后恢复卡片", "description": "输入命中关键字、无匹配关键字,再清空搜索,断言卡片数量与空结果状态;仅搜索当前目录。" }, | |||||
| "42-resource-card-switch-reopened": { "title": "真实资源卡片切换后刷新", "description": "在独立副本导入小方盒,再点回原狐狸卡片;保存刷新后核对原资产 ID、code 与真实网格,不改原模型数据。" }, | |||||
| "43-builtin-workshop-reopened": { "title": "内置车间环境保存重开", "description": "真实切换内置车间、保存和刷新后核对环境类型与网格;树计数、折叠和展开同时验证。" }, | |||||
| "44-builtin-outdoor-reopened": { "title": "内置野外环境保存重开", "description": "真实切换内置野外、保存和刷新后核对环境类型与网格;程序化环境不冒称外部 GLB。" }, | |||||
| "45-builtin-depot-reopened": { "title": "内置装备车库保存重开", "description": "真实加载随包车库 GLB,保存刷新后检查 builtin-gltf 来源与网格;树总数与当前展开行数分开统计。" }, | |||||
| "46-preview-navigation": { "title": "预览前后步与退出", "description": "通过真实按钮验证下一步推进两秒、上一步回零,并用 Escape 返回编辑;预览步进不是创建新的业务步骤。" }, | |||||
| "47-navigation-autosave-log": { "title": "等待自动保存后刷新核对字段", "description": "自定义编码修改后没有点击保存,等待实际 30 秒自动 PUT;刷新确认名称与编码保留。下方日志为本次加载运行日志,FPS 与显存只作状态展示。" }, | |||||
| "51-transform-gizmos": { "title": "真实手柄操作的旋转与单轴缩放测试姿态", "description": "为了验证真实平移、旋转与缩放手柄,特意把狐狸旋转至侧立并缩小 X 轴;画面中的侧立和压扁属于测试姿态,不是加载变形。定位只读投影,没有脚本写姿态;随后撤销/重做、保存刷新核对。" }, | |||||
| "52-leave-save-failure": { "title": "未保存离开遇到保存失败", "description": "关闭确认框保留修改;定向注入保存 503 后仍留在原页,解除异常后重试保存才离开,最终 API 核对数据。" }, | |||||
| "60-same-version-real-recovery": { "title": "真实未保存修改触发同版本恢复", "description": "先在实际属性控件修改,再刷新触发 beforeunload 恢复稿;没有预先注入 localStorage 假快照。此时服务端版本未变化。" }, | |||||
| "61-recovered-draft-explicitly-saved": { "title": "恢复稿经显式保存后落库", "description": "点击恢复后编辑器保留需显式保存状态;实际点击保存才更新服务端版本,恢复名称与原受控模型一致。" }, | |||||
| "62-stale-version-recovery-protection": { "title": "旧版本恢复稿只下载与隔离", "description": "在独立副本模拟另一个编辑器保存;旧稿不显示覆盖恢复按钮,只下载并隔离保留,服务端较新内容未被覆盖。" }, | |||||
| "63-controlled-glb-download-failed": { "title": "受控模型下载失败时禁止编辑", "description": "定向注入资源下载 503,中性加载失败界面保留重试入口,保存与发布均禁用;空白视口不作为模型加载成功。" }, | |||||
| "64-controlled-glb-retry-loaded": { "title": "解除资源故障后实际重试成功", "description": "解除下载故障后点击宿主重试,iframe 重新载入并出现真实模型网格;没有以默认占位模型绕过失败。" }, | |||||
| "65-publish-preflight-readonly": { "title": "发布预检清单与只读开关行为", "description": "打开和关闭预检面板不会写入项目;错误受控资产引用的 JSON 在替换模型前被拒绝。面板绿标不能替代服务端发布校验。" }, | |||||
| "66-depot-saved-return-list": { "title": "车库保存后正常返回列表", "description": "车库环境保存后使用正式宿主导航返回列表,确认不会因旧版规范化器把 depot 误改成 outdoor 而产生虚假的未保存提示;实际修改仍受离开保护。" } | |||||
| } | |||||
| @@ -0,0 +1,498 @@ | |||||
| { | |||||
| "time": "2026-09-06T08:34:35.457Z", | |||||
| "scope": "截图与当前 results.json 的附件逐字节 SHA256 一致性;同名预跑或重拍不自动计本轮通过。", | |||||
| "screenshots": [ | |||||
| { | |||||
| "file": "screenshots/01-components-saved.png", | |||||
| "title": "对象属性与扩展标记保存", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/02-properties-reopened.png", | |||||
| "title": "刷新后的模型属性", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/03-fox-preview.png", | |||||
| "title": "狐狸模型运行预览", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "场景树搜索、可见性、选择、视口工具、原生动画与截图", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/04-new-retry-dialog.png", | |||||
| "title": "新建失败后的重试界面", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/05-new-separate-project.png", | |||||
| "title": "新建独立模型工程", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/06-readonly-permissions.png", | |||||
| "title": "只读模型入口", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "管理员只读权限:编辑、新建、导入、保存发布均不可越权", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/21-truck-timeline-controls.png", | |||||
| "title": "卡车时间轴与部件轨道", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/22-truck-curve-value-five.png", | |||||
| "title": "曲线编辑:部件 X=5 的测试姿态", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/23-truck-blueprint-seven-nodes.png", | |||||
| "title": "七种蓝图节点与真实端口连线", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/24-truck-blueprint-real-message.png", | |||||
| "title": "蓝图执行到操作提示", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/25-truck-blueprint-completed-log.png", | |||||
| "title": "蓝图完成与本次运行日志", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/26-truck-condition-branches-runtime.png", | |||||
| "title": "条件真假出口的运行时补充检查", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/27-truck-preview-auto.png", | |||||
| "title": "进入预览自动触发蓝图", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/27-truck-preview-click.png", | |||||
| "title": "真实单击卡车触发蓝图", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/27-truck-preview-double-click.png", | |||||
| "title": "真实双击卡车触发蓝图", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/28-curve-axis-y-negative.png", | |||||
| "title": "曲线分量切换与负值", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/29-timeline-seek-record.png", | |||||
| "title": "真实刻度定位、方向键与关键帧记录", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/30-assets-environment-reopened.png", | |||||
| "title": "主狐狸与外部方盒环境同时重开", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "受控模型与外部环境 GLB 上传、JSON 往返和刷新重开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/30-blueprint-palette-canvas.png", | |||||
| "title": "蓝图库搜索、真实拖入与画布操作", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/31-bridge-baseline-reopened.png", | |||||
| "title": "匹配模型的基准时间轴保存重开", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/31-invalid-import-keeps-model.png", | |||||
| "title": "无效工程导入保留原模型", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "非法 JSON 与未登记 blob 引用导入失败时保留当前文档", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/32-save-conflict-keeps-recovery.png", | |||||
| "title": "版本冲突阻断保存并保留恢复稿", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "保存请求超时和 409 保留恢复副本,解除故障后可重试", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/33-save-retry-success.png", | |||||
| "title": "保存失败后再次保存成功", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "保存请求超时和 409 保留恢复副本,解除故障后可重试", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/34-published-current-cover.png", | |||||
| "title": "发布版本与当前视口封面", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/35-offline-step-demo-actual-file.png", | |||||
| "title": "实际下载的步骤演示 HTML", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/41-resource-search-restored.png", | |||||
| "title": "资源搜索清空后恢复卡片", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充资源库:搜索清空、真实卡片切换与刷新保留", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/42-resource-card-switch-reopened.png", | |||||
| "title": "真实资源卡片切换后刷新", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充资源库:搜索清空、真实卡片切换与刷新保留", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/43-builtin-workshop-reopened.png", | |||||
| "title": "内置车间环境保存重开", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/44-builtin-outdoor-reopened.png", | |||||
| "title": "内置野外环境保存重开", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/45-builtin-depot-reopened.png", | |||||
| "title": "内置装备车库保存重开", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/46-preview-navigation.png", | |||||
| "title": "预览前后步与退出", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/47-navigation-autosave-log.png", | |||||
| "title": "等待自动保存后刷新核对字段", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/51-transform-gizmos.png", | |||||
| "title": "真实手柄操作的旋转与单轴缩放测试姿态", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "真实三维移动、旋转、缩放手柄拖动及撤销重做保存重开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/52-leave-save-failure.png", | |||||
| "title": "未保存离开遇到保存失败", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/60-same-version-real-recovery.png", | |||||
| "title": "真实未保存修改触发同版本恢复", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/61-recovered-draft-explicitly-saved.png", | |||||
| "title": "恢复稿经显式保存后落库", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/62-stale-version-recovery-protection.png", | |||||
| "title": "旧版本恢复稿只下载与隔离", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/63-controlled-glb-download-failed.png", | |||||
| "title": "受控模型下载失败时禁止编辑", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/64-controlled-glb-retry-loaded.png", | |||||
| "title": "解除资源故障后实际重试成功", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/65-publish-preflight-readonly.png", | |||||
| "title": "发布预检清单与只读开关行为", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "file": "screenshots/66-depot-saved-return-list.png", | |||||
| "title": "车库保存后正常返回列表", | |||||
| "status": "PASS", | |||||
| "associations": [ | |||||
| { | |||||
| "title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开", | |||||
| "status": "PASS", | |||||
| "hashMatches": true | |||||
| } | |||||
| ] | |||||
| } | |||||
| ] | |||||
| } | |||||