Files
openhuman/gitbooks/developing/e2e-testing.zh-CN.md
T
JAYcodrGitHubagent:skill-master <skill-master@openclaw>
3299c16933 Docs/i18n batch c1 developing foundation (#2504)
Co-authored-by: agent:skill-master <skill-master@openclaw>
2026-05-22 15:44:59 -07:00

10 KiB
Raw Blame History

description, icon, lang
description icon lang
使用 WDIO + tauri-driver / Appium 进行端到端测试。CI 和本地设置。 vials zh-CN

E2E 测试指南

概述

桌面 E2E 测试使用 WebDriverIO (WDIO) 通过两个自动化后端驱动 Tauri 应用:

平台 驱动 端口 应用格式 选择器
Linux / CEF 状态 tauri-driver 4444 Debug 二进制文件 CSS / DOM
macOS / Appium Appium Mac2 4723 .app XPath / 辅助功能

OpenHuman 桌面应用目前使用 CEF 运行时(tauri-runtime-cef)。Linux tauri-driver 与 WebKitWebDriver / webkit2gtk 通信,无法驱动 CEF -backed WebView,因此 Linux CEF E2E 在 CI 中被禁用,直到存在 CEF 兼容的驱动或替代 harness。目前支持的路径是 macOS/Appium 用于本地运行,以及在该工作流启用时手动触发 macOS/Appium 工作流运行。


快速开始

Linux / CEF 状态

# 安装 tauri-driver(一次性)
cargo install tauri-driver

# 构建 E2E 应用
pnpm --filter openhuman-app test:e2e:build

# 运行所有流程
pnpm --filter openhuman-app test:e2e:all:flows

# 运行单个 spec
bash app/scripts/e2e-run-spec.sh test/e2e/specs/smoke.spec.ts smoke

在无头 Linux 上,harness 在 Xvfb 虚拟显示下运行。此路径目前仅对非 CEF / WebKit 兼容调试有用;默认 CEF 应用无法被 WebKitWebDriver 自动化。

macOS / Appium

# 安装 Appium + Mac2 驱动(一次性,需要 Node 24+)
npm install -g appium
appium driver install mac2

# 构建 .app 包
pnpm --filter openhuman-app test:e2e:build

# 运行所有流程
pnpm --filter openhuman-app test:e2e:all:flows

macOS 上的 Docker(本地运行 Linux harness

使用 Docker 从 macOS 运行相同的基于 Linux 的 harness。同样的 CEF 限制适用:在存在 CEF 兼容驱动之前,这不是默认 CEF 运行时的支持路径。

# 构建 + 运行所有 E2E 流程
docker compose -f e2e/docker-compose.yml run --rm e2e

# 先构建应用(如需要)
docker compose -f e2e/docker-compose.yml run --rm e2e \
  pnpm --filter openhuman-app test:e2e:build

# 运行单个 spec
docker compose -f e2e/docker-compose.yml run --rm e2e \
  bash app/scripts/e2e-run-spec.sh test/e2e/specs/smoke.spec.ts smoke

需要 Docker Desktop 或 Colima。仓库通过 bind mount 挂载,因此构建在运行之间持久化。


架构

平台检测

app/test/e2e/helpers/platform.ts 导出:

  • isTauriDriver()true 表示 Linuxtauri-driver session
  • isMac2()true 表示 macOSAppium Mac2 session
  • supportsExecuteScript()truebrowser.execute() 可用时(仅 tauri-driver

元素辅助函数

app/test/e2e/helpers/element-helpers.ts 提供统一 API

辅助函数 Mac2 (macOS) tauri-driver (Linux)
waitForText(text) @label/@value/@title 上的 XPath DOM 文本内容上的 XPath
waitForButton(text) XCUIElementTypeButton XPath button / [role="button"] XPath
clickText(text) W3C 指针动作 标准 el.click()
clickNativeButton(text) XCUIElementTypeButton 上的 W3C 指针动作 button 上的标准 el.click()
clickToggle() XCUIElementTypeSwitch / XCUIElementTypeCheckBox [role="switch"] / input[type="checkbox"]
waitForWindowVisible() XCUIElementTypeWindow 窗口句柄检查
waitForWebView() XCUIElementTypeWebView document.readyState 检查
hasAppChrome() XCUIElementTypeMenuBar 窗口句柄检查
dumpAccessibilityTree() 辅助功能 XML HTML 页面源码

稳定的测试 ID

优先为 E2E spec 点击或轮询的 UI affordance 使用稳定的 data-testid hook。使用分类法 <surface>-<element>-<id?>,例如:

  • cron-jobs-panelcron-refresh
  • cron-job-row-<jobId>cron-job-toggle-<jobId>cron-job-run-<jobId>cron-job-view-runs-<jobId>cron-job-remove-<jobId>
  • settings-nav-<routeId>
  • skill-row-<skillId>skill-install-<skillId>skill-uninstall-<skillId>
  • thread-row-<threadId>new-thread-buttonsend-message-button
  • onboarding-next-button

当 spec 瞄准这些 hook 之一时,使用 element-helpers.ts 中的 waitForTestId(testId)clickTestId(testId)。对行/动作发现保留文本选择器,对用户可见文案断言也保留文本选择器。

深度链接辅助函数

app/test/e2e/helpers/deep-link-helpers.ts 处理 auth 深度链接:

  • tauri-driverbrowser.execute(window.__simulateDeepLink(url))(主要),xdg-open(备用)
  • Appium Mac2macos: deepLink 扩展命令(主要),open -a ...(备用)

对于发布候选版,在触碰 CEF preflight、单实例或深度链接启动代码时,还要在 Linux 或 macOS 上运行一次手动 secondary-instance 冒烟测试:

  1. 正常启动 OpenHuman 并保持运行。
  2. 通过 OS opener 触发 openhuman://auth?token=e2e-token&key=auth
  3. 确认已运行的窗口接收到回调,且不会启动第二个完整的 CEF 实例。
  4. 确认 secondary 进程干净退出,没有 CEF 缓存锁错误。

这捕捉了一类回归:secondary 进程在 Tauri 的深度链接转发路径安装之前,于 CEF 缓存 preflight 期间退出。

编写跨平台 spec

  1. 在 spec 中使用 element-helpers.ts 中的辅助函数,永远不要使用原始的 XCUIElementType* 选择器
  2. 使用 clickNativeButton(text) 代替内联 button-clicking 代码
  3. 使用 hasAppChrome() 代替检查 XCUIElementTypeMenuBar
  4. 使用 waitForWebView() 代替检查 XCUIElementTypeWebView
  5. 对于仅 macOS 的测试,使用 process.platform 守卫或单独的 spec 文件
  6. 对 hash 路由使用 navigateViaHash(route);它等待 hash、document.readyState 和挂载的 React root 后返回。在 onboarding 之后,walkOnboarding() 也等待 #/home 加上 Home 页面标记,然后 spec 才会导航到别处。

环境变量

变量 默认值 说明
TAURI_DRIVER_PORT 4444 tauri-driver WebDriver 端口
APPIUM_PORT 4723 Appium 服务器端口
E2E_MOCK_PORT 18473 Mock 后端服务器端口
OPENHUMAN_WORKSPACE (临时目录) 应用工作区目录
OPENHUMAN_SERVICE_MOCK 0 启用服务 mock 模式
OPENHUMAN_E2E_MODE 未设置 启用破坏性测试支持 RPC;E2E runner 将其设为 1
OPENHUMAN_E2E_AUTH_BYPASS 未设置 启用 JWT 绕过认证
DEBUG_E2E_DEEPLINK (verbose) 设为 0 以静默深度链接日志
E2E_FORCE_CARGO_CLEAN 未设置 E2E 构建前强制 cargo clean

CI 工作流

Push / PR 检查

默认的 test.yml 工作流运行前端单元测试和 Rust 检查。其 Linux tauri-driver E2E job 被注释掉了,因为 WebKitWebDriver 无法驱动 CEF-backed WebView。

被禁用的 Linux E2E job 过去会:

  1. 安装系统依赖(webkit2gtk、Xvfb、dbus
  2. 通过 cargo 安装 tauri-driver
  3. 用 mock 服务器 URL 构建应用
  4. 在 Xvfb 下运行所有 E2E 流程

macOS / Appium

macOS/Appium 是当前 CEF 桌面应用支持的自动化后端。在本地运行,或在该工作流启用时通过手动触发的 macOS 工作流运行:

  1. 安装 Appium + Mac2 驱动
  2. 构建 .app
  3. 运行所有 E2E 流程

故障排除

Linux"WebView not ready" 超时

对于默认 CEF 运行时,这通常意味着不支持的 Linux tauri-driver 路径正试图通过 WebKitWebDriver 驱动 CEF-backed WebView。请使用 macOS/Appium,或等待 CEF 兼容的 Linux 驱动。

确保 DISPLAY 已设置且 Xvfb 正在运行:

export DISPLAY=:99
Xvfb :99 -screen 0 1280x1024x24 &

还要确保 dbus 已启动(webkit2gtk 需要):

eval $(dbus-launch --sh-syntax)

Linux:找不到 tauri-driver

cargo install tauri-driver

macOS:深度链接在 tauri dev 中不工作

深度链接需要 .app 包。请改用 pnpm tauri build --debug --bundles app

Docker:首次运行构建很慢

首次 Docker 构建从源码编译 Rust + tauri-driver。后续运行使用缓存层。Cargo registry 和 git 源通过 Docker volume 缓存。

SpecNotifications

文件app/test/e2e/specs/notifications.spec.ts

通过实时 core sidecar 和 Notifications UI 页面测试 notification RPC 方法:

  • notification_ingest,通过 core RPC 创建新通知
  • notification_list,验证摄入的通知被返回
  • notification_mark_read,将通知标记为已读
  • notification_stats,检查聚合统计形状
  • UINotifications 页面渲染集成通知部分([data-testid="integration-notifications-section"]
  • UINotifications 页面显示 System Events 部分([data-testid="system-events-section"]

运行

bash app/scripts/e2e-run-spec.sh test/e2e/specs/notifications.spec.ts notifications

平台说明RPC 测试(notification_ingestnotification_listnotification_mark_readnotification_stats)为 Linux/tauri-driver 和 macOS/Appium Mac2 编写,但默认 CEF 运行时的 Linux 执行被禁用,直到存在 CEF 兼容驱动。UI 断言(Notifications 页面部分)需要 browser.execute() 支持,因此当 supportsExecuteScript() 返回 false 时,它们在 Mac2 上自动跳过。


Agent 可观测的工件流

对于一种规范的、可检查的 run,将截图、页面源码 dump 和 mock 请求日志写入磁盘:

bash app/scripts/e2e-agent-review.sh

工件落在 app/test/e2e/artifacts/<timestamp>-agent-review/。完整详情 + 辅助 APIAGENT-OBSERVABILITY.md。任何失败的测试都会触发 wdio.conf.tsafterTest hook,将 failure-*.png + failure-*.source.xml 写入同一运行目录。


Rust 推理提供商 E2E

这些测试(tests/inference_provider_e2e.rs)使用 wiremock 模拟 HTTP upstream,不需要实时 LLM API 调用。它们覆盖 OpenAI 兼容聊天、Anthropic 认证风格、每模型温度抑制、Ollama 本地提供商和 /v1 HTTP 端点认证层。

# 本地:
bash scripts/test-rust-inference-e2e.sh

# 通过 DockerLinux,与 CI 相同镜像):
docker compose -f e2e/docker-compose.yml run --rm inference-e2e