ha4t package
Subpackages
- ha4t.aircv package
- Submodules
- ha4t.aircv.aircv module
- ha4t.aircv.cal_confidence module
- ha4t.aircv.cv module
- ha4t.aircv.error module
- ha4t.aircv.keypoint_base module
- ha4t.aircv.keypoint_matching module
- ha4t.aircv.keypoint_matching_contrib module
- ha4t.aircv.multiscale_template_matching module
- ha4t.aircv.resolution module
- ha4t.aircv.settings module
- ha4t.aircv.sift module
- ha4t.aircv.template module
- ha4t.aircv.template_matching module
- ha4t.aircv.transform module
- ha4t.aircv.utils module
- Module contents
- Submodules
- ha4t.cdp package
- ha4t.drivers package
- Submodules
- Module contents
BaseDriverBaseDriver.connect()BaseDriver.get_device_info()BaseDriver.screen_size()BaseDriver.screenshot()BaseDriver.tap()BaseDriver.swipe()BaseDriver.press()BaseDriver.find()BaseDriver.find_xpath()BaseDriver.app_start()BaseDriver.app_stop()BaseDriver.app_current()BaseDriver.app_clear()BaseDriver.push_file()BaseDriver.pull_file()BaseDriver.delete_file()
AndroidDriverAndroidDriver.connect()AndroidDriver.get_device_info()AndroidDriver.screen_size()AndroidDriver.screenshot()AndroidDriver.tap()AndroidDriver.swipe()AndroidDriver.press()AndroidDriver.find()AndroidDriver.find_xpath()AndroidDriver.get_element_center()AndroidDriver.app_start()AndroidDriver.app_stop()AndroidDriver.app_current()AndroidDriver.app_clear()AndroidDriver.push_file()AndroidDriver.pull_file()AndroidDriver.delete_file()AndroidDriver.adb_device
IOSDriverIOSDriver.connect()IOSDriver.get_device_info()IOSDriver.screen_size()IOSDriver.screenshot()IOSDriver.tap()IOSDriver.swipe()IOSDriver.press()IOSDriver.find()IOSDriver.find_xpath()IOSDriver.get_element_center()IOSDriver.app_start()IOSDriver.app_stop()IOSDriver.app_current()IOSDriver.push_file()IOSDriver.pull_file()IOSDriver.delete_file()IOSDriver.mkdir()
HarmonyDriverHarmonyDriver.connect()HarmonyDriver.get_device_info()HarmonyDriver.screen_size()HarmonyDriver.screenshot()HarmonyDriver.tap()HarmonyDriver.swipe()HarmonyDriver.press()HarmonyDriver.find()HarmonyDriver.find_xpath()HarmonyDriver.get_element_center()HarmonyDriver.app_start()HarmonyDriver.app_stop()HarmonyDriver.app_current()
- ha4t.utils package
Submodules
Module contents
HA4T —— 跨平台 UI 自动化测试框架。
核心抽象:
- connect(platform=...) 返回 Device,所有平台同一套 API:
dev.click(...)/dev.swipe(...)/dev.wait(...)/dev.assert_element(...)...
Selector类承载跨平台元素定位器::from ha4t import connect, Selector LOGIN = Selector(android={"text": "登录"}, ios={"label": "Login"}) dev = connect(platform="android") dev.click(LOGIN) # 平台分桶自动选 android 分支
临时定位也接受 canonical kwargs,自动按当前平台翻译::
dev.click(text="登录") # iOS 上自动用 label='登录'
模块结构:
- ha4t.selector —— Selector / canonical→native 映射
- ha4t.device —— Device 类(用 mixin 装配出来)
- ha4t.matchers —— OCR / 图像找点(与 Device 解耦的找点策略)
- ha4t.drivers —— Android / iOS / Harmony 平台 driver
POM 工程化用法见工作区根目录 ``AGENTS.md``(编辑器初始化时自动生成)。
- class Device(driver=None, config: DeviceConfig | None = None)[源代码]
基类:
InteractionMixin,QueryMixin,AppMixin,FileMixin,CaptureMixin,DeviceBase跨平台 UI 自动化设备入口。
持有
config+driver,把所有 UI 操作统一暴露在self上。 平台差异由driver隔离,selector 跨平台语义由self._resolve_selector+Selector类承担,Device自身只负责 动作分发。
- connect(platform: str = 'android', device_serial: str | None = None, android_package_name: str | None = None, android_activity_name: str | None = None, **driver_kwargs) Device[源代码]
连接设备,返回
Device。- 参数:
platform -- 平台标识
android/ios/harmonydevice_serial -- 设备序列号;为
None时取系统第一个可用设备android_package_name -- Android 包名(写进
DeviceConfig,start_app默认值)android_activity_name -- Android 启动 Activity(同上)
driver_kwargs -- 透传给底层 driver.connect() 的额外关键字
- include(path: str) None[源代码]
在当前进程内执行另一个用例 .py 文件,复用其步骤。
被引用文件中的
import os / os.environ / from ha4t import ... / from time import sleep / dev = connect(...)这些样板代码会被剥离, 其余源码在调用者的全局命名空间中exec——这样被引用文件可以直接 使用调用者已经建立的dev连接 /sleep等符号,无需重新连接设备。路径解析顺序:调用者所在目录 → 调用者所在目录下的 testcases/(编辑器工作区模式)→ 当前工作目录下的 testcases/ → 当前工作目录 → 字面路径。 通过
_INCLUDE_STACK防止循环引用。
- class Selector(*, image: str | None = None, **kwargs: Any)[源代码]
基类:
object跨平台元素定位器(不可变值对象)。
示例:
# 平台 native selector 分别采集 LOGIN_BTN = Selector(
android={"resourceId": "com.x:id/login", "text": "登录"}, ios={"label": "Login"},
)
# 跨平台共享图像 LOGIN_ICON = Selector(image="login_icon.png")
# 带 meta(_parent 父子关系、_doc 给 AI 看的注释) BACK_BTN = Selector(
_parent="顶部导航", _doc="点击退回上一页", android={"text": "返回"}, ios={"label": "Back"},
)
- 解析顺序(for_platform(p)):
该平台分桶里有 native selector → 返回之
平台分桶为空 → 落回 image`(如有),返回 `{"image": ...}
都没 → raise SelectorNotAvailableError
- property parent: str | None
父元素名;无父返回 None。
- property doc: str | None
元素自由文本说明;无返回 None。
- property image: str | None
图像模板文件名;非图像元素返回 None。
- for_platform(platform: str) Dict[str, Any][源代码]
返回该平台的 native kwargs,可以 ** 解包传给 driver.find。
优先级:平台分桶 > image fallback > raise。 meta 字段(_parent/_doc)从来不在输出里。
- with_platform(platform: str, **kwargs: Any) Selector[源代码]
返回新 Selector,覆盖某平台分桶的字段(不动其它平台 / meta / image)。
- format(**kwargs: Any) Selector[源代码]
按平台分桶逐字段 str.format(**kwargs),返回新 Selector。
用于参数化元素(列表项第 N 个、模板文本含变量等):
- "商品项": Selector(
android={"xpath": "//*[@resource-id='list']/View[{index}]"}, ios={"xpath": "//XCUIElementTypeCell[{index}]"},
)
dev.click(ELEMENTS["商品项"].format(index=2))
非字符串字段(index、image)原样保留。
- classmethod everywhere(**kwargs: Any) Selector[源代码]
所有平台用同一份 native kwargs 的工厂方法。
"取消": Selector.everywhere(text="取消") # 等价 Selector(android={"text":"取消"}, ios={"text":"取消"}, harmony={"text":"取消"})
注意:本工厂走的是 canonical 同名 假设——text="取消" 在所有平台都用 text 字段。这适用于真正所有平台都同样写法的场景;如果各平台字段不同,仍要写完整的 分桶 Selector(android=..., ios=...)。