Zen Browser 如何把 Firefox 外部测试导入仓库:manifest.toml 与 import_external_tests.py 的完整流程
2026/9/11 6:07:01 网站建设 项目流程

Zen Browser 如何把 Firefox 外部测试导入仓库:manifest.toml 与 import_external_tests.py 的完整流程

【免费下载链接】desktopWelcome to a calmer internet项目地址: https://gitcode.com/GitHub_Trending/desktop70/desktop

Zen Browser 在 Firefox 源码之上做定制开发,一部分 Firefox 的既有测试(例如 alerts、sessionstore、zoom)对 Zen 同样有效,仓库通过一条自动化链路把它们复制到 src/zen/tests/mochitests 目录,并生成一份moz.build让这些测试进入构建测试体系。这条链路由两个文件构成:声明“导入哪些测试、禁用哪些用例、替换哪些配置”的 manifest.toml,以及真正执行导入的 scripts/import_external_tests.py。本文按“读清单 → 跑脚本 → 验证产物”的顺序,完整走一遍这个流程。

这套导入机制做了什么

脚本的输入只有 manifest.toml,输出是src/zen/tests/mochitests/整个目录加其中的moz.build。执行一次脚本会发生以下事情(对应脚本中的main()逻辑):

  1. 删除已存在的src/zen/tests/mochitests目录并重建,因此产物完全由 manifest 和引擎源码重新生成,手工改过该目录的内容会被抹掉;
  2. 校验 manifest 中的测试套件名必须按字母序排列,否则报错退出;
  3. 逐个套件从引擎源码复制测试文件到mochitests/<套件名>/
  4. 按 manifest 中的disable/replace-manifest修改复制出来的browser.tomlxpcshell.toml
  5. 生成mochitests/moz.build,把各套件的清单文件注册进BROWSER_CHROME_MANIFESTSXPCSHELL_TESTS_MANIFESTS

产物文件头部都带有# This file is autogenerated by scripts/import_external_tests.py / Do not edit manually.标记,moz.build和所有被改动的 toml 都是如此。

运行前提

  • Python 3.11 或更高:脚本使用标准库tomllib解析 TOML,没有其他第三方依赖(仓库的 requirements.txt 中没有为它引入额外包)。
  • 工作目录必须是仓库根目录:脚本里所有路径都是相对路径(src/zen/testsengine/...)。
  • 仓库根目录下存在完整的engine/Firefox 源码目录,即已经通过npm run downloadsurfer download)获取过上游源码。脚本从engine/下读取测试,目录不存在会直接报Tests folder not found错误并退出。注意 CI 工作流中缓存的引擎路径是.surfer/engine/(见 .github/workflows/sync-upstream.yml),本地npm run download后引擎实际落在哪个目录,以你本地环境为准,脚本要求它在仓库根下的engine/

manifest.toml 的字段与实例

manifest.toml 中每个[套件名]是一个导入单元。当前共 15 个套件:alertsbackforwardcapsgesturelinkHandlingreadermoderemote-settingssafebrowsingservices-cryptosessionstoreshellsynctabMediaIndicatortooltiptextzoom,恰好按字母序排列(脚本会强制校验这一点)。各字段含义如下,均可在 manifest 中找到真实用例:

字段作用manifest 中的实例
source引擎中的测试目录,相对engine/source = "browser/base/content/test/alerts"
is_direct_pathtrue时源目录就是engine/<source>;未设置时脚本会在其后追加/tests多数套件为truetooltiptext未设置,实际读取engine/toolkit/components/tooltiptext/tests
xpcshelltrue时该套件的xpcshell.toml注册进XPCSHELL_TESTS_MANIFESTS,否则其browser.toml注册进BROWSER_CHROME_MANIFESTSremote-settingsservices-cryptosync三个套件为true
disable在源 toml 中找到对应["测试文件名"]条目并在其后插入disabled="Disabled by import_external_tests.py"见下方示例
replace-manifest对源 toml 做字符串替换,键是必须存在的原文片段,值是新片段见下方示例

disable的实例是linkHandling,注释写明了禁用原因:

