mangoautomation 1.1.21__py3-none-any.whl → 1.1.23__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 (67) hide show
  1. mangoautomation/__init__.py +1 -1
  2. mangoautomation/enums/__init__.py +0 -2
  3. mangoautomation/exceptions/__init__.py +0 -3
  4. mangoautomation/exceptions/error_msg.py +4 -4
  5. mangoautomation/mangos/__init__.py +14 -0
  6. mangoautomation/mangos/__pycache__/__init__.cpython-310.pyc +0 -0
  7. mangoautomation/mangos/mangos.cp310-win_amd64.pyd +0 -0
  8. mangoautomation/mangos/mangos.cp312-win_amd64.pyd +0 -0
  9. mangoautomation/mangos/mangos.cpython-310-darwin.so +0 -0
  10. mangoautomation/mangos/mangos.cpython-310-x86_64-linux-gnu.so +0 -0
  11. mangoautomation/mangos/mangos.cpython-312-darwin.so +0 -0
  12. mangoautomation/mangos/mangos.cpython-312-x86_64-linux-gnu.so +0 -0
  13. mangoautomation/models/__init__.py +0 -2
  14. mangoautomation/models/_ui_model.py +2 -1
  15. mangoautomation/tools/__init__.py +0 -2
  16. mangoautomation/tools/_uiautodev.py +1 -3
  17. mangoautomation/uidrive/__init__.py +5 -7
  18. mangoautomation/uidrives/__init__.py +21 -0
  19. mangoautomation/{uidrive → uidrives}/_async_element.py +80 -52
  20. mangoautomation/{uidrive → uidrives}/_base_data.py +16 -4
  21. mangoautomation/{uidrive → uidrives}/_driver_object.py +2 -4
  22. mangoautomation/{uidrive → uidrives}/_sync_element.py +78 -50
  23. mangoautomation/{uidrive → uidrives}/android/__init__.py +2 -16
  24. mangoautomation/{uidrive → uidrives}/android/_application.py +1 -1
  25. mangoautomation/{uidrive → uidrives}/android/_assertion.py +1 -1
  26. mangoautomation/{uidrive → uidrives}/android/_customization.py +1 -1
  27. mangoautomation/{uidrive → uidrives}/android/_element.py +3 -3
  28. mangoautomation/{uidrive → uidrives}/android/_equipment.py +1 -1
  29. mangoautomation/{uidrive → uidrives}/android/_page.py +1 -1
  30. mangoautomation/{uidrive → uidrives}/pc/__init__.py +3 -4
  31. mangoautomation/{uidrive → uidrives}/pc/customization.py +1 -1
  32. mangoautomation/{uidrive → uidrives}/pc/element.py +1 -2
  33. mangoautomation/{uidrive → uidrives}/pc/input_device.py +1 -2
  34. mangoautomation/uidrives/web/__init__.py +10 -0
  35. mangoautomation/uidrives/web/_async_web.py +166 -0
  36. mangoautomation/uidrives/web/_sync_web.py +166 -0
  37. mangoautomation/{uidrive → uidrives}/web/async_web/__init__.py +8 -8
  38. mangoautomation/{uidrive → uidrives}/web/async_web/_assertion.py +1 -1
  39. mangoautomation/{uidrive → uidrives}/web/async_web/_browser.py +2 -2
  40. mangoautomation/{uidrive → uidrives}/web/async_web/_customization.py +1 -1
  41. mangoautomation/{uidrive → uidrives}/web/async_web/_element.py +3 -13
  42. mangoautomation/{uidrive → uidrives}/web/async_web/_input_device.py +1 -1
  43. mangoautomation/{uidrive → uidrives}/web/async_web/_page.py +1 -1
  44. mangoautomation/{uidrive → uidrives}/web/sync_web/__init__.py +8 -8
  45. mangoautomation/{uidrive → uidrives}/web/sync_web/_assertion.py +1 -1
  46. mangoautomation/{uidrive → uidrives}/web/sync_web/_browser.py +3 -3
  47. mangoautomation/{uidrive → uidrives}/web/sync_web/_customization.py +1 -1
  48. mangoautomation/{uidrive → uidrives}/web/sync_web/_element.py +3 -13
  49. mangoautomation/{uidrive → uidrives}/web/sync_web/_input_device.py +1 -1
  50. mangoautomation/{uidrive → uidrives}/web/sync_web/_page.py +2 -2
  51. {mangoautomation-1.1.21.dist-info → mangoautomation-1.1.23.dist-info}/METADATA +4 -4
  52. mangoautomation-1.1.23.dist-info/RECORD +71 -0
  53. tests/__init__.py +0 -10
  54. tests/demo1.py +21 -0
  55. tests/test_ai_element.py +36 -0
  56. tests/test_ui_web.py +31 -31
  57. mangoautomation/uidrive/web/__init__.py +0 -5
  58. mangoautomation-1.1.21.dist-info/RECORD +0 -58
  59. /mangoautomation/{uidrive → uidrives}/android/_new_android.py +0 -0
  60. /mangoautomation/{uidrive → uidrives}/ios/__init__.py +0 -0
  61. /mangoautomation/{uidrive → uidrives}/pc/assertion.py +0 -0
  62. /mangoautomation/{uidrive → uidrives}/pc/new_windows.py +0 -0
  63. /mangoautomation/{uidrive → uidrives}/web/async_web/_new_browser.py +0 -0
  64. /mangoautomation/{uidrive → uidrives}/web/sync_web/_new_browser.py +0 -0
  65. {mangoautomation-1.1.21.dist-info → mangoautomation-1.1.23.dist-info}/LICENSE +0 -0
  66. {mangoautomation-1.1.21.dist-info → mangoautomation-1.1.23.dist-info}/WHEEL +0 -0
  67. {mangoautomation-1.1.21.dist-info → mangoautomation-1.1.23.dist-info}/top_level.txt +0 -0
