mangoautomation 1.1.23__py3-none-any.whl → 1.1.25__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 (40) hide show
  1. mangoautomation/mangos/__pycache__/__init__.cpython-310.pyc +0 -0
  2. mangoautomation/mangos/mangos.cp310-win_amd64.pyd +0 -0
  3. mangoautomation/mangos/mangos.cp312-win_amd64.pyd +0 -0
  4. mangoautomation/mangos/mangos.cpython-310-darwin.so +0 -0
  5. mangoautomation/mangos/mangos.cpython-310-x86_64-linux-gnu.so +0 -0
  6. mangoautomation/mangos/mangos.cpython-312-darwin.so +0 -0
  7. mangoautomation/mangos/mangos.cpython-312-x86_64-linux-gnu.so +0 -0
  8. mangoautomation/uidrives/_driver_object.py +5 -36
  9. mangoautomation-1.1.25.dist-info/METADATA +42 -0
  10. mangoautomation-1.1.25.dist-info/RECORD +48 -0
  11. {mangoautomation-1.1.23.dist-info → mangoautomation-1.1.25.dist-info}/WHEEL +1 -1
  12. tests/demo1.py +94 -21
  13. tests/get_ope.py +12 -3
  14. mangoautomation/uidrives/android/_application.py +0 -70
  15. mangoautomation/uidrives/android/_assertion.py +0 -90
  16. mangoautomation/uidrives/android/_customization.py +0 -15
  17. mangoautomation/uidrives/android/_element.py +0 -169
  18. mangoautomation/uidrives/android/_equipment.py +0 -151
  19. mangoautomation/uidrives/android/_new_android.py +0 -54
  20. mangoautomation/uidrives/android/_page.py +0 -116
  21. mangoautomation/uidrives/web/async_web/__init__.py +0 -165
  22. mangoautomation/uidrives/web/async_web/_assertion.py +0 -303
  23. mangoautomation/uidrives/web/async_web/_browser.py +0 -112
  24. mangoautomation/uidrives/web/async_web/_customization.py +0 -14
  25. mangoautomation/uidrives/web/async_web/_element.py +0 -240
  26. mangoautomation/uidrives/web/async_web/_input_device.py +0 -82
  27. mangoautomation/uidrives/web/async_web/_new_browser.py +0 -153
  28. mangoautomation/uidrives/web/async_web/_page.py +0 -63
  29. mangoautomation/uidrives/web/sync_web/__init__.py +0 -160
  30. mangoautomation/uidrives/web/sync_web/_assertion.py +0 -304
  31. mangoautomation/uidrives/web/sync_web/_browser.py +0 -112
  32. mangoautomation/uidrives/web/sync_web/_customization.py +0 -14
  33. mangoautomation/uidrives/web/sync_web/_element.py +0 -240
  34. mangoautomation/uidrives/web/sync_web/_input_device.py +0 -80
  35. mangoautomation/uidrives/web/sync_web/_new_browser.py +0 -153
  36. mangoautomation/uidrives/web/sync_web/_page.py +0 -61
  37. mangoautomation-1.1.23.dist-info/METADATA +0 -34
  38. mangoautomation-1.1.23.dist-info/RECORD +0 -71
  39. {mangoautomation-1.1.23.dist-info → mangoautomation-1.1.25.dist-info/licenses}/LICENSE +0 -0
  40. {mangoautomation-1.1.23.dist-info → mangoautomation-1.1.25.dist-info}/top_level.txt +0 -0
@@ -19,46 +19,15 @@ class DriverObject:
19
19
  self.android: Optional[NewAndroid] = None
20
20
  self.windows: Optional[NewWindows] = None
21
21
 
22
- def set_web(self,
23
- web_type: int,
24
- web_path: str | None = None,
25
- web_max=False,
26
- web_headers=False,
27
- web_recording=False,
28
- web_h5=None,
29
- is_header_intercept=False,
30
- web_is_default=False,
31
- videos_path=None
32
- ):
22
+ def set_web(self, **kwargs):
23
+ kwargs['log'] = self.log
33
24
  if self.is_async:
34
- self.web = AsyncWebNewBrowser(
35
- web_type,
36
- web_path,
37
- web_max,
38
- web_headers,
39
- web_recording,
40
- web_h5,
41
- is_header_intercept,
42
- web_is_default,
43
- videos_path,
44
- log=self.log,
45
- )
25
+ self.web = AsyncWebNewBrowser(**kwargs)
46
26
  else:
