mangoautomation 1.0.48__py3-none-any.whl → 1.0.50__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.

@@ -1,7 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # @Project: 芒果测试平台
3
- # @Description:
4
- # @Time : 2023-09-09 23:17
3
+ # @Description:# @Time : 2023-09-09 23:17
5
4
  # @Author : 毛鹏
6
5
  import sys
7
6
 
@@ -45,8 +45,7 @@ class ElementResultModel(BaseModel):
45
45
  type: int
46
46
  ope_key: str | None = None
47
47
  ope_value: dict = {}
48
- expect: str | None = None
49
- actual: str | None = None
48
+ ass_msg: str | None = None
50
49
  sql: str | None = None
51
50
  key_list: str | None = None
52
51
  key: str | None = None
@@ -146,20 +146,24 @@ class AsyncElement(AsyncWebDevice, AndroidDriver):
146
146
  if self.element_model.ope_value is None:
147
147
  raise MangoAutomationError(*ERROR_MSG_0053)
148
148
  await self.__ope_value(True)
149
- if self.drive_type == DriveTypeEnum.WEB.value:
150
- await self.web_assertion_element(
151
- self.element_model.name,
152
- self.element_model.ope_key,
153
- {i.f: i.v for i in self.element_model.ope_value}
154
- )
155
- elif self.drive_type == DriveTypeEnum.ANDROID.value:
156
- self.a_assertion_element(
157
- self.element_model.name,
158
- self.element_model.ope_key,
159
- {i.f: i.v for i in self.element_model.ope_value}
160
- )
161
- else:
162
- pass
149
+ try:
150
+ if self.drive_type == DriveTypeEnum.WEB.value:
151
+ self.element_result_model.ass_msg = await self.web_assertion_element(
152
+ self.element_model.name,
153
+ self.element_model.ope_key,
154
+ {i.f: i.v for i in self.element_model.ope_value}
155
+ )
156
+ elif self.drive_type == DriveTypeEnum.ANDROID.value:
157
+ self.element_result_model.ass_msg = self.a_assertion_element(
158
+ self.element_model.name,
159
+ self.element_model.ope_key,
160
+ {i.f: i.v for i in self.element_model.ope_value}
161
+ )
162
+ else:
163
+ pass
164
+ except MangoAutomationError as error:
165
+ self.element_result_model.ass_msg = error.msg
166
+ raise MangoAutomationError(*ERROR_MSG_0054)
163
167
  self.element_result_model.ope_value = {i.f: i.v for i in self.element_model.ope_value if i.d}
164
168
 
165
169
  async def __sql(self):
@@ -146,20 +146,24 @@ class SyncElement(SyncWebDevice, AndroidDriver):
146
146
  if self.element_model.ope_value is None:
147
147
  raise MangoAutomationError(*ERROR_MSG_0053)
148
148
  self.__ope_value(True)
149
- if self.drive_type == DriveTypeEnum.WEB.value:
150
- self.web_assertion_element(
151
- self.element_model.name,
152
- self.element_model.ope_key,
153
- {i.f: i.v for i in self.element_model.ope_value}
154
- )
155
- elif self.drive_type == DriveTypeEnum.ANDROID.value:
156
- self.a_assertion_element(
157
- self.element_model.name,
158
- self.element_model.ope_key,
159
- {i.f: i.v for i in self.element_model.ope_value}
160
- )
161
- else:
162
- pass
149
+ try:
150
+ if self.drive_type == DriveTypeEnum.WEB.value:
151
+ self.element_result_model.ass_msg = self.web_assertion_element(
152
+ self.element_model.name,
153
+ self.element_model.ope_key,
154
+ {i.f: i.v for i in self.element_model.ope_value}
155
+ )
156
+ elif self.drive_type == DriveTypeEnum.ANDROID.value:
157
+ self.element_result_model.ass_msg = self.a_assertion_element(
158
+ self.element_model.name,
159
+ self.element_model.ope_key,
160
+ {i.f: i.v for i in self.element_model.ope_value}
161
+ )
162
+ else:
163
+ pass
164
+ except MangoAutomationError as error:
165
+ self.element_result_model.ass_msg = error.msg
166
+ raise MangoAutomationError(*ERROR_MSG_0054)
163
167
  self.element_result_model.ope_value = {i.f: i.v for i in self.element_model.ope_value if i.d}
164
168
 
165
169
  def __sql(self):