@@ -8,26 +8,13 @@ from uiautomator2 import UiObject, UiObjectNotFoundError
8
8
  from uiautomator2.exceptions import XPathElementNotFoundError
9
9
  from uiautomator2.xpath import XPathSelector
10
10
 
11
+ from mangoautomation.mangos import AndroidApplication, AndroidAssertion, AndroidElement, AndroidCustomization, \
12
+ AndroidEquipment, AndroidPage
11
13
  from mangotools.assertion import MangoAssertion
12
- from ..android._application import AndroidApplication
13
- from ..android._assertion import AndroidAssertion
14
- from ..android._customization import AndroidCustomization
15
- from ..android._element import AndroidElement
16
- from ..android._equipment import AndroidEquipment
17
- from ..android._page import AndroidPage
18
14
  from ...enums import ElementExpEnum
19
15
  from ...exceptions import MangoAutomationError
20
16
  from ...exceptions.error_msg import *
21
17
 
22
- __all__ = [
23
- 'AndroidApplication',
24
- 'AndroidAssertion',
25
- 'AndroidElement',
26
- 'AndroidCustomization',
27
- 'AndroidEquipment',
28
- 'AndroidPage',
29
- 'AndroidDriver',
30
- ]
31
18
 
32
19
  from mangotools.mangos import Mango
33
20
 