47
- self.web = SyncWebNewBrowser(
48
- web_type,
49
- web_path,
50
- web_max,
51
- web_headers,
52
- web_recording,
53
- web_h5,
54
- is_header_intercept,
55
- web_is_default,
56
- videos_path,
57
- log=self.log,
58
- )
27
+ self.web = SyncWebNewBrowser(**kwargs)
59
28
 
60
29
  def set_android(self, and_equipment: str):
61
30
  self.android = NewAndroid(and_equipment)
62
31
 
63
32
  def set_windows(self, win_path: str, win_title: str):
64
- self.windows = NewWindows(win_path, win_title)
33
+ self.windows = NewWindows(win_path, win_title)
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: mangoautomation
3
+ Version: 1.1.25
4
+ Summary: 测试工具
5
+ Home-page: https://gitee.com/mao-peng/testkit
6
+ Author: 毛鹏
7
+ Author-email: 729164035@qq.com
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ License-File: LICENSE
11
+ Requires-Dist: setuptools==78.1.1
12
+ Requires-Dist: pydantic>=2.9.2
13
+ Requires-Dist: playwright==1.43.0
14
+ Requires-Dist: uiautomation>=2.0.20
15
+ Requires-Dist: uiautomator2>=3.2.5
16
+ Requires-Dist: mangotools>=1.1.42
17
+ Requires-Dist: adbutils~=2.8.9
18
+ Requires-Dist: uiautodev>=0.9.0
19
+ Requires-Dist: beautifulsoup4==4.14.2
20
+ Requires-Dist: openai==2.6.1
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
+
30
+ # testkit
31
+
32
+ #### 介绍
33
+
34
+ 测试工具
35
+
36
+ #### 安装教程
37
+
38
+ 1. pip install mangokit
39
+
40
+ #### 使用说明
41
+
42
+ 1.
@@ -0,0 +1,48 @@
1
+ mangoautomation/__init__.py,sha256=JxPNVexFQvkBfh0awPNeHxQGU_gtVgYPwD5rYeuHWEk,125
2
+ mangoautomation/enums/__init__.py,sha256=PnOgNttAXT64elr_Fd1ZthuAddCkm7sh4xwm9Eutm_I,373
3
+ mangoautomation/enums/_base_enum.py,sha256=dpaXsdhWY08BhIzi1B1ksh_p18ZTmhWvTYhbd3n_ONQ,1176
4
+ mangoautomation/enums/_ui_enum.py,sha256=mT_MfQ7TEw-BgHIqH0wXTA_yVWsaWnd3iHSHi9E0pgA,4599
5
+ mangoautomation/exceptions/__init__.py,sha256=2j3ravPuzljR2Mbq8J2JLdXUzII7hzrjdVjmEc_NHJU,211
6
+ mangoautomation/exceptions/_exceptions.py,sha256=BiyST1QPivpfIOuKn1gKhpXOyBv6gfip_KvlQuu8ctw,385
7
+ mangoautomation/exceptions/error_msg.py,sha256=0unQ_tgrRJtVMAOXTzhQJkwO4_7lhMKAMMCfwmzQD58,5517
8
+ mangoautomation/mangos/__init__.py,sha256=gEu8lVHGXm8PDTBZ1XXWNUOAbCtHb37uKQLBRYQR4rs,644
9
+ mangoautomation/mangos/mangos.cp310-win_amd64.pyd,sha256=6s_XmeiYcz5lblKGMNH9f-tlyAV2gfR3A18J-VkdQ4Y,1743360
10
+ mangoautomation/mangos/mangos.cp312-win_amd64.pyd,sha256=Xlu2Yfm3E9zpwlKMLChbVyC1CiVFakjQfs3AzZ1zP0E,1878016
11
+ mangoautomation/mangos/mangos.cpython-310-darwin.so,sha256=Jp5zoaZLf3uGTGppI6r35dgcwCKbghWckC2sAYUZ_KI,3540144
12
+ mangoautomation/mangos/mangos.cpython-310-x86_64-linux-gnu.so,sha256=riKsG3xp6xDy8V5CrpsFcZbxCikcD0--nt_iyK-Adek,10528184
13
+ mangoautomation/mangos/mangos.cpython-312-darwin.so,sha256=RjzbB_3G4fO-i8wDrTVjKSMPXUL1nVpcQY5RCFmuAMI,3455344
14
+ mangoautomation/mangos/mangos.cpython-312-x86_64-linux-gnu.so,sha256=QDLPDGhoQwxn_qJZ1lgfToSXVKBi6Wd7BhIGScwfNBY,10765984
15
+ mangoautomation/mangos/__pycache__/__init__.cpython-310.pyc,sha256=mlbMT0_xx35rLFukbmGWBgelTH327kE0V5k_bJiOPH8,604
16
+ mangoautomation/models/__init__.py,sha256=wHACwBCrd9HCvmrAkTFUV3qmK9GnOa-FJFiL0kOQjME,309
17
+ mangoautomation/models/_ui_model.py,sha256=nfxh_4TpOLzKKWC7c-IgMLVZY5wkTPfyS_Oh-SvsYsk,1825
18
+ mangoautomation/tools/__init__.py,sha256=c3IXhoodknOukOyM6db2tXIdDRodgmUZorEAkkruQf0,282
19
+ mangoautomation/tools/_mate.py,sha256=9lk_EJnAX_OyXbe5WacyHkkcEr2ScBgasl6eUnlklWA,405
20
+ mangoautomation/tools/_uiautodev.py,sha256=KYYWOQ_sp91LN_zeKAuIvCqjabb2_1-VhgOg1K7cQrw,1372
21
+ mangoautomation/uidrive/__init__.py,sha256=9N2DTDyLcmgxAHctBjZOb8LwdDeKQnwEOWZ9kNcM4Uw,350
22
+ mangoautomation/uidrives/__init__.py,sha256=JEoWqpoDIch8JiQ7WcnuDh3Bjg0Yqo_xfkbqY5iHSa8,617
23
+ mangoautomation/uidrives/_async_element.py,sha256=87BhadK9BJtcv_VzJUM3kX5sdp8b8Kk-abkU9oE3T7M,16206
24
+ mangoautomation/uidrives/_base_data.py,sha256=gp9730Hd8uarRv8xARIddgMWGhaJ_RKDd_gjewwWr04,4436
25
+ mangoautomation/uidrives/_driver_object.py,sha256=o2egGOZfkRVS2PEors8t5TPqTLyRbO1EObH8dY87TUo,1033
26
+ mangoautomation/uidrives/_sync_element.py,sha256=TU2E7AKz0Ku4qXLEtxx-whJPJ4KLYLK_EuKgChpcedM,15906
27
+ mangoautomation/uidrives/android/__init__.py,sha256=i6WjXlNq6oUZ4y79Gih_XzI9tV7du-Jrm9IAuROgSzo,5180
28
+ mangoautomation/uidrives/ios/__init__.py,sha256=SdxI8e5AOoAb8JTaDoMkObezIluJ50nm2b6zeDHv1PI,125
29
+ mangoautomation/uidrives/pc/__init__.py,sha256=Jphhspu-3AHCyDX5ZM_-DWeC9ZerWy2Omb3MOck6CI4,2210
30
+ mangoautomation/uidrives/pc/assertion.py,sha256=mH25hZ2i4T8kA1F2loW_nuPJ-Hb0z1pwILTJqkwwpLA,125
31
+ mangoautomation/uidrives/pc/customization.py,sha256=UkpHWFSYsu_t-GmMRDmii1Bs_Y1eKD34oZfJBFHV2Ng,240
32
+ mangoautomation/uidrives/pc/element.py,sha256=OGbJHbgJPBjRjXqM-NIWUnScn7lIHoBxnrakog_s4l8,465
33
+ mangoautomation/uidrives/pc/input_device.py,sha256=k-v7tRW8NkJxzcezqSIfICGRBqEdsssBeRTmtupVTU8,299
34
+ mangoautomation/uidrives/pc/new_windows.py,sha256=lETHZa7cW8Z0iUShzgVTRxqivkYaOo8WIE58q_8KYfQ,2338
35
+ mangoautomation/uidrives/web/__init__.py,sha256=TJyYt6EUoRfWYrV193RHpopKfixipVUp4TrhB5DoEKA,434
36
+ mangoautomation/uidrives/web/_async_web.py,sha256=Uwta7cIYo-0Qe5RbaIvRSQ-IvOxCNtbH_RcIm1JNxEQ,8204
37
+ mangoautomation/uidrives/web/_sync_web.py,sha256=NCF97mYWQBLsOkcEXHKbAGLYGt4rK7NSjks6PubLe_k,8049
38
+ mangoautomation-1.1.25.dist-info/licenses/LICENSE,sha256=03WP-mgFmo8ofRYDe1HVDQUEUKQZ2q6P6Q-2A4c-46A,1085
39
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ tests/demo1.py,sha256=Wcz63WWXe48arwmCh23ejT66ZbJFV2I7J05AOEZ5aq8,3056
41
+ tests/get_ope.py,sha256=2m7gkOiVSIAzTwnoQwp2JaphM5rPClqvwf24x7R3Az4,476
42
+ tests/test_ai_element.py,sha256=k__iifxebvPPfGdRS-yzkEH80fBIlKJcZ-m3N6Xkz6Q,1437
43
+ tests/test_ui_and.py,sha256=A_0pqG6s5Ts02He7P3NwuDSK3g9Q3VP1Sb_P8wq6g0Q,125
44
+ tests/test_ui_web.py,sha256=RBACNYc7XdvENHzg4YElsSQlEmPVa_AyOKWTYTPXM14,2578
45
+ mangoautomation-1.1.25.dist-info/METADATA,sha256=fGMYvzrKvRmM0hYw29tMr-A5LMYQm3fVUB4VBFVfSss,941
46
+ mangoautomation-1.1.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
+ mangoautomation-1.1.25.dist-info/top_level.txt,sha256=g-uCmjvEODG8WFbmwbGM0-G0zHntHv8ZsS0PQRaMGtE,22
48
+ mangoautomation-1.1.25.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
tests/demo1.py CHANGED
@@ -1,21 +1,94 @@
1
- from openai import OpenAI
2
-
3
- client = OpenAI(api_key="sk-rruuhjnqawsvduyxlcqckbtgwkprctgkvwcelenooixbhthy",
4
- base_url="https://api.siliconflow.cn/v1")
5
- response = client.chat.completions.create(
6
- # model='Pro/deepseek-ai/DeepSeek-R1',
7
- model="THUDM/GLM-Z1-9B-0414",
8
- messages=[
9
- {'role': 'user',
10
- 'content': "推理模型会给市场带来哪些新的机会"}
11
- ],
12
- stream=True
13
- )
14
-
15
- for chunk in response:
16
- if not chunk.choices:
17
- continue
18
- if chunk.choices[0].delta.content:
19
- print(chunk.choices[0].delta.content, end="", flush=True)
20
- if chunk.choices[0].delta.reasoning_content:
21
- print(chunk.choices[0].delta.reasoning_content, end="", flush=True)
1
+ from bs4 import BeautifulSoup
2
+
3
+
4
+ def get_optimized_page_html(html_content) -> str:
5
+ soup = BeautifulSoup(html_content, 'html.parser')
6
+
7
+ # 配置化的清理规则
8
+ cleanup_rules = {
9
+ # 直接删除的标签
10
+ 'remove_tags': [
11
+ 'script', 'style', 'link', 'noscript', 'path',
12
+ 'svg', 'head', 'symbol', 'doubao-ai-csui', 'template'
13
+ ],
14
+
15
+ # 按class删除的元素
16
+ 'remove_by_class': [
17
+ 'watermark-box'
18
+ ],
19
+
20
+ # 按属性删除的元素
21
+ 'remove_by_attrs': {
22
+ # 'tag_name': {'attr': 'value'}
23
+ },
24
+
25
+ # 清空内容但保留标签的条件
26
+ 'empty_content_conditions': [
27
+ {
28
+ 'tag': 'textarea',
29
+ 'condition': lambda el: el.get('style') and 'display:none' in el.get('style')
30
+ }
31
+ ],
32
+
33
+ # 要删除的属性
34
+ 'remove_attributes': [
35
+ 'style',
36
+ 'ssr'
37
+ ],
38
+
39
+ # 要删除的属性前缀(包含该前缀的属性都会被删除)
40
+ 'remove_attribute_prefixes': [
41
+ 'data-v-',
42
+ 'data-testid'
43
+ ]
44
+ }
45
+
46
+ # 执行清理规则
47
+ # 1. 删除指定标签
48
+ for tag_name in cleanup_rules['remove_tags']:
49
+ for element in soup.find_all(tag_name):
50
+ element.decompose()
51
+
52
+ # 2. 按class删除元素
53
+ for class_name in cleanup_rules['remove_by_class']:
54
+ for element in soup.find_all(class_=class_name):
55
+ element.decompose()
56
+
57
+ # 3. 按属性删除元素
58
+ for tag_name, attrs in cleanup_rules['remove_by_attrs'].items():
59
+ for element in soup.find_all(tag_name, attrs=attrs):
60
+ element.decompose()
61
+
62
+ # 4. 清空特定元素内容
63
+ for condition_config in cleanup_rules['empty_content_conditions']:
64
+ tag = condition_config['tag']
65
+ condition_func = condition_config['condition']
66
+ for element in soup.find_all(tag):
67
+ if condition_func(element):
68
+ element.string = ''
69
+
70
+ # 5. 删除属性和属性前缀
71
+ for element in soup.find_all():
72
+ # 删除指定属性
73
+ for attr in cleanup_rules['remove_attributes']:
74
+ if element.has_attr(attr):
75
+ del element[attr]
76
+
77
+ # 删除包含特定前缀的属性
78
+ for attr_prefix in cleanup_rules['remove_attribute_prefixes']:
79
+ for attr in list(element.attrs.keys()):
80
+ if attr.startswith(attr_prefix):
81
+ del element[attr]
82
+
83
+ # 将BeautifulSoup对象转换为字符串
84
+ html_content_str = str(soup)
85
+ return html_content_str
86
+
87
+
88
+ with open('element.txt', 'r', encoding='utf-8') as f:
89
+ file_content = f.read()
90
+ optimize = get_optimized_page_html(file_content)
91
+ print(f'原始的html大小:{len(file_content)}')
92
+ print(f'优化之后的html大小:{len(optimize)}')
93
+ with open('optimized.html', 'w', encoding='utf-8') as f:
94
+ f.write(optimize)
tests/get_ope.py CHANGED
@@ -3,6 +3,15 @@
3
3
  # @Description:
