Skip to main content

跨平台 UI 自动化框架,当前聚焦 HarmonyOS

Project description

devhelmkit

跨平台 UI 自动化框架,当前聚焦 HarmonyOS。

PyPI version PyPI downloads Python versions PyPI license Publish GitHub stars

API 参考

概述

devhelmkit 为 HarmonyOS 设备提供 UI 自动化测试能力。通过 hdc 直连设备,无需任何测试框架运行时。

核心目标:

  • 简洁 APId(text="登录").click()d.app_start()d.dump_hierarchy()
  • 直连设备:仅通过 hdc 通信,不依赖测试框架
  • 跨平台抽象BaseDriver 契约 + 平台实现(HarmonyOS 已全功能可用,Android 预留)
  • 高级能力:鼠标、触控笔、指关节、触控板、多指手势

功能特性

  • 选择器链d(text="xx") / d(id="xx") / d.xpath("//Text")
  • 控件操作:点击、长按、输入、拖拽、滑动、属性查询
  • 设备控制:亮屏/熄屏、解锁、按键、旋转、截图
  • 应用管理:启动、停止、安装、卸载
  • 高级手势:完整鼠标操作、触控笔(带压力)、指关节敲击、多指
  • 触控板:多指滑动、滑动停顿
  • 事件监听:Toast 监听、UI 事件(对话框/窗口/组件)
  • WebView 自动化:通过 chromedriver + selenium 测试应用内网页
  • 图像匹配:模板匹配(多尺度 + 颜色校验)和特征匹配(SIFT/ORB)
  • OCR:通过 RapidOCR(ONNX Runtime)识别屏幕文本
  • 双查找后端:uitest(设备端 RPC)+ uitree(本地布局解析)
  • 屏幕录制:JPEG 帧捕获与 MP4 编码
  • 资源管理:自动清理 socket/端口转发,可选停止守护进程
  • 网页版 UIViewer:本地双端口 Web 服务,实时投屏查看控件
  • 跨平台:Windows / Linux / macOS,可配置 hdc 路径

UIViewer 网页版控件查看器

UIViewer 提供本地 Web 界面,支持实时投屏、控件树查看和触控操作。

启动

devhelmkit-uiviewer

无需参数,启动后自动打开浏览器。每次启动使用系统分配的空闲端口,互不冲突。

开启性能排查日志(采集帧率、推流帧率、触控 RPC 耗时):

devhelmkit-uiviewer --perf

两种采集模式

模式 截图来源 控件树来源 触控 说明
单次 (snapshot) hdc snapshot_display hdc dumpLayout 文件导出 禁用 不启动 RPC 和截图推流
实时 (live) uitest startCaptureScreen dump_hierarchy rpc 启用 down/move/up 实时投屏 + 触控

功能

  • 页面内选择/切换手机
  • 模式切换:单次 (HDC) / 实时 (UITest)
  • 截图上叠加控件 bounds,高亮 hover/selected 节点
  • 右侧控件树和属性面板,属性值一键复制
  • 实时模式支持鼠标 down/move/up 映射为设备 touch
  • 实时模式设备导航键:返回 / 主页 / 多任务
  • 实时模式锁定画面后检视控件(锁定时重新抓取控件树,与锁定瞬间画面对应)
  • 画面刷新:实时投屏为变化驱动,画面静止时可点击画面内刷新按钮唤醒一帧
  • 关闭时清理 uitest 可选(默认保留)
  • 单次模式手动刷新时,截图帧与控件树来自同一次刷新链路

端口

启动时自动分配两个系统空闲端口:

  • control_port:页面、API、配置、touch 控制
  • jpeg_port:JPEG/MJPEG 图片流

运行时端点按职责隔离:

端口 端点 职责
control_port GET /GET /index.htmlGET /static/app.js 页面与静态资源
control_port GET /api/runtimeGET /api/devicesGET /api/session?serial=... 运行时端口、设备列表、会话状态
control_port POST /api/session/selectPOST /api/session/modePOST /api/session/cleanupPOST /api/session/close 设备选择、模式切换、清理策略、关闭会话
control_port POST /api/refreshGET /api/hierarchy?serial=...POST /api/touch 刷新帧与控件树、实时控件树、live 触控
control_port POST /api/keyPOST /api/live/refresh live 设备导航键、强制刷新一帧画面
jpeg_port GET /snapshot.jpg?serial=...&frame=... snapshot 单帧 JPEG;网页刷新链路读取 /api/refresh 缓存帧
jpeg_port GET /stream.mjpeg?serial=... live MJPEG 图片流

