已合并
test(e2e): 补齐产物打包下载与 Skill 文件夹导入的浏览器旅程 #156
test(e2e): 补齐产物打包下载与 Skill 文件夹导入的浏览器旅程 #156
已合并
wang_cheng_zhao创建于 9月20日
wang_cheng_zhao成员
9月20日

What type of PR is this?

/kind task


What does this PR do / why do we need it:

补上两条浏览器旅程。Web 端有两处 ZIP 路径此前只有库级单测,没有任何旅程覆盖用户真正拿到的结果——这个缺口是 #152(依赖 CVE 升级)在描述里记下的,那次升级恰好动了负责打包解包的 fflate:

  • 多份产物打包下载:apps/web/src/artifact-download.ts 的 createArtifactArchive 在浏览器里把选中的产物压成 artifacts.zip。
  • Skill 文件夹导入:apps/web/src/skill-folder-import.ts 在浏览器里把整个本地目录压成 zip 上传,服务端 packages/specialist/src/skills.ts 再流式解开它。

原有的库级单测(apps/web/tests/artifactDownload.test.tsx、apps/web/tests/skill-folder-import.test.tsx、services/api/src/skills.test.ts)保持不动,本 PR 只增加旅程。

J10 多份交付物可以打包成一个压缩包带走(test/journey-artifact-archive.spec.ts)

一轮分析在两个不同目录下产出并声明两份交付物,用户进入多选、勾选两份、点「下载所选」。断言落在用户真正拿到的东西上:下载文件名是 artifacts.zip,解开后条目正是 results/summary.md 与 tables/measurements.csv,内容逐字节等于产物本身,界面给出「产物压缩包已下载」。顺带覆盖了一个容易回归的细节:没勾选任何产物时下载按钮是禁用的,勾选后才可用并显示已选数量。

解包用的是 CPython 自带的 zipfile(旅程里那一步分析本来就用 python3 跑,机器上必然有)。刻意不复用 fflate 来验证 fflate 写出的文件:那样即使双方约定出一个别的解压工具都打不开的格式,测试也会通过,而用户是拿自己的解压工具打开它的。

J11 本地 Skill 文件夹可以直接导入(test/journey-skill-folder-import.spec.ts)

旅程当场在运行输出目录写两个目录:一个只有 readme.md,一个是合规 Skill 目录(SKILL.md + reference/notes.md)。

用户先拿错目录:产品拒绝并直接说明原因(提示里点名缺少 SKILL.md),列表没有多出任何东西。再选正确目录:Skill 资源浏览器打开这个 Skill,文件树里展开 reference 能看到 notes.md,点开后编辑器里的内容与本地文件逐字相同——整个目录(而不只是 SKILL.md)经过「浏览器打包 → 上传 → 服务端解开」后完整落地。关掉浏览器后,Skill 卡片出现在列表里并带着 SKILL.md 里的描述,已安装计数加一。旅程结束时按名字反查并删除自己导入的 Skill,失败时也会删。

一处顺带发现的问题(本 PR 未改)

skill-folder-import.ts 里的几条失败提示是硬编码英文,没有进消息目录,所以中文界面下用户看到的是 The selected folder must contain SKILL.md at its root.(截图见 J11 第 2 步的旅程报告)。这与 #149 清理中文界面残留英文的方向一致,建议单独提一个 PR 把这几条文案迁进 i18n/messages.ts。J11 的断言只检查提示里是否点名 SKILL.md,不绑定语言,所以那次改动不需要动这条旅程。


Which issue(s) this PR fixes:

本 PR 只补测试覆盖,不对应 Issue;它跟进的是 #152 在描述里记录的覆盖缺口。


Test Plan and Test result:What scenarios were tested, and what were the verification results(Function, performance, reliability, etc.):

验证提交:9dbbc227(2 files,+325,基于当前 origin/main e79fd693)。三层 CI 全部在本机跑过,E2E 用 4472/4473(evolve 4475、memory-graph 17974)以避开本机常驻实例与其他并行任务的端口。