@@ -68,7 +55,6 @@ class AndroidDriver(AndroidPage,
68
55
  is_method = callable(getattr(AndroidAssertion(self.base_data), ope_key, None))
69
56
  if is_method and ope_value.get('actual') is None:
70
57
  raise MangoAutomationError(*ERROR_MSG_0031, value=(name,))
71
-
72
58
  try:
73
59
  if is_method:
74
60
  self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
@@ -10,7 +10,7 @@ from mangotools.models import MethodModel
10
10
  from ...exceptions import MangoAutomationError
11
11
  from ...exceptions.error_msg import ERROR_MSG_0046
12
12
  from ...tools import Meta
13
- from ...uidrive._base_data import BaseData
13
+ from ...uidrives._base_data import BaseData
14
14
 
15
15
 
16
16
  class AndroidApplication(metaclass=Meta):
@@ -6,7 +6,7 @@
6
6
  from uiautomator2 import UiObject
7
7
 
8
8
  from mangoautomation.tools import Meta
9
- from mangoautomation.uidrive._base_data import BaseData
9
+ from mangoautomation.uidrives._base_data import BaseData
10
10
  from mangotools.decorator import sync_method_callback
11
11
  from mangotools.models import MethodModel
12
12
 
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
  from mangoautomation.tools import Meta
8
- from mangoautomation.uidrive._base_data import BaseData
8
+ from mangoautomation.uidrives._base_data import BaseData
9
9
 
10
10
 
11
11
  class AndroidCustomization(metaclass=Meta):
@@ -9,12 +9,12 @@ import time
9
9
  from uiautomator2 import UiObject
10
10
  from uiautomator2.xpath import XPathSelector
11
11
 
12
+ from mangotools.decorator import sync_method_callback
13
+ from mangotools.models import MethodModel
12
14
  from ...exceptions import MangoAutomationError
13
15
  from ...exceptions.error_msg import ERROR_MSG_0043, ERROR_MSG_0044
14
16
  from ...tools import Meta
15
- from ...uidrive._base_data import BaseData
16
- from mangotools.decorator import sync_method_callback
17
- from mangotools.models import MethodModel
17
+ from ...uidrives._base_data import BaseData
18
18
 
19
19
 
20
20
  class AndroidElement(metaclass=Meta):
@@ -8,7 +8,7 @@ from time import sleep
8
8
  from mangotools.decorator import sync_method_callback
9
9
  from mangotools.models import MethodModel
10
10
  from ...tools import Meta
11
- from ...uidrive._base_data import BaseData
11
+ from ...uidrives._base_data import BaseData
12
12
 
13
13
 
14
14
  class AndroidEquipment(metaclass=Meta):
@@ -9,7 +9,7 @@ from uiautomator2 import Direction
9
9
  from mangotools.decorator import sync_method_callback
10
10
  from mangotools.models import MethodModel
11
11
  from ...tools import Meta
12
- from ...uidrive._base_data import BaseData
12
+ from ...uidrives._base_data import BaseData
13
13
 
14
14
 
15
15
  class AndroidPage(metaclass=Meta):
@@ -24,13 +24,12 @@ else:
24
24
  from uiautomation import Control
25
25
  import uiautomation
26
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
27
+ from mangoautomation.uidrives.pc.element import WinElement
28
+ from mangoautomation.uidrives.pc.input_device import WinDeviceInput
30
29
 
31
30
 
32
31
  class WinDriver(WinElement, WinDeviceInput):
33
- def __init__(self, base_data: BaseData):
32
+ def __init__(self, base_data):
34
33
  super().__init__(base_data)
35
34
 
36
35
  def find_element(
@@ -3,7 +3,7 @@
3
3
  # @Description:
4
4
  # @Time : 2024-08-13 14:07
5
5
  # @Author : 毛鹏
6
- from ...uidrive._base_data import BaseData
6
+ from ...uidrives._base_data import BaseData
7
7
 
8
8
 
9
9
  class PlaywrightCustomization(BaseData):
@@ -1,11 +1,10 @@
1
1
  from ...tools import Meta
2
- from ...uidrive._base_data import BaseData
3
2
 
4
3
 
5
4
  class WinElement(metaclass=Meta):
6
5
  """元素操作"""
7
6
 
8
- def __init__(self, base_data: BaseData):
7
+ def __init__(self, base_data):
9
8
  self.base_data = base_data
10
9
 
11
10
  def click(self, control):
@@ -4,11 +4,10 @@
4
4
  # @Time : 2024-11-30 23:44
5
5
  # @Author : 毛鹏
6
6
  from ...tools import Meta
7
- from ...uidrive._base_data import BaseData
8
7
 
9
8
 
10
9
  class WinDeviceInput(metaclass=Meta):
11
10
  """输入设备操作"""
12
11
 
13
- def __init__(self, base_data: BaseData):
12
+ def __init__(self, base_data):
14
13
  self.base_data = base_data
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2023/5/16 14:50
5
+ # @Author : 毛鹏
6
+ from ._async_web import AsyncWebDevice, AsyncWebCustomization, AsyncWebAssertion
7
+ from ._sync_web import SyncWebDevice, SyncWebCustomization, SyncWebAssertion
8
+
9
+ __all__ = ['AsyncWebDevice', 'AsyncWebCustomization', 'AsyncWebAssertion', 'SyncWebDevice', 'SyncWebCustomization',
10
+ 'SyncWebAssertion']
@@ -0,0 +1,166 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2025-04-04 21:42
5
+ # @Author : 毛鹏
6
+ import re
7
+ import traceback
8
+
9
+ from playwright.async_api import Locator, Error, TimeoutError
10
+
11
+ from mangoautomation.mangos import AsyncWebAssertion, AsyncWebBrowser, AsyncWebCustomization, AsyncWebElement, \
12
+ AsyncWebDeviceInput, AsyncWebPage, ElementMain
13
+ from mangotools.assertion import MangoAssertion
14
+ from mangotools.enums import StatusEnum
15
+ from mangotools.mangos import Mango
16
+ from ...enums import ElementExpEnum
17
+ from ...exceptions import MangoAutomationError
18
+ from ...exceptions.error_msg import *
19
+
20
+ re = re
21
+
22
+
23
+ class AsyncWebDevice(AsyncWebBrowser,
24
+ AsyncWebPage,
25
+ AsyncWebElement,
26
+ AsyncWebDeviceInput,
27
+ AsyncWebCustomization):
28
+
29
+ def __init__(self, base_data):
30
+ super().__init__(base_data)
31
+
32
+ async def open_url(self, is_open: bool = False):
33
+ if not self.base_data.is_open_url or is_open:
34
+ self.base_data.log.debug(f'打开url,is_open_url:{self.base_data.is_open_url},url:{self.base_data.url}')
35
+ await self.w_goto(self.base_data.url)
36
+ self.base_data.is_open_url = True
37
+
38
+ async def web_action_element(self, name, ope_key, ope_value, ):
39
+ self.base_data.log.debug(f'操作元素{name}:,key:{ope_key},value:{ope_value}')
40
+ try:
41
+ await ElementMain.a_element(self, ope_key, ope_value)
42
+ except TimeoutError as error:
43
+ self.base_data.log.debug(f'WEB自动化操作失败-1,类型:{type(error)},失败详情:{error}')
44
+ raise MangoAutomationError(*ERROR_MSG_0011, value=(name,))
45
+ except Error as error:
46
+ self.base_data.log.error(f'WEB自动化操作失败-2,类型:{type(error)},失败详情:{error}')
47
+ raise MangoAutomationError(*ERROR_MSG_0032, value=(name,))
48
+ except ValueError as error:
49
+ self.base_data.log.error(f'WEB自动化操作失败-3,类型:{type(error)},失败详情:{error}')
50
+ raise MangoAutomationError(*ERROR_MSG_0012)
51
+
52
+ async def web_assertion_element(self, name, ope_key, ope_value) -> str:
53
+ self.base_data.log.debug(f'断言元素,名称:{name},key:{ope_key},value:{ope_value}')
54
+ is_method = callable(getattr(AsyncWebAssertion, ope_key, None))
55
+ try:
56
+ if is_method:
57
+ if ope_value.get('actual', None) is None:
58
+ raise MangoAutomationError(*ERROR_MSG_0031, value=(name,))
59
+ self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
60
+ return await Mango.a_e(AsyncWebAssertion(self.base_data), ope_key, ope_value)
61
+ else:
62
+ self.base_data.log.debug(f'开始断言-2,方法:{ope_key},断言值:{ope_value}')
63
+ return MangoAssertion(self.base_data.mysql_connect, self.base_data.test_data) \
64
+ .ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
65
+ except AssertionError as error:
66
+ self.base_data.log.debug(f'WEB自动化断言失败-1,类型:{type(error)},失败详情:{error}')
67
+ raise MangoAutomationError(*ERROR_MSG_0017, value=error.args)
68
+ except AttributeError as error:
69
+ self.base_data.log.error(f'WEB自动化断言失败-2,类型:{type(error)},失败详情:{error}')
70
+ raise MangoAutomationError(*ERROR_MSG_0048)
71
+ except ValueError as error:
72
+ self.base_data.log.error(f'WEB自动化断言失败-3,类型:{type(error)},失败详情:{error}')
73
+ raise MangoAutomationError(*ERROR_MSG_0005)
74
+ except Error as error:
75
+ self.base_data.log.error(f'WEB自动化断言失败-4,类型:{type(error)},失败详情:{error}')
76
+ raise MangoAutomationError(*ERROR_MSG_0052, value=(name,), )
77
+
78
+ async def web_find_element(self, name, _type, exp, loc, sub, is_iframe) \
79
+ -> tuple[Locator, int, str] | tuple[list[Locator], int, str]:
80
+ self.base_data.log.debug(
81
+ f'查找元素-1,名称:{name},_type:{_type},exp:{exp},loc:{loc},sub:{sub},is_iframe:{is_iframe}')
82
+ if is_iframe != StatusEnum.SUCCESS.value:
83
+ locator: Locator = await self.__find_ele(self.base_data.page, exp, loc)
84
+ try:
85
+ return await self.__element_info(locator, sub)
86
+ except Error as error:
87
+ self.base_data.log.debug(
88
+ f'WEB自动化查找元素失败-1,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
89
+ raise MangoAutomationError(*ERROR_MSG_0041, value=(name, loc))
90
+ else:
91
+ return await self.__is_iframe(_type, exp, loc, sub)
92
+
93
+ async def __element_info(self, locator: Locator, sub) -> tuple[Locator, int, str]:
94
+ count = await locator.count()
95
+ if count < 1:
96
+ raise MangoAutomationError(*ERROR_MSG_0053)
97
+ if sub is not None:
98
+ loc_result = locator.nth(sub - 1) if sub else locator
99
+ else:
100
+ loc_result = locator.nth(0)
101
+
102
+ try:
103
+ text = await self.w_get_text(loc_result)
104
+ except Exception:
105
+ text = None
106
+ return loc_result, count, text
107
+
108
+ async def ai_element_info(self, locator: Locator) -> tuple[Locator, int, str]:
109
+ count = await locator.count()
110
+ if count < 1:
111
+ raise MangoAutomationError(*ERROR_MSG_0053)
112
+ try:
113
+ text = await self.w_get_text(locator.nth(0))
114
+ except Exception:
115
+ text = None
116
+ return locator.nth(0), count, text
117
+
118
+ async def __is_iframe(self, _type, exp, loc, sub):
119
+ ele_list: list[Locator] = []
120
+ for i in self.base_data.page.frames:
121
+ locator: Locator = await self.__find_ele(i, exp, loc)
122
+ try:
123
+ count = await locator.count()
124
+ except Error as error:
125
+ self.base_data.log.debug(
126
+ f'WEB自动化查找元素失败-2,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
127
+ raise MangoAutomationError(*ERROR_MSG_0041, )
128
+ if count > 0:
129
+ for nth in range(0, count):
130
+ ele_list.append(locator.nth(nth))
131
+ else:
132
+ raise MangoAutomationError(*ERROR_MSG_0023)
133
+ try:
134
+ count = len(ele_list)
135
+ loc = ele_list[sub - 1] if sub else ele_list[0]
136
+ try:
137
+ text = await self.w_get_text(loc)
138
+ except Exception:
139
+ text = None
140
+ return loc, count, text
141
+ except IndexError:
142
+ raise MangoAutomationError(*ERROR_MSG_0025, value=(len(ele_list),))
143
+
144
+ async def __find_ele(self, page, exp, loc) -> Locator:
145
+ if exp == ElementExpEnum.LOCATOR.value:
146
+ try:
147
+ return eval(f"await page.{loc}")
148
+ except SyntaxError:
149
+ try:
150
+ return eval(f"page.{loc}")
151
+ except SyntaxError as error:
152
+ self.base_data.log.error(f'WEB自动化查找元素失败-3,类型:{type(error)},失败详情:{error}')
153
+ raise MangoAutomationError(*ERROR_MSG_0022)
154
+ except NameError as error:
155
+ self.base_data.log.error(f'WEB自动化查找元素失败-4,类型:{type(error)},失败详情:{error}')
156
+ raise MangoAutomationError(*ERROR_MSG_0060)
157
+ elif exp == ElementExpEnum.XPATH.value:
158
+ return page.locator(f'xpath={loc}')
159
+ elif exp == ElementExpEnum.CSS.value:
160
+ return page.locator(loc)
161
+ elif exp == ElementExpEnum.TEXT.value:
162
+ return page.get_by_text(loc, exact=True)
163
+ elif exp == ElementExpEnum.PLACEHOLDER.value:
164
+ return page.get_by_placeholder(loc)
165
+ else:
166
+ raise MangoAutomationError(*ERROR_MSG_0020)
@@ -0,0 +1,166 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Project: 芒果测试平台
3
+ # @Description:
4
+ # @Time : 2025-04-04 21:42
5
+ # @Author : 毛鹏
6
+ import re
7
+ import traceback
8
+
9
+ from playwright.sync_api import Locator, TimeoutError, Error
10
+
11
+ from mangoautomation.mangos import SyncWebAssertion, SyncWebBrowser, SyncWebCustomization, SyncWebElement, \
12
+ SyncWebDeviceInput, SyncWebPage, ElementMain
13
+ from mangotools.assertion import MangoAssertion
14
+ from mangotools.enums import StatusEnum
15
+ from mangotools.mangos import Mango
16
+ from ...enums import ElementExpEnum
17
+ from ...exceptions import MangoAutomationError
18
+ from ...exceptions.error_msg import *
19
+
20
+ re = re
21
+
22
+
23
+ class SyncWebDevice(SyncWebBrowser,
24
+ SyncWebPage,
25
+ SyncWebElement,
26
+ SyncWebDeviceInput,
27
+ SyncWebCustomization):
28
+
29
+ def __init__(self, base_data):
30
+ super().__init__(base_data)
31
+
32
+ def open_url(self, is_open: bool = False):
33
+ if not self.base_data.is_open_url or is_open:
34
+ self.base_data.log.debug(f'打开url,is_open_url:{self.base_data.is_open_url},url:{self.base_data.url}')
35
+ self.w_goto(self.base_data.url)
36
+ self.base_data.is_open_url = True
37
+
38
+ def web_action_element(self, name, ope_key, ope_value, ):
39
+ self.base_data.log.debug(f'操作元素,名称:{name},key:{ope_key},value:{ope_value}')
40
+ try:
41
+ ElementMain.s_element(self, ope_key, ope_value)
42
+ except TimeoutError as error:
43
+ self.base_data.log.debug(f'WEB自动化操作失败-1,类型:{type(error)},失败详情:{error}')
44
+ raise MangoAutomationError(*ERROR_MSG_0011, value=(name,))
45
+ except Error as error:
46
+ self.base_data.log.error(f'WEB自动化操作失败-2,类型:{type(error)},失败详情:{error}')
47
+ raise MangoAutomationError(*ERROR_MSG_0032, value=(name,))
48
+ except ValueError as error:
49
+ self.base_data.log.error(f'WEB自动化操作失败-3,类型:{type(error)},失败详情:{error}')
50
+ raise MangoAutomationError(*ERROR_MSG_0012)
51
+
52
+ def web_assertion_element(self, name, ope_key, ope_value) -> str:
53
+ self.base_data.log.debug(f'断言元素,名称:{name},key:{ope_key},value:{ope_value}')
54
+ is_method = callable(getattr(SyncWebAssertion, ope_key, None))
55
+ try:
56
+ if is_method:
57
+ if ope_value.get('actual', None) is None:
58
+ raise MangoAutomationError(*ERROR_MSG_0031, value=(name,))
59
+ self.base_data.log.debug(f'开始断言-1,方法:{ope_key},断言值:{ope_value}')
60
+ return Mango.s_e(SyncWebAssertion(self.base_data), ope_key, ope_value)
61
+ else:
62
+ self.base_data.log.debug(f'开始断言-2,方法:{ope_key},断言值:{ope_value}')
63
+ return MangoAssertion(self.base_data.mysql_connect, self.base_data.test_data) \
64
+ .ass(ope_key, ope_value.get('actual'), ope_value.get('expect'))
65
+ except AssertionError as error:
66
+ self.base_data.log.debug(f'WEB自动化断言失败-1,类型:{type(error)},失败详情:{error}')
67
+ raise MangoAutomationError(*ERROR_MSG_0017, value=error.args)
68
+ except AttributeError as error:
69
+ self.base_data.log.error(f'WEB自动化断言失败-2,类型:{type(error)},失败详情:{error}')
70
+ raise MangoAutomationError(*ERROR_MSG_0048)
71
+ except ValueError as error:
72
+ self.base_data.log.error(f'WEB自动化断言失败-3,类型:{type(error)},失败详情:{error}')
73
+ raise MangoAutomationError(*ERROR_MSG_0005)
74
+ except Error as error:
75
+ self.base_data.log.error(f'WEB自动化断言失败-4,类型:{type(error)},失败详情:{error}')
76
+ raise MangoAutomationError(*ERROR_MSG_0052, value=(name,), )
77
+
78
+ def web_find_element(self, name, _type, exp, loc, sub, is_iframe) \
79
+ -> tuple[Locator, int, str] | tuple[list[Locator], int, str]:
80
+ self.base_data.log.debug(
81
+ f'查找元素,名称:{name},_type:{_type},exp:{exp},loc:{loc},sub:{sub},is_iframe:{is_iframe}')
82
+ if is_iframe != StatusEnum.SUCCESS.value:
83
+ locator: Locator = self.__find_ele(self.base_data.page, exp, loc)
84
+ try:
85
+ return self.__element_info(locator, sub)
86
+ except Error as error:
87
+ self.base_data.log.debug(
88
+ f'WEB自动化查找元素失败-1,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
89
+ raise MangoAutomationError(*ERROR_MSG_0041, )
90
+ else:
91
+ return self.__is_iframe(_type, exp, loc, sub)
92
+
93
+ def __element_info(self, locator: Locator, sub) -> tuple[Locator, int, str]:
94
+ count = locator.count()
95
+ if count < 1:
96
+ raise MangoAutomationError(*ERROR_MSG_0053)
97
+ if sub is not None:
98
+ loc_result = locator.nth(sub - 1) if sub else locator
99
+ else:
100
+ loc_result = locator.nth(0)
101
+
102
+ try:
103
+ text = self.w_get_text(loc_result)
104
+ except Exception:
105
+ text = None
106
+ return loc_result, count, text
107
+
108
+ def ai_element_info(self, locator: Locator) -> tuple[Locator, int, str]:
109
+ count = locator.count()
110
+ if count < 1:
111
+ raise MangoAutomationError(*ERROR_MSG_0053)
112
+ try:
113
+ text = self.w_get_text(locator.nth(0))
114
+ except Exception:
115
+ text = None
116
+ return locator.nth(0), count, text
117
+
118
+ def __is_iframe(self, _type, exp, loc, sub):
119
+ ele_list: list[Locator] = []
120
+ for i in self.base_data.page.frames:
121
+ locator: Locator = self.__find_ele(i, exp, loc)
122
+ try:
123
+ count = locator.count()
124
+ except Error as error:
125
+ self.base_data.log.debug(
126
+ f'WEB自动化查找元素失败-2,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
127
+ raise MangoAutomationError(*ERROR_MSG_0041, )
128
+ if count > 0:
129
+ for nth in range(0, count):
130
+ ele_list.append(locator.nth(nth))
131
+ else:
132
+ raise MangoAutomationError(*ERROR_MSG_0023)
133
+ try:
134
+ count = len(ele_list)
135
+ loc = ele_list[sub - 1] if sub else ele_list[0]
136
+ try:
137
+ text = self.w_get_text(loc)
138
+ except Exception:
139
+ text = None
140
+ return loc, count, text
141
+ except IndexError:
142
+ raise MangoAutomationError(*ERROR_MSG_0025, value=(len(ele_list),))
143
+
144
+ def __find_ele(self, page, exp, loc) -> Locator:
145
+ if exp == ElementExpEnum.LOCATOR.value:
146
+ try:
147
+ return eval(f"page.{loc}")
148
+ except SyntaxError:
149
+ try:
150
+ return eval(f"await page.{loc}")
151
+ except SyntaxError as error:
152
+ self.base_data.log.error(f'WEB自动化查找元素失败-3,类型:{type(error)},失败详情:{error}')
153
+ raise MangoAutomationError(*ERROR_MSG_0022)
154
+ except NameError as error:
155
+ self.base_data.log.error(f'WEB自动化查找元素失败-4,类型:{type(error)},失败详情:{error}')
156
+ raise MangoAutomationError(*ERROR_MSG_0060)
157
+ elif exp == ElementExpEnum.XPATH.value:
158
+ return page.locator(f'xpath={loc}')
159
+ elif exp == ElementExpEnum.CSS.value:
160
+ return page.locator(loc)
161
+ elif exp == ElementExpEnum.TEXT.value:
162
+ return page.get_by_text(loc, exact=True)
163
+ elif exp == ElementExpEnum.PLACEHOLDER.value:
164
+ return page.get_by_placeholder(loc)
165
+ else:
166
+ raise MangoAutomationError(*ERROR_MSG_0020)
@@ -14,13 +14,13 @@ from mangotools.mangos import Mango
14
14
  from ....enums import ElementExpEnum, ElementOperationEnum
15
15
  from ....exceptions import MangoAutomationError
16
16
  from ....exceptions.error_msg import *
17
- from ....uidrive._base_data import BaseData
18
- from ....uidrive.web.async_web._assertion import AsyncWebAssertion
19
- from ....uidrive.web.async_web._browser import AsyncWebBrowser
20
- from ....uidrive.web.async_web._customization import AsyncWebCustomization
21
- from ....uidrive.web.async_web._element import AsyncWebElement
22
- from ....uidrive.web.async_web._input_device import AsyncWebDeviceInput
23
- from ....uidrive.web.async_web._page import AsyncWebPage
17
+ from ....uidrives._base_data import BaseData
18
+ from ....uidrives.web.async_web._assertion import AsyncWebAssertion
19
+ from ....uidrives.web.async_web._browser import AsyncWebBrowser
20
+ from ....uidrives.web.async_web._customization import AsyncWebCustomization
21
+ from ....uidrives.web.async_web._element import AsyncWebElement
22
+ from ....uidrives.web.async_web._input_device import AsyncWebDeviceInput
23
+ from ....uidrives.web.async_web._page import AsyncWebPage
24
24
 
25
25
  re = re
26
26
  __all__ = [
@@ -54,7 +54,7 @@ class AsyncWebDevice(AsyncWebBrowser,
54
54
  try:
55
55
  await Mango.a_e(self, ope_key, ope_value)
56
56
  except TimeoutError as error:
57
- self.base_data.log.error(f'WEB自动化操作失败-1,类型:{type(error)},失败详情:{error}')
57
+ self.base_data.log.debug(f'WEB自动化操作失败-1,类型:{type(error)},失败详情:{error}')
58
58
  raise MangoAutomationError(*ERROR_MSG_0011, value=(name,))
59
59
  except Error as error:
60
60
  self.base_data.log.error(f'WEB自动化操作失败-2,类型:{type(error)},失败详情:{error}')
@@ -10,7 +10,7 @@ from mangotools.models import MethodModel
10
10
  from ....exceptions import MangoAutomationError
11
11
  from ....exceptions.error_msg import ERROR_MSG_0021
12
12
  from ....tools import Meta
13
- from ....uidrive._base_data import BaseData
13
+ from ....uidrives._base_data import BaseData
14
14
 
15
15
 
16
16
  class AsyncWebAssertion(metaclass=Meta):
@@ -53,11 +53,11 @@ class AsyncWebBrowser(metaclass=Meta):
53
53
  raise MangoAutomationError(*ERROR_MSG_0058, value=(url,))
54
54
 
55
55
  @async_method_callback('web', '浏览器操作', 2, [
56
- MethodModel(n='存储路径', f='path', p='请输入截图保存路径', d=True)])
56
+ MethodModel(n='存储路径', f='path', p='请输入截图名称', d=True)])
57
57
  async def w_screenshot(self, path: str):
58
58
  """整个页面截图"""
59
59
  try:
60
- await self.base_data.page.screenshot(path=path, full_page=True, timeout=10000)
60
+ await self.base_data.page.screenshot(path=os.path.join(self.base_data.screenshot_path, path), full_page=True, timeout=10000)
61
61
  except (TargetClosedError, TimeoutError) as error:
62
62
  self.base_data.log.debug(
63
63
  f'截图出现异常失败-1,类型:{type(error)},失败详情:{error},失败明细:{traceback.format_exc()}')
@@ -3,8 +3,8 @@
3
3
  # @Description: # @Time : 2023-04-26 22:22
4
4
  # @Author : 毛鹏
5
5
 
6
- from ....tools import Meta
7
6
  from ..._base_data import BaseData
7
+ from ....tools import Meta
8
8
 
9
9
 
10
10
  class AsyncWebCustomization(metaclass=Meta):
@@ -4,8 +4,8 @@
4
4
  # @Author : 毛鹏
5
5
  import asyncio
6
6
  import os
7
- import time
8
7
 
8
+ import time
9
9
  from playwright.async_api import Locator, Error, TimeoutError
10
10
 
11
11
  from mangotools.decorator import async_method_callback
@@ -25,15 +25,11 @@ class AsyncWebElement(metaclass=Meta):
25
25
  @async_method_callback('web', '元素操作', 0, [MethodModel(f='locating')])
26
26
  async def w_click(self, locating: Locator):
27
27
  """元素单击"""
28
- if await locating.count() < 1:
29
- raise TimeoutError('元素个数小于1,直接操作超时!')
30
28
  await locating.click()
31
29
 
32
30
  @async_method_callback('web', '元素操作', 1, [MethodModel(f='locating')])
33
31
  async def w_dblclick(self, locating: Locator):
34
32
  """元素双击"""
35
- if await locating.count() < 1:
36
- raise TimeoutError('元素个数小于1,直接操作超时!')
37
33
  await locating.dblclick()
38
34
 
39
35
  @async_method_callback('web', '元素操作', 2, [MethodModel(f='locating')])
@@ -46,8 +42,6 @@ class AsyncWebElement(metaclass=Meta):
46
42
  MethodModel(n='输入内容', f='input_value', p='请输入输入内容', d=True)])
47
43
  async def w_input(self, locating: Locator, input_value: str):
48
44
  """元素输入"""
49
- if await locating.count() < 1:
50
- raise TimeoutError('元素个数小于1,直接操作超时!')
51
45
  await locating.fill(str(input_value))
52
46
 
53
47
  @async_method_callback('web', '元素操作', 4, [MethodModel(f='locating')])
@@ -61,8 +55,6 @@ class AsyncWebElement(metaclass=Meta):
61
55
  MethodModel(n='缓存的key', f='set_cache_key', p='请输入获取元素文本后存储的key', d=True)])
62
56
  async def w_get_text(self, locating: Locator, set_cache_key=None):
63
57
  """获取元素文本"""
64
- if await locating.count() < 1:
65
- raise TimeoutError('元素个数小于1,直接操作超时!')
66
58
  methods = [
67
59
  ("inner_text", locating.inner_text),
68
60
  ("text_content", locating.text_content),
@@ -87,8 +79,6 @@ class AsyncWebElement(metaclass=Meta):
87
79
  MethodModel(n='输入文本', f='input_value', p='请输入输入内容', d=True)])
88
80
  async def w_clear_input(self, locating: Locator, input_value: str):
89
81
  """元素清空再输入"""
90
- if await locating.count() < 1:
91
- raise TimeoutError('元素个数小于1,直接操作超时!')
92
82
  await locating.clear()
93
83
  await locating.fill(str(input_value))
94
84
 
@@ -237,10 +227,10 @@ class AsyncWebElement(metaclass=Meta):
237
227
 
238
228
  @async_method_callback('web', '元素操作', 15, [
239
229
  MethodModel(f='locating'),
240
- MethodModel(n='保存路径', f='path', p='请输入截图保存路径', d=True)])
230
+ MethodModel(n='保存路径', f='path', p='请输入截图名称', d=True)])
241
231
  async def w_ele_screenshot(self, locating: Locator, path: str):
242
232
  """元素截图"""
243
- await locating.screenshot(path=path)
233
+ await locating.screenshot(path=os.path.join(self.base_data.download_path, path))
244
234
 
245
235
  @async_method_callback('web', '元素操作', 20, [
246
236
  MethodModel(f='locating1'),
@@ -6,7 +6,7 @@
6
6
  from mangotools.decorator import async_method_callback
7
7
  from mangotools.models import MethodModel
8
8
  from ....tools import Meta
9
- from ....uidrive._base_data import BaseData
9
+ from ....uidrives._base_data import BaseData
10
10
 
11
11
 
12
12
  class AsyncWebDeviceInput(metaclass=Meta):
@@ -9,7 +9,7 @@ from playwright.async_api import Locator
9
9
  from mangotools.decorator import async_method_callback
10
10
  from mangotools.models import MethodModel
11
11
  from ....tools import Meta
12
- from ....uidrive._base_data import BaseData
12
+ from ....uidrives._base_data import BaseData
13
13
 
14
14
 
15
15
  class AsyncWebPage(metaclass=Meta):