浏览器不直连裸 TCP;图片只从 jpeg_port 拉取,控制 API 只走 control_port

进程退出时只释放本次实例创建的端口和资源。

安装

前置条件

  • Python 3.8+(Windows / Linux / macOS)
  • HarmonyOS 设备,已开启开发者模式和 USB 调试
  • hdc(HarmonyOS Device Connector)— 用于设备通信

安装 hdc

hdc 随 HarmonyOS SDK 一起提供:

  1. 下载 HarmonyOS SDK(选择 Command Line Tools)
  2. 解压后,hdc 位于 sdk/<版本>/toolchains/ 目录
  3. 将该目录添加到系统 PATH
  4. 验证:
hdc -v
# HarmonyOS Device Connector vX.X.X

验证设备连接:

hdc list targets
# ABCD1234567890

安装 devhelmkit

方式一:pip(推荐)

pip install devhelmkit

方式二:源码安装

git clone https://github.com/yabi-zzh/devhelmkit.git
cd devhelmkit
pip install -e .

依赖

核心依赖(自动安装):

用途
Pillow>=9.0.0 截图处理

基础安装即包含原生自动化能力:控件查找/操作、设备控制、手势、事件监听、屏幕录制等核心功能无需任何额外依赖。

可选依赖(按需安装):

Extra 安装命令 额外引入的包 功能范围
cv pip install devhelmkit[cv] opencv-python-headless, numpy 图像匹配(模板 + 特征)
ocr pip install devhelmkit[ocr] rapidocr-onnxruntime, opencv-python-headless, numpy OCR 文本识别(含图像匹配能力)
webview pip install devhelmkit[webview] selenium WebView / 应用内浏览器自动化
all pip install devhelmkit[all] 以上全部 全部能力(cv + ocr + webview)
dev pip install devhelmkit[dev] pytest, pytest-cov, build, twine 开发 / 测试 / 发布工具链

依赖关系ocr 已包含 cv 的全部依赖(opencv + numpy),安装 [ocr] 后无需再装 [cv][all]cv + ocr + webview 的超集。

快速开始

import devhelmkit

# 自动发现并连接设备
d = devhelmkit.connect()

# 启动应用
d.app_start("com.huawei.hmos.settings")

# 查找并操作控件
d(text="搜索").click()
d(className="TextInput").input_text("devhelmkit")

# 截图
d.screenshot().save("screen.png")

# 导出控件树
hierarchy = d.dump_hierarchy()

# 关闭连接,释放 socket 和端口转发
d.close()

资源清理

使用 with 语句或 try/finally 确保资源释放:

import devhelmkit

with devhelmkit.connect() as d:
    d.app_start("com.huawei.hmos.settings")
    d(text="搜索").click()
# 退出时自动调用 close()

关闭时同时停止设备端 uitest 守护进程(默认:保留以便复用):

# 方式一:运行时指定
d.close(stop_daemon=True)

# 方式二:通过配置
from devhelmkit.harmony.config import HarmonyDriverConfig

config = HarmonyDriverConfig(stop_daemon_on_close=True)
d = devhelmkit.connect(config=config)

指定设备

# 多设备时指定序列号
d = devhelmkit.connect(serial="1234567890ABCDEF")

# 显式指定平台
d = devhelmkit.connect(platform="harmony")

配置 hdc 路径

当 hdc 不在 PATH 中,或需要使用特定版本时:

import devhelmkit
from devhelmkit.harmony.device.hdc import HdcDevice

# 全局设置(影响后续所有连接)
HdcDevice.set_hdc_path("/path/to/hdc")

d = devhelmkit.connect()

或通过配置:

from devhelmkit.harmony.config import HarmonyDriverConfig

config = HarmonyDriverConfig(hdc_path="/path/to/hdc")
d = devhelmkit.connect(config=config)

API 示例

控件操作

# 等待控件出现
d(text="登录").wait(timeout=10)

# 输入文本
d(id="username").input_text("admin")

# 清空文本
d(id="username").clear_text()

# 长按
d(text="条目").long_click()

# 拖拽到另一控件
d(text="A").drag_to_component(d(text="B"))

# 获取属性
print(d(text="标题").info)
print(d(text="标题").bounds)

图像匹配

需要安装:pip install devhelmkit[cv]

