ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Bitwarden AutomationDriver 全解析:通过 DevTools 驱动浏览器、桌面与 Web 客户端的端到端自动化

Bitwarden AutomationDriver 全解析:通过 DevTools 驱动浏览器、桌面与 Web 客户端的端到端自动化 Bitwarden AutomationDriver 全解析通过 DevTools 驱动浏览器、桌面与 Web 客户端的端到端自动化【免费下载链接】clientsBitwarden client apps (web, browser extension, desktop, and cli).项目地址: https://gitcode.com/GitHub_Trending/cl/clientsbitwarden/automation-driver是 Bitwarden 客户端仓库中一个面向机器交互的自动化驱动库它以注册表的形式挂在所有 Angular 构建Browser 扩展、Desktop 桌面端、Web 网页端的全局对象上让端到端测试脚本、自动化流程与 AI Agent 可以在运行时通过 DevTools 控制客户端。阅读本文后你将掌握bitwardenAutomationDriver的挂载原理、能力capability注册机制、七大内置能力的具体 API以及如何在你的测试脚本中用它完成锁库、功能开关覆盖、状态读取等自动化操作。AutomationDriver 是什么从仓库根目录下的 libs/automation-driver/README.md 可以看到这个库的核心是暴露一个AutomationDriver对象——它是注入到 Bitwarden 客户端中的“钩子”hook用于机器与客户端之间的交互它被挂载到所有 Angular 构建browser、desktop、web的全局对象上端到端测试E2E tests、自动化脚本和 Agent 可以在运行时通过 dev-tools 驱动客户端CLI 不受支持——apps/cli不是 Angular 构建因此没有该全局对象。从库的元数据看libs/automation-driver/package.json 中该包名为bitwarden/automation-driver版本0.0.1描述为 Automation driver library for E2E test automation of Bitwarden clients采用 GPL-3.0 许可证属于仓库内部私有包private: true。核心设计能力注册表Capability RegistryAutomationDriver本身不实现任何业务功能它是一个注册表registry持有若干具名能力named capabilities但从不自己构造它们——这是刻意为之的架构决策因为这样可以保证“一个能力可以存在于拥有其依赖的任何库中”避免自动化驱动库反向依赖各业务模块。核心抽象定义在 libs/automation-driver/src/automation-capability.tsexport abstract class AutomationCapability { /** Key the capability is looked up by, e.g. driver.get(lock). Must be unique. */ abstract readonly automationName: string; }任何能力只需要继承AutomationCapability并提供唯一的automationName作为查找键。注册表的实现位于 libs/automation-driver/src/automation-driver.service.ts它展示了三个关键行为构造时收集能力通过Inject(AutomationCapability)注入所有以 multi-provider 方式注册的能力并以automationName为键存入Map重名即抛错如果两个能力声明了相同的automationName构造时会抛出Duplicate automation capability name: name防止静默覆盖挂载全局对象attachToGlobal(global)将自身挂到global.bitwardenAutomationDriver上并且不覆盖已存在的同名全局对象。对应的单元测试 libs/automation-driver/src/automation-driver.service.spec.ts 完整验证了这五个行为按名查找、未注册返回undefined、列出全部能力名、空注册表返回空数组、重名抛错、以及attachToGlobal不覆盖已有实例。能力注册multi-provider 注入能力通过 Angular 的 multi-provider 机制注册。README 给出了标准的注册模板也出现在 automation-capability.ts 的 JSDoc 中safeProvider({ provide: AutomationCapability, useFactory: (messagingService: MessagingService) new DesktopNavigationCapability(messagingService), deps: [MessagingService], multi: true, });注册位置有两个层次所有客户端共享的能力注册在 libs/angular/src/services/jslib-services.module.tsL1645-L1679即 capability every client supports单个客户端独有能力注册在该客户端的 provider module 中例如桌面端的 apps/desktop/src/app/services/services.module.tsL246-L270注释明确写着 Desktop-only automation capabilities。在jslib-services.module.ts中AutomationDriver自身的注册方式值得注意——它使用useClass且deps直接注入AutomationCapability数组源码注释说明Angular 的deps无法直接表达 multi-provider 解析为数组因此将 token 转型为SafeInjectionTokenAutomationCapability[]。从 DevTools 使用list 与 get客户端运行后在 DevTools 控制台即可通过全局对象bitwardenAutomationDriver操作。README 给出的最小示例bitwardenAutomationDriver.list(); // [featureFlags, state, lock, logging, processReload] await bitwardenAutomationDriver.get(lock).listUsers();两个关键 API 都定义在 automation-driver.service.tslist(): string[]——列出所有已注册能力名用于运行时发现可用表面surfacegetT(name): T | undefined——按名查找能力当运行中的客户端未提供该能力时返回undefined例如在 Web 端调用桌面专属能力因此调用前应做好空值判断。上例中list()返回 5 个名字说明该客户端注册了 featureFlags、state、lock、logging、processReload而桌面专属的biometrics与desktopNavigation只会出现在桌面端注册表中。七大内置能力详解能力实现全部位于 libs/automation-driver/src/capabilities/公共导出见 capabilities/index.ts。下面按自动化场景逐一展开。1. featureFlags功能开关覆盖feature-flags.ts 中的FeatureFlagsCapabilityautomationName: featureFlags是每个客户端都提供的能力用于读取和覆盖功能开关是灰度验证的利器set(flag, value)写入覆盖值内部通过StateProvider.getGlobal(GLOBAL_FEATURE_FLAG_OVERRIDES)更新全局覆盖记录源码注释提醒该覆盖记录实际是“按 flag 键控的 partial map”尽管其类型声明为完整 Recordclear(flag)删除单个覆盖恢复服务器/默认解析clearAll()清空全部覆盖get(flag)读取当前生效值解析优先级为覆盖 服务器配置 默认值通过ConfigService.getFeatureFlag实现。对应的 feature-flags.spec.ts 覆盖了设置覆盖、清除单个、清除全部、读取生效值四条路径。2. state按地址读取任意状态state.ts 中的StateCapabilityautomationName: state允许绕过领域模块的 KeyDefinition 直接按地址读原始状态同样在全部客户端可用。它接受的地址结构为字段说明默认值stateName所属StateDefinition的名称如vaultSettings必填key该状态定义内的键如showCardsCurrentTab必填location存储位置StorageLocationdisk两个读取 APIreadGlobal(address)读取全局状态readUser(userId, address)读取指定用户的状态内部通过UserKeyDefinition.buildKey(userId)构造键。该实现有两条刻意的设计约束源码注释有明确说明其一读取返回存储中的原始 JSON不做领域反序列化因此加密的保险库数据读出来仍是密文其二读取刻意绕过 state providers——因为 provider 的缓存仅按 state name 键控若在这里注册临时定义会替换掉所属领域注册的反序列化器与clearOn事件从而影响整个进程。从源码结构看StateAddress完整镜像了StateDefinition的声明维度。3. lock账户锁状态检查与切换lock.ts 中的LockCapabilityautomationName: lock允许检查和改变已知账户的锁状态是解锁类 E2E 测试的核心listUsers(): PromiseUserLockStatus[]列出每个已知账户的锁状态UserLockStatus包含userId、email、statusAuthenticationStatus枚举的键源码显示没有认证状态的用户会被标记为LoggedOut见 lock.spec.ts 中 reports users with no auth status as logged out 用例lock(userId)锁定指定用户行为等价于用户手动锁库LockSource.ManualunlockWithMasterPassword(userId, masterPassword)主密码解锁unlockWithPin(userId, pin)PIN 解锁unlockWithBiometrics(userId)生物识别解锁。4. logging读取飞行记录器事件logging.ts 中的LoggingCapabilityautomationName: logging读取 SDK 的 FlightRecorder 事件缓冲readEvents()读取缓冲区内全部事件countEvents()仅返回事件数量不读取内容。从源码注释看它只在带有 WASM SDK 的客户端上接线其依赖FlightRecorder来自bitwarden/logging。5. processReload重载客户端进程process-reload.ts 中的ProcessReloadCapabilityautomationName: processReload执行客户端提供的进程重载函数其ReloadProcess类型为() Promisevoid | void在 Web 端可以是location.reload()在桌面端则是一次指向主进程的 IPC 调用。它只在能够自行重载的客户端上接线。6. biometrics驱动模拟生物识别桌面端专属biometrics.ts 中的BiometricsCapabilityautomationName: biometrics通过客户端提供的AutomationBiometricsController驱动主进程中的自动化生物识别服务。该接口刻意保持通用——公共文件不对桌面端代码产生依赖桌面客户端通过 IPC 提供转发实现。其 API 为setStatus(status)设置模拟的BiometricsStatuslistPending()列出等待审批的生物识别请求approve(id?)按 id 批准待处理请求不传 id 时批准最旧的一个deny(id?)按 id 拒绝待处理请求不传 id 时拒绝最旧的一个。在桌面端请求队列会阻塞直到自动化脚本批准或拒绝这正是为了让测试可控而设计。IPC 的接线方式见 apps/desktop/src/app/services/services.module.tsL253-L265它将setStatus/listPending/approve/deny分别转发到ipc.keyManagement.automation.biometrics底层服务实现在 apps/desktop/src/key-management/biometrics/automation-biometrics.service.ts含listPendingRequests、approveRequest、denyRequest与awaitApproval阻塞逻辑IPC 监听器与 preload 桥接分别在automation-biometrics-ipc.listener.ts和 apps/desktop/src/key-management/preload.ts。7. desktopNavigation桌面端菜单导航桌面端专属desktop-navigation.ts 中的DesktopNavigationCapabilityautomationName: desktopNavigation通过MessagingService触发桌面端的菜单栏消息处理器目前提供openSettings()打开设置页发送openSettings消息。这是 README 注册示例中的能力也是“客户端专属能力注册在客户端自身 provider module”的典型实例。能力在客户端间的分布把注册点汇总可以清晰地看到能力矩阵能力注册位置适用范围featureFlagsjslib-services.module.ts全部 Angular 客户端state同上全部 Angular 客户端lock同上全部 Angular 客户端logging同上全部 Angular 客户端需 WASM SDKprocessReloaddesktop/services.module.ts桌面端可自行重载的客户端biometrics同上桌面端desktopNavigation同上桌面端因此在 Web 端执行list()通常得到 README 示例中的 5 个名字而在桌面端还会额外看到processReload、biometrics、desktopNavigation。调用前用list()或对get()结果判空即可写出跨客户端兼容的自动化脚本。全局挂载时机与入口bitwardenAutomationDriver的挂载发生在各客户端的初始化服务InitService中且紧跟在containerService.attachToGlobal之后Web 端apps/web/src/app/core/init.service.tsL108-L109挂到this.win桌面端apps/desktop/src/app/services/init.service.tsL124-L125同样挂到this.win浏览器扩展apps/browser/src/popup/services/init.service.tsL45挂到self。由于attachToGlobal不覆盖已存在实例多次初始化或热加载不会破坏已建立的全局引用这一点同样有单元测试保障。测试与质量保障除上文提到的各能力 spec 外仓库为该库建立了完整的测试矩阵automation-driver.service.spec.ts注册表本身的 get/list/重名/挂载行为feature-flags.spec.ts覆盖写入/清除/生效值读取lock.spec.ts账户锁状态列出与四种解锁路径biometrics.spec.ts模拟状态设置、待审批列表、按 id 批准与拒绝其余能力state、logging、process-reload、desktop-navigation同样配有对应.spec.ts文件。此外 libs/automation-driver/jest.config.js、tsconfig.json 与 project.json 构成了该库独立的构建与测试配置package.json中的构建脚本为tsc --noEmit -p tsconfig.lib.json仅类型检查。使用边界与注意事项CLI 不支持bitwardenAutomationDriver只存在于 Angular 构建browser、desktop、webCLI 不在其列能力缺失时get返回undefined调用前务必判空或用list()先探测能力名全局唯一重名会导致构造期抛错注册新能力时避免与既有名称冲突state 读取是“原样 JSON”不做领域反序列化加密数据保持加密适合调试与状态断言不适合替代领域层的读写 API不要在自动化中绕过 provider 写状态StateCapability刻意只读源码仅暴露readGlobal/readUser其绕过 provider 的设计原因缓存键控与反序列化器替换风险已在前文详述。总结AutomationDriver用“注册表 multi-provider 能力”的架构为 Bitwarden 浏览器扩展、桌面端与 Web 端提供了一套统一、可发现、按需裁剪的运行时自动化表面通过list()探测、get()获取即可在 DevTools 中驱动功能开关覆盖、锁状态切换、状态读取、日志读取、进程重载乃至桌面端生物识别审批。对于 E2E 测试作者与自动化工具链开发者而言理解其能力矩阵与注册机制是写出跨客户端、稳定可控的自动化脚本的前提。【免费下载链接】clientsBitwarden client apps (web, browser extension, desktop, and cli).项目地址: https://gitcode.com/GitHub_Trending/cl/clients创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表