4
4
  # @Time : 2025-08-31 17:41
5
5
  # @Author : 毛鹏
6
- loc = 'await page.cdeadapage.'
7
- cleaned_loc = loc.replace('page.', '').replace('await', '')
8
- print(cleaned_loc)
6
+ from mangoautomation.uidrive import DriverObject
7
+
8
+ d = DriverObject(1, )
9
+ d.set_web(web_type=2, # type: ignore
10
+ web_path=3, # type: ignore
11
+ web_max=1,
12
+ web_headers=4,
13
+ web_recording=5,
14
+ web_h5=1,
15
+ web_is_default=1, # type: ignore
16
+ videos_path=2,
17
+ user_cache_path=3)
@@ -1,70 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # @Project: 芒果测试平台
3
- # @Description:
4
- # @Time : 2023-09-09 23:17
5
- # @Author : 毛鹏
6
- import time
7
-
8
- from mangotools.decorator import sync_method_callback
9
- from mangotools.models import MethodModel
10
- from ...exceptions import MangoAutomationError
11
- from ...exceptions.error_msg import ERROR_MSG_0046
12
- from ...tools import Meta
13
- from ...uidrives._base_data import BaseData
14
-
15
-
16
- class AndroidApplication(metaclass=Meta):
17
- """应用操作"""
18
-
19
- def __init__(self, base_data: BaseData):
20
- self.base_data = base_data
21
-
22
- def is_app_installed(self, package_name: str) -> bool:
23
- return any(package_name in str(i) for i in self.base_data.android.shell("pm list packages"))
24
-
25
- @sync_method_callback('android', '应用操作', 0,
26
- [MethodModel(n='包名', f='package_name', p='请输入应用名称', d=True)])
27
- def a_start_app(self, package_name: str):
28
- """启动应用"""
29
- if not package_name:
30
- raise MangoAutomationError(*ERROR_MSG_0046)
31
- if not self.is_app_installed(package_name):
32
- raise MangoAutomationError(*ERROR_MSG_0046)
33
- self.base_data.android.app_start(package_name)
34
- time.sleep(4)
35
-
36
- @sync_method_callback('android', '应用操作', 1, [
37
- MethodModel(n='包名', f='package_name', p='请输入应用名称', d=True)])
38
- def a_close_app(self, package_name: str):
39
- """关闭应用"""
40
- if not package_name:
41
- raise MangoAutomationError(*ERROR_MSG_0046)
42
- if not self.is_app_installed(package_name):
43
- raise MangoAutomationError(*ERROR_MSG_0046)
44
-
45
- self.base_data.android.app_stop(package_name)
46
-
47
- @sync_method_callback('android', '应用操作', 2, [
48
- MethodModel(n='包名', f='package_name', p='请输入应用名称', d=True)])
49
- def a_clear_app(self, package_name: str):
50
- """清除app数据"""
51
- if not package_name:
52
- raise MangoAutomationError(*ERROR_MSG_0046)
53
- if not self.is_app_installed(package_name):
54
- raise MangoAutomationError(*ERROR_MSG_0046)
55
-
56
- self.base_data.android.app_clear(package_name)
57
-
58
- @sync_method_callback('android', '应用操作', 3)
59
- def a_app_stop_all(self):
60
- """停止所有app"""
61
- self.base_data.android.app_stop_all()
62
-
63
- @sync_method_callback('android', '应用操作', 4, [
64
- MethodModel(n='包名List', f='package_name', p='请输入应用名称列表', d=True)])
65
- def a_app_stop_appoint(self, package_name_list: list):
66
- """停止除指定app外所有app"""
67
- for i in package_name_list:
68
- if not self.is_app_installed(i):
69
- raise MangoAutomationError(*ERROR_MSG_0046)
70
- self.base_data.android.app_stop_all(excludes=package_name_list)
@@ -1,90 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # @Project: 芒果测试平台
3
- # @Description:
4
- # @Time : 2023-09-09 23:17
5
- # @Author : 毛鹏
6
- from uiautomator2 import UiObject
7
-
8
- from mangoautomation.tools import Meta
9
- from mangoautomation.uidrives._base_data import BaseData
10
- from mangotools.decorator import sync_method_callback
11
- from mangotools.models import MethodModel
12
-
13
-
14
- class AndroidAssertion(metaclass=Meta):
15
- """元素断言"""
16
-
17
- def __init__(self, base_data: BaseData):
18
- self.base_data = base_data
19
-
20
- @sync_method_callback('ass_android', '元素断言', 1, [
21
- MethodModel(f='actual')])
22
- def a_assert_ele_exists(self, actual: UiObject):
23
- """元素存在"""
24
- assert actual.count, f'实际={actual.count}, 预期=元素存在'
25
- return f'实际={actual.count}, 预期=元素存在'
26
-
27
- @sync_method_callback('ass_android', '元素断言', 2, [
28
- MethodModel(f='actual'),
29
- MethodModel(n='预期值', f='expect', p='请输入预期内容', d=True)])
30
- def a_assert_ele_count(self, actual: UiObject, expect):
31
- """元素计数"""
32
- assert int(actual.count) == int(expect), f'实际={actual.count}, 预期={expect}'
33
- return f'实际={actual.count}, 预期={expect}'
34
-
35
- @sync_method_callback('ass_android', '元素断言', 3, [
36
- MethodModel(f='actual'),
37
- MethodModel(n='预期值', f='expect', p='请输入预期文本', d=True)])
38
- def a_assert_ele_text(self, actual: UiObject, expect: str):
39
- """元素文本内容"""
40
- assert actual.get_text() == expect, f"实际='{actual.get_text()}', 预期='{expect}'"
41
- return f'实际={actual.get_text()}, 预期={expect}'
42
-
43
- @sync_method_callback('ass_android', '元素断言', 4, [
44
- MethodModel(f='actual')])
45
- def a_assert_ele_clickable_true(self, actual: UiObject):
46
- """元素可点击"""
47
- assert actual.info['clickable'], f"实际={actual.info['clickable']}, 预期=可点击"
48
- return f"实际={actual.info['clickable']}, 预期=可点击"
49
-
50
- @sync_method_callback('ass_android', '元素断言', 5, [
51
- MethodModel(f='actual')])
52
- def a_assert_ele_clickable_false(self, actual: UiObject):
53
- """元素不可点击"""
54
- assert not actual.info['clickable'], f"实际={actual.info['clickable']}, 预期=元素不可点击"
55
- return f"实际={actual.info['clickable']}, 预期=元素不可点击"
56
-
57
- @sync_method_callback('ass_android', '元素断言', 6, [
58
- MethodModel(f='actual')])
59
- def a_assert_ele_visible_true(self, actual: UiObject):
60
- """元素可见"""
61
- assert actual.exists and actual.info['visible'], f"实际={actual.info['visible']}, 预期=元素可见"
62
-
63
- return f"实际={actual.info['visible']}, 预期=元素可见"
64
-
65
- @sync_method_callback('ass_android', '元素断言', 7, [
66
- MethodModel(f='actual')])
67
- def a_assert_ele_visible_false(self, actual: UiObject):
68
- """元素不可见"""
69
- assert actual.exists and not actual.info['visible'], f"实际={actual.info['visible']}, 预期=元素不可见"
70
- return f"实际={actual.info['visible']}, 预期=元素不可见"
71
-
72
- @sync_method_callback('ass_android', '元素断言', 8, [
73
- MethodModel(n='预期值', f='expect', p='请输入弹窗标题文本', d=False)])
74
- def a_assert_dialog_exists(self, expect: str):
75
- """弹窗存在"""
76
- dialog = self.base_data.android(text=expect) if expect else self.base_data.android(
77
- className="android.app.AlertDialog")
78
- assert dialog.exists, "未找到预期弹窗"
79
- return f"实际={dialog.exists}, 预期=弹窗存在"
80
-
81
- @sync_method_callback('ass_android', '元素断言', 9, [
82
- MethodModel(f='actual'),
83
- MethodModel(n='预期值', f='expect', p='请输入断言目标文本', d=True)])
84
- def a_assert_ele_in_list(self, actual: UiObject, expect: str):
85
- """列表滑动后目标元素存在"""
86
- if not actual.exists:
87
- raise AssertionError("传入的元素不是可滑动的列表")
88
- actual.scroll.vert.to(text=expect)
89
- assert self.base_data.android(text=expect).exists, f"列表中未找到文本: {expect}"
90
- return f"实际={self.base_data.android(text=expect).exists}, 预期={expect}"
@@ -1,15 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # @Project: 芒果测试平台
3
- # @Description: # @Time : 2023-04-26 22:22
4
- # @Author : 毛鹏
5
-
6
-
7
- from mangoautomation.tools import Meta
8
- from mangoautomation.uidrives._base_data import BaseData
9
-
10
-
11
- class AndroidCustomization(metaclass=Meta):
12
- """定制开发"""
13
-
14
- def __init__(self, base_data: BaseData):
15
- self.base_data = base_data
@@ -1,169 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # @Project: 芒果测试平台
3
- # @Description:
4
- # @Time : 2023-09-09 23:17
5
- # @Author : 毛鹏
6
- import os.path
7
-
8
- import time
9
- from uiautomator2 import UiObject
10
- from uiautomator2.xpath import XPathSelector
11
-
12
- from mangotools.decorator import sync_method_callback
13
- from mangotools.models import MethodModel
14
- from ...exceptions import MangoAutomationError
15
- from ...exceptions.error_msg import ERROR_MSG_0043, ERROR_MSG_0044
16
- from ...tools import Meta
17
- from ...uidrives._base_data import BaseData
18
-
19
-
20
- class AndroidElement(metaclass=Meta):
21
- """元素操作"""
22
-
23
- def __init__(self, base_data: BaseData):
24
- self.base_data = base_data
25
-
26
- @sync_method_callback('android', '元素操作', 0, [
27
- MethodModel(f='locating')])
28
- def a_click(self, locating: UiObject | XPathSelector):
29
- """元素单击"""
30
- locating.click()
31
-
32
- @sync_method_callback('android', '元素操作', 1, [
33
- MethodModel(f='locating')])
34
- def a_double_click(self, locating: UiObject):
35
- """元素双击"""
36
- locating.click()
37
-
38
- @sync_method_callback('android', '元素操作', 2, [
39
- MethodModel(n='输入文本', f='locating'), MethodModel(f='text', p='请输入内容', d=True)])
40
- def a_input(self, locating: UiObject, text):
41
- """单击输入"""
42
- locating.click()
43
- self.base_data.android.set_fastinput_ime(True)
44
- time.sleep(1)
45
- self.base_data.android.send_keys(text)
46
-
47
- @sync_method_callback('android', '元素操作', 3, [
48
- MethodModel(f='locating'), MethodModel(n='设置文本', f='text', p='请输入内容', d=True)])
49
- def a_set_text(self, locating: UiObject, text):
50
- """设置文本"""
51
- locating.set_text(text)
52
-
53
- @sync_method_callback('android', '元素操作', 4, [
54
- MethodModel(f='locating'),
55
- MethodModel(n='x坐标', f='x', p='请输入x坐标', d=True),
56
- MethodModel(n='y坐标', f='y', p='请输入y坐标', d=True)])
57
- def a_click_coord(self, x, y):
58
- """坐标单击"""
59
- self.base_data.android.click(x, y)
60
-
61
- @sync_method_callback('android', '元素操作', 5, [
62
- MethodModel(n='x坐标', f='x', p='请输入x坐标', d=True),
63
- MethodModel(n='y坐标', f='y', p='请输入y坐标', d=True)])
64
- def a_double_click_coord(self, x, y):
65
- """坐标双击"""
66
- self.base_data.android.double_click(x, y)
67
-
68
- @sync_method_callback('android', '元素操作', 6, [
69
- MethodModel(f='locating'),
70
- MethodModel(n='长按时间', f='time_', p='请输入长按时间', d=True)])
71
- def a_long_click(self, locating: UiObject, time_):
72
- """长按元素"""
73
- locating.long_click(duration=float(time_))
74
-
75
- @sync_method_callback('android', '元素操作', 7, [MethodModel(f='locating')])
76
- def a_clear_text(self, locating: UiObject):
77
- """清空输入框"""
78
- locating.clear_text()
79
-
80
- @sync_method_callback('android', '元素操作', 8, [
81
- MethodModel(f='locating'), MethodModel(n='缓存的key', f='set_cache_key', p='请输入元素文本存储的key', d=True)])
82
- def a_get_text(self, locating: UiObject, set_cache_key=None):
83
- """获取元素文本"""
84
- value = locating.get_text()
85
- if set_cache_key:
86
- self.base_data.test_data.set_cache(key=set_cache_key, value=value)
87
- return value
88
-
89
- @sync_method_callback('android', '元素操作', 9, [
90
- MethodModel(f='locating'),
91
- MethodModel(n='截图名称', f='file_name', p='请输入元素截图存储的名称,后续可以通过名称获取', d=True)])
92
- def a_element_screenshot(self, locating: UiObject, file_name: str):
93
- """元素截图"""
94
- im = locating.screenshot()
95
- file_path = os.path.join(self.base_data.screenshot_path, file_name)
96
- self.base_data.test_data.set_cache(file_name, file_path)
97
- im.save(file_path)
98
-
99
- @sync_method_callback('android', '元素操作', 10, [
100
- MethodModel(f='locating')])
101
- def a_pinch_in(self, locating: UiObject):
102
- """元素缩小"""
103
- locating.pinch_in()
104
-
105
- @sync_method_callback('android', '元素操作', 11, [
106
- MethodModel(f='locating')])
107
- def a_pinch_out(self, locating: UiObject):
108
- """元素放大"""
109
- locating.pinch_out()
110
-
111
- @sync_method_callback('android', '元素操作', 12, [
112
- MethodModel(f='locating'), MethodModel(n='等待时间', f='time_', p='请输入等待元素出现的时间', d=True)])
113
- def a_wait(self, locating: UiObject, time_):
114
- """等待元素出现"""
115
- if not locating.wait(timeout=float(time_)):
116
- raise MangoAutomationError(*ERROR_MSG_0043)
117
-
118
- @sync_method_callback('android', '元素操作', 13, [
119
- MethodModel(f='locating'), MethodModel(n='等待时间', f='time_', p='请输入等待元素消失的时间', d=True)])
120
- def a_wait_gone(self, locating: UiObject, time_: str):
121
- """等待元素消失"""
122
- if not locating.wait_gone(timeout=float(time_)):
123
- raise MangoAutomationError(*ERROR_MSG_0044)
124
-
125
- @sync_method_callback('android', '元素操作', 14, [
126
- MethodModel(f='locating'), MethodModel(f='locating2')])
127
- def a_drag_to_ele(self, locating: UiObject, locating2: UiObject):
128
- """拖动A元素到达B元素上"""
129
- locating.drag_to(locating2)
130
-
131
- @sync_method_callback('android', '元素操作', 15, [
132
- MethodModel(f='locating'),
133
- MethodModel(n='x坐标', f='x', p='请输入x坐标', d=True),
134
- MethodModel(n='y坐标', f='y', p='请输入y坐标', d=True)])
135
- def a_drag_to_coord(self, locating: UiObject, x, y):
136
- """拖动元素到坐标上"""
137
- locating.drag_to(x, y)
138
-
139
- @sync_method_callback('android', '元素操作', 16, [MethodModel(f='locating')])
140
- def a_swipe_right(self, locating: UiObject):
141
- """元素内向右滑动"""
142
- locating.swipe('right')
143
-
144
- @sync_method_callback('android', '元素操作', 17, [MethodModel(f='locating')])
145
- def a_swipe_left(self, locating: UiObject):
146
- """元素内向左滑动"""
147
- locating.swipe('left')
148
-
149
- @sync_method_callback('android', '元素操作', 18, [MethodModel(f='locating')])
150
- def a_swipe_up(self, locating: UiObject):
151
- """元素内向上滑动"""
152
- locating.swipe('up')
153
-
154
- @sync_method_callback('android', '元素操作', 19, [MethodModel(f='locating')])
155
- def a_swipe_ele(self, locating: UiObject):
156
- """元素内向下滑动"""
157
- locating.swipe('down')
158
-
159
- @sync_method_callback('android', '元素操作', 20, [
160
- MethodModel(f='locating'),
161
- MethodModel(n='x坐标', f='x_key', p='请输入x坐标', d=True),
162
- MethodModel(n='y坐标', f='y_key', p='请输入y坐标', d=True)])
163
- def a_get_center(self, locating: UiObject, x_key, y_key):
164
- """提取元素坐标"""
165
- x, y = locating.center()
166
- if x_key and y_key:
167
- self.base_data.test_data.set_cache(key=x_key, value=x)
168
- self.base_data.test_data.set_cache(key=y_key, value=y)
169
- return x, y