pnpm ci:ut:passed — 静态检查(architecture:check 17 passed + 275 个包源文件边界检查、typecheck 全仓通过、ci:selftest 53 passed、binary:test 40 passed / 1 skipped);Node 包测试 2326 passed / 0 failed / 2 skipped(本 PR 点名不动的三份库级单测都在里面:apps/web 790 passed 含 artifactDownload 与 skill-folder-import,services/api 903 passed / 1 skipped 含 skills 的 ZIP 导入用例);runner 245 passed / 5 skipped;Python paper 2 / gateway 26 / memory-graph 94 passed + 77 skipped / evolve 316 passed。

pnpm ci:st:passed — Agent loop smoke PASS。

pnpm ci:e2e(mocked 浏览器子集):passed — discovered 43 / passed 41 / failed 0 / skipped 2。43 = 原有 41 + 本 PR 新增 2 条。两条 skipped 与本 PR 无关:journey-prepare-environment J3 被该层自身的 SCIENTIFIC_ENVS=0 判为 BLOCKED;literature-review 的「Connector 未启用时的失败反馈」在仓库里就是 test.fixme。

用户视角 E2E 结论:PASS(浏览器 / Playwright mocked 组)

旅程 场景 预期 实际
J10 journey-artifact-archive 一轮分析产出并声明 results/summary.md 与 tables/measurements.csv,多选两份后下载 未选中时下载按钮禁用;选中后可用并显示已选 2 项;浏览器收到 artifacts.zip;解开后条目为这两条路径、内容逐字节一致;界面提示「产物压缩包已下载」 全部命中,3/3 步通过(6.5s)
J11 journey-skill-folder-import 先选一个只有 readme.md 的目录,再选合规 Skill 目录 前者被拒绝且提示点名缺少 SKILL.md,列表不变;后者导入后 Skill 浏览器打开,文件树含 SKILL.md 与 reference/notes.md,打开后者内容与本地文件一致;关掉浏览器后卡片在列表中出现、已安装计数加一 全部命中,4/4 步通过(2.9s)

两条旅程的 report.md / report.html 与逐步骤截图由 journey 固定装置自动产出(journey-reports/,未提交)。

上面三层的完整数字取自 ee729ef7。此后只改了 J10 读取压缩包的方式(从仓内自写的 ZIP 读取器换成 CPython zipfile),得到当前的 9dbbc227:ci:ut / ci:st 不执行 Playwright 规格,结论不受影响;E2E 侧在同一套隔离栈上重跑了改动涉及的两条旅程,2 passed。

一次需要说明的失败与归因:在一个复用过的数据目录上先跑了一次,journey-compact-process:304、journey-first-run J1、journey-model-settings J6 三条失败,报错分别是 Run this journey with fresh isolated Skill library data、找不到「创建项目」空态、找不到「还没有服务商」空态——都是这三条旅程自己要求的干净前置被历史数据破坏,与本 PR 新增的两条旅程无关(它们各自在 finally 里删掉自己创建的项目/模型/Skill)。把该层的数据目录清空后重跑,43 条中 41 passed / 0 failed / 2 skipped,上面的数字取自这一次。


Self-checklist:(请自检,在[ ]内打上x,我们将检视你的完成情况,否则会导致pr无法合入)

likedislike
Pull Request已成功合入, 合并人@openJiuwen-bot
(感谢 wang_cheng_zhao 的贡献)
atomgit-bot
atomgit-bot
9月20日 评论:

变更摘要

本 PR 补齐了 Web 端两条此前只有库级单测、缺少浏览器旅程覆盖的 ZIP 路径:多份产物打包下载与本地 Skill 文件夹导入。新增一个独立的 ZIP 读取辅助模块 test/helpers/zip-archive.ts,仅依赖 Node 自带 node:zlib 的 inflateRawSync,通过解析中央目录来解包产品生成的归档,从而避免「用打包方同一库解包」带来的自证风险。在此基础上新增两条 Playwright 旅程 test/journey-artifact-archive.spec.ts(J10)与 test/journey-skill-folder-import.spec.ts(J11),分别覆盖 createArtifactArchive 产出的 artifacts.zip 以及 Skill 目录整包上传后在服务端解开并安装的完整用户流程。

