applib-ui 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. applib_ui-0.0.1/PKG-INFO +170 -0
  2. applib_ui-0.0.1/README.md +144 -0
  3. applib_ui-0.0.1/applib_ui/__init__.py +13 -0
  4. applib_ui-0.0.1/applib_ui/case.py +79 -0
  5. applib_ui-0.0.1/applib_ui/cli.py +75 -0
  6. applib_ui-0.0.1/applib_ui/core/__init__.py +0 -0
  7. applib_ui-0.0.1/applib_ui/core/android/__init__.py +16 -0
  8. applib_ui-0.0.1/applib_ui/core/android/case.py +8 -0
  9. applib_ui-0.0.1/applib_ui/core/android/driver.py +191 -0
  10. applib_ui-0.0.1/applib_ui/core/android/element.py +291 -0
  11. applib_ui-0.0.1/applib_ui/core/android/page.py +6 -0
  12. applib_ui-0.0.1/applib_ui/core/android/recorder.py +171 -0
  13. applib_ui-0.0.1/applib_ui/core/android/remote_adb.py +69 -0
  14. applib_ui-0.0.1/applib_ui/core/android/remote_driver.py +176 -0
  15. applib_ui-0.0.1/applib_ui/core/img/__init__.py +4 -0
  16. applib_ui-0.0.1/applib_ui/core/img/driver.py +43 -0
  17. applib_ui-0.0.1/applib_ui/core/img/element.py +73 -0
  18. applib_ui-0.0.1/applib_ui/core/ios/__init__.py +16 -0
  19. applib_ui-0.0.1/applib_ui/core/ios/case.py +8 -0
  20. applib_ui-0.0.1/applib_ui/core/ios/driver.py +290 -0
  21. applib_ui-0.0.1/applib_ui/core/ios/elem.py +222 -0
  22. applib_ui-0.0.1/applib_ui/core/ios/local_wda.py +576 -0
  23. applib_ui-0.0.1/applib_ui/core/ios/page.py +6 -0
  24. applib_ui-0.0.1/applib_ui/core/ios/recorder.py +202 -0
  25. applib_ui-0.0.1/applib_ui/core/ios/remote_driver.py +220 -0
  26. applib_ui-0.0.1/applib_ui/core/ios/remote_wda.py +54 -0
  27. applib_ui-0.0.1/applib_ui/core/ocr/__init__.py +5 -0
  28. applib_ui-0.0.1/applib_ui/core/ocr/driver.py +185 -0
  29. applib_ui-0.0.1/applib_ui/core/ocr/element.py +65 -0
  30. applib_ui-0.0.1/applib_ui/device.py +53 -0
  31. applib_ui-0.0.1/applib_ui/element.py +210 -0
  32. applib_ui-0.0.1/applib_ui/page.py +6 -0
  33. applib_ui-0.0.1/applib_ui/pytest_plugin.py +57 -0
  34. applib_ui-0.0.1/applib_ui/running/__init__.py +0 -0
  35. applib_ui-0.0.1/applib_ui/running/conf.py +14 -0
  36. applib_ui-0.0.1/applib_ui/running/conf.yml +19 -0
  37. applib_ui-0.0.1/applib_ui/running/runner.py +33 -0
  38. applib_ui-0.0.1/applib_ui/utils/__init__.py +1 -0
  39. applib_ui-0.0.1/applib_ui/utils/aes_util.py +47 -0
  40. applib_ui-0.0.1/applib_ui/utils/allure_util.py +213 -0
  41. applib_ui-0.0.1/applib_ui/utils/base64_util.py +21 -0
  42. applib_ui-0.0.1/applib_ui/utils/common.py +84 -0
  43. applib_ui-0.0.1/applib_ui/utils/config.py +135 -0
  44. applib_ui-0.0.1/applib_ui/utils/cv_util.py +110 -0
  45. applib_ui-0.0.1/applib_ui/utils/dingtalk.py +56 -0
  46. applib_ui-0.0.1/applib_ui/utils/excel_util.py +101 -0
  47. applib_ui-0.0.1/applib_ui/utils/log.py +12 -0
  48. applib_ui-0.0.1/applib_ui/utils/mail.py +47 -0
  49. applib_ui-0.0.1/applib_ui/utils/mysql_util.py +74 -0
  50. applib_ui-0.0.1/applib_ui/utils/nacos_util.py +52 -0
  51. applib_ui-0.0.1/applib_ui/utils/pytest_util.py +89 -0
  52. applib_ui-0.0.1/applib_ui/utils/swagger_util.py +195 -0
  53. applib_ui-0.0.1/applib_ui.egg-info/PKG-INFO +170 -0
  54. applib_ui-0.0.1/applib_ui.egg-info/SOURCES.txt +61 -0
  55. applib_ui-0.0.1/applib_ui.egg-info/dependency_links.txt +1 -0
  56. applib_ui-0.0.1/applib_ui.egg-info/entry_points.txt +5 -0
  57. applib_ui-0.0.1/applib_ui.egg-info/requires.txt +20 -0
  58. applib_ui-0.0.1/applib_ui.egg-info/top_level.txt +1 -0
  59. applib_ui-0.0.1/pyproject.toml +50 -0
  60. applib_ui-0.0.1/setup.cfg +4 -0
  61. applib_ui-0.0.1/tests/test_device.py +50 -0
  62. applib_ui-0.0.1/tests/test_pytest_integration.py +150 -0
  63. applib_ui-0.0.1/tests/test_runner.py +46 -0
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: applib-ui
3
+ Version: 0.0.1
4
+ Summary: Android / iOS 通用 UI 自动化测试框架
5
+ Project-URL: Repository, https://github.com/purewhite-88/applib
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Framework :: Pytest
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: click==8.1.7
11
+ Requires-Dist: loguru==0.7.0
12
+ Requires-Dist: PyYAML<7,>=6.0.2
13
+ Requires-Dist: allure-pytest<3,>=2.13.5
14
+ Requires-Dist: pytest<10,>=8.2
15
+ Provides-Extra: android
16
+ Requires-Dist: uiautomator2==3.2.4; extra == "android"
17
+ Provides-Extra: ios
18
+ Requires-Dist: tidevice==0.12.10; extra == "ios"
19
+ Requires-Dist: facebook-wda==1.5.0; extra == "ios"
20
+ Provides-Extra: image
21
+ Requires-Dist: numpy<3,>=1.26; extra == "image"
22
+ Requires-Dist: opencv-python<5,>=4.8; extra == "image"
23
+ Provides-Extra: ocr
24
+ Requires-Dist: requests<3,>=2.28; extra == "ocr"
25
+ Requires-Dist: natocr==2.3.0; extra == "ocr"
26
+
27
+ # applib-ui
28
+
29
+ 基于 pytest 的 Android / iOS 自动化测试库,提供设备驱动、页面对象、双平台元素定位、截图、录屏和 Allure 报告支持。Python 要求为 3.10 及以上。
30
+
31
+ ## 安装
32
+
33
+ 在业务测试项目的虚拟环境中安装对应平台的依赖:
34
+
35
+ ```bash
36
+ python -m pip install 'applib-ui[android]'
37
+ # iOS
38
+ python -m pip install 'applib-ui[ios]'
39
+ # 双平台、图像识别及 OCR
40
+ python -m pip install 'applib-ui[android,ios,image,ocr]'
41
+ ```
42
+
43
+ 基础包安装命令为 `python -m pip install applib-ui`,Python 导入名为 `applib_ui`。
44
+
45
+ 如需从源码开发安装:
46
+
47
+ ```bash
48
+ python -m pip install -e '/path/to/applib-ui[android]'
49
+ # iOS
50
+ python -m pip install -e '/path/to/applib-ui[ios]'
51
+ # 双平台、图像识别及 OCR
52
+ python -m pip install -e '/path/to/applib-ui[android,ios,image,ocr]'
53
+ ```
54
+
55
+ 仅安装基础包 `python -m pip install -e /path/to/applib-ui` 即可使用 pytest 插件与通用工具。设备驱动和识别库按实际使用的功能安装。
56
+
57
+ Android 需要可用的 adb 及已授权设备;iOS 需要 macOS、已签名且可运行的 WDA,以及现有 WDA 启动流程所需的 tidevice / go-ios 工具。录屏还需要对应平台使用的 scrcpy / ffmpeg。
58
+
59
+ ## 使用 pytest
60
+
61
+ 安装后插件自动加载,无需在业务项目中编写 `pytest_plugins`。插件通过标准的 [pytest 插件入口](https://docs.pytest.org/en/stable/how-to/writing_plugins.html#making-your-plugin-installable-by-others)注册。
62
+
63
+ ```python
64
+ # tests/test_app.py
65
+
66
+ def test_launch(app_driver):
67
+ app_driver.start_app()
68
+ ```
69
+
70
+ ```bash
71
+ pytest tests/test_app.py --app-platform android --app-device SERIAL --app-package com.example.app
72
+ pytest tests/test_app.py --app-platform ios --app-device UDID --app-package com.example.app
73
+ # 筛选、参数化和报告使用 pytest 自身的参数
74
+ pytest tests -k launch --app-platform android --app-device SERIAL --alluredir report
75
+ # 仅收集,不连接设备
76
+ pytest tests --collect-only --app-platform android
77
+ ```
78
+
79
+ `app_driver` 是函数级 fixture,每条用例建立一个设备驱动,用例结束后停止未结束的录屏并释放连接。普通测试无需配置设备。`app_config` fixture 返回当前的 `App` 配置。
80
+
81
+ 也可以在业务项目的 `pytest.ini` 中设置默认参数:
82
+
83
+ ```ini
84
+ [pytest]
85
+ app_platform = android
86
+ app_device = SERIAL
87
+ app_package = com.example.app
88
+ ```
89
+
90
+ 三个命令行参数分别覆盖对应的 INI 配置。平台配置在用例收集前生效,供页面元素选择对应定位方式。会话结束后恢复运行前的配置,同一进程连续运行不会留下本次参数。一次 pytest 会话对应一个平台和一台设备;多设备请分别启动进程。
91
+
92
+ 如果主动设置了 `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1`,需要显式加 `-p applib_ui.pytest_plugin`;使用报告参数时还需加载 Allure 插件。
93
+
94
+ ## 页面对象与测试类
95
+
96
+ ```python
97
+ from applib_ui import Elem, Page, TestCase
98
+
99
+
100
+ class HomePage(Page):
101
+ login = Elem(
102
+ '登录',
103
+ android=('text', '登录'),
104
+ ios=('name', '登录'),
105
+ )
106
+
107
+
108
+ class TestLogin(TestCase):
109
+ def start(self):
110
+ self.start_app()
111
+
112
+ def test_login(self):
113
+ HomePage(self.dr).login.click()
114
+ ```
115
+
116
+ 保留 `start_class` / `end_class`、`start` / `end` 扩展钩子,异常会交由 pytest 报告。驱动释放由 fixture 负责,`start` / `end` 失败时仍执行清理。新用例可以直接使用普通测试函数和 fixture,无需继承基类。
117
+
118
+ 平台专用接口分别从 `applib_ui.core.android`、`applib_ui.core.ios` 导入。专用 `TestCase` 要求配置匹配的平台,并会在每条用例开始前解锁设备。Sonic 远程连接可通过业务 `conftest.py` 设置 `App.sonic_host`、`App.sonic_user`、`App.sonic_pwd`;iOS 远程连接还需要设置 `App.sib_path`。
119
+
120
+ ## 其他入口
121
+
122
+ ```bash
123
+ applib-ui --version
124
+ applib-ui run tests --app-platform android --app-device SERIAL --app-package com.example.app
125
+ applib-ui start-wda -u UDID
126
+ applib-ui stop-wda -u UDID
127
+ applib-ui restart-wda -u UDID
128
+ ```
129
+
130
+ `applib-ui run` 透传 pytest 参数并返回 pytest 退出码。程序调用方式:
131
+
132
+ ```python
133
+ from applib_ui import main
134
+
135
+ exit_code = main(
136
+ case_path='tests',
137
+ report_path='report', # 传 None 关闭此入口默认添加的 Allure 输出
138
+ did='SERIAL',
139
+ pkg='com.example.app',
140
+ platform='android',
141
+ pytest_args=['-k', 'login'],
142
+ )
143
+ raise SystemExit(exit_code)
144
+ ```
145
+
146
+ ## 配置与目录
147
+
148
+ - `applib_ui/core/android/`:Android 本地 / 远程驱动、元素及录屏。
149
+ - `applib_ui/core/ios/`:iOS 驱动、WDA、元素及录屏。
150
+ - `applib_ui/core/img/`、`applib_ui/core/ocr/`:图像及 OCR。
151
+ - `applib_ui/pytest_plugin.py`:pytest 参数、配置和 fixture。
152
+ - `applib_ui/running/`:程序入口及默认 YAML 配置。
153
+ - `applib_ui/utils/`:通用工具。
154
+
155
+ 发布名和命令为 `applib-ui`,Python 导入名为 `applib_ui`,Android 目录和元素关键字统一为 `android`。升级业务用例时需同步修改导入和元素定义,不提供旧名称别名。
156
+
157
+ 运行环境变量统一使用 `APPLIB_UI_` 前缀:`APPLIB_UI_WDA_TIMEOUT`、`APPLIB_UI_TUNNEL_PORT_BASE`、`APPLIB_UI_OCR_LANG`、`APPLIB_UI_OCR_FALLBACK_LANG`。iOS 端口注册、配对文件和日志使用 `~/.applib-ui/` 目录。
158
+
159
+ `order()`、`depend()` 仍分别依赖额外安装的 pytest-ordering、pytest-dependency;基础包不会自动安装这两个插件。数据参数化可直接用 `pytest.mark.parametrize` 或 `data()`。
160
+
161
+ ## 开发验证
162
+
163
+ ```bash
164
+ python -m pip install -e .
165
+ python -m pytest
166
+ ```
167
+
168
+ 仓库测试使用模拟驱动验证 pytest 接入、异常清理和退出码,不会连接设备。Android / iOS 真机行为需在具备上述设备环境的业务项目中验证。
169
+
170
+ 本仓库未额外声明许可证。
@@ -0,0 +1,144 @@
1
+ # applib-ui
2
+
3
+ 基于 pytest 的 Android / iOS 自动化测试库,提供设备驱动、页面对象、双平台元素定位、截图、录屏和 Allure 报告支持。Python 要求为 3.10 及以上。
4
+
5
+ ## 安装
6
+
7
+ 在业务测试项目的虚拟环境中安装对应平台的依赖:
8
+
9
+ ```bash
10
+ python -m pip install 'applib-ui[android]'
11
+ # iOS
12
+ python -m pip install 'applib-ui[ios]'
13
+ # 双平台、图像识别及 OCR
14
+ python -m pip install 'applib-ui[android,ios,image,ocr]'
15
+ ```
16
+
17
+ 基础包安装命令为 `python -m pip install applib-ui`,Python 导入名为 `applib_ui`。
18
+
19
+ 如需从源码开发安装:
20
+
21
+ ```bash
22
+ python -m pip install -e '/path/to/applib-ui[android]'
23
+ # iOS
24
+ python -m pip install -e '/path/to/applib-ui[ios]'
25
+ # 双平台、图像识别及 OCR
26
+ python -m pip install -e '/path/to/applib-ui[android,ios,image,ocr]'
27
+ ```
28
+
29
+ 仅安装基础包 `python -m pip install -e /path/to/applib-ui` 即可使用 pytest 插件与通用工具。设备驱动和识别库按实际使用的功能安装。
30
+
31
+ Android 需要可用的 adb 及已授权设备;iOS 需要 macOS、已签名且可运行的 WDA,以及现有 WDA 启动流程所需的 tidevice / go-ios 工具。录屏还需要对应平台使用的 scrcpy / ffmpeg。
32
+
33
+ ## 使用 pytest
34
+
35
+ 安装后插件自动加载,无需在业务项目中编写 `pytest_plugins`。插件通过标准的 [pytest 插件入口](https://docs.pytest.org/en/stable/how-to/writing_plugins.html#making-your-plugin-installable-by-others)注册。
36
+
37
+ ```python
38
+ # tests/test_app.py
39
+
40
+ def test_launch(app_driver):
41
+ app_driver.start_app()
42
+ ```
43
+
44
+ ```bash
45
+ pytest tests/test_app.py --app-platform android --app-device SERIAL --app-package com.example.app
46
+ pytest tests/test_app.py --app-platform ios --app-device UDID --app-package com.example.app
47
+ # 筛选、参数化和报告使用 pytest 自身的参数
48
+ pytest tests -k launch --app-platform android --app-device SERIAL --alluredir report
49
+ # 仅收集,不连接设备
50
+ pytest tests --collect-only --app-platform android
51
+ ```
52
+
53
+ `app_driver` 是函数级 fixture,每条用例建立一个设备驱动,用例结束后停止未结束的录屏并释放连接。普通测试无需配置设备。`app_config` fixture 返回当前的 `App` 配置。
54
+
55
+ 也可以在业务项目的 `pytest.ini` 中设置默认参数:
56
+
57
+ ```ini
58
+ [pytest]
59
+ app_platform = android
60
+ app_device = SERIAL
61
+ app_package = com.example.app
62
+ ```
63
+
64
+ 三个命令行参数分别覆盖对应的 INI 配置。平台配置在用例收集前生效,供页面元素选择对应定位方式。会话结束后恢复运行前的配置,同一进程连续运行不会留下本次参数。一次 pytest 会话对应一个平台和一台设备;多设备请分别启动进程。
65
+
66
+ 如果主动设置了 `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1`,需要显式加 `-p applib_ui.pytest_plugin`;使用报告参数时还需加载 Allure 插件。
67
+
68
+ ## 页面对象与测试类
69
+
70
+ ```python
71
+ from applib_ui import Elem, Page, TestCase
72
+
73
+
74
+ class HomePage(Page):
75
+ login = Elem(
76
+ '登录',
77
+ android=('text', '登录'),
78
+ ios=('name', '登录'),
79
+ )
80
+
81
+
82
+ class TestLogin(TestCase):
83
+ def start(self):
84
+ self.start_app()
85
+
86
+ def test_login(self):
87
+ HomePage(self.dr).login.click()
88
+ ```
89
+
90
+ 保留 `start_class` / `end_class`、`start` / `end` 扩展钩子,异常会交由 pytest 报告。驱动释放由 fixture 负责,`start` / `end` 失败时仍执行清理。新用例可以直接使用普通测试函数和 fixture,无需继承基类。
91
+
92
+ 平台专用接口分别从 `applib_ui.core.android`、`applib_ui.core.ios` 导入。专用 `TestCase` 要求配置匹配的平台,并会在每条用例开始前解锁设备。Sonic 远程连接可通过业务 `conftest.py` 设置 `App.sonic_host`、`App.sonic_user`、`App.sonic_pwd`;iOS 远程连接还需要设置 `App.sib_path`。
93
+
94
+ ## 其他入口
95
+
96
+ ```bash
97
+ applib-ui --version
98
+ applib-ui run tests --app-platform android --app-device SERIAL --app-package com.example.app
99
+ applib-ui start-wda -u UDID
100
+ applib-ui stop-wda -u UDID
101
+ applib-ui restart-wda -u UDID
102
+ ```
103
+
104
+ `applib-ui run` 透传 pytest 参数并返回 pytest 退出码。程序调用方式:
105
+
106
+ ```python
107
+ from applib_ui import main
108
+
109
+ exit_code = main(
110
+ case_path='tests',
111
+ report_path='report', # 传 None 关闭此入口默认添加的 Allure 输出
112
+ did='SERIAL',
113
+ pkg='com.example.app',
114
+ platform='android',
115
+ pytest_args=['-k', 'login'],
116
+ )
117
+ raise SystemExit(exit_code)
118
+ ```
119
+
120
+ ## 配置与目录
121
+
122
+ - `applib_ui/core/android/`:Android 本地 / 远程驱动、元素及录屏。
123
+ - `applib_ui/core/ios/`:iOS 驱动、WDA、元素及录屏。
124
+ - `applib_ui/core/img/`、`applib_ui/core/ocr/`:图像及 OCR。
125
+ - `applib_ui/pytest_plugin.py`:pytest 参数、配置和 fixture。
126
+ - `applib_ui/running/`:程序入口及默认 YAML 配置。
127
+ - `applib_ui/utils/`:通用工具。
128
+
129
+ 发布名和命令为 `applib-ui`,Python 导入名为 `applib_ui`,Android 目录和元素关键字统一为 `android`。升级业务用例时需同步修改导入和元素定义,不提供旧名称别名。
130
+
131
+ 运行环境变量统一使用 `APPLIB_UI_` 前缀:`APPLIB_UI_WDA_TIMEOUT`、`APPLIB_UI_TUNNEL_PORT_BASE`、`APPLIB_UI_OCR_LANG`、`APPLIB_UI_OCR_FALLBACK_LANG`。iOS 端口注册、配对文件和日志使用 `~/.applib-ui/` 目录。
132
+
133
+ `order()`、`depend()` 仍分别依赖额外安装的 pytest-ordering、pytest-dependency;基础包不会自动安装这两个插件。数据参数化可直接用 `pytest.mark.parametrize` 或 `data()`。
134
+
135
+ ## 开发验证
136
+
137
+ ```bash
138
+ python -m pip install -e .
139
+ python -m pytest
140
+ ```
141
+
142
+ 仓库测试使用模拟驱动验证 pytest 接入、异常清理和退出码,不会连接设备。Android / iOS 真机行为需在具备上述设备环境的业务项目中验证。
143
+
144
+ 本仓库未额外声明许可证。
@@ -0,0 +1,13 @@
1
+ from .running.runner import main
2
+ from .running.conf import App
3
+ from .utils.config import FileConfig
4
+ from .utils.pytest_util import *
5
+ from .utils.allure_util import *
6
+ from .utils.log import logger
7
+ from .page import Page
8
+ from .element import Elem
9
+ from .case import TestCase
10
+
11
+
12
+ __version__ = "0.0.1"
13
+ __description__ = "Android / iOS 通用 UI 自动化测试框架"
@@ -0,0 +1,79 @@
1
+ import time
2
+
3
+ import pytest
4
+
5
+ from .running.conf import App
6
+ from .utils.log import logger
7
+
8
+
9
+ class TestCase:
10
+ """pytest 测试基类;也可以直接在测试函数中使用 app_driver fixture。"""
11
+
12
+ dr = None
13
+
14
+ def start_class(self):
15
+ pass
16
+
17
+ def end_class(self):
18
+ pass
19
+
20
+ @classmethod
21
+ def setup_class(cls):
22
+ cls().start_class()
23
+
24
+ @classmethod
25
+ def teardown_class(cls):
26
+ cls().end_class()
27
+
28
+ def start(self):
29
+ pass
30
+
31
+ def end(self):
32
+ pass
33
+
34
+ @pytest.fixture(autouse=True)
35
+ def _app_lifecycle(self, app_driver):
36
+ self.dr = app_driver
37
+ try:
38
+ if getattr(self, '_platform', None) is not None:
39
+ self.dr.unlock()
40
+ self.start()
41
+ yield
42
+ finally:
43
+ self.end()
44
+
45
+ @staticmethod
46
+ def sleep(n: float):
47
+ logger.info(f"暂停: {n}s")
48
+ time.sleep(n)
49
+
50
+ def shot(self, name: str, delay=0):
51
+ if delay:
52
+ self.sleep(delay)
53
+ return self.dr.shot(name)
54
+
55
+ def start_record(self, video_name='record'):
56
+ """开始录屏"""
57
+ return self.dr.start_record(video_name)
58
+
59
+ def stop_record(self):
60
+ """结束录屏并上传 allure"""
61
+ return self.dr.stop_record()
62
+
63
+ def start_app(self, force=True, activity=None, use_monkey=False):
64
+ if force:
65
+ self.stop_app()
66
+ if App.platform == 'ios':
67
+ self.dr.start_app()
68
+ elif activity is not None:
69
+ self.dr.start_app(activity=activity)
70
+ elif use_monkey:
71
+ self.dr.start_app(use_monkey=True)
72
+ else:
73
+ self.dr.start_app()
74
+
75
+ def stop_app(self):
76
+ self.dr.stop_app()
77
+
78
+ def back(self):
79
+ self.dr.back()
@@ -0,0 +1,75 @@
1
+ import click
2
+ from . import __version__
3
+
4
+ @click.group()
5
+ @click.version_option(version=__version__, help="Show version.")
6
+ def main():
7
+ """applib-ui 移动端自动化工具。"""
8
+
9
+
10
+ @main.command(context_settings={'ignore_unknown_options': True})
11
+ @click.argument('pytest_args', nargs=-1, type=click.UNPROCESSED)
12
+ def run(pytest_args):
13
+ """运行 pytest,透传路径、筛选条件和报告等参数。"""
14
+ import pytest
15
+
16
+ raise SystemExit(pytest.main(list(pytest_args)))
17
+
18
+
19
+ @main.command()
20
+ @click.option('-u', '--udid', help="Specify the udid.")
21
+ def restart_wda(udid):
22
+ """
23
+ 重启wda
24
+ @param udid: IOS设备udid
25
+ @return:
26
+ """
27
+ from .core.ios.local_wda import LocalWdaInit
28
+
29
+ LocalWdaInit(udid=udid).restart_wda()
30
+
31
+ @main.command()
32
+ @click.option('-u', '--udid', help="Specify the udid.")
33
+ def start_wda(udid):
34
+ """
35
+ 启动wda
36
+ @param udid: IOS设备udid
37
+ @return:
38
+ """
39
+ from .core.ios.local_wda import LocalWdaInit
40
+
41
+ LocalWdaInit(udid=udid).run()
42
+
43
+ @main.command()
44
+ @click.option('-u', '--udid', help="Specify the udid.")
45
+ def stop_wda(udid):
46
+ """
47
+ 杀掉wda
48
+ @param udid: IOS设备udid
49
+ @return:
50
+ """
51
+ from .core.ios.local_wda import LocalWdaInit
52
+
53
+ LocalWdaInit(udid=udid).kill_wda_server()
54
+
55
+
56
+ # @main.command()
57
+ # @click.option('-p', '--platform', help="Specify the platform.")
58
+ # @click.option('-u', '--url', help="Specify the url.")
59
+ # def inspector(platform, url):
60
+ # """
61
+ # 获取元素定位信息
62
+ # @param platform: 平台,android、ios、web
63
+ # @param url:针对web,需要录制的页面的url
64
+ # @return:
65
+ # """
66
+ # import os
67
+ # if platform in ['android', 'ios', 'web']:
68
+ # os.system('weditor')
69
+ # elif platform == 'web':
70
+ # if not url:
71
+ # raise KeyError('url不能为空')
72
+ # os.system(f'playwright codegen {url}')
73
+ # else:
74
+ # raise KeyError('只支持android、ios、web')
75
+
File without changes
@@ -0,0 +1,16 @@
1
+ """android 平台接口,按需加载驱动依赖。"""
2
+
3
+ from importlib import import_module
4
+
5
+ __all__ = ['Elem', 'Page', 'Driver', 'RemoteDriver', 'TestCase']
6
+
7
+ _MODULES = {'Elem': 'element', 'Page': 'page', 'Driver': 'driver',
8
+ 'RemoteDriver': 'remote_driver', 'TestCase': 'case'}
9
+
10
+
11
+ def __getattr__(name):
12
+ if name not in _MODULES:
13
+ raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
14
+ value = getattr(import_module(f'.{_MODULES[name]}', __name__), name)
15
+ globals()[name] = value
16
+ return value
@@ -0,0 +1,8 @@
1
+ from ...case import TestCase as BaseTestCase
2
+
3
+
4
+ class TestCase(BaseTestCase):
5
+ """Android pytest 测试基类。"""
6
+
7
+ _platform = 'android'
8
+