首页 / 资讯中心 / 文章详情

MetaMask Extension 测试 Fixture 数据生成指南:利用 stateHooks.metamaskGetState 捕获真实钱包状态

MetaMask Extension 测试 Fixture 数据生成指南:利用 stateHooks.metamaskGetState 捕获真实钱包状态 ★ FEATURED ARTICLE
MetaMask Extension 测试 Fixture 数据生成指南利用 stateHooks.metamaskGetState 捕获真实钱包状态【免费下载链接】metamask-extension:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites项目地址: https://gitcode.com/GitHub_Trending/me/metamask-extension本指南面向在 MetaMask 浏览器扩展仓库中编写 E2E 测试与开发调试的工程师讲解如何通过在浏览器扩展的 background 上下文中调用stateHooks.metamaskGetState把运行时真实钱包状态一键导出为 fixture JSON 文件。读完本文你将掌握 fixture 数据的标准生成流程、其底层注入机制与源码实现以及仓库中围绕 fixture 构建的服务器、构建器与校验工具链。什么是 Fixture 数据在 MetaMask 扩展仓库中fixture 是一份用于模拟钱包运行状态的 JSON 数据其核心作用是让 E2E 测试test/e2e目录下的大量 spec 用例在无需完成完整 onboarding 流程的前提下直接以预设的账户、密钥环vault、网络、代币、交易记录等状态启动扩展从而缩短测试路径、提高可重复性。仓库中 fixture 相关的基础设施主要位于test/e2e/fixtures/默认 fixture、构建器、校验器与 fixture 服务器app/scripts/fixtures/面向开发调试的“带状态启动”辅助脚本app/scripts/background.js与app/scripts/lib/setup-initial-state-hooks.jsstateHooks的注入与实现生成 Fixture 的标准流程官方文档docs/generating-fixture-data.md给出的流程非常精简只需三步在开发development或测试test模式下加载未打包的扩展在扩展的 background 上下文中执行检查调用stateHooks.metamaskGetState并对返回结果调用copy。对应的核心命令仅一行copy(await stateHooks.metamaskGetState());copy是 Chrome DevTools 控制台提供的全局工具函数Console Utilities API 之一用于把任意表达式结果以 JSON 字符串形式复制到系统剪贴板。因此在扩展的 background 上下文控制台中执行上述语句后整个持久化钱包状态就会以可粘贴的 JSON 形式进入剪贴板随后直接粘贴到你的 fixture 文件中即可。分步操作说明以开发/测试模式加载扩展通过yarn start之类的开发命令或测试构建产物启动扩展并以「加载已解压的扩展程序」方式载入浏览器。只有在开发或测试模式构建下stateHooks.metamaskGetState才会被注入到全局作用域这一点下文会结合源码详细说明。打开 background 上下文在扩展管理页面点击「服务工作线程」MV3 为 Service WorkerMV2 为背景页的“检查视图”或在扩展弹窗/完整页面的开发者工具中切换到对应上下文。执行导出命令在 Console 中输入copy(await stateHooks.metamaskGetState());回车后状态即被复制。粘贴到 fixture 文件新建一个 JSON 文件参考test/e2e/fixtures/default-fixture.json的结构把剪贴板内容整体粘贴进去供测试或本地复现使用。stateHooks.metamaskGetState 的注入条件与底层实现在普通的生产构建中stateHooks.metamaskGetState并不存在。它的注入逻辑位于 app/scripts/background.jsif (process.env.IN_TEST || process.env.METAMASK_DEBUG) { global.stateHooks.metamaskGetState persistenceManager.get.bind( persistenceManager, { validateVault: false }, ); }从源码可以确认两个关键事实注入条件是构建环境变量只有设置了IN_TEST测试模式或METAMASK_DEBUG开发调试模式时该 hook 才会挂载到global.stateHooks上。这正是文档要求“以开发或测试模式加载扩展”的原因。底层是 PersistenceManager 的get方法metamaskGetState直接绑定为persistenceManager.get并以{ validateVault: false }作为固定参数即读取持久化状态时跳过 vault 完整性校验。这样导出的状态包含完整的data各 controller 状态与metastorageKind、version 等元信息可以原样回灌。persistenceManager与stateHooks的初始化位于 app/scripts/lib/setup-initial-state-hooks.js其中还定义了getPersistedState、getBackupState、getSentryState等其他全局钩子。可以推断stateHooks是 MetaMask 在 background 初始化早期暴露的一组测试/诊断接口metamaskGetState只是其中之一专门服务于“导出完整状态”这一场景。粘贴之后仓库内的 Fixture 消费链路导出并粘贴的 fixture 并不是孤立文件仓库中存在一整套消费、校验与替换机制Fixture 服务器与状态替换test/e2e/fixtures/fixture-server.js 使用 Koa 在localhost:12345提供 fixture 服务并实现了__FIXTURE_SUBSTITUTION__前缀替换机制当状态中某个字符串以该前缀开头时会按命令动态替换。目前支持两类命令currentDateInMilliseconds替换为当前时间戳毫秒用于需要“相对当前时间”的状态字段CONTRACT相关命令从合约注册表contractRegistry中查询并替换为已部署合约的真实地址。这意味着 fixture 中可以写入占位符而不是硬编码地址或时间从而保证测试在不同环境下的可用性。Fixture 构建器除手工导出粘贴外仓库还提供了程序化构建 fixture 的方式test/e2e/fixtures/fixture-builder-v2.tsFixtureBuilderV2类通过withAccountsController、withKeyringController、withNetworkController、withTransactionController等链式方法组装各 controller 状态app/scripts/fixtures/generate-wallet-state.jsgenerateWalletState函数基于FixtureBuilderV2生成带 vault 的完整钱包状态可配合app/scripts/fixtures/下with-address-book.js、with-erc20-tokens.js、with-networks.js等模块组合出不同业务场景。可以理解为两种互补的路径手工导出本文主题适合捕获线上/真实操作后的精确状态与脚本生成适合批量、可参数化的状态组装。默认 Fixture 与校验test/e2e/fixtures/default-fixture.json是 E2E 测试的默认基准状态test/e2e/fixtures/fixture-validation.ts负责对 fixture 内容做合法性校验test/e2e/fixtures/onboarding-fixture.json用于 onboarding 流程相关用例。如果手工导出的 JSON 结构与校验器预期不一致测试运行时会直接失败因此粘贴后建议用仓库现有的 fixture 校验逻辑先做一次静态检查。结合源码测试失败时的状态快照对比生成的 fixture 除了用于预设状态也可反向用于调试。在 test/e2e/webdriver/driver.js 中E2E 测试失败时会执行window.stateHooks?.getCleanAppState()把 UI 侧的“干净状态”以 JSON 快照写入test-artifacts目录const uiState await this.driver.executeScript( () window.stateHooks?.getCleanAppState window.stateHooks.getCleanAppState(), );这与metamaskGetState形成了镜像关系前者在测试失败时抓取“当前实际状态”用于分析后者在开发时抓取“想要复现的目标状态”用于生成 fixture。两者配合即可实现“导出状态 → 作为 fixture → 复现问题 → 对比状态”的完整调试闭环。注意事项与适用前提仅限开发/测试构建metamaskGetState依赖IN_TEST或METAMASK_DEBUG环境变量注入生产构建不可用这也是文档第一步强调加载模式的原因。状态可能包含敏感信息导出的 JSON 包含完整钱包状态含加密 vault 等数据请勿提交到公开仓库或日志仓库中已有 隐私快照约束 等机制导出内容同样应遵循相关策略。按需裁剪手工导出的是全量持久化状态若只需某个 controller如 NetworkController的状态可以粘贴后再裁剪或改用FixtureBuilderV2的按需组装方式。环境差异替换机制如currentDateInMilliseconds、合约地址会因运行环境不同产生差异粘贴后应检查是否存在需要替换的硬编码值。【免费下载链接】metamask-extension:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites项目地址: https://gitcode.com/GitHub_Trending/me/metamask-extension创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站