# HA4T 🐍
[![PyPI version](https://badge.fury.io/py/ha4t.svg)](https://badge.fury.io/py/ha4t)
[![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen)](https://exuils.github.io/HA4T/)
HA4T (Hybrid App For Testing Tool)
是一个跨平台的UI自动化框架,适用于混合型app、web和原生app等。该框架基于airtest、飞浆OCR、WS、uiautomator2和facebook_wda进行开发。
## 特性
- 跨平台支持:适用于iOS、Android和Web应用
- 多种定位方式:支持图像识别、OCR文字识别、webview定位、原生控件定位等
- 灵活的操作API:提供点击、滑动、输入等常用操作
## 安装
使用pip安装HA4T:
```bash
pip install ha4t
```
## 快速开始
以下是一个简单的示例,展示如何使用HA4T进行基本操作:
```python
# 原生定位
from ha4t import connect
from ha4t.api import *
connect(platform="android")
# 启动应用
start_app(activity="com.xxx.xxx.MainActivity",app_name="com.xxx.xxx")
# 等待
wait(text="添加新项目",timeout=30)
# orc 文字识别定位 中/英
click("添加新项目")
# 图像匹配定位
click(image = "./添加新项目.png")
from ha4t.aircv.cv import Template
click(Template("./添加新项目.png"))
# u2 元素定位
click(text="添加新项目")
# webview 定位
from ha4t.cdp.cdp import CDP
from ha4t.cdp.server import CdpServer
from ha4t.cdp.by import By
cdp_server = CdpServer()
cdp_server.start_server_for_android_app(device.driver.adb_device)
cdp = CDP(cdp_server.ws_endpoint)
window = cdp.get_page(["homePage"])
time.sleep(3)
window.click((By.TEXT, "新建项目"))
```
## 详细文档(未完善)
查看我们的[详细文档](https://exuils.github.io/HA4T/)以获取更多信息,包括:
- 完整的API参考
- 高级用法指南
- 最佳实践和技巧
## 问题和支持
如果您遇到任何问题或需要支持,请[提交一个issue](https://github.com/Exuils/HA4T/issues)。
## 许可证
本项目采用MIT许可证。详情请见[LICENSE](LICENSE)文件。
## 致谢
HA4T 的开发得益于以下开源项目:
- [airtest](https://github.com/NetEase/airtest)
- [uiautomator2](https://github.com/openatx/uiautomator2)
- [facebook-wda](https://github.com/openatx/facebook-wda)
- [paddleocr](https://github.com/PaddlePaddle/PaddleOCR)
- [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy)
感谢这些项目的贡献者们!
如果您觉得HA4T对您有帮助,请考虑给我们一个星标 ⭐️
Raw data
{
"_id": null,
"home_page": "https://github.com/exuils/HA4T",
"name": "HA4T",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "automation, automated-test, game, android, ios, hybrid-app",
"author": "caishilong",
"author_email": "caishilong@exuils.com",
"download_url": "https://files.pythonhosted.org/packages/19/e1/93439914281e5b7d03d5de2f5649d7c18967dd320673acbfcd54db375407/ha4t-0.0.7.tar.gz",
"platform": null,
"description": "# HA4T \ud83d\udc0d\r\n\r\n[![PyPI version](https://badge.fury.io/py/ha4t.svg)](https://badge.fury.io/py/ha4t)\r\n[![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen)](https://exuils.github.io/HA4T/)\r\n\r\nHA4T (Hybrid App For Testing Tool)\r\n\u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684UI\u81ea\u52a8\u5316\u6846\u67b6\uff0c\u9002\u7528\u4e8e\u6df7\u5408\u578bapp\u3001web\u548c\u539f\u751fapp\u7b49\u3002\u8be5\u6846\u67b6\u57fa\u4e8eairtest\u3001\u98de\u6d46OCR\u3001WS\u3001uiautomator2\u548cfacebook_wda\u8fdb\u884c\u5f00\u53d1\u3002\r\n\r\n## \u7279\u6027\r\n\r\n- \u8de8\u5e73\u53f0\u652f\u6301\uff1a\u9002\u7528\u4e8eiOS\u3001Android\u548cWeb\u5e94\u7528\r\n- \u591a\u79cd\u5b9a\u4f4d\u65b9\u5f0f\uff1a\u652f\u6301\u56fe\u50cf\u8bc6\u522b\u3001OCR\u6587\u5b57\u8bc6\u522b\u3001webview\u5b9a\u4f4d\u3001\u539f\u751f\u63a7\u4ef6\u5b9a\u4f4d\u7b49\r\n- \u7075\u6d3b\u7684\u64cd\u4f5cAPI\uff1a\u63d0\u4f9b\u70b9\u51fb\u3001\u6ed1\u52a8\u3001\u8f93\u5165\u7b49\u5e38\u7528\u64cd\u4f5c\r\n\r\n## \u5b89\u88c5\r\n\r\n\u4f7f\u7528pip\u5b89\u88c5HA4T\uff1a\r\n\r\n```bash\r\npip install ha4t\r\n```\r\n\r\n## \u5feb\u901f\u5f00\u59cb\r\n\r\n\u4ee5\u4e0b\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff0c\u5c55\u793a\u5982\u4f55\u4f7f\u7528HA4T\u8fdb\u884c\u57fa\u672c\u64cd\u4f5c\uff1a\r\n\r\n```python\r\n\r\n# \u539f\u751f\u5b9a\u4f4d\r\nfrom ha4t import connect\r\nfrom ha4t.api import *\r\n\r\nconnect(platform=\"android\")\r\n\r\n# \u542f\u52a8\u5e94\u7528\r\nstart_app(activity=\"com.xxx.xxx.MainActivity\",app_name=\"com.xxx.xxx\")\r\n\r\n# \u7b49\u5f85\r\nwait(text=\"\u6dfb\u52a0\u65b0\u9879\u76ee\",timeout=30)\r\n\r\n# orc \u6587\u5b57\u8bc6\u522b\u5b9a\u4f4d \u4e2d/\u82f1\r\nclick(\"\u6dfb\u52a0\u65b0\u9879\u76ee\")\r\n# \u56fe\u50cf\u5339\u914d\u5b9a\u4f4d\r\nclick(image = \"./\u6dfb\u52a0\u65b0\u9879\u76ee.png\")\r\nfrom ha4t.aircv.cv import Template\r\nclick(Template(\"./\u6dfb\u52a0\u65b0\u9879\u76ee.png\"))\r\n# u2 \u5143\u7d20\u5b9a\u4f4d\r\nclick(text=\"\u6dfb\u52a0\u65b0\u9879\u76ee\")\r\n\r\n\r\n# webview \u5b9a\u4f4d\r\nfrom ha4t.cdp.cdp import CDP\r\nfrom ha4t.cdp.server import CdpServer\r\nfrom ha4t.cdp.by import By\r\n\r\ncdp_server = CdpServer()\r\ncdp_server.start_server_for_android_app(device.driver.adb_device)\r\ncdp = CDP(cdp_server.ws_endpoint)\r\n\r\n\r\nwindow = cdp.get_page([\"homePage\"])\r\ntime.sleep(3)\r\nwindow.click((By.TEXT, \"\u65b0\u5efa\u9879\u76ee\"))\r\n```\r\n\r\n## \u8be6\u7ec6\u6587\u6863(\u672a\u5b8c\u5584)\r\n\r\n\u67e5\u770b\u6211\u4eec\u7684[\u8be6\u7ec6\u6587\u6863](https://exuils.github.io/HA4T/)\u4ee5\u83b7\u53d6\u66f4\u591a\u4fe1\u606f\uff0c\u5305\u62ec\uff1a\r\n\r\n- \u5b8c\u6574\u7684API\u53c2\u8003\r\n- \u9ad8\u7ea7\u7528\u6cd5\u6307\u5357\r\n- \u6700\u4f73\u5b9e\u8df5\u548c\u6280\u5de7\r\n\r\n\r\n## \u95ee\u9898\u548c\u652f\u6301\r\n\r\n\u5982\u679c\u60a8\u9047\u5230\u4efb\u4f55\u95ee\u9898\u6216\u9700\u8981\u652f\u6301\uff0c\u8bf7[\u63d0\u4ea4\u4e00\u4e2aissue](https://github.com/Exuils/HA4T/issues)\u3002\r\n\r\n## \u8bb8\u53ef\u8bc1\r\n\r\n\u672c\u9879\u76ee\u91c7\u7528MIT\u8bb8\u53ef\u8bc1\u3002\u8be6\u60c5\u8bf7\u89c1[LICENSE](LICENSE)\u6587\u4ef6\u3002\r\n\r\n## \u81f4\u8c22\r\n\r\nHA4T \u7684\u5f00\u53d1\u5f97\u76ca\u4e8e\u4ee5\u4e0b\u5f00\u6e90\u9879\u76ee\uff1a\r\n\r\n- [airtest](https://github.com/NetEase/airtest)\r\n- [uiautomator2](https://github.com/openatx/uiautomator2)\r\n- [facebook-wda](https://github.com/openatx/facebook-wda)\r\n- [paddleocr](https://github.com/PaddlePaddle/PaddleOCR)\r\n- [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy)\r\n\r\n\u611f\u8c22\u8fd9\u4e9b\u9879\u76ee\u7684\u8d21\u732e\u8005\u4eec\uff01\r\n\u5982\u679c\u60a8\u89c9\u5f97HA4T\u5bf9\u60a8\u6709\u5e2e\u52a9\uff0c\u8bf7\u8003\u8651\u7ed9\u6211\u4eec\u4e00\u4e2a\u661f\u6807 \u2b50\ufe0f\r\n",
"bugtrack_url": null,
"license": "Apache License 2.0",
"summary": "\u8de8\u5e73\u53f0\u7684UI\u81ea\u52a8\u5316\u6846\u67b6\uff0c\u9002\u7528\u4e8e\u6df7\u5408\u578bapp",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/exuils/HA4T"
},
"split_keywords": [
"automation",
" automated-test",
" game",
" android",
" ios",
" hybrid-app"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e2e6b89bfa4cc1fe6755f1f2927a2c7e5ea790529e228d30779d26edbcd3ed3a",
"md5": "179e56b8b04fab44b85aaa70678f27dc",
"sha256": "f61ed32a509c60d014d39628ca724ae55abcb4c33954c7dde5ad37634d690270"
},
"downloads": -1,
"filename": "HA4T-0.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "179e56b8b04fab44b85aaa70678f27dc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 21288450,
"upload_time": "2024-11-01T10:19:15",
"upload_time_iso_8601": "2024-11-01T10:19:15.088409Z",
"url": "https://files.pythonhosted.org/packages/e2/e6/b89bfa4cc1fe6755f1f2927a2c7e5ea790529e228d30779d26edbcd3ed3a/HA4T-0.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "19e193439914281e5b7d03d5de2f5649d7c18967dd320673acbfcd54db375407",
"md5": "747899bfa12143353c04c45e5e4f7aa8",
"sha256": "f5dd24420fc0826e47f8e06e3ce3a96452da3dc6412e19acced3638931e3cacc"
},
"downloads": -1,
"filename": "ha4t-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "747899bfa12143353c04c45e5e4f7aa8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 21179873,
"upload_time": "2024-11-01T10:19:37",
"upload_time_iso_8601": "2024-11-01T10:19:37.769493Z",
"url": "https://files.pythonhosted.org/packages/19/e1/93439914281e5b7d03d5de2f5649d7c18967dd320673acbfcd54db375407/ha4t-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-01 10:19:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "exuils",
"github_project": "HA4T",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "colorlog",
"specs": [
[
"~=",
"6.8.2"
]
]
},
{
"name": "pillow",
"specs": [
[
"~=",
"10.4.0"
]
]
},
{
"name": "requests",
"specs": [
[
"~=",
"2.32.3"
]
]
},
{
"name": "uiautomator2",
"specs": [
[
"~=",
"3.2.2"
]
]
},
{
"name": "websockets",
"specs": [
[
"~=",
"10.4"
]
]
},
{
"name": "numpy",
"specs": [
[
"~=",
"1.26.4"
]
]
},
{
"name": "paddleocr",
"specs": [
[
"~=",
"2.8.1"
]
]
},
{
"name": "setuptools",
"specs": [
[
"~=",
"73.0.1"
]
]
},
{
"name": "six",
"specs": [
[
"~=",
"1.16.0"
]
]
},
{
"name": "wheel",
"specs": [
[
"~=",
"0.43.0"
]
]
},
{
"name": "tornado",
"specs": [
[
"~=",
"6.4.1"
]
]
},
{
"name": "logzero",
"specs": [
[
"~=",
"1.7.0"
]
]
},
{
"name": "logging-reset",
"specs": []
},
{
"name": "adbutils",
"specs": [
[
"~=",
"2.7.2"
]
]
},
{
"name": "facebook-wda",
"specs": []
},
{
"name": "paddlepaddle",
"specs": []
},
{
"name": "paddleocr",
"specs": []
},
{
"name": "tidevice",
"specs": []
},
{
"name": "deepdiff",
"specs": [
[
"~=",
"7.0.1"
]
]
},
{
"name": "opencv-python",
"specs": [
[
"~=",
"4.10.0.84"
]
]
},
{
"name": "matplotlib",
"specs": [
[
"~=",
"3.9.2"
]
]
},
{
"name": "pytest",
"specs": [
[
"~=",
"8.3.3"
]
]
},
{
"name": "psutil",
"specs": [
[
"~=",
"6.1.0"
]
]
},
{
"name": "mock",
"specs": [
[
"~=",
"5.1.0"
]
]
},
{
"name": "allure-pytest",
"specs": []
}
],
"lcname": "ha4t"
}