@@ -72,10 +72,11 @@ class AndroidDriver(AndroidPage,
72
72
  try:
73
73
  if is_method:
74
74
  self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
75
- Mango.s_e(AndroidAssertion(self.base_data), ope_key, ope_value)
75
+ return Mango.s_e(AndroidAssertion(self.base_data), ope_key, ope_value)
76
76
  else:
77
77
  self.base_data.log.debug(f'开始断言-2,方法:{ope_key},断言值:{ope_value}')
78
- MangoAssertion(self.base_data.mysql_connect).ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
78
+ return MangoAssertion(self.base_data.mysql_connect) \
79
+ .ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
79
80
  except AssertionError as error:
80
81
  self.base_data.log.error(f'安卓自动化失败-1,类型:{type(error)},失败详情:{error}')
81
82
  raise MangoAutomationError(*ERROR_MSG_0017, value=error.args)
@@ -17,64 +17,68 @@ class AndroidAssertion(metaclass=Meta):
17
17
  def __init__(self, base_data: BaseData):
18
18
  self.base_data = base_data
19
19
 
20
- @sync_method_callback('ass_android', '元素断言', 1,[
20
+ @sync_method_callback('ass_android', '元素断言', 1, [
21
21
  MethodModel(f='actual')])
22
22
  def a_assert_ele_exists(self, actual: UiObject):
23
23
  """元素存在"""
24
- assert actual.count
24
+ assert actual.count, f'实际={actual.count}, 预期=元素存在'
25
+ return f'实际={actual.count}, 预期=元素存在'
25
26
 
26
- @sync_method_callback('ass_android', '元素断言', 2,[
27
+ @sync_method_callback('ass_android', '元素断言', 2, [
27
28
  MethodModel(f='actual'),
28
29
  MethodModel(f='expect', p='请输入预期内容', d=True)])
29
30
  def a_assert_ele_count(self, actual: UiObject, expect):
30
31
  """元素计数"""
31
- assert int(actual.count) == int(expect)
32
+ assert int(actual.count) == int(expect), f'实际={actual.count}, 预期={expect}'
33
+ return f'实际={actual.count}, 预期={expect}'
32
34
 
33
- @sync_method_callback('ass_android', '元素断言', 3,[
35
+ @sync_method_callback('ass_android', '元素断言', 3, [
34
36
  MethodModel(f='actual'),
35
37
  MethodModel(f='expect', p='请输入预期文本', d=True)])
36
38
  def a_assert_ele_text(self, actual: UiObject, expect: str):
37
39
  """元素文本内容"""
38
- assert actual.get_text() == expect, \
39
- f"实际='{actual.get_text()}', 预期='{expect}'"
40
+ assert actual.get_text() == expect, f"实际='{actual.get_text()}', 预期='{expect}'"
41
+ return f'实际={actual.get_text()}, 预期={expect}'
40
42
 
41
- @sync_method_callback('ass_android', '元素断言', 4,[
43
+ @sync_method_callback('ass_android', '元素断言', 4, [
42
44
  MethodModel(f='actual')])
43
45
  def a_assert_ele_clickable_true(self, actual: UiObject):
44
46
  """元素可点击"""
45
- assert actual.info['clickable'], \
46
- f"实际={actual.info['clickable']}, 预期=可点击"
47
+ assert actual.info['clickable'], f"实际={actual.info['clickable']}, 预期=可点击"
48
+ return f"实际={actual.info['clickable']}, 预期=可点击"
47
49
 
48
- @sync_method_callback('ass_android', '元素断言', 5,[
50
+ @sync_method_callback('ass_android', '元素断言', 5, [
49
51
  MethodModel(f='actual')])
50
52
  def a_assert_ele_clickable_false(self, actual: UiObject):
51
53
  """元素不可点击"""
52
- assert not actual.info['clickable'], \
53
- f"实际={actual.info['clickable']}, 预期=元素不可点击"
54
+ assert not actual.info['clickable'], f"实际={actual.info['clickable']}, 预期=元素不可点击"
55
+ return f"实际={actual.info['clickable']}, 预期=元素不可点击"
54
56
 
55
- @sync_method_callback('ass_android', '元素断言', 6,[
57
+ @sync_method_callback('ass_android', '元素断言', 6, [
56
58
  MethodModel(f='actual')])
57
59
  def a_assert_ele_visible_true(self, actual: UiObject):
58
60
  """元素可见"""
59
- assert actual.exists and actual.info['visible'], \
60
- f"实际={actual.info['visible']}, 预期=元素可见"
61
+ assert actual.exists and actual.info['visible'], f"实际={actual.info['visible']}, 预期=元素可见"
61
62
 
62
- @sync_method_callback('ass_android', '元素断言', 7,[
63
+ return f"实际={actual.info['visible']}, 预期=元素可见"
64
+
65
+ @sync_method_callback('ass_android', '元素断言', 7, [
63
66
  MethodModel(f='actual')])
64
67
  def a_assert_ele_visible_false(self, actual: UiObject):
65
68
  """元素不可见"""
66
- assert actual.exists and not actual.info['visible'], \
67
- f"实际={actual.info['visible']}, 预期=元素不可见"
69
+ assert actual.exists and not actual.info['visible'], f"实际={actual.info['visible']}, 预期=元素不可见"
70
+ return f"实际={actual.info['visible']}, 预期=元素不可见"
68
71
 
69
- @sync_method_callback('ass_android', '元素断言', 8,[
72
+ @sync_method_callback('ass_android', '元素断言', 8, [
70
73
  MethodModel(f='expect', p='请输入弹窗标题文本', d=False)])
71
74
  def a_assert_dialog_exists(self, expect: str):
72
75
  """弹窗存在"""
73
76
  dialog = self.base_data.android(text=expect) if expect else self.base_data.android(
74
77
  className="android.app.AlertDialog")
75
78
  assert dialog.exists, "未找到预期弹窗"
79
+ return f"实际={dialog.exists}, 预期=弹窗存在"
76
80
 
77
- @sync_method_callback('ass_android', '元素断言', 9,[
81
+ @sync_method_callback('ass_android', '元素断言', 9, [
78
82
  MethodModel(f='actual'),
79
83
  MethodModel(f='expect', p='请输入断言目标文本', d=True)])
80
84
  def a_assert_ele_in_list(self, actual: UiObject, expect: str):
@@ -83,3 +87,4 @@ class AndroidAssertion(metaclass=Meta):
83
87
  raise AssertionError("传入的元素不是可滑动的列表")
84
88
  actual.scroll.vert.to(text=expect)
85
89
  assert self.base_data.android(text=expect).exists, f"列表中未找到文本: {expect}"
90
+ return f"实际={self.base_data.android(text=expect).exists}, 预期={expect}"
@@ -64,7 +64,7 @@ class AsyncWebDevice(AsyncWebBrowser,
64
64
  self.base_data.log.error(f'WEB自动化操作失败-3,类型:{type(error)},失败详情:{error}')
65
65
  raise MangoAutomationError(*ERROR_MSG_0012)
66
66
 
67
- async def web_assertion_element(self, name, ope_key, ope_value):
67
+ async def web_assertion_element(self, name, ope_key, ope_value) -> str:
68
68
  self.base_data.log.debug(f'断言元素,名称:{name},key:{ope_key},value:{ope_value}')
69
69
  is_method = callable(getattr(AsyncWebAssertion, ope_key, None))
70
70
  try:
@@ -73,10 +73,11 @@ class AsyncWebDevice(AsyncWebBrowser,
73
73
  traceback.print_exc()
74
74
  raise MangoAutomationError(*ERROR_MSG_0031, value=(name,))
75
75
  self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
76
- await Mango.a_e(AsyncWebAssertion(self.base_data), ope_key, ope_value)
76
+ return await Mango.a_e(AsyncWebAssertion(self.base_data), ope_key, ope_value)
77
77
  else:
78
78
  self.base_data.log.debug(f'开始断言-2,方法:{ope_key},断言值:{ope_value}')
79
- MangoAssertion(self.base_data.mysql_connect).ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
79
+ return MangoAssertion(self.base_data.mysql_connect) \
80
+ .ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
80
81
  except AssertionError as error:
81
82
  self.base_data.log.debug(f'WEB自动化断言失败-1,类型:{type(error)},失败详情:{error}')
82
83
  raise MangoAutomationError(*ERROR_MSG_0017, value=error.args)
@@ -28,6 +28,7 @@ class AsyncWebAssertion(metaclass=Meta):
28
28
  await exp(actual).to_have_count(int(expect))
29
29
  except AssertionError as e:
30
30
  raise AssertionError(f'实际={await actual.count()}, 预期={expect}') from e
31
+ return f'实际={await actual.count()}, 预期={expect}'
31
32
 
32
33
  @async_method_callback('ass_web', '元素断言', 1, [MethodModel(f='actual')])
33
34
  async def w_all_not_to_be_empty(self, actual: Locator):
@@ -35,6 +36,7 @@ class AsyncWebAssertion(metaclass=Meta):
35
36
  count = await actual.count()
36
37
  if count == 0:
37
38
  assert False, f'实际={count}, 预期>0'
39
+ return f'实际={count}, 预期>0'
38
40
 
39
41
  @async_method_callback('ass_web', '元素断言', 1, [
40
42
  MethodModel(f='actual'),
@@ -43,10 +45,13 @@ class AsyncWebAssertion(metaclass=Meta):
43
45
  """元素是否存在"""
44
46
  if int(expect) == 0:
45
47
  assert actual is None, f'实际={actual}, 预期={expect}'
48
+ return f'实际={actual}, 预期={expect}'
49
+
46
50
  else:
47
51
  if actual:
48
52
  try:
49
- await exp(actual).to_have_count(int(expect)),
53
+ await exp(actual).to_have_count(int(expect))
54
+ return f'实际={actual.count()}, 预期={expect}'
50
55
  except AssertionError as e:
51
56
  raise AssertionError(f'实际={actual.count()}, 预期={expect}') from e
52
57
  else:
@@ -61,6 +66,7 @@ class AsyncWebAssertion(metaclass=Meta):
61
66
  await exp(actual).not_to_contain_text(expect)
62
67
  except AssertionError as e:
63
68
  raise AssertionError(f'实际={actual}, 预期={expect}') from e
69
+ return f'实际={actual}, 预期={expect}'
64
70
 
65
71
  @async_method_callback('ass_web', '元素断言', 3, [MethodModel(f='actual')])
66
72
  async def w_not_to_be_empty(self, actual: Locator):
@@ -69,6 +75,7 @@ class AsyncWebAssertion(metaclass=Meta):
69
75
  await exp(actual).not_to_be_empty()
70
76
  except AssertionError as e:
71
77
  raise AssertionError(f'实际={actual}, 预期=不为空') from e
78
+ return f'实际={actual}, 预期=不为空'
72
79
 
73
80
  @async_method_callback('ass_web', '元素断言', 4, [MethodModel(f='actual')])
74
81
  async def w_not_to_be_enabled(self, actual: Locator):
@@ -77,6 +84,7 @@ class AsyncWebAssertion(metaclass=Meta):
77
84
  await exp(actual).not_to_be_enabled()
78
85
  except AssertionError as e:
79
86
  raise AssertionError(f'实际={actual}, 预期=不启用') from e
87
+ return f'实际={actual}, 预期=不启用'
80
88
 
81
89
  @async_method_callback('ass_web', '元素断言', 5, [MethodModel(f='actual')])
82
90
  async def w_not_to_be_focused(self, actual: Locator):
@@ -85,6 +93,7 @@ class AsyncWebAssertion(metaclass=Meta):
85
93
  await exp(actual).not_to_be_focused()
86
94
  except AssertionError as e:
87
95
  raise AssertionError(f'实际={actual}, 预期=不聚焦') from e
96
+ return f'实际={actual}, 预期=不聚焦'
88
97
 
89
98
  @async_method_callback('ass_web', '元素断言', 6, [MethodModel(f='actual')])
90
99
  async def w_not_to_be_hidden(self, actual: Locator):
@@ -93,6 +102,7 @@ class AsyncWebAssertion(metaclass=Meta):
93
102
  await exp(actual).not_to_be_hidden()
94
103
  except AssertionError as e:
95
104
  raise AssertionError(f'实际={actual}, 预期=不可隐藏') from e
105
+ return f'实际={actual}, 预期=不可隐藏'
96
106
 
97
107
  @async_method_callback('ass_web', '元素断言', 7, [MethodModel(f='actual')])
98
108
  async def w_not_to_be_in_viewport(self, actual: Locator):
@@ -101,6 +111,7 @@ class AsyncWebAssertion(metaclass=Meta):
101
111
  await exp(actual).not_to_be_in_viewport()
102
112
  except AssertionError as e:
103
113
  raise AssertionError(f'实际={actual}, 预期=不在视窗中') from e
114
+ return f'实际={actual}, 预期=不在视窗中'
104
115
 
105
116
  @async_method_callback('ass_web', '元素断言', 8, [MethodModel(f='actual')])
106
117
  async def w_not_to_be_visible(self, actual: Locator):
@@ -109,6 +120,7 @@ class AsyncWebAssertion(metaclass=Meta):
109
120
  await exp(actual).not_to_be_visible()
110
121
  except AssertionError as e:
111
122
  raise AssertionError(f'实际={actual}, 预期=不可见') from e
123
+ return f'实际={actual}, 预期=不可见'
112
124
 
113
125
  @async_method_callback('ass_web', '元素断言', 9, [
114
126
  MethodModel(f='actual'),
@@ -119,6 +131,7 @@ class AsyncWebAssertion(metaclass=Meta):
119
131
  await exp(actual).not_to_have_class(expect)
120
132
  except AssertionError as e:
121
133
  raise AssertionError(f'实际={actual}, 预期=没有阶级') from e
134
+ return f'实际={actual}, 预期=没有阶级'
122
135
 
123
136
  @async_method_callback('ass_web', '元素断言', 10, [MethodModel(f='actual')])
124
137
  async def w_to_be_checked(self, actual: Locator):
@@ -127,6 +140,7 @@ class AsyncWebAssertion(metaclass=Meta):
127
140
  await exp(actual).to_be_checked()
128
141
  except AssertionError as e:
129
142
  raise AssertionError(f'实际={actual}, 预期=复选框已选中') from e
143
+ return f'实际={actual}, 预期=复选框已选中'
130
144
 
131
145
  @async_method_callback('ass_web', '元素断言', 11, [MethodModel(f='actual')])
132
146
  async def w_to_be_disabled(self, actual: Locator):
@@ -135,6 +149,7 @@ class AsyncWebAssertion(metaclass=Meta):
135
149
  await exp(actual).to_be_disabled()
136
150
  except AssertionError as e:
137
151
  raise AssertionError(f'实际={actual}, 预期=已禁用') from e
152
+ return f'实际={actual}, 预期=已禁用'
138
153
 
139
154
  @async_method_callback('ass_web', '元素断言', 12, [MethodModel(f='actual')])
140
155
  async def w_not_to_be_editable(self, actual: Locator):
@@ -143,15 +158,18 @@ class AsyncWebAssertion(metaclass=Meta):
143
158
  await exp(actual).to_be_editable()
144
159
  except AssertionError as e:
145
160
  raise AssertionError(f'实际={actual}, 预期=已启用') from e
161
+ return f'实际={actual}, 预期=已启用'
146
162
 
147
163
  @async_method_callback('ass_web', '元素断言', 13, [MethodModel(f='actual')])
148
164
  async def w_to_be_empty(self, actual: Locator | list | None):
149
165
  """元素为空"""
150
166
  if actual is None:
151
167
  assert True, f'实际={actual}, 预期=为空'
168
+ return f'实际={actual}, 预期=为空'
152
169
  else:
153
170
  try:
154
171
  await exp(actual).to_be_empty()
172
+ return f'实际={actual}, 预期=为空'
155
173
  except AssertionError as e:
156
174
  raise AssertionError(f'实际={actual}, 预期=为空') from e
157
175
 
@@ -162,6 +180,7 @@ class AsyncWebAssertion(metaclass=Meta):
162
180
  await exp(actual).to_be_visible()
163
181
  except AssertionError as e:
164
182
  raise AssertionError(f'实际={actual}, 预期=可见') from e
183
+ return f'实际={actual}, 预期=可见'
165
184
  # @staticmethod
166
185
  # async def w_not_to_have_actuals(actual: Locator, actuals: list):
167
186
  # """选择已选择选项"""
@@ -282,9 +301,3 @@ class AsyncWebAssertion(metaclass=Meta):
282
301
  # """有价值"""
283
302
  # locator = self.page.locator("input[type=number]")
284
303
  # exp(locator).to_have_actual(re.compile(r"[0-9]"))
285
-
286
-
287
- if __name__ == '__main__':
288
- from mangokit.decorator import func_info
289
-
290
- print(func_info)
@@ -101,7 +101,7 @@ class AsyncWebNewBrowser:
101
101
  raise MangoAutomationError(*ERROR_MSG_0009, value=(self.web_path,))
102
102
 
103
103
  async def new_context(self) -> BrowserContext:
104
- args_dict = {}
104
+ args_dict = {'ignore_https_errors': True}
105
105
  if self.web_is_default:
106
106
  args_dict["viewport"] = {"width": 1920, "height": 1080}
107
107
  if self.web_h5:
@@ -64,7 +64,7 @@ class SyncWebDevice(SyncWebBrowser,
64
64
  self.base_data.log.error(f'WEB自动化操作失败-3,类型:{type(error)},失败详情:{error}')
65
65
  raise MangoAutomationError(*ERROR_MSG_0012)
66
66
 
67
- def web_assertion_element(self, name, ope_key, ope_value):
67
+ def web_assertion_element(self, name, ope_key, ope_value) -> str:
68
68
  self.base_data.log.debug(f'断言元素,名称:{name},key:{ope_key},value:{ope_value}')
69
69
  is_method = callable(getattr(SyncWebAssertion, ope_key, None))
70
70
  try:
@@ -72,10 +72,11 @@ class SyncWebDevice(SyncWebBrowser,
72
72
  if ope_value.get('actual', None) is None:
73
73
  raise MangoAutomationError(*ERROR_MSG_0031, value=(name,))
74
74
  self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
75
- Mango.s_e(SyncWebAssertion(self.base_data), ope_key, ope_value)
75
+ return Mango.s_e(SyncWebAssertion(self.base_data), ope_key, ope_value)
76
76
  else:
77
77
  self.base_data.log.debug(f'开始断言-2,方法:{ope_key},断言值:{ope_value}')
78
- MangoAssertion(self.base_data.mysql_connect).ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
78
+ return MangoAssertion(self.base_data.mysql_connect) \
79
+ .ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
79
80
  except AssertionError as error:
80
81
  self.base_data.log.debug(f'WEB自动化断言失败-1,类型:{type(error)},失败详情:{error}')
81
82
  raise MangoAutomationError(*ERROR_MSG_0017, value=error.args)
@@ -5,10 +5,12 @@
5
5
 
6
6
  from playwright.sync_api import Locator, expect as exp
7
7
 
8
- from ....tools import Meta
9
- from ....uidrive._base_data import BaseData
10
8
  from mangotools.decorator import sync_method_callback
9
+ from mangotools.exceptions.error_msg import ERROR_MSG_0021
11
10
  from mangotools.models import MethodModel
11
+ from ....exceptions import MangoAutomationError
12
+ from ....tools import Meta
13
+ from ....uidrive._base_data import BaseData
12
14
 
13
15
 
14
16
  class SyncWebAssertion(metaclass=Meta):
@@ -26,6 +28,7 @@ class SyncWebAssertion(metaclass=Meta):
26
28
  exp(actual).to_have_count(int(expect))
27
29
  except AssertionError as e:
28
30
  raise AssertionError(f'实际={actual.count()}, 预期={expect}') from e
31
+ return f'实际={actual.count()}, 预期={expect}'
29
32
 
30
33
  @sync_method_callback('ass_web', '元素断言', 1, [MethodModel(f='actual')])
31
34
  def w_all_not_to_be_empty(self, actual: Locator):
@@ -33,6 +36,7 @@ class SyncWebAssertion(metaclass=Meta):
33
36
  count = actual.count()
34
37
  if count == 0:
35
38
  assert False, f'实际={count}, 预期>0'
39
+ return f'实际={count}, 预期>0'
36
40
 
37
41
  @sync_method_callback('ass_web', '元素断言', 1, [
38
42
  MethodModel(f='actual'),
@@ -41,10 +45,12 @@ class SyncWebAssertion(metaclass=Meta):
41
45
  """元素存在个数"""
42
46
  if int(expect) == 0:
43
47
  assert actual is None, f'实际={actual}, 预期={expect}'
48
+ return f'实际={actual}, 预期={expect}'
44
49
  else:
45
50
  if actual:
46
51
  try:
47
52
  exp(actual).to_have_count(int(expect))
53
+ return f'实际={actual.count()}, 预期={expect}'
48
54
  except AssertionError as e:
49
55
  raise AssertionError(f'实际={actual.count()}, 预期={expect}') from e
50
56
  else:
@@ -59,6 +65,7 @@ class SyncWebAssertion(metaclass=Meta):
59
65
  exp(actual).not_to_contain_text(expect)
60
66
  except AssertionError as e:
61
67
  raise AssertionError(f'实际={actual}, 预期={expect}') from e
68
+ return f'实际={actual}, 预期={expect}'
62
69
 
63
70
  @sync_method_callback('ass_web', '元素断言', 3, [MethodModel(f='actual')])
64
71
  def w_not_to_be_empty(self, actual: Locator):
@@ -67,6 +74,7 @@ class SyncWebAssertion(metaclass=Meta):
67
74
  exp(actual).not_to_be_empty()
68
75
  except AssertionError as e:
69
76
  raise AssertionError(f'实际={actual}, 预期=不为空') from e
77
+ return f'实际={actual}, 预期=不为空'
70
78
 
71
79
  @sync_method_callback('ass_web', '元素断言', 4, [MethodModel(f='actual')])
72
80
  def w_not_to_be_enabled(self, actual: Locator):
@@ -75,6 +83,7 @@ class SyncWebAssertion(metaclass=Meta):
75
83
  exp(actual).not_to_be_enabled()
76
84
  except AssertionError as e:
77
85
  raise AssertionError(f'实际={actual}, 预期=不启用') from e
86
+ return f'实际={actual}, 预期=不启用'
78
87
 
79
88
  @sync_method_callback('ass_web', '元素断言', 5, [MethodModel(f='actual')])
80
89
  def w_not_to_be_focused(self, actual: Locator):
@@ -83,6 +92,7 @@ class SyncWebAssertion(metaclass=Meta):
83
92
  exp(actual).not_to_be_focused()
84
93
  except AssertionError as e:
85
94
  raise AssertionError(f'实际={actual}, 预期=不聚焦') from e
95
+ return f'实际={actual}, 预期=不聚焦'
86
96
 
87
97
  @sync_method_callback('ass_web', '元素断言', 6, [MethodModel(f='actual')])
88
98
  def w_not_to_be_hidden(self, actual: Locator):
@@ -91,6 +101,7 @@ class SyncWebAssertion(metaclass=Meta):
91
101
  exp(actual).not_to_be_hidden()
92
102
  except AssertionError as e:
93
103
  raise AssertionError(f'实际={actual}, 预期=不可隐藏') from e
104
+ return f'实际={actual}, 预期=不可隐藏'
94
105
 
95
106
  @sync_method_callback('ass_web', '元素断言', 7, [MethodModel(f='actual')])
96
107
  def w_not_to_be_in_viewport(self, actual: Locator):
@@ -99,6 +110,7 @@ class SyncWebAssertion(metaclass=Meta):
99
110
  exp(actual).not_to_be_in_viewport()
100
111
  except AssertionError as e:
101
112
  raise AssertionError(f'实际={actual}, 预期=不在视窗中') from e
113
+ return f'实际={actual}, 预期=不在视窗中'
102
114
 
103
115
  @sync_method_callback('ass_web', '元素断言', 8, [MethodModel(f='actual')])
104
116
  def w_not_to_be_visible(self, actual: Locator):
@@ -107,6 +119,7 @@ class SyncWebAssertion(metaclass=Meta):
107
119
  exp(actual).not_to_be_visible()
108
120
  except AssertionError as e:
109
121
  raise AssertionError(f'实际={actual}, 预期=不可见') from e
122
+ return f'实际={actual}, 预期=不可见'
110
123
 
111
124
  @sync_method_callback('ass_web', '元素断言', 9, [
112
125
  MethodModel(f='actual'),
@@ -117,6 +130,7 @@ class SyncWebAssertion(metaclass=Meta):
117
130
  exp(actual).not_to_have_class(expect)
118
131
  except AssertionError as e:
119
132
  raise AssertionError(f'实际={actual}, 预期=没有阶级') from e
133
+ return f'实际={actual}, 预期=没有阶级'
120
134
 
121
135
  @sync_method_callback('ass_web', '元素断言', 10, [MethodModel(f='actual')])
122
136
  def w_to_be_checked(self, actual: Locator):
@@ -125,6 +139,7 @@ class SyncWebAssertion(metaclass=Meta):
125
139
  exp(actual).to_be_checked()
126
140
  except AssertionError as e:
127
141
  raise AssertionError(f'实际={actual}, 预期=复选框已选中') from e
142
+ return f'实际={actual}, 预期=复选框已选中'
128
143
 
129
144
  @sync_method_callback('ass_web', '元素断言', 11, [MethodModel(f='actual')])
130
145
  def w_to_be_disabled(self, actual: Locator):
@@ -133,6 +148,7 @@ class SyncWebAssertion(metaclass=Meta):
133
148
  exp(actual).to_be_disabled()
134
149
  except AssertionError as e:
135
150
  raise AssertionError(f'实际={actual}, 预期=已禁用') from e
151
+ return f'实际={actual}, 预期=已禁用'
136
152
 
137
153
  @sync_method_callback('ass_web', '元素断言', 12, [MethodModel(f='actual')])
138
154
  def w_not_to_be_editable(self, actual: Locator):
@@ -141,15 +157,19 @@ class SyncWebAssertion(metaclass=Meta):
141
157
  exp(actual).to_be_editable()
142
158
  except AssertionError as e:
143
159
  raise AssertionError(f'实际={actual}, 预期=已启用') from e
160
+ return f'实际={actual}, 预期=已启用'
144
161
 
145
162
  @sync_method_callback('ass_web', '元素断言', 13, [MethodModel(f='actual')])
146
163
  def w_to_be_empty(self, actual: Locator | list | None):
147
164
  """元素为空"""
148
165
  if actual is None:
149
166
  assert True, f'实际={actual}, 预期=为空'
167
+ return f'实际={actual}, 预期=为空'
168
+
150
169
  else:
151
170
  try:
152
171
  exp(actual).to_be_empty()
172
+ return f'实际={actual}, 预期=为空'
153
173
  except AssertionError as e:
154
174
  raise AssertionError(f'实际={actual}, 预期=为空') from e
155
175
 
@@ -160,6 +180,8 @@ class SyncWebAssertion(metaclass=Meta):
160
180
  exp(actual).to_be_visible()
161
181
  except AssertionError as e:
162
182
  raise AssertionError(f'实际={actual}, 预期=可见') from e
183
+ return f'实际={actual}, 预期=可见'
184
+
163
185
  # @staticmethod
164
186
  # def w_not_to_have_actuals(actual: Locator, actuals: list):
165
187
  # """选择已选择选项"""
@@ -101,7 +101,7 @@ class SyncWebNewBrowser:
101
101
  raise MangoAutomationError(*ERROR_MSG_0009, value=(self.web_path,))
102
102
 
103
103
  def new_context(self) -> BrowserContext:
104
- args_dict = {}
104
+ args_dict = {'ignore_https_errors': True}
105
105
  if self.web_is_default:
106
106
  args_dict["viewport"] = {"width": 1920, "height": 1080}
107
107
  if self.web_h5:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mangoautomation
3
- Version: 1.0.48
3
+ Version: 1.0.50
4
4
  Summary: 测试工具
5
5
  Home-page: https://gitee.com/mao-peng/testkit
6
6
  Author: 毛鹏
@@ -12,7 +12,7 @@ Requires-Dist: pydantic ==2.9.2
12
12
  Requires-Dist: playwright ==1.43.0
13
13
  Requires-Dist: uiautomation ==2.0.20
14
14
  Requires-Dist: uiautomator2 ==3.2.5
15
- Requires-Dist: mangotools >=1.1.14
15
+ Requires-Dist: mangotools >=1.1.17
16
16
  Requires-Dist: adbutils ~=2.8.9
17
17
  Requires-Dist: uiautodev ==0.9.0
18
18
 
@@ -5,19 +5,19 @@ mangoautomation/enums/_ui_enum.py,sha256=rdkejsyc4ogZbyNfZcp1q0V0bDPo14vg0A6or6S
5
5
  mangoautomation/exceptions/__init__.py,sha256=dXtRZSuYg3e_lwYUKYvYjtxTKHITdbi2l9XkHk9DpfY,374
6
6
  mangoautomation/exceptions/_error_msg.py,sha256=GrB9crXQMNlq1Ng8a7RsuKfDHDhXglu_CQ_62lhj_iQ,5437
7
7
  mangoautomation/exceptions/_exceptions.py,sha256=BiyST1QPivpfIOuKn1gKhpXOyBv6gfip_KvlQuu8ctw,385
8
- mangoautomation/models/__init__.py,sha256=Vc0MADLdIY2TkWelDeXdvLlg3QbVF5U8pc_-1UyWsNU,418
9
- mangoautomation/models/_ui_model.py,sha256=IGophozQMO-NQjM_DPdlwud484yfWQw1CRwbDWjI3Vs,1446
8
+ mangoautomation/models/__init__.py,sha256=59J8VjshTxZK4xX_-_NBqdLZ1OuvuZPSpljY1Jc-4eQ,416
9
+ mangoautomation/models/_ui_model.py,sha256=wKiBNpGDhSVCAYf798I0bMzdhCGXfSOptMCQrBLTUCM,1416
10
10
  mangoautomation/tools/__init__.py,sha256=cc6zpsEdp3JiIx7HfOz-Vob7oTIIFzsuxDLgl20har4,443
11
11
  mangoautomation/tools/_mate.py,sha256=9lk_EJnAX_OyXbe5WacyHkkcEr2ScBgasl6eUnlklWA,405
12
12
  mangoautomation/tools/_uiautodev.py,sha256=RMOQMXse744xwUDb1_l7qDv9mUiqZt1Gm5sbB-nlgDk,1388
13
13
  mangoautomation/uidrive/__init__.py,sha256=Tk_gh4Qg2qnewEGxa-7Id4fkQLY3fvQE4X7JB0BEscY,577
14
- mangoautomation/uidrive/_async_element.py,sha256=al5j4bw8OcBo2Prb8gHTzbtf3KYL-Tr5fPoRUuOlEoY,13424
14
+ mangoautomation/uidrive/_async_element.py,sha256=CqQoYVkMjbFoAzFeWgdytf2fJ27-1ZZG_ZLmqAuRin0,13729
15
15
  mangoautomation/uidrive/_base_data.py,sha256=ur2Ts40MAhOYXb0vGVXZdSwEVCI3Csri9I9f1pw1r4Y,3766
16
16
  mangoautomation/uidrive/_driver_object.py,sha256=Re8j6VLHKfwW2VFdi-1XFRuix8tRBLcHYRBLVF6CApE,1962
17
- mangoautomation/uidrive/_sync_element.py,sha256=e67DngrDdJyug5nT-Gf1fcTAHAM-0lVmvrAHOhgfwjQ,13242
18
- mangoautomation/uidrive/android/__init__.py,sha256=T-Xyd0_Ea4G4YAbasI4cGF4Sb8c4383ohRmRExs8mAs,5461
17
+ mangoautomation/uidrive/_sync_element.py,sha256=IKLhqttcV1d5zFj41IgIs56_bJZMNEPkO7Ah64hcpKg,13547
18
+ mangoautomation/uidrive/android/__init__.py,sha256=SWn7PwRZOf34LCE9KigClDaV8R0n70rqLsG6hCeAok0,5499
19
19
  mangoautomation/uidrive/android/_application.py,sha256=EeEM0MPtOPeYeKx92mtMFWqGpCRmri-D_CzXvPt13RA,2800
20
- mangoautomation/uidrive/android/_assertion.py,sha256=IytUBalJwOQNwwVFaL-Di79-TBFbBs5pnoCVqqptZQg,3631
20
+ mangoautomation/uidrive/android/_assertion.py,sha256=Gzic7cH3_Vr6NLiMBPRJr7q1F8YFF2dEopINMR4XQFc,4289
21
21
  mangoautomation/uidrive/android/_customization.py,sha256=pCLMmruozOyCJQZWAYupxxKqpWmZyCYsfSBw3XW7vf0,381
22
22
  mangoautomation/uidrive/android/_element.py,sha256=lOrQyQhOoJ2LrbiQ9t0wxH7LcpwZgyDxU0iUuKaSjRo,6989
23
23
  mangoautomation/uidrive/android/_equipment.py,sha256=WRaXLf4DuVzxG8TL5c4lHam6hZo_jsWwitYQUun3Srk,5125
@@ -31,27 +31,27 @@ mangoautomation/uidrive/pc/element.py,sha256=LdlWHhvXsaHH6jTp6nNrF81OWPtx81dct4y
31
31
  mangoautomation/uidrive/pc/input_device.py,sha256=F6ZqKja3XkJww66x3l9Idha3R19D832J-5TfiKWmUso,353
32
32
  mangoautomation/uidrive/pc/new_windows.py,sha256=lETHZa7cW8Z0iUShzgVTRxqivkYaOo8WIE58q_8KYfQ,2338
33
33
  mangoautomation/uidrive/web/__init__.py,sha256=MgTklzty_SvX4UemCnqJuViq3cIjUgAjFoEtP-mcDWw,123
34
- mangoautomation/uidrive/web/async_web/__init__.py,sha256=oIVFUs3RX7Z_cSkz2mAzWceBF38zSr0lPaD0LahTlWA,8356
35
- mangoautomation/uidrive/web/async_web/_assertion.py,sha256=8cLYPe3pP6FrcjDZoFOphP7psgoJJMozq0Z_BDGNXCo,11859
34
+ mangoautomation/uidrive/web/async_web/__init__.py,sha256=awtvLCGjUKIx46d2rZpO2CcuBK2WAKZ7PN6yt6ztlBA,8401
35
+ mangoautomation/uidrive/web/async_web/_assertion.py,sha256=iC_j2pZN1pr2kFmxjEb8fBSX91M0BmrcRKARe3JH-kQ,12761
36
36
  mangoautomation/uidrive/web/async_web/_browser.py,sha256=39YroURzagpq0HoEn1RZnNf1KDKXIgWpKSvp5L_Yut0,5286
37
37
  mangoautomation/uidrive/web/async_web/_customization.py,sha256=uw6p9uLHLXglgSkH4qjDl1v0iGlaNjvf8LljRH5cAHU,347
38
38
  mangoautomation/uidrive/web/async_web/_element.py,sha256=btIkX2nlic17sgSbXtNZ8h5wD-rPyIK6TH5fH4WaoPk,9506
39
39
  mangoautomation/uidrive/web/async_web/_input_device.py,sha256=sMAMHb_8QyPx3pKci0gRDQc2O7h1OYMGyA7fCWl81iM,3288
40
- mangoautomation/uidrive/web/async_web/_new_browser.py,sha256=gKjrbDQwDON-Omd2QFKdzMHYLxWd0L_cdM_tXYNz5TI,5597
40
+ mangoautomation/uidrive/web/async_web/_new_browser.py,sha256=WsQ-s2QCjXiePN_u4bLwpds_QpuDd9V2w6hLuLCB-zg,5624
41
41
  mangoautomation/uidrive/web/async_web/_page.py,sha256=TCYf79qQdVBBTTNq2COZFJVcLCgg5Ksu9lMgmQPVInU,2147
42
- mangoautomation/uidrive/web/sync_web/__init__.py,sha256=HLVBtv6kyM2DhHUQx-vRF3vgus8mSrShh3wEiCwHbLM,7916
43
- mangoautomation/uidrive/web/sync_web/_assertion.py,sha256=zZ4_4WiBQFSRwAh0P0JANa5z-ozbNTh3bnUqcZBti9s,11424
42
+ mangoautomation/uidrive/web/sync_web/__init__.py,sha256=31U15FJftsv6yyDlKT-2zN0CNPyolZPRuPh7mdeKKas,7961
43
+ mangoautomation/uidrive/web/sync_web/_assertion.py,sha256=hVA7-Z3CfPgkmtnK_3M5UGo6sct88W6AJfQTnrqu9jU,12534
44
44
  mangoautomation/uidrive/web/sync_web/_browser.py,sha256=c7xHkIIFPawlzcVkGjwqeKfWAM--87wEJb3V3Ysi29w,5146
45
45
  mangoautomation/uidrive/web/sync_web/_customization.py,sha256=E_pfI8gKd0O6r4huJIvA6hoW-X9fSDVL4zEUqhHgxwE,355
46
46
  mangoautomation/uidrive/web/sync_web/_element.py,sha256=P5kSFkKyRP8a7qpKJZf_Lhp6Ik1jgHfIVB8Tgpl7kNw,9078
47
47
  mangoautomation/uidrive/web/sync_web/_input_device.py,sha256=8t6tJgMb4zgb4Sv02XP3gUU0ZVbApCs3WaILv8Fe1iY,3169
48
- mangoautomation/uidrive/web/sync_web/_new_browser.py,sha256=-JYteNz2O84BRHDwiaGKnl0estWdmnAnbhJclhg2Id0,5489
48
+ mangoautomation/uidrive/web/sync_web/_new_browser.py,sha256=LNwhzjf0SbsBAaIXD_bEq623MsX2RvSdLc6tIt1ygjA,5516
49
49
  mangoautomation/uidrive/web/sync_web/_page.py,sha256=MNekcL7o5YXEloeuvi3YrpOZxGhEWfrq-5i4PbtTLFg,2027
50
50
  tests/__init__.py,sha256=UhCNFqiVjxdh4CXESNo4oE7qfjpYYVkeHbSE5-7LGDY,125
51
51
  tests/test_ui_and.py,sha256=4k0_3bx_k2KbZifeRWGK65sxtdiPUOjkNzZ5oxjrc18,672
52
52
  tests/test_ui_web.py,sha256=MFaUN8O5qKOMMgyk2eelhKZsYcSJm0Do6pCgsdBZEH4,2765
53
- mangoautomation-1.0.48.dist-info/LICENSE,sha256=03WP-mgFmo8ofRYDe1HVDQUEUKQZ2q6P6Q-2A4c-46A,1085
54
- mangoautomation-1.0.48.dist-info/METADATA,sha256=NC4bFUdW6US4OdQYfK3MKQ4WK4RyPHyTTptpOFcVDRw,660
55
- mangoautomation-1.0.48.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
56
- mangoautomation-1.0.48.dist-info/top_level.txt,sha256=g-uCmjvEODG8WFbmwbGM0-G0zHntHv8ZsS0PQRaMGtE,22
57
- mangoautomation-1.0.48.dist-info/RECORD,,
53
+ mangoautomation-1.0.50.dist-info/LICENSE,sha256=03WP-mgFmo8ofRYDe1HVDQUEUKQZ2q6P6Q-2A4c-46A,1085
54
+ mangoautomation-1.0.50.dist-info/METADATA,sha256=v8R6xLYzBVZjRc64yeRMgpmZ6RwBdZdhw5gQgOO8r1I,660
55
+ mangoautomation-1.0.50.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
56
+ mangoautomation-1.0.50.dist-info/top_level.txt,sha256=g-uCmjvEODG8WFbmwbGM0-G0zHntHv8ZsS0PQRaMGtE,22
57
+ mangoautomation-1.0.50.dist-info/RECORD,,