# 模板匹配(默认,快速)
rect = d.vision.find_image("icon.png")
if rect:
    print(f"找到,位置: {rect}")

# 特征匹配(抗缩放/旋转)
rect = d.vision.find_image("icon.png", mode="feature", threshold=0.7)

# 查找并点击
d.vision.touch_image("button.png")

# 检查是否存在
if d.vision.exists_image("logo.png"):
    print("Logo 已找到")

# 等待图像出现
d.vision.wait_image("loading_done.png", timeout=15)

OCR

需要安装:pip install devhelmkit[ocr]

# 查找并点击文本
d.vision.click_text("设置")

# 模糊匹配(忽略大小写的子串匹配)
d.vision.click_text("设置", fuzzy=True)

# 获取 OCR 结果含坐标
result = d.vision.find_text("登录")
if result:
    print(f"找到: {result.text} 位置: {result.bounds} 置信度: {result.confidence}")

# 识别区域内所有文本
results = d.vision.ocr(region=(100, 200, 500, 400))
for r in results:
    print(f"{r.text} @ {r.bounds} (置信度={r.confidence:.2f})")

手势

# 滑动
d.swipe(100, 500, 100, 100)

# 双指滑动
d.two_finger_swipe((0, 400), (200, 400), (880, 400), (680, 400))

# 自定义手势
from devhelmkit.model.input import GestureAction

g = GestureAction()
g.add_step("move", 100, 200)
g.add_step("move", 200, 300)
d.inject_gesture(g, speed=1000)

鼠标

# 左键点击
d.mouse_click((500, 500))

# 右键点击
d.mouse_click((500, 500), button_id=1)

# 滚轮
d.mouse_scroll((500, 500), "down", steps=3)

# 拖拽
d.mouse_drag((100, 100), (300, 300))

触控笔

# 点击
d.pen_click((500, 500))

# 带压力长按
d.pen_long_click((500, 500), pressure=0.8)

# 方向滑动
d.pen_swipe("UP", distance=60)

事件监听

# Toast 监听
d.start_listen_toast()
d(text="提交").click()
print("Toast:", d.get_latest_toast(timeout=3))

# 检查 Toast
if d.check_toast("保存成功", fuzzy="contains"):
    print("操作成功")

屏幕录制

方式一:手动控制

# 开始录制
d.start_recording("/tmp/recording")

# ... 执行操作 ...

# 停止并编码为 MP4
video_path = d.stop_recording("/tmp/recording/output.mp4")
print(f"视频已保存: {video_path}")

方式二:上下文管理器(推荐)

# 异常时自动停止录屏,资源必定释放
with d.record("/tmp/output.mp4") as rec:
    d(text="登录").click()
    d(text="密码").input_text("xxx")
# 退出 with 块时自动合成视频
print(f"视频已保存: {rec.video_path}")

设备控制

# 亮屏/熄屏
d.wake_up_display()
d.close_display()

# 按键
from devhelmkit.model.keys import KeyCode

d.press_keycode(KeyCode.ENTER)  # 确认键

# 截图
img = d.screenshot()
img.save("capture.png")

# 安装应用
d.app_install("/path/to/app.hap")

应用管理

# 启动应用(自动探测 main ability,无需手动指定 Ability 名)
d.app_start("com.example.app")

# 指定 Ability 启动
d.app_start("com.example.app", "EntryAbility")

# 强制重启(回桌面 → 停止 → 启动)
d.force_start_app("com.example.app")

# 强制重启并清除数据
d.force_start_app("com.example.app", clear_data=True)

# 停止 / 卸载 / 清除数据
d.app_stop("com.example.app")
d.app_uninstall("com.example.app")
d.clear_app_data("com.example.app")

# 查询应用信息
d.app_list()                    # 已安装应用列表
d.has_app("com.example.app")    # 是否已安装
d.app_current()                 # 当前前台应用 (package, ability)
d.get_app_info("com.example.app")  # 完整应用信息 dict

深链 / Schema

# 网页 URL(自动用系统浏览器打开)
d.open_url("https://www.example.com")

# 应用深链(由系统选择处理方,如 kwai:// 触发快手App)
d.open_url("kwai://myprofile")

# 强制指定是否用系统浏览器
d.open_url("https://www.example.com", system_browser=False)

WebView 自动化

需要安装:pip install devhelmkit[webview]

需下载与设备 WebView 版本匹配的 chromedriver:

