devhelmkit 0.1.0__py3-none-any.whl

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 (58) hide show
  1. devhelmkit/__init__.py +44 -0
  2. devhelmkit/android/__init__.py +7 -0
  3. devhelmkit/android/driver.py +18 -0
  4. devhelmkit/assets/so/arm64-v8a/agent_v1.so +0 -0
  5. devhelmkit/assets/so/arm64-v8a/agent_v2.so +0 -0
  6. devhelmkit/assets/so/x86_64/agent.so +0 -0
  7. devhelmkit/core/__init__.py +3 -0
  8. devhelmkit/core/base_component.py +214 -0
  9. devhelmkit/core/base_driver.py +414 -0
  10. devhelmkit/core/base_window.py +25 -0
  11. devhelmkit/core/selector_spec.py +102 -0
  12. devhelmkit/entry.py +90 -0
  13. devhelmkit/exceptions.py +56 -0
  14. devhelmkit/harmony/__init__.py +3 -0
  15. devhelmkit/harmony/agent/__init__.py +7 -0
  16. devhelmkit/harmony/agent/so_manager.py +300 -0
  17. devhelmkit/harmony/config.py +124 -0
  18. devhelmkit/harmony/device/__init__.py +6 -0
  19. devhelmkit/harmony/device/hdc.py +430 -0
  20. devhelmkit/harmony/driver.py +1416 -0
  21. devhelmkit/harmony/finder/__init__.py +12 -0
  22. devhelmkit/harmony/finder/component_finder.py +336 -0
  23. devhelmkit/harmony/finder/popup_handler.py +81 -0
  24. devhelmkit/harmony/finder/selector_adapter.py +101 -0
  25. devhelmkit/harmony/finder/xpath_query.py +110 -0
  26. devhelmkit/harmony/rpc/__init__.py +12 -0
  27. devhelmkit/harmony/rpc/client.py +126 -0
  28. devhelmkit/harmony/rpc/proxy_v2.py +106 -0
  29. devhelmkit/harmony/rpc/remote_object.py +48 -0
  30. devhelmkit/harmony/uiobject.py +246 -0
  31. devhelmkit/harmony/uiwindow.py +43 -0
  32. devhelmkit/harmony/webview/__init__.py +17 -0
  33. devhelmkit/harmony/webview/chromedriver_manager.py +251 -0
  34. devhelmkit/harmony/webview/devtools_finder.py +131 -0
  35. devhelmkit/harmony/webview/webview_driver.py +326 -0
  36. devhelmkit/model/__init__.py +3 -0
  37. devhelmkit/model/action.py +147 -0
  38. devhelmkit/model/app_state.py +50 -0
  39. devhelmkit/model/constants.py +22 -0
  40. devhelmkit/model/display.py +32 -0
  41. devhelmkit/model/format_string.py +24 -0
  42. devhelmkit/model/input.py +50 -0
  43. devhelmkit/model/json_base.py +42 -0
  44. devhelmkit/model/keys.py +375 -0
  45. devhelmkit/model/match_pattern.py +15 -0
  46. devhelmkit/model/page.py +13 -0
  47. devhelmkit/model/params.py +42 -0
  48. devhelmkit/model/rect.py +58 -0
  49. devhelmkit/model/runnable.py +18 -0
  50. devhelmkit/utils/__init__.py +3 -0
  51. devhelmkit/utils/logger.py +72 -0
  52. devhelmkit/utils/retry.py +46 -0
  53. devhelmkit/utils/timeout.py +64 -0
  54. devhelmkit-0.1.0.dist-info/METADATA +411 -0
  55. devhelmkit-0.1.0.dist-info/RECORD +58 -0
  56. devhelmkit-0.1.0.dist-info/WHEEL +5 -0
  57. devhelmkit-0.1.0.dist-info/licenses/LICENSE +201 -0
  58. devhelmkit-0.1.0.dist-info/top_level.txt +1 -0
