mangoautomation 1.0.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.

Potentially problematic release.


This version of mangoautomation might be problematic. Click here for more details.

Files changed (55) hide show
  1. mangoautomation/__init__.py +5 -0
  2. mangoautomation/enums/__init__.py +19 -0
  3. mangoautomation/enums/_base_enum.py +38 -0
  4. mangoautomation/enums/_ui_enum.py +110 -0
  5. mangoautomation/exceptions/__init__.py +14 -0
  6. mangoautomation/exceptions/_error_msg.py +73 -0
  7. mangoautomation/exceptions/_exceptions.py +14 -0
  8. mangoautomation/models/__init__.py +15 -0
  9. mangoautomation/models/_ui_model.py +61 -0
  10. mangoautomation/tools/__init__.py +13 -0
  11. mangoautomation/tools/_mate.py +12 -0
  12. mangoautomation/uidrive/__init__.py +20 -0
  13. mangoautomation/uidrive/_async_element.py +286 -0
  14. mangoautomation/uidrive/_base_data.py +103 -0
  15. mangoautomation/uidrive/_driver_object.py +63 -0
  16. mangoautomation/uidrive/_sync_element.py +286 -0
  17. mangoautomation/uidrive/android/__init__.py +127 -0
  18. mangoautomation/uidrive/android/_application.py +69 -0
  19. mangoautomation/uidrive/android/_assertion.py +84 -0
  20. mangoautomation/uidrive/android/_customization.py +15 -0
  21. mangoautomation/uidrive/android/_element.py +168 -0
  22. mangoautomation/uidrive/android/_equipment.py +150 -0
  23. mangoautomation/uidrive/android/_new_android.py +54 -0
  24. mangoautomation/uidrive/android/_page.py +116 -0
  25. mangoautomation/uidrive/pc/__init__.py +80 -0
  26. mangoautomation/uidrive/pc/assertion.py +5 -0
  27. mangoautomation/uidrive/pc/customization.py +10 -0
  28. mangoautomation/uidrive/pc/element.py +21 -0
  29. mangoautomation/uidrive/pc/input_device.py +14 -0
  30. mangoautomation/uidrive/pc/new_windows.py +79 -0
  31. mangoautomation/uidrive/web/__init__.py +5 -0
  32. mangoautomation/uidrive/web/async_web/__init__.py +174 -0
  33. mangoautomation/uidrive/web/async_web/_assertion.py +290 -0
  34. mangoautomation/uidrive/web/async_web/_browser.py +97 -0
  35. mangoautomation/uidrive/web/async_web/_customization.py +14 -0
  36. mangoautomation/uidrive/web/async_web/_element.py +199 -0
  37. mangoautomation/uidrive/web/async_web/_input_device.py +83 -0
  38. mangoautomation/uidrive/web/async_web/_new_browser.py +151 -0
  39. mangoautomation/uidrive/web/async_web/_page.py +62 -0
  40. mangoautomation/uidrive/web/sync_web/__init__.py +174 -0
  41. mangoautomation/uidrive/web/sync_web/_assertion.py +282 -0
  42. mangoautomation/uidrive/web/sync_web/_browser.py +96 -0
  43. mangoautomation/uidrive/web/sync_web/_customization.py +14 -0
  44. mangoautomation/uidrive/web/sync_web/_element.py +198 -0
  45. mangoautomation/uidrive/web/sync_web/_input_device.py +79 -0
  46. mangoautomation/uidrive/web/sync_web/_new_browser.py +146 -0
  47. mangoautomation/uidrive/web/sync_web/_page.py +61 -0
  48. mangoautomation-1.0.0.dist-info/LICENSE +21 -0
  49. mangoautomation-1.0.0.dist-info/METADATA +30 -0
  50. mangoautomation-1.0.0.dist-info/RECORD +55 -0
  51. mangoautomation-1.0.0.dist-info/WHEEL +5 -0
  52. mangoautomation-1.0.0.dist-info/top_level.txt +2 -0
  53. tests/__init__.py +5 -0
  54. tests/test_ui_and.py +29 -0
  55. tests/test_ui_web.py +77 -0
