mangoautomation 1.0.60__tar.gz → 1.1.2__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.
Potentially problematic release.
This version of mangoautomation might be problematic. Click here for more details.
- {mangoautomation-1.0.60/mangoautomation.egg-info → mangoautomation-1.1.2}/PKG-INFO +2 -10
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/enums/_ui_enum.py +3 -1
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/exceptions/error_msg.py +2 -2
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/models/_ui_model.py +19 -16
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/_async_element.py +83 -54
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/_sync_element.py +85 -56
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/__init__.py +1 -1
- {mangoautomation-1.0.60 → mangoautomation-1.1.2/mangoautomation.egg-info}/PKG-INFO +2 -10
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/setup.py +1 -1
- mangoautomation-1.1.2/tests/get_ope.py +8 -0
- mangoautomation-1.0.60/tests/get_ope.py +0 -12
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/LICENSE +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/MANIFEST.in +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/README.md +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/enums/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/enums/_base_enum.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/exceptions/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/exceptions/_exceptions.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/models/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/tools/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/tools/_mate.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/tools/_uiautodev.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/_base_data.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/_driver_object.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_application.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_assertion.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_customization.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_element.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_equipment.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_new_android.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_page.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/ios/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/assertion.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/customization.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/element.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/input_device.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/new_windows.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_assertion.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_browser.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_customization.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_element.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_input_device.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_new_browser.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_page.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_assertion.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_browser.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_customization.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_element.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_input_device.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_new_browser.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_page.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation.egg-info/SOURCES.txt +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation.egg-info/dependency_links.txt +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation.egg-info/requires.txt +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation.egg-info/top_level.txt +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/setup.cfg +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/tests/__init__.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/tests/test_ui_and.py +0 -0
- {mangoautomation-1.0.60 → mangoautomation-1.1.2}/tests/test_ui_web.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: mangoautomation
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: 测试工具
|
|
5
5
|
Home-page: https://gitee.com/mao-peng/testkit
|
|
6
6
|
Author: 毛鹏
|
|
@@ -18,14 +18,6 @@ Requires-Dist: uiautomator2>=3.2.5
|
|
|
18
18
|
Requires-Dist: mangotools>=1.1.42
|
|
19
19
|
Requires-Dist: adbutils~=2.8.9
|
|
20
20
|
Requires-Dist: uiautodev>=0.9.0
|
|
21
|
-
Dynamic: author
|
|
22
|
-
Dynamic: author-email
|
|
23
|
-
Dynamic: classifier
|
|
24
|
-
Dynamic: description
|
|
25
|
-
Dynamic: home-page
|
|
26
|
-
Dynamic: license-file
|
|
27
|
-
Dynamic: requires-dist
|
|
28
|
-
Dynamic: summary
|
|
29
21
|
|
|
30
22
|
# testkit
|
|
31
23
|
|
|
@@ -73,10 +73,12 @@ class ElementOperationEnum(BaseEnum):
|
|
|
73
73
|
ASS = 1
|
|
74
74
|
SQL = 2
|
|
75
75
|
CUSTOM = 3
|
|
76
|
+
CONDITION = 4
|
|
77
|
+
PYTHON_CODE = 5
|
|
76
78
|
|
|
77
79
|
@classmethod
|
|
78
80
|
def obj(cls):
|
|
79
|
-
return {0: "
|
|
81
|
+
return {0: "元素操作", 1: "断言操作", 2: "SQL变量", 3: "自定义变量", 4: "条件判断", 5: "python代码"}
|
|
80
82
|
|
|
81
83
|
|
|
82
84
|
class DeviceEnum(BaseEnum):
|
|
@@ -38,8 +38,8 @@ ERROR_MSG_0029 = (4029, '页面无元素【{}】,表达式:{}')
|
|
|
38
38
|
ERROR_MSG_0030 = (4030, '断言时没有找到元素')
|
|
39
39
|
ERROR_MSG_0031 = (4031, '元素未找到准备进行断言获取元素文本类容异常')
|
|
40
40
|
ERROR_MSG_0032 = (4032, '元素【{}】的元素表达式定位有多个,或其他元素异常,请检查元素是否可用')
|
|
41
|
-
ERROR_MSG_0036 = (4036, '
|
|
42
|
-
ERROR_MSG_0038 = (4038, '
|
|
41
|
+
ERROR_MSG_0036 = (4036, 'sql参数在数据库中查询不到结果,sql:{}')
|
|
42
|
+
ERROR_MSG_0038 = (4038, 'sql参数的sql_key不是列表')
|
|
43
43
|
ERROR_MSG_0040 = (
|
|
44
44
|
340, '设备启动超时!请检查设备是否开启了:文件传输模式、开发者模式、usb调试,开启后请重新连接电脑,设备号:{}')
|
|
45
45
|
ERROR_MSG_0041 = (4041, '查找页面元素【{}】时直接失败,报错信息:{}')
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
|
+
from mangoautomation.enums import ElementOperationEnum
|
|
9
10
|
from mangotools.models import MysqlConingModel, MethodModel
|
|
10
11
|
|
|
11
12
|
|
|
@@ -18,24 +19,24 @@ class EnvironmentConfigModel(BaseModel):
|
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class ElementListModel(BaseModel):
|
|
21
|
-
exp: int
|
|
22
|
-
loc: str
|
|
22
|
+
exp: int
|
|
23
|
+
loc: str
|
|
24
|
+
sub: int | None = None
|
|
25
|
+
is_iframe: int | None
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
class ElementModel(BaseModel):
|
|
26
29
|
id: int
|
|
27
|
-
type:
|
|
30
|
+
type: ElementOperationEnum
|
|
28
31
|
name: str | None
|
|
29
32
|
elements: list[ElementListModel] = []
|
|
30
33
|
sleep: int | None
|
|
31
|
-
sub: int | None
|
|
32
|
-
is_iframe: int | None
|
|
33
34
|
ope_key: str | None
|
|
34
|
-
ope_value: list[MethodModel] | None
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
ope_value: list[MethodModel] | None = None
|
|
36
|
+
sql_execute: list[dict] | None = None
|
|
37
|
+
custom: list[dict] | None = None
|
|
38
|
+
condition_value: dict | None = None
|
|
39
|
+
func: str | None = None
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
class ElementListResultModel(BaseModel):
|
|
@@ -43,25 +44,27 @@ class ElementListResultModel(BaseModel):
|
|
|
43
44
|
exp: int | None = None
|
|
44
45
|
ele_quantity: int = 0
|
|
45
46
|
element_text: str | None = None
|
|
47
|
+
sub: int | None = None
|
|
48
|
+
is_iframe: int | None
|
|
46
49
|
|
|
47
50
|
|
|
48
51
|
class ElementResultModel(BaseModel):
|
|
49
52
|
id: int
|
|
50
53
|
name: str | None = None
|
|
51
54
|
sleep: int | None = None
|
|
52
|
-
sub: int | None = None
|
|
53
55
|
|
|
54
56
|
type: int
|
|
55
57
|
ope_key: str | None = None
|
|
56
|
-
ope_value:
|
|
58
|
+
ope_value: list[MethodModel] | None = None
|
|
59
|
+
sql_execute: list[dict] | None = None
|
|
60
|
+
custom: list[dict] | None = None
|
|
61
|
+
condition_value: dict | None = None
|
|
57
62
|
ass_msg: str | None = None
|
|
58
|
-
sql: str | None = None
|
|
59
|
-
key_list: str | None = None
|
|
60
|
-
key: str | None = None
|
|
61
|
-
value: str | None = None
|
|
62
63
|
|
|
63
64
|
elements: list[ElementListResultModel] = []
|
|
64
65
|
status: int = 0
|
|
65
66
|
error_message: str | None = None
|
|
66
67
|
picture_path: str | None = None
|
|
67
68
|
picture_name: str | None = None
|
|
69
|
+
|
|
70
|
+
next_node_id: int | None = None
|
|
@@ -28,8 +28,9 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
28
28
|
super().__init__(base_data)
|
|
29
29
|
self.drive_type = drive_type
|
|
30
30
|
self.element_model: Optional[ElementModel | None] = None
|
|
31
|
-
self.element_data: dict | None = None
|
|
32
31
|
self.element_result_model: Optional[ElementResultModel | None] = None
|
|
32
|
+
self.element_list_model: Optional[list[ElementModel] | None] = None
|
|
33
|
+
self.test_data = self.base_data.test_data
|
|
33
34
|
|
|
34
35
|
async def open_device(self, is_open: bool = False):
|
|
35
36
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
@@ -42,21 +43,20 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
42
43
|
self.base_data.log.debug(f'不存在这个类型,如果是非管理员看到这种提示,请联系管理员')
|
|
43
44
|
raise Exception('不存在的设备类型')
|
|
44
45
|
|
|
45
|
-
async def element_main(self,
|
|
46
|
+
async def element_main(self,
|
|
47
|
+
element_model: ElementModel,
|
|
48
|
+
element_list_model: list[ElementModel] | None = None) -> ElementResultModel:
|
|
46
49
|
self.element_model = element_model
|
|
47
|
-
self.
|
|
50
|
+
self.element_list_model = element_list_model
|
|
48
51
|
self.element_result_model = ElementResultModel(
|
|
49
52
|
id=self.element_model.id,
|
|
50
53
|
name=self.element_model.name,
|
|
51
|
-
sub=self.element_model.sub,
|
|
52
54
|
sleep=self.element_model.sleep,
|
|
53
55
|
|
|
54
|
-
type=self.element_model.type,
|
|
56
|
+
type=self.element_model.type.value,
|
|
55
57
|
ope_key=self.element_model.ope_key,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
key=self.element_model.key,
|
|
59
|
-
value=self.element_model.value,
|
|
58
|
+
sql_execute=self.element_model.sql_execute,
|
|
59
|
+
custom=self.element_model.custom,
|
|
60
60
|
|
|
61
61
|
status=StatusEnum.FAIL.value,
|
|
62
62
|
)
|
|
@@ -91,14 +91,18 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
91
91
|
@async_retry()
|
|
92
92
|
async def __main(self):
|
|
93
93
|
self.base_data.verify_equipment(self.drive_type)
|
|
94
|
-
if self.element_model.type == ElementOperationEnum.OPE
|
|
94
|
+
if self.element_model.type == ElementOperationEnum.OPE:
|
|
95
95
|
await self.__ope()
|
|
96
|
-
elif self.element_model.type == ElementOperationEnum.ASS
|
|
96
|
+
elif self.element_model.type == ElementOperationEnum.ASS:
|
|
97
97
|
await self.__ass()
|
|
98
|
-
elif self.element_model.type == ElementOperationEnum.SQL
|
|
98
|
+
elif self.element_model.type == ElementOperationEnum.SQL:
|
|
99
99
|
await self.__sql()
|
|
100
|
-
elif self.element_model.type == ElementOperationEnum.CUSTOM
|
|
100
|
+
elif self.element_model.type == ElementOperationEnum.CUSTOM:
|
|
101
101
|
await self.__custom()
|
|
102
|
+
elif self.element_model.type == ElementOperationEnum.CONDITION:
|
|
103
|
+
await self.__condition()
|
|
104
|
+
elif self.element_model.type == ElementOperationEnum.PYTHON_CODE:
|
|
105
|
+
await self.__python_code()
|
|
102
106
|
else:
|
|
103
107
|
raise MangoAutomationError(*ERROR_MSG_0015)
|
|
104
108
|
|
|
@@ -106,11 +110,9 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
106
110
|
try:
|
|
107
111
|
for i in self.element_model.elements:
|
|
108
112
|
i.loc = self.base_data.test_data.replace(i.loc)
|
|
109
|
-
self.
|
|
113
|
+
i.sub = self.base_data.test_data.replace(i.sub)
|
|
110
114
|
self.element_model.sleep = self.base_data.test_data.replace(self.element_model.sleep)
|
|
111
115
|
self.element_result_model.sleep = self.element_model.sleep
|
|
112
|
-
self.element_model.sub = self.base_data.test_data.replace(self.element_model.sub)
|
|
113
|
-
self.element_result_model.sub = self.element_model.sub
|
|
114
116
|
|
|
115
117
|
except MangoAutomationError as error:
|
|
116
118
|
self.base_data.log.error(f'操作元素解析数据失败,类型:{type(error)}, 详情:{error}')
|
|
@@ -144,62 +146,76 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
144
146
|
)
|
|
145
147
|
else:
|
|
146
148
|
pass
|
|
147
|
-
self.element_result_model.ope_value =
|
|
149
|
+
self.element_result_model.ope_value = self.element_model.ope_value
|
|
150
|
+
for i in self.element_result_model.ope_value:
|
|
151
|
+
if not isinstance(i.v, str):
|
|
152
|
+
i.v = str(i.v)
|
|
148
153
|
|
|
149
|
-
async def __ass(self):
|
|
154
|
+
async def __ass(self, _ope_value: dict | None = None):
|
|
150
155
|
if self.element_model.ope_value is None:
|
|
151
156
|
raise MangoAutomationError(*ERROR_MSG_0054)
|
|
152
157
|
await self.__ope_value(True)
|
|
158
|
+
ope_value = {i.f: i.v for i in self.element_model.ope_value}
|
|
159
|
+
if _ope_value is not None:
|
|
160
|
+
ope_value.update(_ope_value)
|
|
153
161
|
try:
|
|
154
162
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
155
163
|
self.element_result_model.ass_msg = await self.web_assertion_element(
|
|
156
164
|
self.element_model.name,
|
|
157
165
|
self.element_model.ope_key,
|
|
158
|
-
|
|
166
|
+
ope_value
|
|
159
167
|
)
|
|
160
168
|
elif self.drive_type == DriveTypeEnum.ANDROID.value:
|
|
161
169
|
self.element_result_model.ass_msg = self.a_assertion_element(
|
|
162
170
|
self.element_model.name,
|
|
163
171
|
self.element_model.ope_key,
|
|
164
|
-
|
|
172
|
+
ope_value
|
|
165
173
|
)
|
|
166
174
|
else:
|
|
167
175
|
pass
|
|
168
176
|
except MangoAutomationError as error:
|
|
169
177
|
self.element_result_model.ass_msg = error.msg
|
|
170
178
|
raise error
|
|
171
|
-
self.element_result_model.ope_value =
|
|
179
|
+
self.element_result_model.ope_value = self.element_model.ope_value
|
|
180
|
+
for i in self.element_result_model.ope_value:
|
|
181
|
+
if not isinstance(i.v, str):
|
|
182
|
+
i.v = str(i.v)
|
|
172
183
|
|
|
173
184
|
async def __sql(self):
|
|
174
|
-
|
|
175
|
-
sql = self.base_data.test_data.replace(self.element_model.sql)
|
|
176
|
-
key_list = self.element_model.key_list
|
|
177
|
-
else:
|
|
178
|
-
sql = self.base_data.test_data.replace(self.element_data.get('sql'))
|
|
179
|
-
key_list = self.element_data.get('key_list')
|
|
180
|
-
if self.base_data.mysql_connect:
|
|
185
|
+
async def run(sql, key_list):
|
|
181
186
|
result_list: list[dict] = self.base_data.mysql_connect.condition_execute(sql)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
self.base_data.test_data.set_cache(key, result.get(value))
|
|
187
|
-
except SyntaxError as error:
|
|
188
|
-
self.base_data.log.debug(
|
|
189
|
-
f'SQL执行失败-1,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
|
|
190
|
-
raise MangoAutomationError(*ERROR_MSG_0038)
|
|
187
|
+
self.base_data.log.debug(f'sql参数->key:{sql},value:{result_list}')
|
|
188
|
+
if not isinstance(result_list, list) and not len(result_list) > 0:
|
|
189
|
+
raise MangoAutomationError(*ERROR_MSG_0036, value=(self.element_model.sql_execute,))
|
|
190
|
+
self.base_data.test_data.set_sql_cache(key_list, result_list[0])
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
if self.base_data.mysql_connect:
|
|
193
|
+
for i in self.element_model.sql_execute:
|
|
194
|
+
await run(i.get('sql'), i.get('key_list'))
|
|
194
195
|
|
|
195
196
|
async def __custom(self):
|
|
196
|
-
|
|
197
|
-
key
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
for i in self.element_model.custom:
|
|
198
|
+
self.base_data.test_data.set_cache(i.get('key'), self.base_data.test_data.replace(i.get('value')))
|
|
199
|
+
|
|
200
|
+
async def __condition(self):
|
|
201
|
+
error_list = []
|
|
202
|
+
for i in self.element_list_model:
|
|
203
|
+
try:
|
|
204
|
+
condition_value = self.base_data.test_data.replace(i.condition_value)
|
|
205
|
+
self.base_data.log.debug(f'执行条件判断数据:{self.element_model.id},{condition_value}')
|
|
206
|
+
await self.__ass(condition_value)
|
|
207
|
+
self.element_result_model.next_node_id = i.id
|
|
208
|
+
return
|
|
209
|
+
except Exception as error:
|
|
210
|
+
self.base_data.log.debug(f'节点判断中-错误:{error},明细:{traceback.print_exc()}')
|
|
211
|
+
error_list.append(error)
|
|
212
|
+
raise error_list[0]
|
|
213
|
+
|
|
214
|
+
async def __python_code(self):
|
|
215
|
+
self.base_data.log.debug(f'执行python函数:{self.element_model.func}')
|
|
216
|
+
global_namespace = {}
|
|
217
|
+
exec(self.element_model.func, global_namespace)
|
|
218
|
+
global_namespace['func'](self)
|
|
203
219
|
|
|
204
220
|
async def __ope_value(self, is_ass: bool = False):
|
|
205
221
|
try:
|
|
@@ -212,17 +228,34 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
212
228
|
'_type': self.element_model.type,
|
|
213
229
|
'exp': self.element_model.elements[random_element].exp,
|
|
214
230
|
'loc': self.element_model.elements[random_element].loc,
|
|
215
|
-
'sub': self.element_model.sub
|
|
231
|
+
'sub': self.element_model.elements[random_element].sub
|
|
216
232
|
}
|
|
217
233
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
218
234
|
loc, ele_quantity, element_text = await self.web_find_ele(
|
|
219
|
-
**find_params, is_iframe=self.element_model.is_iframe)
|
|
235
|
+
**find_params, is_iframe=self.element_model.elements[random_element].is_iframe)
|
|
220
236
|
elif self.drive_type == DriveTypeEnum.ANDROID.value:
|
|
221
237
|
loc, ele_quantity, element_text = self.a_find_ele(**find_params)
|
|
222
238
|
else:
|
|
223
239
|
loc, ele_quantity, element_text = None, 0, None
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
new_element = ElementListResultModel(
|
|
241
|
+
exp=self.element_model.elements[random_element].exp,
|
|
242
|
+
loc=self.element_model.elements[random_element].loc,
|
|
243
|
+
sub=self.element_model.elements[random_element].sub,
|
|
244
|
+
ele_quantity=ele_quantity,
|
|
245
|
+
element_text=element_text,
|
|
246
|
+
is_iframe=self.element_model.elements[random_element].is_iframe
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
element_exists = any(
|
|
250
|
+
existing.exp == new_element.exp and
|
|
251
|
+
existing.loc == new_element.loc and
|
|
252
|
+
existing.sub == new_element.sub and
|
|
253
|
+
existing.is_iframe == new_element.is_iframe
|
|
254
|
+
for existing in self.element_result_model.elements
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
if not element_exists:
|
|
258
|
+
self.element_result_model.elements.append(new_element)
|
|
226
259
|
if is_ass:
|
|
227
260
|
if callable(getattr(AsyncWebAssertion, self.element_model.ope_key, None)):
|
|
228
261
|
i.v = loc
|
|
@@ -230,10 +263,6 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
|
|
|
230
263
|
i.v = element_text
|
|
231
264
|
else:
|
|
232
265
|
i.v = loc
|
|
233
|
-
elif self.element_data:
|
|
234
|
-
for f, v in self.element_data.items():
|
|
235
|
-
if f == i.f:
|
|
236
|
-
i.v = self.base_data.test_data.replace(v)
|
|
237
266
|
i.v = self.base_data.test_data.replace(i.v)
|
|
238
267
|
|
|
239
268
|
except AttributeError as error:
|
|
@@ -28,8 +28,9 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
28
28
|
super().__init__(base_data)
|
|
29
29
|
self.drive_type = drive_type
|
|
30
30
|
self.element_model: Optional[ElementModel | None] = None
|
|
31
|
-
self.element_data: dict | None = None
|
|
32
31
|
self.element_result_model: Optional[ElementResultModel | None] = None
|
|
32
|
+
self.element_list_model: Optional[list[ElementModel] | None] = None
|
|
33
|
+
self.test_data = self.base_data.test_data
|
|
33
34
|
|
|
34
35
|
def open_device(self, is_open: bool = False):
|
|
35
36
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
@@ -42,21 +43,20 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
42
43
|
self.base_data.log.error(f'不存在这个类型,如果是非管理员看到这种提示,请联系管理员')
|
|
43
44
|
raise Exception('不存在的设备类型')
|
|
44
45
|
|
|
45
|
-
def element_main(self,
|
|
46
|
+
def element_main(self,
|
|
47
|
+
element_model: ElementModel,
|
|
48
|
+
element_list_model: list[ElementModel] | None = None) -> ElementResultModel:
|
|
46
49
|
self.element_model = element_model
|
|
47
|
-
self.
|
|
50
|
+
self.element_list_model = element_list_model
|
|
48
51
|
self.element_result_model = ElementResultModel(
|
|
49
52
|
id=self.element_model.id,
|
|
50
53
|
name=self.element_model.name,
|
|
51
|
-
sub=self.element_model.sub,
|
|
52
54
|
sleep=self.element_model.sleep,
|
|
53
55
|
|
|
54
|
-
type=self.element_model.type,
|
|
56
|
+
type=self.element_model.type.value,
|
|
55
57
|
ope_key=self.element_model.ope_key,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
key=self.element_model.key,
|
|
59
|
-
value=self.element_model.value,
|
|
58
|
+
sql_execute=self.element_model.sql_execute,
|
|
59
|
+
custom=self.element_model.custom,
|
|
60
60
|
|
|
61
61
|
status=StatusEnum.FAIL.value,
|
|
62
62
|
)
|
|
@@ -91,14 +91,18 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
91
91
|
@sync_retry()
|
|
92
92
|
def __main(self):
|
|
93
93
|
self.base_data.verify_equipment(self.drive_type)
|
|
94
|
-
if self.element_model.type == ElementOperationEnum.OPE
|
|
94
|
+
if self.element_model.type == ElementOperationEnum.OPE:
|
|
95
95
|
self.__ope()
|
|
96
|
-
elif self.element_model.type == ElementOperationEnum.ASS
|
|
96
|
+
elif self.element_model.type == ElementOperationEnum.ASS:
|
|
97
97
|
self.__ass()
|
|
98
|
-
elif self.element_model.type == ElementOperationEnum.SQL
|
|
98
|
+
elif self.element_model.type == ElementOperationEnum.SQL:
|
|
99
99
|
self.__sql()
|
|
100
|
-
elif self.element_model.type == ElementOperationEnum.CUSTOM
|
|
100
|
+
elif self.element_model.type == ElementOperationEnum.CUSTOM:
|
|
101
101
|
self.__custom()
|
|
102
|
+
elif self.element_model.type == ElementOperationEnum.CONDITION:
|
|
103
|
+
self.__condition()
|
|
104
|
+
elif self.element_model.type == ElementOperationEnum.PYTHON_CODE:
|
|
105
|
+
self.__python_code()
|
|
102
106
|
else:
|
|
103
107
|
raise MangoAutomationError(*ERROR_MSG_0015)
|
|
104
108
|
|
|
@@ -106,11 +110,9 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
106
110
|
try:
|
|
107
111
|
for i in self.element_model.elements:
|
|
108
112
|
i.loc = self.base_data.test_data.replace(i.loc)
|
|
109
|
-
self.
|
|
113
|
+
i.sub = self.base_data.test_data.replace(i.sub)
|
|
110
114
|
self.element_model.sleep = self.base_data.test_data.replace(self.element_model.sleep)
|
|
111
115
|
self.element_result_model.sleep = self.element_model.sleep
|
|
112
|
-
self.element_model.sub = self.base_data.test_data.replace(self.element_model.sub)
|
|
113
|
-
self.element_result_model.sub = self.element_model.sub
|
|
114
116
|
|
|
115
117
|
except MangoAutomationError as error:
|
|
116
118
|
self.base_data.log.error(f'操作元素解析数据失败,类型:{type(error)}, 详情:{error}')
|
|
@@ -144,62 +146,76 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
144
146
|
)
|
|
145
147
|
else:
|
|
146
148
|
pass
|
|
147
|
-
self.element_result_model.ope_value =
|
|
149
|
+
self.element_result_model.ope_value = self.element_model.ope_value
|
|
150
|
+
for i in self.element_result_model.ope_value:
|
|
151
|
+
if not isinstance(i.v, str):
|
|
152
|
+
i.v = str(i.v)
|
|
148
153
|
|
|
149
|
-
def __ass(self):
|
|
154
|
+
async def __ass(self, _ope_value: dict | None = None):
|
|
150
155
|
if self.element_model.ope_value is None:
|
|
151
156
|
raise MangoAutomationError(*ERROR_MSG_0054)
|
|
152
157
|
self.__ope_value(True)
|
|
158
|
+
ope_value = {i.f: i.v for i in self.element_model.ope_value}
|
|
159
|
+
if _ope_value is not None:
|
|
160
|
+
ope_value.update(_ope_value)
|
|
153
161
|
try:
|
|
154
162
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
155
163
|
self.element_result_model.ass_msg = self.web_assertion_element(
|
|
156
164
|
self.element_model.name,
|
|
157
165
|
self.element_model.ope_key,
|
|
158
|
-
|
|
166
|
+
ope_value
|
|
159
167
|
)
|
|
160
168
|
elif self.drive_type == DriveTypeEnum.ANDROID.value:
|
|
161
169
|
self.element_result_model.ass_msg = self.a_assertion_element(
|
|
162
170
|
self.element_model.name,
|
|
163
171
|
self.element_model.ope_key,
|
|
164
|
-
|
|
172
|
+
ope_value
|
|
165
173
|
)
|
|
166
174
|
else:
|
|
167
175
|
pass
|
|
168
176
|
except MangoAutomationError as error:
|
|
169
177
|
self.element_result_model.ass_msg = error.msg
|
|
170
178
|
raise error
|
|
171
|
-
self.element_result_model.ope_value =
|
|
179
|
+
self.element_result_model.ope_value = self.element_model.ope_value
|
|
180
|
+
for i in self.element_result_model.ope_value:
|
|
181
|
+
if not isinstance(i.v, str):
|
|
182
|
+
i.v = str(i.v)
|
|
172
183
|
|
|
173
184
|
def __sql(self):
|
|
174
|
-
|
|
175
|
-
sql = self.base_data.test_data.replace(self.element_model.sql)
|
|
176
|
-
key_list = self.element_model.key_list
|
|
177
|
-
else:
|
|
178
|
-
sql = self.base_data.test_data.replace(self.element_data.get('sql'))
|
|
179
|
-
key_list = self.element_data.get('key_list')
|
|
180
|
-
if self.base_data.mysql_connect:
|
|
185
|
+
def run(sql, key_list):
|
|
181
186
|
result_list: list[dict] = self.base_data.mysql_connect.condition_execute(sql)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
self.base_data.test_data.set_cache(key, result.get(value))
|
|
187
|
-
except SyntaxError as error:
|
|
188
|
-
self.base_data.log.debug(
|
|
189
|
-
f'SQL执行失败-1,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
|
|
190
|
-
raise MangoAutomationError(*ERROR_MSG_0038)
|
|
187
|
+
self.base_data.log.debug(f'sql参数->key:{sql},value:{result_list}')
|
|
188
|
+
if not isinstance(result_list, list) and not len(result_list) > 0:
|
|
189
|
+
raise MangoAutomationError(*ERROR_MSG_0036, value=(self.element_model.sql_execute,))
|
|
190
|
+
self.base_data.test_data.set_sql_cache(key_list, result_list[0])
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
if self.base_data.mysql_connect:
|
|
193
|
+
for i in self.element_model.sql_execute:
|
|
194
|
+
run(i.get('sql'), i.get('key_list'))
|
|
194
195
|
|
|
195
196
|
def __custom(self):
|
|
196
|
-
|
|
197
|
-
key
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
for i in self.element_model.custom:
|
|
198
|
+
self.base_data.test_data.set_cache(i.get('key'), self.base_data.test_data.replace(i.get('value')))
|
|
199
|
+
|
|
200
|
+
def __condition(self):
|
|
201
|
+
error_list = []
|
|
202
|
+
for i in self.element_list_model:
|
|
203
|
+
try:
|
|
204
|
+
condition_value = self.base_data.test_data.replace(i.condition_value)
|
|
205
|
+
self.base_data.log.debug(f'执行条件判断数据:{self.element_model.id},{condition_value}')
|
|
206
|
+
self.__ass(condition_value)
|
|
207
|
+
self.element_result_model.next_node_id = i.id
|
|
208
|
+
return
|
|
209
|
+
except Exception as error:
|
|
210
|
+
self.base_data.log.debug(f'节点判断中-错误:{error},明细:{traceback.print_exc()}')
|
|
211
|
+
error_list.append(error)
|
|
212
|
+
raise error_list[0]
|
|
213
|
+
|
|
214
|
+
def __python_code(self):
|
|
215
|
+
self.base_data.log.debug(f'执行python函数:{self.element_model.func}')
|
|
216
|
+
global_namespace = {}
|
|
217
|
+
exec(self.element_model.func, global_namespace)
|
|
218
|
+
global_namespace['func'](self)
|
|
203
219
|
|
|
204
220
|
def __ope_value(self, is_ass: bool = False):
|
|
205
221
|
try:
|
|
@@ -212,17 +228,34 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
212
228
|
'_type': self.element_model.type,
|
|
213
229
|
'exp': self.element_model.elements[random_element].exp,
|
|
214
230
|
'loc': self.element_model.elements[random_element].loc,
|
|
215
|
-
'sub': self.element_model.sub
|
|
231
|
+
'sub': self.element_model.elements[random_element].sub
|
|
216
232
|
}
|
|
217
233
|
if self.drive_type == DriveTypeEnum.WEB.value:
|
|
218
|
-
loc, ele_quantity, element_text = self.web_find_ele(
|
|
219
|
-
|
|
234
|
+
loc, ele_quantity, element_text = self.web_find_ele(
|
|
235
|
+
**find_params,is_iframe=self.element_model.is_iframe)
|
|
220
236
|
elif self.drive_type == DriveTypeEnum.ANDROID.value:
|
|
221
237
|
loc, ele_quantity, element_text = self.a_find_ele(**find_params)
|
|
222
238
|
else:
|
|
223
239
|
loc, ele_quantity, element_text = None, 0, None
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
new_element = ElementListResultModel(
|
|
241
|
+
exp=self.element_model.elements[random_element].exp,
|
|
242
|
+
loc=self.element_model.elements[random_element].loc,
|
|
243
|
+
sub=self.element_model.elements[random_element].sub,
|
|
244
|
+
ele_quantity=ele_quantity,
|
|
245
|
+
element_text=element_text,
|
|
246
|
+
is_iframe=self.element_model.elements[random_element].is_iframe
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
element_exists = any(
|
|
250
|
+
existing.exp == new_element.exp and
|
|
251
|
+
existing.loc == new_element.loc and
|
|
252
|
+
existing.sub == new_element.sub and
|
|
253
|
+
existing.is_iframe == new_element.is_iframe
|
|
254
|
+
for existing in self.element_result_model.elements
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
if not element_exists:
|
|
258
|
+
self.element_result_model.elements.append(new_element)
|
|
226
259
|
if is_ass:
|
|
227
260
|
if callable(getattr(SyncWebAssertion, self.element_model.ope_key, None)):
|
|
228
261
|
i.v = loc
|
|
@@ -230,11 +263,7 @@ class SyncElement(SyncWebDevice, AndroidDriver):
|
|
|
230
263
|
i.v = element_text
|
|
231
264
|
else:
|
|
232
265
|
i.v = loc
|
|
233
|
-
|
|
234
|
-
for f, v in self.element_data.items():
|
|
235
|
-
if f == i.f:
|
|
236
|
-
i.v = self.base_data.test_data.replace(v)
|
|
237
|
-
i.v = self.base_data.test_data.replace(i.v)
|
|
266
|
+
i.v = self.base_data.test_data.replace(i.v)
|
|
238
267
|
|
|
239
268
|
except AttributeError as error:
|
|
240
269
|
self.base_data.log.debug(
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/__init__.py
RENAMED
|
@@ -126,7 +126,7 @@ class AsyncWebDevice(AsyncWebBrowser,
|
|
|
126
126
|
raise MangoAutomationError(*ERROR_MSG_0023)
|
|
127
127
|
if not ele_list:
|
|
128
128
|
raise MangoAutomationError(*ERROR_MSG_0023)
|
|
129
|
-
if not ele_list and _type == ElementOperationEnum.OPE
|
|
129
|
+
if not ele_list and _type == ElementOperationEnum.OPE:
|
|
130
130
|
raise MangoAutomationError(*ERROR_MSG_0029, value=(name, loc))
|
|
131
131
|
try:
|
|
132
132
|
count = len(ele_list)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: mangoautomation
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: 测试工具
|
|
5
5
|
Home-page: https://gitee.com/mao-peng/testkit
|
|
6
6
|
Author: 毛鹏
|
|
@@ -18,14 +18,6 @@ Requires-Dist: uiautomator2>=3.2.5
|
|
|
18
18
|
Requires-Dist: mangotools>=1.1.42
|
|
19
19
|
Requires-Dist: adbutils~=2.8.9
|
|
20
20
|
Requires-Dist: uiautodev>=0.9.0
|
|
21
|
-
Dynamic: author
|
|
22
|
-
Dynamic: author-email
|
|
23
|
-
Dynamic: classifier
|
|
24
|
-
Dynamic: description
|
|
25
|
-
Dynamic: home-page
|
|
26
|
-
Dynamic: license-file
|
|
27
|
-
Dynamic: requires-dist
|
|
28
|
-
Dynamic: summary
|
|
29
21
|
|
|
30
22
|
# testkit
|
|
31
23
|
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# @Project: 芒果测试平台
|
|
3
|
-
# @Description:
|
|
4
|
-
# @Time : 2025-08-31 17:41
|
|
5
|
-
# @Author : 毛鹏
|
|
6
|
-
import json
|
|
7
|
-
from mangoautomation.uidrive import *
|
|
8
|
-
from mangotools.decorator import func_info
|
|
9
|
-
|
|
10
|
-
print(json.dumps(func_info, ensure_ascii=False, indent=4))
|
|
11
|
-
with open('ope.json', 'w') as f:
|
|
12
|
-
f.write(json.dumps(func_info, ensure_ascii=False, indent=4))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/__init__.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_application.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_assertion.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_customization.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_element.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_equipment.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/android/_new_android.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/pc/customization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_assertion.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_browser.py
RENAMED
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_element.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/async_web/_page.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/__init__.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_assertion.py
RENAMED
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_browser.py
RENAMED
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_element.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation/uidrive/web/sync_web/_page.py
RENAMED
|
File without changes
|
|
File without changes
|
{mangoautomation-1.0.60 → mangoautomation-1.1.2}/mangoautomation.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|