主要改动

  • 新增独立 ZIP 解析工具: test/helpers/zip-archive.ts 定义 ZipEntry 接口与 readZipEntries/readZipText,基于 inflateRawSync 按中央目录逐条解析,支持 STORED/DEFLATED 两种压缩方式,并在签名异常、压缩方式不支持或解压大小与声明不一致时抛错。
  • 新增产物打包下载旅程 J10: test/journey-artifact-archive.spec.ts 通过 scriptedModel 驱动的本地 stub 在 results/summary.md 与 tables/measurements.csv 写入并 declare_artifact,验证多选状态下「下载所选」按钮的禁用/启用与「已选 2 项」提示,再下载 artifacts.zip 并用独立解包器比对路径与内容一致。
  • 新增 Skill 文件夹导入旅程 J11: test/journey-skill-folder-import.spec.ts 通过 input[webkitdirectory] 分别上传含 SKILL.md 的合法目录与仅含 readme.md 的非法目录,验证非法目录时错误提示包含 SKILL.md 且不产生安装,合法目录导入后打开「Skill 资源浏览器」核对 SKILL.md 与 reference/notes.md 文件树,并确认列表卡片与「已安装」计数增加。
  • 导入旅程的清理与状态校验: J11 通过 /api/skills 接口按名称解析已导入 Skill 的 id,并在 finally 中回退按名称查找后执行 DELETE 清理,避免上传成功但 id 查询失败时残留安装记录。
  • 旅程隔离与安全约束: 两条旅程均设置 zh-CN 本地化、使用旅程独占的 Project/Session 或 Skill 库状态、由本地 stub 提供模型且声明无外部成本与外部凭据访问。
likedislike
不准确?
atomgit-bot
atomgit-bot
9月20日 评论:

AtomGit AI 助手使用指南

在 PR 评论中使用命令即可触发。支持在普通评论和代码行评论中使用。

功能 命令 说明
代码审查 /ai review 检查代码质量、潜在问题、安全风险
PR 摘要 /ai summary 生成 PR 变更内容的结构化摘要
代码解释 /ai explain 解释代码变更的逻辑和意图
自由提问 @atomgit-bot <问题> 询问关于本 PR 的任何问题
帮助 /ai help 显示此帮助信息

免责声明

AI 助手可能存在误判,请结合自身判断。可以对评论点 👍 或 👎 帮助我们改进。

likedislike
不准确?
atomgit-bot
atomgit-bot
9月20日 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
openJiuwen-bot成员
9月20日 评论:

欢迎来到 openJiuwen 社区

Hey @wang_cheng_zhao , 感谢你对社区的贡献.

机器人使用手册

有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。

likedislike
OopenJiuwen-bot成员
9月20日 添加了label:openJiuwen-cla/yes
openJiuwen-bot成员
9月20日 评论:

The pipeline(pipeline number:156) is running. Please wait a moment...

likedislike
OopenJiuwen-bot成员
9月20日 添加了label:ci-running
wang_cheng_zhao成员
9月20日 评论:

AI 自动检视,仅供参考,问题都需要人工评估分析.

本 PR 补了两条此前产品侧已有、但浏览器旅程未覆盖的路径:J10 多选交付物打包下载成 artifacts.zip,以及 J11 用本地 Skill 文件夹(webkitdirectory)导入。相对最新 origin/main 三文件、+398 行、ahead 1 / behind 0,范围干净,没有夹带无关改动。