@@ -0,0 +1,168 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台# @Description:
3
+ # @Time : 2023-09-09 23:17
4
+ # @Author : 毛鹏
5
+ import os.path
6
+
7
+ import time
8
+ from uiautomator2 import UiObject
9
+ from uiautomator2.xpath import XPathSelector
10
+
11
+ from ...exceptions import MangoAutomationError
12
+ from ...exceptions._error_msg import ERROR_MSG_0043, ERROR_MSG_0044
13
+ from ...tools import Meta
14
+ from ...uidrive._base_data import BaseData
15
+ from mangotools.decorator import sync_method_callback
16
+ from mangotools.models import MethodModel
17
+
18
+
19
+ class AndroidElement(metaclass=Meta):
20
+ """元素操作"""
21
+
22
+ def __init__(self, base_data: BaseData):
23
+ self.base_data = base_data
24
+
25
+ @sync_method_callback('android', '元素操作', 0, [
26
+ MethodModel(f='locating')])
27
+ def a_click(self, locating: UiObject | XPathSelector):
28
+ """元素单击"""
29
+ locating.click()
30
+
31
+ @sync_method_callback('android', '元素操作', 1, [
32
+ MethodModel(f='locating')])
33
+ def a_double_click(self, locating: UiObject):
34
+ """元素双击"""
35
+ locating.click()
36
+
37
+ @sync_method_callback('android', '元素操作', 2, [
38
+ MethodModel(f='locating'), MethodModel(f='text', p='请输入内容', d=True)])
39
+ def a_input(self, locating: UiObject, text):
40
+ """单击输入"""
41
+ locating.click()
42
+ self.base_data.android.set_fastinput_ime(True)
43
+ time.sleep(1)
44
+ self.base_data.android.send_keys(text)
45
+
46
+ @sync_method_callback('android', '元素操作', 3, [
47
+ MethodModel(f='locating'), MethodModel(f='text', p='请输入内容', d=True)])
48
+ def a_set_text(self, locating: UiObject, text):
49
+ """设置文本"""
50
+ locating.set_text(text)
51
+
52
+ @sync_method_callback('android', '元素操作', 4, [
53
+ MethodModel(f='locating'),
54
+ MethodModel(f='x', p='请输入x坐标', d=True),
55
+ MethodModel(f='y', p='请输入y坐标', d=True)])
56
+ def a_click_coord(self, x, y):
57
+ """坐标单击"""
58
+ self.base_data.android.click(x, y)
59
+
60
+ @sync_method_callback('android', '元素操作', 5, [
61
+ MethodModel(f='x', p='请输入x坐标', d=True),
62
+ MethodModel(f='y', p='请输入y坐标', d=True)])
63
+ def a_double_click_coord(self, x, y):
64
+ """坐标双击"""
65
+ self.base_data.android.double_click(x, y)
66
+
67
+ @sync_method_callback('android', '元素操作', 6, [
68
+ MethodModel(f='locating'),
69
+ MethodModel(f='time_', p='请输入长按坐标时间', d=True)])
70
+ def a_long_click(self, locating: UiObject, time_):
71
+ """长按元素"""
72
+ locating.long_click(duration=float(time_))
73
+
74
+ @sync_method_callback('android', '元素操作', 7, [MethodModel(f='locating')])
75
+ def a_clear_text(self, locating: UiObject):
76
+ """清空输入框"""
77
+ locating.clear_text()
78
+
79
+ @sync_method_callback('android', '元素操作', 8, [
80
+ MethodModel(f='locating'), MethodModel(f='set_cache_key', p='请输入元素文本存储的key', d=True)])
81
+ def a_get_text(self, locating: UiObject, set_cache_key=None):
82
+ """获取元素文本"""
83
+ value = locating.get_text()
84
+ if set_cache_key:
85
+ self.base_data.test_data.set_cache(key=set_cache_key, value=value)
86
+ return value
87
+
88
+ @sync_method_callback('android', '元素操作', 9, [
89
+ MethodModel(f='locating'),
90
+ MethodModel(f='file_name', p='请输入元素截图存储的名称,后续可以通过名称获取', d=True)])
91
+ def a_element_screenshot(self, locating: UiObject, file_name: str):
92
+ """元素截图"""
93
+ im = locating.screenshot()
94
+ file_path = os.path.join(self.base_data.screenshot_path, file_name)
95
+ self.base_data.test_data.set_cache(file_name, file_path)
96
+ im.save(file_path)
97
+
98
+ @sync_method_callback('android', '元素操作', 10, [
99
+ MethodModel(f='locating')])
100
+ def a_pinch_in(self, locating: UiObject):
101
+ """元素缩小"""
102
+ locating.pinch_in()
103
+
104
+ @sync_method_callback('android', '元素操作', 11, [
105
+ MethodModel(f='locating')])
106
+ def a_pinch_out(self, locating: UiObject):
107
+ """元素放大"""
108
+ locating.pinch_out()
109
+
110
+ @sync_method_callback('android', '元素操作', 12, [
111
+ MethodModel(f='locating'), MethodModel(f='time_', p='请输入等待元素出现的时间', d=True)])
112
+ def a_wait(self, locating: UiObject, time_):
113
+ """等待元素出现"""
114
+ if not locating.wait(timeout=float(time_)):
115
+ raise MangoAutomationError(*ERROR_MSG_0043)
116
+
117
+ @sync_method_callback('android', '元素操作', 13, [
118
+ MethodModel(f='locating'), MethodModel(f='time_', p='请输入等待元素消失的时间', d=True)])
119
+ def a_wait_gone(self, locating: UiObject, time_: str):
120
+ """等待元素消失"""
121
+ if not locating.wait_gone(timeout=float(time_)):
122
+ raise MangoAutomationError(*ERROR_MSG_0044)
123
+
124
+ @sync_method_callback('android', '元素操作', 14, [
125
+ MethodModel(f='locating'), MethodModel(f='locating2')])
126
+ def a_drag_to_ele(self, locating: UiObject, locating2: UiObject):
127
+ """拖动A元素到达B元素上"""
128
+ locating.drag_to(locating2)
129
+
130
+ @sync_method_callback('android', '元素操作', 15, [
131
+ MethodModel(f='locating'),
132
+ MethodModel(f='x', p='请输入x坐标', d=True),
133
+ MethodModel(f='y', p='请输入y坐标', d=True)])
134
+ def a_drag_to_coord(self, locating: UiObject, x, y):
135
+ """拖动元素到坐标上"""
136
+ locating.drag_to(x, y)
137
+
138
+ @sync_method_callback('android', '元素操作', 16, [MethodModel(f='locating')])
139
+ def a_swipe_right(self, locating: UiObject):
140
+ """元素内向右滑动"""
141
+ locating.swipe('right')
142
+
143
+ @sync_method_callback('android', '元素操作', 17, [MethodModel(f='locating')])
144
+ def a_swipe_left(self, locating: UiObject):
145
+ """元素内向左滑动"""
146
+ locating.swipe('left')
147
+
148
+ @sync_method_callback('android', '元素操作', 18, [MethodModel(f='locating')])
149
+ def a_swipe_up(self, locating: UiObject):
150
+ """元素内向上滑动"""
151
+ locating.swipe('up')
152
+
153
+ @sync_method_callback('android', '元素操作', 19, [MethodModel(f='locating')])
154
+ def a_swipe_ele(self, locating: UiObject):
155
+ """元素内向下滑动"""
156
+ locating.swipe('down')
157
+
158
+ @sync_method_callback('android', '元素操作', 20, [
159
+ MethodModel(f='locating'),
160
+ MethodModel(f='x_key', p='请输入x坐标', d=True),
161
+ MethodModel(f='y_key', p='请输入y坐标', d=True)])
162
+ def a_get_center(self, locating: UiObject, x_key, y_key):
163
+ """提取元素坐标"""
164
+ x, y = locating.center()
165
+ if x_key and y_key:
166
+ self.base_data.test_data.set_cache(key=x_key, value=x)
167
+ self.base_data.test_data.set_cache(key=y_key, value=y)
168
+ return x, y
@@ -0,0 +1,150 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台# @Description:
3
+ # @Time : 03-09-09 3:17
4
+ # @Author : 毛鹏
5
+ from time import sleep
6
+
7
+ from ...tools import Meta
8
+ from ...uidrive._base_data import BaseData
9
+ from mangotools.decorator import sync_method_callback
10
+ from mangotools.models import MethodModel
11
+
12
+
13
+ class AndroidEquipment(metaclass=Meta):
14
+ """设备操作"""
15
+
16
+ def __init__(self, base_data: BaseData):
17
+ self.base_data = base_data
18
+
19
+ @sync_method_callback('android', '设备操作', 1, [
20
+ MethodModel(f='_time', p='请输入等待时间', d=True)])
21
+ def a_sleep(self, time_: int):
22
+ """强制等待"""
23
+ sleep(time_)
24
+
25
+ @sync_method_callback('android', '设备操作', )
26
+ def a_screen_on(self):
27
+ """打开屏幕"""
28
+ self.base_data.android.screen_on()
29
+ self.a_sleep(1)
30
+
31
+ @sync_method_callback('android', '设备操作', )
32
+ def a_screen_off(self):
33
+ """关闭屏幕"""
34
+ self.base_data.android.screen_off()
35
+ self.a_sleep(1)
36
+
37
+ @sync_method_callback('android', '设备操作', )
38
+ def a_swipe_left(self):
39
+ """获取屏幕开关状态"""
40
+ self.base_data.android.info.get('screenOn')
41
+
42
+ @sync_method_callback('android', '设备操作', )
43
+ def a_get_window_size(self):
44
+ """提取屏幕尺寸"""
45
+ w, h = self.base_data.android.window_size()
46
+ return w, h
47
+
48
+ @sync_method_callback('android', '设备操作', [
49
+ MethodModel(f='feli_path', p='请输入计算机文件路径', d=True),
50
+ MethodModel(f='catalogue', p='请输入设备目录', d=True)])
51
+ def a_push(self, feli_path, catalogue):
52
+ """推送一个文件到设备"""
53
+ self.base_data.android.push(feli_path, catalogue)
54
+
55
+ @sync_method_callback('android', '设备操作', [
56
+ MethodModel(f='feli_path', p='请输入设备文件路径', d=True),
57
+ MethodModel(f='catalogue', p='请输入计算机目录', d=True)])
58
+ def a_pull(self, feli_path, catalogue):
59
+ """提取文件"""
60
+ self.base_data.android.pull(feli_path, catalogue)
61
+
62
+ @sync_method_callback('android', '设备操作', )
63
+ def a_unlock(self):
64
+ """解锁屏幕"""
65
+ self.base_data.android.unlock()
66
+
67
+ @sync_method_callback('android', '设备操作', )
68
+ def a_press_home(self):
69
+ """按home键"""
70
+ self.base_data.android.press('home')
71
+
72
+ @sync_method_callback('android', '设备操作', )
73
+ def a_press_back(self):
74
+ """按back键"""
75
+ self.base_data.android.press('back')
76
+
77
+ @sync_method_callback('android', '设备操作', )
78
+ def a_press_left(self):
79
+ """按left键"""
80
+ self.base_data.android.press('left')
81
+
82
+ @sync_method_callback('android', '设备操作', )
83
+ def a_press_right(self):
84
+ """按right键"""
85
+ self.base_data.android.press('right')
86
+
87
+ @sync_method_callback('android', '设备操作', )
88
+ def a_press_up(self):
89
+ """按up键"""
90
+ self.base_data.android.press('up')
91
+
92
+ @sync_method_callback('android', '设备操作', )
93
+ def a_press_down(self):
94
+ """按down键"""
95
+ self.base_data.android.press('down')
96
+
97
+ @sync_method_callback('android', '设备操作', )
98
+ def a_press_center(self):
99
+ """按center键"""
100
+ self.base_data.android.press('center')
101
+
102
+ @sync_method_callback('android', '设备操作', )
103
+ def a_press_menu(self):
104
+ """按menu键"""
105
+ self.base_data.android.press('menu')
106
+
107
+ @sync_method_callback('android', '设备操作', )
108
+ def a_press_search(self):
109
+ """按search键"""
110
+ self.base_data.android.press('search')
111
+
112
+ @sync_method_callback('android', '设备操作', )
113
+ def a_press_enter(self):
114
+ """按enter键"""
115
+ self.base_data.android.press('enter')
116
+
117
+ @sync_method_callback('android', '设备操作', )
118
+ def a_press_delete(self):
119
+ """按delete键"""
120
+ self.base_data.android.press('delete')
121
+
122
+ @sync_method_callback('android', '设备操作', )
123
+ def a_press_recent(self):
124
+ """按recent键"""
125
+ self.base_data.android.press('recent')
126
+
127
+ @sync_method_callback('android', '设备操作', )
128
+ def a_press_volume_up(self):
129
+ """按volume_up键"""
130
+ self.base_data.android.press('volume_up')
131
+
132
+ @sync_method_callback('android', '设备操作', )
133
+ def a_press_volume_down(self):
134
+ """按volume_down键"""
135
+ self.base_data.android.press('volume_down')
136
+
137
+ @sync_method_callback('android', '设备操作', )
138
+ def a_press_volume_mute(self):
139
+ """按volume_mute键"""
140
+ self.base_data.android.press('volume_mute')
141
+
142
+ @sync_method_callback('android', '设备操作', )
143
+ def a_press_camera(self):
144
+ """按camera键"""
145
+ self.base_data.android.press('camera')
146
+
147
+ @sync_method_callback('android', '设备操作', )
148
+ def a_press_power(self):
149
+ """按power键"""
150
+ self.base_data.android.press('power')
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2024-05-23 15:05
5
+ # @Author : 毛鹏
6
+
7
+ from typing import Optional
8
+
9
+ import uiautomator2 as u2
10
+ from adbutils import AdbTimeout
11
+ from uiautomator2 import ConnectError
12
+
13
+ from ...exceptions import MangoAutomationError
14
+ from ...exceptions._error_msg import ERROR_MSG_0042, ERROR_MSG_0045, ERROR_MSG_0040
15
+
16
+ """
17
+ python -m uiautomator2 init
18
+ python -m weditor
19
+
20
+ """
21
+
22
+
23
+ class NewAndroid:
24
+
25
+ def __init__(self, and_equipment):
26
+ self.and_equipment = and_equipment
27
+ self.info: Optional[dict | None] = None
28
+ self.example_dict = []
29
+
30
+ def new_android(self):
31
+ if self.and_equipment is None:
32
+ raise MangoAutomationError(*ERROR_MSG_0042)
33
+ try:
34
+
35
+ android = u2.connect(self.and_equipment)
36
+ self.info = android.info
37
+ # msg = f"设备启动成功!产品名称:{self.info.get('productName')}"
38
+ self.example_dict.append({
39
+ 'config': self.and_equipment,
40
+ 'info': self.info,
41
+ 'android': android
42
+ })
43
+ except ConnectError:
44
+ raise MangoAutomationError(*ERROR_MSG_0040, value=(self.and_equipment,))
45
+ except RuntimeError:
46
+ raise MangoAutomationError(*ERROR_MSG_0045, value=(self.and_equipment,))
47
+ except (AdbTimeout, TimeoutError):
48
+ raise MangoAutomationError(*ERROR_MSG_0040, value=(self.and_equipment,))
49
+ else:
50
+ android.implicitly_wait(10)
51
+ return android
52
+
53
+ def close_android(self):
54
+ pass
@@ -0,0 +1,116 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description: # @Time : 2023/4/6 13:31
4
+ # @Author : 毛鹏
5
+ import os.path
6
+
7
+ from uiautomator2 import Direction
8
+
9
+ from ...tools import Meta
10
+ from ...uidrive._base_data import BaseData
11
+ from mangotools.decorator import sync_method_callback
12
+ from mangotools.models import MethodModel
13
+
14
+
15
+ class AndroidPage(metaclass=Meta):
16
+ """页面操作"""
17
+
18
+ def __init__(self, base_data: BaseData):
19
+ self.base_data = base_data
20
+
21
+ @sync_method_callback('android', '页面操作')
22
+ def a_swipe_right(self):
23
+ """右滑"""
24
+ self.base_data.android.swipe_ext(Direction.HORIZ_FORWARD)
25
+
26
+ @sync_method_callback('android', '页面操作')
27
+ def a_swipe_left(self):
28
+ """左滑"""
29
+ self.base_data.android.swipe_ext(Direction.HORIZ_BACKWARD)
30
+
31
+ @sync_method_callback('android', '页面操作')
32
+ def a_swipe_up(self):
33
+ """上滑"""
34
+ self.base_data.android.swipe_ext(Direction.FORWARD)
35
+
36
+ @sync_method_callback('android', '页面操作')
37
+ def a_swipe_down(self):
38
+ """下滑"""
39
+ self.base_data.android.swipe_ext(Direction.BACKWARD)
40
+
41
+ @sync_method_callback('android', '页面操作', [
42
+ MethodModel(f='sx', p='请输入sx坐标', d=True),
43
+ MethodModel(f='sy', p='请输入sy坐标', d=True),
44
+ MethodModel(f='ex', p='请输入ex坐标', d=True),
45
+ MethodModel(f='ey', p='请输入ey坐标', d=True)])
46
+ def a_swipe(self, sx, sy, ex, ey):
47
+ """坐标滑动"""
48
+ self.base_data.android.swipe(sx, sy, ex, ey, 0.5)
49
+
50
+ @sync_method_callback('android', '页面操作', [
51
+ MethodModel(f='sx', p='请输入sx坐标', d=True),
52
+ MethodModel(f='sy', p='请输入sy坐标', d=True),
53
+ MethodModel(f='ex', p='请输入ex坐标', d=True),
54
+ MethodModel(f='ey', p='请输入ey坐标', d=True)])
55
+ def a_drag(self, sx, sy, ex, ey):
56
+ """坐标拖动"""
57
+ self.base_data.android.drag(sx, sy, ex, ey, 0.5)
58
+
59
+ @sync_method_callback('android', '页面操作')
60
+ def a_open_quick_settings(self):
61
+ """打开快速通知"""
62
+ self.base_data.android.open_quick_settings()
63
+
64
+ @sync_method_callback('android', '页面操作', [
65
+ MethodModel(f='file_name', p='请输入截图文件名称', d=True)])
66
+ def a_screenshot(self, file_name: str):
67
+ """屏幕截图"""
68
+ self.base_data.android.screenshot(filename=os.path.join(self.base_data.screenshot_path, file_name))
69
+
70
+ @sync_method_callback('android', '页面操作', [
71
+ MethodModel(f='x', p='请输入按下的x坐标', d=True),
72
+ MethodModel(f='y', p='请输入按下的x坐标', d=True),
73
+ MethodModel(f='time_', p='请输入长按时间', d=True)])
74
+ def a_long_click(self, x, y, time_):
75
+ """长按屏幕N秒"""
76
+ self.base_data.android.long_click(x, y, time_)
77
+
78
+ @sync_method_callback('android', '页面操作')
79
+ def a_set_orientation_natural(self):
80
+ """设置为natural"""
81
+ self.base_data.android.set_orientation("natural")
82
+
83
+ @sync_method_callback('android', '页面操作')
84
+ def a_set_orientation_left(self):
85
+ """设置为natural"""
86
+ self.base_data.android.set_orientation("left")
87
+
88
+ @sync_method_callback('android', '页面操作')
89
+ def a_set_orientation_right(self):
90
+ """设置为right"""
91
+ self.base_data.android.set_orientation("right")
92
+
93
+ @sync_method_callback('android', '页面操作')
94
+ def a_set_orientation_upsidedown(self):
95
+ """设置为upsidedown"""
96
+ self.base_data.android.set_orientation("upsidedown")
97
+
98
+ @sync_method_callback('android', '页面操作')
99
+ def a_freeze_rotation(self):
100
+ """冻结旋转"""
101
+ self.base_data.android.freeze_rotation()
102
+
103
+ @sync_method_callback('android', '页面操作')
104
+ def a_freeze_rotation_false(self):
105
+ """取消冻结旋转"""
106
+ self.base_data.android.freeze_rotation(False)
107
+
108
+ @sync_method_callback('android', '页面操作')
109
+ def a_dump_hierarchy(self):
110
+ """获取转储的内容"""
111
+ return self.base_data.android.dump_hierarchy()
112
+
113
+ @sync_method_callback('android', '页面操作')
114
+ def a_open_notification(self):
115
+ """打开通知"""
116
+ return self.base_data.android.dump_hierarchy()
@@ -0,0 +1,80 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description: # @Time : 2023-07-15 12:02
4
+ # @Author : 毛鹏
5
+ from typing import Optional
6
+
7
+ import sys
8
+
9
+ if not sys.platform.startswith('win32'):
10
+ print("警告: uiautomation 仅支持 Windows,当前环境已自动跳过")
11
+
12
+
13
+ class Auto:
14
+ pass
15
+
16
+
17
+ auto = Auto()
18
+
19
+
20
+ class Control:
21
+ pass
22
+ else:
23
+
24
+ from uiautomation import Control
25
+ import uiautomation
26
+
27
+ from mangoautomation.uidrive._base_data import BaseData
28
+ from mangoautomation.uidrive.pc.element import WinElement
29
+ from mangoautomation.uidrive.pc.input_device import WinDeviceInput
30
+
31
+
32
+ class WinDriver(WinElement, WinDeviceInput):
33
+ def __init__(self, base_data: BaseData):
34
+ super().__init__(base_data)
35
+
36
+ def find_element(
37
+ self,
38
+ *,
39
+ control_type: str = "Control",
40
+ name: Optional[str] = None,
41
+ automation_id: Optional[str] = None,
42
+ depth: int = 2,
43
+ parent: Optional[Control] = None,
44
+ **extra_attrs
45
+ ) -> Control:
46
+
47
+ if not any([name, automation_id, extra_attrs]):
48
+ raise ValueError("必须提供至少一个定位参数(name/automation_id/其他属性)")
49
+
50
+ # 设置默认父控件
51
+ parent = parent or self.base_data.window.GetParentControl()
52
+
53
+ # 构造搜索参数
54
+ search_params = {
55
+ "searchDepth": depth,
56
+ "Timeout": 10 * 1000,
57
+ **{
58
+ key.capitalize() if key != "className" else "ClassName": value
59
+ for key, value in {
60
+ "name": name,
61
+ "automationId": automation_id,
62
+ **extra_attrs
63
+ }.items()
64
+ if value is not None
65
+ }
66
+ }
67
+
68
+ # 获取控件类并查找
69
+ control_class = getattr(uiautomation, f"{control_type}Control", Control)
70
+ control = control_class(parent=parent, **search_params)
71
+
72
+ if not control.Exists():
73
+ raise ElementNotFoundError(
74
+ f"未找到控件: type={control_type}, params={search_params}"
75
+ )
76
+ return control
77
+
78
+
79
+ class ElementNotFoundError(Exception):
80
+ pass
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2024-11-30 23:44
5
+ # @Author : 毛鹏
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2024-08-13 14:07
5
+ # @Author : 毛鹏
6
+ from ...uidrive._base_data import BaseData
7
+
8
+
9
+ class PlaywrightCustomization(BaseData):
10
+ """定制开发"""
@@ -0,0 +1,21 @@
1
+ from ...tools import Meta
2
+ from ...uidrive._base_data import BaseData
3
+
4
+
5
+ class WinElement(metaclass=Meta):
6
+ """元素操作"""
7
+
8
+ def __init__(self, base_data: BaseData):
9
+ self.base_data = base_data
10
+
11
+ def click(self, control):
12
+ """点击控件"""
13
+ control.Click()
14
+
15
+ def input_text(self, control, text: str):
16
+ """输入文本"""
17
+ control.SendKeys(text)
18
+
19
+ def get_text(self, control) -> str:
20
+ """获取控件文本"""
21
+ return control.Name
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2024-11-30 23:44
5
+ # @Author : 毛鹏
6
+ from ...tools import Meta
7
+ from ...uidrive._base_data import BaseData
8
+
9
+
10
+ class WinDeviceInput(metaclass=Meta):
11
+ """输入设备操作"""
12
+
13
+ def __init__(self, base_data: BaseData):
14
+ self.base_data = base_data