devhelmkit/__init__.py ADDED
@@ -0,0 +1,44 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """devhelmkit:跨平台 UI 自动化框架。
4
+
5
+ 包根只导出稳定入口、公共契约与统一异常,平台实现延迟导入。
6
+ """
7
+ from devhelmkit.entry import connect
8
+ from devhelmkit.core.base_driver import BaseDriver
9
+ from devhelmkit.core.base_component import BaseComponent
10
+ from devhelmkit.core.base_window import BaseWindow
11
+ from devhelmkit.core.selector_spec import SelectorSpec, build_selector
12
+ from devhelmkit.exceptions import (
13
+ DevhelmError,
14
+ DeviceNotFoundError,
15
+ DeviceConnectError,
16
+ PlatformNotSupportedError,
17
+ DevhelmTimeoutError,
18
+ RpcError,
19
+ BackendObjectDroppedError,
20
+ ComponentNotFoundError,
21
+ ComponentDisappearedError,
22
+ AgentError,
23
+ )
24
+
25
+ __all__ = [
26
+ "connect",
27
+ "BaseDriver",
28
+ "BaseComponent",
29
+ "BaseWindow",
30
+ "SelectorSpec",
31
+ "build_selector",
32
+ "DevhelmError",
33
+ "DeviceNotFoundError",
34
+ "DeviceConnectError",
35
+ "PlatformNotSupportedError",
36
+ "DevhelmTimeoutError",
37
+ "RpcError",
38
+ "BackendObjectDroppedError",
39
+ "ComponentNotFoundError",
40
+ "ComponentDisappearedError",
41
+ "AgentError",
42
+ ]
43
+
44
+ __version__ = "0.1.0"
@@ -0,0 +1,7 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """Android 平台预留骨架。
4
+
5
+ 首阶段不实现 Android 能力,connect(platform="android") 由入口层
6
+ 统一抛 PlatformNotSupportedError。
7
+ """
@@ -0,0 +1,18 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """AndroidDriver:Android 平台占位实现。
4
+
5
+ 首阶段不引入 AndroidUiObject、AdbDevice、uiautomator2 适配层。
6
+ connect(platform="android") 由 entry.py 统一抛 PlatformNotSupportedError,
7
+ 不会到达本类。
8
+
9
+ 后续接入 Android 时,在此实现 BaseDriver 契约,并解除 entry.py 中的
10
+ 平台拦截。
11
+ """
12
+ from devhelmkit.core.base_driver import BaseDriver
13
+
14
+
15
+ class AndroidDriver(BaseDriver):
16
+ """Android 平台占位驱动,未实现任何契约方法。"""
17
+
18
+ pass
Binary file
@@ -0,0 +1,3 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """跨平台契约层:不包含任何平台实现。"""
@@ -0,0 +1,214 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """BaseComponent:跨平台控件对象契约。
4
+
5
+ 对齐 U2 单对象模型:所有操作和关系方法统一在此定义。
6
+ 内部持有 SelectorSpec(纯数据),不依赖任何可操作选择器抽象。
7
+ 命名原则:U2 风格 snake_case 为基准,语义化方法为补充。
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from abc import ABC, abstractmethod
12
+ from typing import Any, Dict, Optional, Tuple, Union, TYPE_CHECKING
13
+
14
+ if TYPE_CHECKING:
15
+ from PIL.Image import Image
16
+ from devhelmkit.core.selector_spec import SelectorSpec
17
+ from devhelmkit.core.base_driver import BaseDriver
18
+
19
+
20
+ class BaseComponent(ABC):
21
+ """控件契约(查找到的控件对象)。"""
22
+
23
+ def __init__(self, driver: 'BaseDriver', selector: 'SelectorSpec'):
24
+ """
25
+ Args:
26
+ driver: 驱动实例
27
+ selector: 定位条件(纯数据)
28
+ """
29
+ self._driver = driver
30
+ self._selector = selector
31
+
32
+ # ============================================================
33
+ # 点击类
34
+ # ============================================================
35
+
36
+ @abstractmethod
37
+ def click(self) -> None:
38
+ """点击。"""
39
+
40
+ @abstractmethod
41
+ def long_click(self, duration: float = 0.5) -> None:
42
+ """长按。"""
43
+
44
+ @abstractmethod
45
+ def double_click(self) -> None:
46
+ """双击。"""
47
+
48
+ @abstractmethod
49
+ def click_exists(self, timeout: float = 0) -> bool:
50
+ """存在则点击,返回是否成功。"""
51
+
52
+ # ============================================================
53
+ # 文本类
54
+ # ============================================================
55
+
56
+ @abstractmethod
57
+ def set_text(self, text: str) -> None:
58
+ """输入文本。"""
59
+
60
+ @abstractmethod
61
+ def get_text(self) -> str:
62
+ """获取文本。"""
63
+
64
+ @abstractmethod
65
+ def clear_text(self) -> None:
66
+ """清空文本。"""
67
+
68
+ @abstractmethod
69
+ def input_text(self, text: str) -> None:
70
+ """输入文本(set_text 别名)。"""
71
+
72
+ # ============================================================
73
+ # 状态类
74
+ # ============================================================
75
+
76
+ @abstractmethod
77
+ def exists(self) -> bool:
78
+ """是否存在。"""
79
+
80
+ @abstractmethod
81
+ def wait(self, timeout: float) -> bool:
82
+ """等待出现。"""
83
+
84
+ @abstractmethod
85
+ def wait_gone(self, timeout: float) -> bool:
86
+ """等待消失。"""
87
+
88
+ # ============================================================
89
+ # 信息类
90
+ # ============================================================
91
+
92
+ @property
93
+ @abstractmethod
94
+ def info(self) -> Dict[str, Any]:
95
+ """控件信息(text/id/class/bounds/clickable/enabled/visible)。"""
96
+
97
+ @property
98
+ @abstractmethod
99
+ def bounds(self) -> Any:
100
+ """控件坐标 Rect(left, top, right, bottom)。"""
101
+
102
+ @abstractmethod
103
+ def center(self) -> Tuple[int, int]:
104
+ """控件中心点 (x, y)。"""
105
+
106
+ @abstractmethod
107
+ def get_attribute(self, name: str) -> Any:
108
+ """获取控件属性。"""
109
+
110
+ @abstractmethod
111
+ def screenshot(self, filename: Optional[str] = None) -> Union['Image', str, None]:
112
+ """控件截图。"""
113
+
114
+ @property
115
+ @abstractmethod
116
+ def description(self) -> str:
117
+ """description 属性。"""
118
+
119
+ @abstractmethod
120
+ def get_hint(self) -> str:
121
+ """获取 hint 属性。"""
122
+
123
+ @abstractmethod
124
+ def get_all_properties(self) -> dict:
125
+ """获取所有属性。"""
126
+
127
+ @abstractmethod
128
+ def get_original_text(self) -> str:
129
+ """获取原始文本。"""
130
+
131
+ # ============================================================
132
+ # 布尔属性
133
+ # ============================================================
134
+
135
+ @property
136
+ @abstractmethod
137
+ def is_long_clickable(self) -> bool:
138
+ """是否可长按。"""
139
+
140
+ @property
141
+ @abstractmethod
142
+ def is_checked(self) -> bool:
143
+ """是否已选中。"""
144
+
145
+ @property
146
+ @abstractmethod
147
+ def is_checkable(self) -> bool:
148
+ """是否可选中。"""
149
+
150
+ @property
151
+ @abstractmethod
152
+ def is_selected(self) -> bool:
153
+ """是否处于选中态。"""
154
+
155
+ # ============================================================
156
+ # 拖拽类
157
+ # ============================================================
158
+
159
+ @abstractmethod
160
+ def drag_to(self, x: int, y: int) -> None:
161
+ """拖拽到坐标。"""
162
+
163
+ @abstractmethod
164
+ def drag_to_component(self, other: 'BaseComponent') -> None:
165
+ """拖拽到另一控件。"""
166
+
167
+ # ============================================================
168
+ # 缩放类
169
+ # ============================================================
170
+
171
+ @abstractmethod
172
+ def pinch_in(self, scale: float = 0.5) -> None:
173
+ """控件上捏合缩小。"""
174
+
175
+ @abstractmethod
176
+ def pinch_out(self, scale: float = 1.5) -> None:
177
+ """控件上捏合放大。"""
178
+
179
+ # ============================================================
180
+ # 滚动类
181
+ # ============================================================
182
+
183
+ @abstractmethod
184
+ def scroll_search(self, target, vertical: bool = True,
185
+ offset: Optional[int] = None) -> Optional['BaseComponent']:
186
+ """滚动查找子控件。"""
187
+
188
+ @abstractmethod
189
+ def scroll_to_top(self, speed: int = 600) -> None:
190
+ """滚动到顶部。"""
191
+
192
+ @abstractmethod
193
+ def scroll_to_bottom(self, speed: int = 600) -> None:
194
+ """滚动到底部。"""
195
+
196
+ # ============================================================
197
+ # 关系选择器(返回新的 BaseComponent,持有衍生 SelectorSpec)
198
+ # ============================================================
199
+
200
+ @abstractmethod
201
+ def child(self, **kwargs) -> 'BaseComponent':
202
+ """子控件。"""
203
+
204
+ @abstractmethod
205
+ def sibling(self, **kwargs) -> 'BaseComponent':
206
+ """兄弟控件。"""
207
+
208
+ @abstractmethod
209
+ def after(self, **kwargs) -> 'BaseComponent':
210
+ """之后控件。"""
211
+
212
+ @abstractmethod
213
+ def before(self, **kwargs) -> 'BaseComponent':
214
+ """之前控件。"""