做法上合理。产物打包侧故意不用产品同款 fflate 去验 ZIP,而是用 Node 自带 inflateRawSync 写了独立的中央目录读取(test/helpers/zip-archive.ts),避免「打包和解压约定一致却对别的解压工具无效」的假绿;旅程再核对路径与正文。Skill 导入先喂无 SKILL.md 的目录断言拒绝文案,再喂合规目录,断言资源浏览器文件树、参考文件正文、列表卡片描述与「已安装」计数,finally 里按名称兜底删除,失败半途也不会留脏数据。两条都挂 @mocked,E2E-META 契约与现有 J 系列一致,check-e2e-meta 对本批无新增报错。

可合

likedislike
openJiuwen-bot成员
9月20日 评论:

❌ 流水线 ab6e0c538bf54af482814e47c2962dff 执行失败。

可在 https://gitcode.com/openJiuwen/sciencediscovery/pull/156/check 查看完整构建日志。

在 PR 评论中发送 rerun 可重新触发 CI 流水线。

任务名称子任务状态详情
代码检查SCA(开源合规)FAILED点此跳转
Anti-poison(防投毒)PASSED点此跳转
CodeCheck(静态检查)PASSED点此跳转
Blacklist(禁用词)PASSED点此跳转
UThost tierPASSED公开日志
guest tier (QEMU TCG sandbox)PASSED公开日志
ST-PASSED公开日志
Binaryx86_64 debug packagePASSED公开日志
aarch64 debug packagePASSED公开日志
likedislike
OopenJiuwen-bot成员
9月20日 添加了label:ci-failed
OopenJiuwen-bot成员
9月20日 删除了label:ci-running
wang_cheng_zhao成员
9月20日 评论:

rerun

likedislike
openJiuwen-bot成员
9月20日 评论:

The pipeline(pipeline number:156) is running. Please wait a moment...

likedislike
OopenJiuwen-bot成员
9月20日 删除了label:ci-failed
OopenJiuwen-bot成员
9月20日 添加了label:ci-running
openJiuwen-bot成员
9月20日 评论:

❌ 流水线 15ec6f0586e04feca5cd38ee56c6d863 执行失败。

可在 https://gitcode.com/openJiuwen/sciencediscovery/pull/156/check 查看完整构建日志。

在 PR 评论中发送 rerun 可重新触发 CI 流水线。

任务名称子任务状态详情
代码检查SCA(开源合规)FAILED点此跳转
Anti-poison(防投毒)PASSED点此跳转
CodeCheck(静态检查)PASSED点此跳转
Blacklist(禁用词)PASSED点此跳转
UThost tierPASSED公开日志
guest tier (QEMU TCG sandbox)PASSED公开日志
ST-PASSED公开日志
Binaryx86_64 debug packagePASSED公开日志
aarch64 debug packagePASSED公开日志
likedislike
OopenJiuwen-bot成员
9月20日 添加了label:ci-failed
此处折叠了5条事件消息 查看更多
Wwang_cheng_zhao成员
9月20日 修改了pull request 的描述
openJiuwen-bot成员
9月20日 评论:

CLA 签署成功

wang_cheng_zhao, 感谢您的代码贡献。 所有的代码贡献者都已完成了 CLA 签署。 👍

likedislike
openJiuwen-bot成员
9月20日 评论:

The pipeline(pipeline number:156) is running. Please wait a moment...

likedislike
OopenJiuwen-bot成员
9月20日 删除了label:ci-failed
OopenJiuwen-bot成员
9月20日 添加了label:ci-running
wang_cheng_zhao成员
9月20日 评论:

上一轮检视:https://gitcode.com/openJiuwen/sciencediscovery/pull/156?ref=&did=8bdba4bd484c915a9f1dd1f5a095ec3d268f1c4a#tid-190565454

AI 自动检视,仅供参考,问题都需要人工评估分析.

本轮相对上一轮 HEAD(ee729ef7 → 9dbbc227)主要是把独立 ZIP 校验从自写的 Node 解析器换成了 CPython zipfile:删掉 test/helpers/zip-archive.ts,在 J10 旅程里用 execFileSync("python3", ["-c", ...]) 读下载下来的 artifacts.zip。J11 Skill 文件夹导入旅程本轮无改动。相对最新 origin/main 仍是 ahead=1、behind=0,落点只剩两个规格文件。