# 方式一:使用内置下载脚本(推荐)
# 自动探测设备 WebView 版本并下载
python scripts/download_chromedriver.py --auto

# 指定版本号下载
python scripts/download_chromedriver.py 114 -o ./chromedriver

# 查看可用版本
python scripts/download_chromedriver.py --list

或手动下载后按以下结构放置:

chromedriver_search_path/
├── chromedriver_114/
│   ├── chromedriver.exe      # Windows
│   ├── chromedriver          # Linux
│   └── chromedriver.mac      # macOS
└── chromedriver_132/
    ├── chromedriver.exe
    ├── chromedriver
    └── chromedriver.mac
# 连接应用 WebView
wv = d.webview(
    "com.huawei.hmos.browser",
    chromedriver_search_path="/path/to/chromedriver_search_path"
)

# 通过 selenium webdriver 操作
wv.driver.get("https://www.example.com")
wv.driver.find_element("id", "search").send_keys("devhelmkit")

# 释放资源
wv.close()

架构

devhelmkit/                # 仓库根
├── src/devhelmkit/        # 包源码(src layout)
│   ├── core/              # 跨平台契约
│   │   ├── base_driver.py     # BaseDriver:设备驱动契约
│   │   ├── base_component.py  # BaseComponent:控件契约
│   │   ├── base_window.py     # BaseWindow:窗口契约
│   │   ├── selector_spec.py   # SelectorSpec:纯数据选择器
│   │   └── vision/            # 图像匹配 + OCR(平台无关)
│   │       ├── image_matcher.py    # OpenCV 模板 + 特征匹配
│   │       ├── ocr_engine.py       # RapidOCR 封装
│   │       └── vision_extension.py # d.vision 命名空间
│   ├── model/             # 纯数据类型(Rect / KeyCode / GestureAction / ...)
│   ├── harmony/           # HarmonyOS 平台实现
│   │   ├── driver.py          # 平台驱动门面
│   │   ├── config.py          # HarmonyDriverConfig
│   │   ├── device/            # hdc 命令封装 + RPC 通道
│   │   ├── rpc/               # 二进制 RPC 协议 + 远程对象管理
│   │   ├── finder/            # 控件查找(uitest + uitree 双后端)
│   │   ├── agent/             # 设备端 uitest 守护进程管理
│   │   └── webview/           # WebView 自动化(chromedriver + selenium)
│   ├── uiviewer/          # 网页版控件查看器(双端口 Web 服务)
│   ├── android/           # Android 平台(预留)
│   ├── utils/             # 工具(日志 / 重试 / 超时)
│   └── assets/so/         # 设备端 agent.so 二进制
└── scripts/           # 辅助脚本(chromedriver 下载工具)

完整 API 参考见 api_reference.md

开发

代码结构约定

  • core/ 不得依赖平台实现
  • model/ 无内部依赖,可跨平台复用
  • 平台实现按 device/rpc/finder/ 组织
  • RPC 层不感知 UI 对象;设备通道不理解控件定位

贡献

欢迎提交 Issue 和 Pull Request。

参与本项目请遵守行为准则。版本变更记录见 CHANGELOG.md

许可证

Apache License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devhelmkit-0.3.1.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devhelmkit-0.3.1-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file devhelmkit-0.3.1.tar.gz.

File metadata

  • Download URL: devhelmkit-0.3.1.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for devhelmkit-0.3.1.tar.gz
Algorithm Hash digest
SHA256 737bad6b8eaf7e946ced8151d8049e41b2a982b7136c7cd385b39f7fcf553b38
MD5 1c7f01d5b63dd09c399c40155fcc1901
BLAKE2b-256 84c133dccf6ec1155a8eebb66131c87ca20484a27f57283f42b236c774ef4c5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for devhelmkit-0.3.1.tar.gz:

Publisher: publish.yml on yabi-zzh/devhelmkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file devhelmkit-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: devhelmkit-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for devhelmkit-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5ebf70c8973028c677c28db5e7b5f3c8d31e7eaacc30e381018f748a3ef8af8e
MD5 6fd90ac211ec0bf7d2af23b7daa8dd8f
BLAKE2b-256 1dfb214fedcdf4e44c9a3c39403c9dfaa6aa88e17f1c91f49dea439e97d482b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for devhelmkit-0.3.1-py3-none-any.whl:

Publisher: publish.yml on yabi-zzh/devhelmkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page