[linkHandling] source = "browser/base/content/test/linkHandling" is_direct_path = true disable = [ # Glance opens with alt+click, firefox doesnt know that. "browser_javascript_links.js", ]

replace-manifest有三类典型用法:

# 1. 注入 Zen 特有的 pref 覆盖。gesture 套件把源 toml 里的 [DEFAULT] 段整体替换, # 关闭 window-sync,避免它干扰手势测试: [gesture.replace-manifest] "[DEFAULT]" = '''[DEFAULT] prefs = [ "zen.window-sync.enabled=false", ]''' # 2. 修复相对路径。remote-settings 测试复制后层级变浅了一层, # 相对路径多指了一层 services/: [remote-settings.replace-manifest] "../../../" = "../../../../services/" # 3. 追加 pref。sync 套件在原有 fxaccounts pref 后追加 formfill pref: [sync.replace-manifest] '"identity.fxaccounts.enabled=true"' = '"identity.fxaccounts.enabled=true", "browser.formfill.enable=true"'

sessionstore是配置最重的一个套件:disable列出了 50 个测试文件,并且replace-manifest把源 toml 中的prefs = [替换成先关闭zen.window-sync.enabled的写法。

执行导入

在仓库根目录运行:

python3 scripts/import_external_tests.py

正常运行时脚本会打印每个套件的导入进度:

Importing test suite 'alerts' from 'browser/base/content/test/alerts' ... Writing moz.build file to 'src/zen/tests/mochitests/moz.build'

脚本没有任何命令行参数,全部行为由 manifest.toml 决定;想改导入内容就改 manifest,重跑脚本。再次运行前不需要手动清理,main()会先rmtree整个输出目录。注意该命令会删除并重建src/zen/tests/mochitests/,如果该目录里有你未提交的本地改动,运行前先确认。

出错时脚本给出的明确诊断

脚本的失败路径都有可定位的错误信息,ERROR:前缀后直接退出:

  • Test suites in manifest.toml are not in alphabetical order.—— 新增套件时没有按字母序插入;
  • Tests folder not found: <path>——engine/中不存在source指向的目录(引擎未下载,或 Firefox 上游改了目录结构);
  • None of the valid manifest files ['browser.toml', 'xpcshell.toml'] found in tests folder '<path>'—— 源目录里连一个清单文件都没有;
  • Ignore file '<file>' not found in tests folder '<path>'——ignore列表里的文件名在源目录中不存在;
  • Could not disable test '<test>' as it was not found in '<toml_file>'——disable中的测试在源 toml 里没有对应条目,通常意味着上游测试文件已被删除或改名;
  • Could not replace manifest entry '<key>' as it was not found in '<toml_file>'——replace-manifest的键在源 toml 中找不到。

这些错误说明 manifest 已经和引擎里的实际测试脱节,修复方式是更新 manifest 使其与当前上游测试目录一致,而不是手改输出目录。

验证导入结果

导入后有三处可以核对:

  1. git status/git diff查看src/zen/tests/mochitests/下的变更;

  2. 打开生成的 moz.build,确认两个列表与 manifest 的xpcshell标记一致。当前仓库中的实际内容是:

    BROWSER_CHROME_MANIFESTS += [ "alerts/browser.toml", "backforward/browser.toml", "caps/browser.toml", "gesture/browser.toml", "linkHandling/browser.toml", "readermode/browser.toml", "safebrowsing/browser.toml", "sessionstore/browser.toml", "shell/browser.toml", "tabMediaIndicator/browser.toml", "tooltiptext/browser.toml", "zoom/browser.toml", ] XPCSHELL_TESTS_MANIFESTS += [ "remote-settings/xpcshell.toml", "services-crypto/xpcshell.toml", "sync/xpcshell.toml", ]

    即除remote-settingsservices-cryptosync三个 xpcshell 套件外,其余 12 个套件都注册了browser.toml

  3. 抽查被disable的测试:如 mochitests/shell/browser.toml 中,browser_1119088.jsbrowser_setDesktopBackgroundPreview.js对应的["..."]条目后各有一行disabled="Disabled by import_external_tests.py",与 manifest 中shell套件的disable列表一一对应。

与 CI 的关系及限制

在 .github/workflows/sync-upstream.yml 中,该脚本是上游同步流程的最后一步之一:npm run download获取引擎、npm run sync同步补丁之后,只有git status --porcelain检测到文件变化时才会执行python3 scripts/import_external_tests.py,随后创建指向dev分支的同步 PR。值得注意的一个细节:CI 里该步骤带了|| true,导入失败不会阻断工作流,PR 描述中只有外部补丁(update_external_patches.py)的应用状态会提示失败。也就是说,测试导入的失败在 CI 中是静默的,本地重跑时必须自己盯住脚本的ERROR:输出。

边界条件汇总:

  • engine/目录缺失或source路径失效时脚本整体失败,不产生部分输出(输出目录在失败前已被清空,此时mochitests/只剩moz.build或为空,需要用 git 恢复或修复 manifest 后重跑);
  • 脚本只处理 manifest 中声明的 15 个套件,src/zen/tests/下其余目录(boostsfoldersspaces等)是 Zen 自有的测试,不在这条导入链路范围内;
  • ignore字段脚本支持(复制时跳过指定文件,且要求文件确实存在),但当前 manifest 没有套件使用它;
  • 导入产物本身不参与本文场景之外的构建流程说明,如何运行这些测试请参考package.json中的test脚本(python3 scripts/run_tests.py)。

【免费下载链接】desktopWelcome to a calmer internet项目地址: https://gitcode.com/GitHub_Trending/desktop70/desktop

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询