做法上仍然坚持「解压侧与打包侧不共用同一套库」——浏览器/前端打的包用系统 Python 打开,比维护一份手写 central-directory 解析更省、也更贴近真实用户用外部工具开包的场景。E2E 环境本身就依赖本机 python3(同旅程里 stub 的 run_shell 也在用),所以这条路径和现有假设一致。

结论:可合

likedislike
openJiuwen-bot成员
9月20日 评论:

✅ 流水线 a6d41cd939a24c1f9a0207745bf04b6f 执行成功。

可在 https://gitcode.com/openJiuwen/sciencediscovery/pull/156/check 查看完整构建日志。

在 PR 评论中发送 rerun 可重新触发 CI 流水线。

任务名称子任务状态详情
代码检查SCA(开源合规)PASSED点此跳转
Anti-poison(防投毒)PASSED点此跳转
CodeCheck(静态检查)PASSED点此跳转
Blacklist(禁用词)PASSED点此跳转
UThost tierPASSED公开日志
guest tier (QEMU TCG sandbox)PASSED公开日志
ST-PASSED公开日志
Binaryx86_64 debug packagePASSEDbinary · SHA256SUMS
aarch64 debug packagePASSEDbinary · SHA256SUMS
likedislike
OopenJiuwen-bot成员
9月20日 添加了label:ci-successful
OopenJiuwen-bot成员
9月20日 删除了label:ci-running
wang_cheng_zhao成员
9月20日 评论:

补充说明一次强制推送的原因,便于评审对照历史。

第一版(ee729ef7)里,J10 用仓内自写的 test/helpers/zip-archive.ts 解压下载到的 artifacts.zip——一个走 ZIP 中央目录、用 Node 自带 inflateRawSync 解压的最小读取器。流水线上SCA(开源合规)连续两次 FAILED(两次是不同的扫描任务 id,其余七项全部 PASSED),扫描详情在 openlibing 上、当前账号打不开。这个 PR 不改任何依赖,唯一可能被开源合规扫到的就是那段自写的 ZIP 解析代码——它和公开实现长得像,很容易被判为片段匹配。

现在(9dbbc227)改为用 CPython 自带的 zipfile 解包:同样不依赖被测的 fflate(这正是这条断言的意义),旅程本来就要用 python3 跑分析那一步,机器上必然有;仓内少了 90 行自写解析器。改完后 SCA 恢复 PASSED,流水线八项全绿。

改动只涉及 J10 读取压缩包的方式,断言本身没有放松:仍然核对两个条目的路径与逐字节内容。改后在同一套隔离栈上重跑了这两条旅程,2 passed。

likedislike
wang_cheng_zhao成员
9月20日 评论:

本 PR 描述里提到的那处「中文界面下拒绝提示仍是英文」已经单独立项并提交:Issue #120,修复在 PR #164。J11 的断言只检查提示里是否点名 SKILL.md、不绑定语言,所以那边合入后这条旅程不需要任何改动,两边合入顺序也没有要求。

likedislike
wang_cheng_zhao成员
9月20日 评论:

/merge

likedislike
openJiuwen-bot成员
9月20日 评论:

🔄 收到 @wang_cheng_zhao 的 /merge,正在校验并把 PR !156 以 rebase 方式合入 main…

likedislike
OopenJiuwen-bot成员
9月20日 合入了pull request
openJiuwen-bot成员
9月20日 评论:

✅ 自动合并完成(由 @wang_cheng_zhao 的 /merge 评论触发)。

PR !156 已以 rebase 方式合并到 main:c23f5da..7d02755(1 个提交)

GitCode 的审批规则尚未满足(审批人:hong-ye-zhou,yi-zhang95),已按 CODEOWNERS 授权强制合入。

likedislike