CUA Driver 跨平台 E2E 测试框架收敛Rust 类型化用例目录与桌面观察者架构解析【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua本篇文章深入解读 CUA Driver 仓库中 Rust E2E 测试框架的收敛方案test-harness-convergence-plan.md如何用一份 Rust 类型化用例目录typed case catalog替代历史上散落的矩阵文件、Python 收集器和 shell 脚本把 AX/PX 定位、前台/后台投递、驱动后端路由从测试家族收敛为动作维度并借助跨平台桌面观察者DesktopObserver把工具返回 ok升级为目标状态与桌面副作用双重可证。读完本文你将理解 CUA Driver 贡献者视角下单一来源 Rust 目录 严格环境预检 独立结果记录的 E2E 架构以及这套方案在 Windows、macOS、Linux X11/Wayland 上的落地形态与实施切片。说明该文档是历史性方案Historical plan其评审结论、规则与实施切片记录的是收敛过程本身已实现并持续更新的贡献者工作流以 test-harnesses-guide.md、test-matrix.md 和 e2e-ci-reporting.md 为准。本文以该方案为主体并结合当前仓库源码印证其落地状态。一、为什么需要收敛从测试家族到动作维度方案开篇的 Re-review 结论确立了收敛的三大方向这也是理解整个方案的主线Rust 拥有场景、断言与结果记录Rust owns scenarios, assertions, and result records。测试的定义权集中在 Rust 集成测试源码中而不是分散在 Python 收集器、matrix.yaml或 shell 脚本里仓库本地repo-local的 harness 应用是规范的 E2E 目标。Electron、Tauri、WPF、WinUI3、WebView2、AppKit、SwiftUI、GTK3 等测试宿主均由仓库源码构建而不是依赖外部安装的任意应用AX/PX 定位与前台/后台投递是动作上的维度不是测试家族。background/foreground是每个动作行的属性不需要为此维护一套独立的后台投递测试套件焦点focus、z-order、光标cursor、桌面desktop检查则是可附加到任意动作行的横切观察项。贡献者的调用方式保持无选择器selector-free在任意 OS 上运行同一命令即执行完整矩阵CI 可以把完整矩阵扇出fan out到内部 job 中以便失败隔离但那是执行细节不是另一套公开测试套件。方案在此基础上对早期计划做了五处修订不把历史单元格数量当作目标。共享矩阵必须覆盖所有受支持的路由组合任何遗漏都要给出路由等价equivalent_to或不支持能力的理由测试状态与驱动行为分离。一个测试通过可能是因为必需动作被成功投递也可能是因为声明的不可支持路由被正确拒绝。这两种结果在报告中必须保持可区分环境就绪性作为 lane 预检。缺失桌面、TCC 授权、fixture、AT-SPI 总线、录制器或交互式 Windows 会话时必须在行为单元格运行之前失败一次而不是在每个单元格里各自报错用 Rust 类型化用例目录作为矩阵唯一来源。不新增第二个matrix.yaml、Python 收集器或 shell 维护的场景清单每个单元格保留一份证据包但在显式状态重置能证明隔离时复用驱动与 harness 进程。目标的度量是更少但更强的测试每个单元格都有命名的覆盖理由named coverage reasons和强外部 oracle测试数量不是成功指标。二、八条不可妥协规则方案给出了一套可执行的判定纪律任何单元格都不得绕过成功的工具响应永不等于投递成功。已投递动作必须改变 fixture 或桌面状态且该状态由测试独立读取后台动作还必须证明未抢占焦点、未抬高目标窗口、未移动真实光标、未泄漏部分输入在适用时拒绝refusal仅在同时满足以下条件时有效单元格契约期望拒绝、驱动返回允许的结构化拒绝码、桌面观察者未观察到副作用要求投递的单元格在驱动拒绝时失败——即使拒绝是诚实的必需的规范 fixture 或桌面能力不能变成通过的提前返回。可选测试必须在执行前声明为可选已知缺口不使用#[should_panic]也不计入绿色覆盖。它们运行在具名的可选 lane 中并关联 issue 直到修复Shell 与 PowerShell 运行器只负责构建环境、收集产物不得从 Cargo 输出推断行为结果每次运行必须记录被测的 Rust 源码构建。macOS 可因 TCC 原因通过已安装的 app bundle 代理执行但该 bundle 必须来自同一源码修订source revision。最后一条在源码中有直接呼应运行器通过CUA_E2E_SOURCE_SHA环境变量与.cua-e2e-source-sha标记文件把源码 SHA 注入测试环境EnvironmentRecord会序列化source_sha字段见 e2e.rs 的EnvironmentRecord::ready/error最终报告会携带该 SHA。三、目标测试模型类型化用例目录3.1 CaseSpec单一结构声明所有行为单元格每个行为单元格都在 Rust 中声明web 与原生 harness 测试共享同一结构方案原文struct CaseSpec { id: static str, platform: Platform, display_server: DisplayServer, harness: Harness, action: Action, targeting: Targeting, delivery: Delivery, scope: Scope, expectation: ContractExpectation, oracles: static [OracleKind], route: DriverRoute, } enum ContractExpectation { Deliver, Refuse { allowed_codes: static [RefusalCode] }, }在当前仓库中该结构已落地为序列化契约类型见 e2e.rsCaseSpec携带cell_id、platform、display_server、harness、toolkit、action、targeting、delivery、scope、driver_route、expected_behavior、oracles并提供delivered(...)、expecting_refusal(allowed_codes)构造器。方案强调的几个关键点RefusalCode是枚举而非字符串前缀检查。初始 Windows 集合为BackgroundUnavailable、BackgroundOccluded、BackgroundUipiBlockedLinux 当前只声明BackgroundUnavailable。单元格列出其受控环境允许的确切代码。源码中 RefusalCode 已扩展为 18 个结构化代码含浏览器路由、绑定、consent 等并通过from_driver_code将驱动返回的字符串映射为枚举Targeting使用Ax、Px、Page或NotApplicable。schema 中字段名是targeting而非capture_mode——捕获capture是独立的读取契约DriverRoute命名支撑覆盖的实现路径如 UIA Invoke、PostMessage、坐标注入、CGEvent、AT-SPI action、libei、CDP。它是测试元数据不是请求参数。源码中的 DriverRoute 枚举覆盖了 Win32/UIA、macOS AX/CGEvent、Linux AT-SPI/XSendEvent/XTest/libei/Wayland 虚拟指针/CDP 等 26 种路由并提供了shared_web_route(...)函数按平台 × 显示服务器 × 动作 × 定位 × 投递解析出每个共享单元格应走的驱动路由——这正是每个单元格显式路由的实现依据。目录即唯一事实来源目录是机器可读的清单贡献者文档与覆盖表从它生成或与它核对不存在需要同步的第二个矩阵文件。方案还给出了CaseSpec::validate的语义拒绝契约只允许后台投递声明、必须有 allowed code、且必须同时声明 Focus/ZOrder/NoLeakedInput 三个 oracle——这些校验在 e2e.rs 中逐条实现。3.2 结果记录 v2独立字段消除歧义所有结果使用一个 schema 版本与独立字段字段含义cell_id稳定的用例 idplatform,display_serverOS 与 Win32/Quartz/X11/Wayland 环境harness,toolkitElectron、Tauri、WPF、WinUI3、WebView2、AppKit、SwiftUI、GTK3action,targeting,delivery,scope契约维度driver_route该单元格覆盖的后端路径expected_behaviorDELIVER或REFUSEtest_statusPASS、FAIL、SKIP或ENVIRONMENT_ERRORobserved_behaviorDELIVERED、REFUSED、NO_EFFECT、ERROR或NOT_RUNrefusal_codeobserved 为REFUSED时的结构化代码oracles应用状态与附加的桌面观察known_issue可选 issue id它永远不会把失败变成通过evidence视频、轨迹、截图、结构化状态与日志路径这一设计移除了含糊的EXPECTED_REFUSAL状态。拒绝契约通过的唯一条件是expected_behaviorREFUSE、observed_behaviorREFUSED、代码在允许集合内、且所有 no-side-effect oracle 通过。报告对 delivered 与 refused 的通过分别计数。对应实现见 CaseResult::evaluate要求投递却被拒绝 → 失败期望拒绝却投递 → unexpected delivery requires contract review拒绝码不在允许集合 → 失败。3.3 覆盖选择不恢复笛卡尔积不要自动恢复完整笛卡尔积而是按驱动路由选择单元格工具同时暴露两种投递模式时每个受支持动作都有前台与后台覆盖该动作使用的每条不同定位路径至少一个单元格每条不同的 OS 后端路由至少一个单元格仅当改变路由或曾产生真实兼容缺陷时才保留渲染器/工具包重复每个遗漏组合都要命名equivalent_to单元格或不支持契约的理由。当前共享目录每 harness 应用声明 40 个单元格即每个平台 Electron Tauri 共 80 个共享单元格。新增组合仅在其触及不同驱动路由时添加只有当另一单元格以相同或更强 oracle 证明同一路由时才能删除。四、横切桌面观察者DesktopObserver方案要求新增一个 testkit 接口在操作前后对桌面状态做快照DesktopObservation foreground window target z-order and minimized state focus-change journal real cursor position optional leaked-input journal观察者要附加到每个后台投递单元格、拒绝单元格、launch/minimize 单元格、承诺不改焦点的截图/捕获单元格、光标证据单元格。对于成功的后台投递单元格同时要求目标状态改变与桌面不变量不变对于拒绝要求目标无变化 桌面不变量不变。仅凭焦点通过永远不能证明输入已投递。这一设计在 observer.rs 中完整实现ObserverBackendtrait 提供capabilities()、snapshot(target)、start_journal()、drain_journal()observer.rsDesktopObserver::observe(requested, action)封装前快照 → 启动日志 → 执行动作 → 稳定期默认 150ms→ 排空日志 → 后快照 → 评估 delta的完整流程observer.rsevaluate函数逐 oracle 判定违规焦点变化含日志中的瞬时变化、目标 z-order 上升、真实光标移动超过 1px、前台哨兵收到输入等都会记录为 violationsobserver.rs平台后端能力差异显式化Windows 与 macOS 后端支持 focus/z-order/cursor 但不支持 leaked_inputLinux 在 X11/Hyprland 支持三项而在 Sway/GNOME/cua-compositor 下光标能力受限Wayland 不暴露物理指针位置issue #2194 在跟踪能力检查的光标观察器。能力不足时ensure_supported()会报错而不是静默通过。配套的前台哨兵Foreground Sentinel一个全屏覆盖目标窗口的 Electron 哨兵提供焦点日志与泄漏输入日志。Windows、macOS、X11 都要求哨兵的活动焦点日志报告焦点丢失Wayland 因 Electron/Ozone 对外部表面焦点切换不总是发出 DOMblur事件改用合成器支持的本地焦点观察器但哨兵心跳与泄漏输入日志在 Wayland 上仍然强制。预检会故意向哨兵注入输入并故意抬高后台目标只有观察到泄漏输入与瞬时焦点丢失、哨兵被恢复并再次完全遮挡目标后lane 才继续——这个阳性对照positive control防止坏掉的护栏让所有后台行看起来都绿。五、进程与证据生命周期方案定义的边界每个 lane 一个 Rust 源码构建每个 lane 一个驱动守护进程或 MCP 进程每个 harness 组一个 harness 进程当 fixture 有已验证的重置操作时每个单元格一个录制会话与结果记录crash、重置失败或窗口身份变化后重启 harness。每次 fixture 重置都必须返回一个 generation token。下一个单元格在行动前验证新 token 与干净的标记状态。在 harness 具备该重置契约之前保持 process-per-cell 隔离。test-harnesses-guide.md把替换剩余固定等待为外部状态轮询、增加 fixture 重置 token 后再复用 harness 进程列为待办清单之一。视频对每个规范 E2E 单元格都是强制的。视频捕获在 lane 预检中测试一次录制器失败会在用例目录运行前中止整个 lane而不是对每个单元格生成相同的权限失败。六、环境预检失败一次而不是失败 80 次每个 OS 运行器执行一次预检并输出一条环境记录。规范调用开启严格模式缺失必需能力产生ENVIRONMENT_ERROR永远不能以通过的形式从测试返回。公共检查项源码修订与驱动版本匹配、必需 fixture 二进制存在、显示/用户会话可交互、驱动能列出并检查预检 fixture、辅助功能与捕获权限可用、短视频能起止并通过ffprobe、产物目录可写。平台必需预检Windows非 Session-0 交互桌面、输入桌面、前台哨兵、FFmpeg、UIA 可见性macOSApp-bundle 守护身份、活动 socket、辅助功能、屏幕录制、fixture 窗口可见性Linux X11X server、DBus、AT-SPI、窗口管理器、捕获、输入后端Linux Wayland合成器、DBus、AT-SPI、portal/捕获路径、libei 或声明拒绝路径落地示例Linux 运行器 run-rust-e2e.sh 在跑任何行为测试前先执行e2e_environment_preflight_test的canonical_e2e_environment_is_ready用例并检查ffmpeg/ffprobe/jqWayland 下检查wf-recorder/grim/wtypeCUA_REQUIRE_GUI1让 GUI 生命周期证明在无桌面时失败而非静默通过。Windows 运行器scripts/ci/windows/run-rust-e2e.ps1 -RequireGui同理macOS 走 tests/runners/macos-lume/run-all.sh 维护者包装器provision 精确源码构建并验证 TCC/签名契约后再把行为矩阵委托给规范运行器。七、文件归属与处置每个行为一个清晰 owner方案的文件所有权表以下为原文完整表格当前文件最终 owner 或处置cross_platform_behavior_test.rsShared Electron/Tauri 用例目录 外部 fixture 状态与桌面副作用 oracleharness_wpf_test.rsWPF 特定行使用公共 case/result runnerharness_winui3_test.rsWinUI3 特定行只保留工具包特有行为harness_web_test.rsWebView2 与 Page/CDP 行为不要把 Page 定位与 AX/PX 标签混用harness_appkit_test.rs规范 AppKit 行包括前后台 AX scroll 与精确的 PX 后台拖拽拒绝harness_swiftui_test.rs规范 SwiftUI 树/捕获、后台动作与 popover 触发行瞬态面板枚举是独立缺口harness_gtk3_test.rs最小 GTK3/AT-SPI 行X11 与 Wayland旧 Windows UX guard 目标在 typed launch/cursor/shared/capture/desktop-scope owners 通过替换审计后删除modality_input_e2e_test.rs删除shared 单元格拥有 web 动作Notepad 行没有投递 oraclemodality_background_test.rs删除typed WPF 后台动作行与捕获归属通过替换审计capture_contract_test.rs树/图像包含行为的唯一 owner规范前置条件失败而非跳过desktop_scope_os_test.rs平台特定的窗口/桌面 scope 契约modality_focus_test.rs删除shared click/type 单元格拥有焦点保持启动焦点有 typed 动作 ownerinstalled_app_launch_macos_test.rs规范登录 macOS lane 中 Calculator/TextEdit 启动与焦点行installed_app_textedit_macos_test.rs规范登录 macOS lane 中 TextEdit AX 集成schema 断言留在协议测试harness_libreoffice_test.rs可选已装应用 lane排除在规范运行与计数之外protocol_*、schema、transport 测试单元/协议门禁无桌面视频、无行为矩阵行tests/fixtures/shared/scenarios.json仅在 selector 与 marker 引用审计后修剪这条唯一 owner原则在当前目录结构中得到体现cross_platform_behavior_test.rs承载 Electron/Tauri/WKWebView 共享矩阵harness_*_test.rs按工具包各司其职协议/模式测试保持桌面无关、无视频详见 test-harnesses-guide.md 的 Repository Map 与 Target Ownership 小节。test-matrix.md还指出WebView/CDP/page-tool 集成留在使用它的 shared 或 native owner内部不是第三个公开测试家族或命令。八、CI 形态与报告/证据8.1 贡献者调用与 CI 分工贡献者调用保持无选择器。PR 阶段按受影响 OS 路径跑单元/协议 job共享核心或 schema 变更触发 Linux Windows 单元 job平台专属变更触发该平台单元 jobE2E 由维护者调度可成为可选的合入前门禁。维护者 E2E 的规范环境Windows 用 GitHub-hosted runner预检证明有交互桌面时Azure RDP runner 仅是可选的环境对等重放不是第二行为事实来源。Linux host runner 在 Xvfb 下跑 X11Nix 源码门禁独立纯 Wayland 维护者 lane 用 Nix dev shellLinux 无 GIF 要求。macOS 在登录且 TCC 授权的宿主上经规范 macOS runner 运行。CI 可以把完整矩阵扇出为 shared/native/capture-scope job——这些是执行分区不是替代的公开测试套件。8.2 报告器与证据校验Rust 为每个声明单元格输出一条记录共享报告器随后拒绝重复或缺失的 cell id对照用例契约校验结果校验必需视频证据存在且非空渲染行为表与声明覆盖表当某个声明单元格无结果时失败。禁止解析test ... ok行来生成行为行。每个内部 lane 上传一个产物归档每个行为单元格一个稳定证据子目录GitHub summary 每行以其精确视频路径文本链接到所属 lane 归档trajectory.json路径保留在results.jsonl与归档中。该流程已在 cua-e2e-report.rs 与 validate_catalog 中实现报告器拒绝重复声明/结果、结果契约变更、未声明结果环境记录冲突会断言失败CatalogPolicy从环境读取CUA_E2E_EXPECTED_MIN_CELLS与CUA_E2E_FORBID_SKIPSLinux 规范运行强制 80 个共享单元格、macOS 为 120跳过计数在禁止跳过后直接报错。Linux 运行器还会在视频校验阶段做三件事所有recording.mp4必须通过ffprobe每条视频必须有对应的 typed result 行防孤儿产物一行recording-error.txt存在即判失败。九、实施切片六步收敛路线方案把落地拆为六个可验证的切片每个都有明确出口条件Slice 1 契约与预检敲定CaseSpec、结果枚举、拒绝码枚举与单一 schema 版本报告器增加重复/缺失/矛盾记录校验Windows/Linux/macOS 运行器增加严格环境预检停止 shell 运行器伪造行为行。出口会话/fixture/权限/录制器缺失时作为环境错误一次性失败。Slice 2 共享矩阵完整性每个共享单元格映射显式驱动路由补齐缺失路由单元格并记录省略等价后台与拒绝单元格挂桌面观察者保留 editor-save 与所有外部标记映射完所有断言后移除三个旧共享测试。出口无假拖拽通过、无任意错误冒充拒绝、无共享旧测试、每共享单元格一份结果/证据包。Slice 3 Windows 收敛guard/modality-input/modality-background 断言迁入 shared、WPF、WinUI3、capture、launch 或 desktop-scope owner现有失败动作保留为失败的必需投递单元格或关联 issue 的可选单元格不得转换为绿色拒绝Windows desktop-scope 进规范运行单元格对等校验后才删除过渡文件。Slice 4 macOS 与 Linux 收敛AppKit/SwiftUI/GTK3 采用公共 case/result runner规范提前返回跳过替换为预检失败Linux schema 检查与真实桌面行为分离AppKit scroll 与真实应用检查移入显式可选 issue lane。出口原生单元格与共享单元格输出相同记录X11 与 Wayland 是独立维度macOS 失败能区分 TCC 与驱动行为。Slice 5 抖动与 fixture 清理固定坐标替换为发现几何CDP 端口按进程分配固定 sleep 替换为外部标记的 deadline 轮询fixture 增加 generation-token 重置仅证明干净状态后才复用 harness 进程修剪无活引用 selector/oracle 的 fixture 控件与标记。Slice 6 CI 验证与删除macOS 全矩阵在install-local与 TCC 预检后保持绿色接受的 GitHub-hosted Windows 矩阵作为规范结果Linux X11 与 Nix 源码运行作为受支持的 Linux 门禁纯 Wayland 作为实验性 issue 关联 lane 运行直到#1922关闭删除每个过渡文件前比较新旧单元格从生成目录更新贡献者文档与 PR 描述。十、删除门禁与完成定义任何测试或 fixture 路径可删除的七项门禁所有断言映射到 CaseSpec 或单元/可选 owner替换 oracle 相等或更强在受影响的每个 OS 上比较新旧结果必需投递失败保持可见拒绝单元格使用显式允许代码与桌面副作用证明同一变更中运行器/文档/产物标签停止引用旧目标报告器未发现缺失声明单元格。完成定义Definition of Done方案原文要点Rust 有一个类型化行为目录与一个结果 schema必需 GUI 前置条件不能靠提前返回通过测试状态与观察到的驱动行为是独立字段每个受支持动作按不同驱动路由有前后台覆盖并给出省略理由每个投递动作有外部目标状态 oracle每个后台或拒绝单元格有桌面副作用证据无永久 guard/modality/delivery 测试家族无#[should_panic]已知缺口 E2E 测试无孤儿目标计入覆盖shared 与 native harness 输出相同结果/证据形态单元/协议测试保持桌面无关且无视频Windows、macOS 与受支持的 Linux X11 完整运行产生分类结果与逐单元格证据链接实验性 Wayland 与环境失败显式停止或失败不得产生虚假的行为通过。十一、落地状态与当前工作流方案执行记录显示该计划于 2026-07-12 达成归属与报告目标Windows run29211506624在6d7f02e4通过 114/114 行登录 macOS 矩阵在448d052f通过 133/133 行stable installed-app TCC 身份Linux X11 run29213365684与 Sway run29213349962在72083bb4各通过 108/108 行71 次投递 37 次精确拒绝。可选的嵌套cua-compositorlane 仍为实验性并报告其 typed 失败不贡献 stock-Wayland 支持声明。部分原生目标仍用固定等待shared 与 Windows web 目标轮询外部状态并按进程分配 CDP 端口。当前矩阵的实时覆盖状态请查阅 action-support.md各 OS 投递/拒绝/未证明动作台账、test-matrix.md矩阵维度与单元/E2E 分层与 test-harnesses-guide.md贡献者工作流fixture → Rust 场景 → 声明维度与 oracle → 更新文档 → 跑规范命令。对贡献者而言新增场景的路径是固定的更新仓库本地 fixture 及其外部状态标记 → 在libs/cua-driver/rust/crates/cua-driver/tests/下添加 Rust 场景 → 声明 AX/PX 定位、前后台投递、scope 与 oracle → 更新 test-matrix.md 与 guide → 先跑最小 Rust 测试再跑 OS 规范命令后视为矩阵完成。核心信条始终如一一份 Rust 目录、一份结果 schema、一套跨平台规范运行器——CUA Driver 用收敛而非扩张把桌面输入真的投递了吗变成了可独立复验的证据问题。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考