uiautodev 0.3.7__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of uiautodev might be problematic. Click here for more details.
- uiautodev/__init__.py +2 -6
- uiautodev/cli.py +1 -1
- uiautodev/command_proxy.py +44 -8
- uiautodev/command_types.py +8 -0
- uiautodev/driver/android.py +40 -50
- uiautodev/driver/base_driver.py +33 -4
- uiautodev/driver/ios.py +20 -14
- uiautodev/model.py +5 -1
- uiautodev/router/device.py +19 -7
- {uiautodev-0.3.7.dist-info → uiautodev-0.5.0.dist-info}/METADATA +5 -5
- {uiautodev-0.3.7.dist-info → uiautodev-0.5.0.dist-info}/RECORD +14 -14
- {uiautodev-0.3.7.dist-info → uiautodev-0.5.0.dist-info}/LICENSE +0 -0
- {uiautodev-0.3.7.dist-info → uiautodev-0.5.0.dist-info}/WHEEL +0 -0
- {uiautodev-0.3.7.dist-info → uiautodev-0.5.0.dist-info}/entry_points.txt +0 -0
uiautodev/__init__.py
CHANGED
|
@@ -4,9 +4,5 @@
|
|
|
4
4
|
"""Created on Mon Mar 04 2024 14:28:53 by codeskyblue
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
__version__ = version("uiautodev")
|
|
11
|
-
except PackageNotFoundError:
|
|
12
|
-
__version__ = "0.0.0"
|
|
7
|
+
# version is auto managed by poetry
|
|
8
|
+
__version__ = "0.5.0"
|
uiautodev/cli.py
CHANGED
|
@@ -140,7 +140,7 @@ def self_update():
|
|
|
140
140
|
@click.option("-f", "--force", is_flag=True, default=False, help="shutdown alrealy runningserver")
|
|
141
141
|
@click.option("-s", "--no-browser", is_flag=True, default=False, help="silent mode, do not open browser")
|
|
142
142
|
def server(port: int, host: str, reload: bool, force: bool, no_browser: bool):
|
|
143
|
-
|
|
143
|
+
print("uiautodev version:", __version__)
|
|
144
144
|
if force:
|
|
145
145
|
try:
|
|
146
146
|
httpx.get(f"http://{host}:{port}/shutdown", timeout=3)
|
uiautodev/command_proxy.py
CHANGED
|
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import time
|
|
10
10
|
import typing
|
|
11
|
-
from typing import Callable, Dict, Optional
|
|
11
|
+
from typing import Callable, Dict, List, Optional, Union
|
|
12
12
|
|
|
13
13
|
from pydantic import BaseModel
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ from uiautodev.command_types import AppLaunchRequest, AppTerminateRequest, By, C
|
|
|
17
17
|
WindowSizeResponse
|
|
18
18
|
from uiautodev.driver.base_driver import BaseDriver
|
|
19
19
|
from uiautodev.exceptions import ElementNotFoundError
|
|
20
|
-
from uiautodev.model import Node
|
|
20
|
+
from uiautodev.model import Node, AppInfo
|
|
21
21
|
from uiautodev.utils.common import node_travel
|
|
22
22
|
|
|
23
23
|
COMMANDS: Dict[Command, Callable] = {}
|
|
@@ -39,17 +39,21 @@ def get_command_params_type(command: Command) -> Optional[BaseModel]:
|
|
|
39
39
|
return type_hints.get("params")
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def send_command(driver: BaseDriver, command: Command, params=None):
|
|
42
|
+
def send_command(driver: BaseDriver, command: Union[str, Command], params=None):
|
|
43
43
|
if command not in COMMANDS:
|
|
44
44
|
raise NotImplementedError(f"command {command} not implemented")
|
|
45
45
|
func = COMMANDS[command]
|
|
46
|
-
|
|
47
|
-
if
|
|
46
|
+
params_model = get_command_params_type(command)
|
|
47
|
+
if params_model:
|
|
48
48
|
if params is None:
|
|
49
49
|
raise ValueError(f"params is required for {command}")
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
if isinstance(params, dict):
|
|
51
|
+
params = params_model.model_validate(params)
|
|
52
|
+
elif isinstance(params, params_model):
|
|
53
|
+
pass
|
|
54
|
+
else:
|
|
55
|
+
raise TypeError(f"params should be {params_model}", params)
|
|
56
|
+
if not params:
|
|
53
57
|
return func(driver)
|
|
54
58
|
return func(driver, params)
|
|
55
59
|
|
|
@@ -105,6 +109,31 @@ def home(driver: BaseDriver):
|
|
|
105
109
|
driver.home()
|
|
106
110
|
|
|
107
111
|
|
|
112
|
+
@register(Command.BACK)
|
|
113
|
+
def back(driver: BaseDriver):
|
|
114
|
+
driver.back()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@register(Command.APP_SWITCH)
|
|
118
|
+
def app_switch(driver: BaseDriver):
|
|
119
|
+
driver.app_switch()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@register(Command.VOLUME_UP)
|
|
123
|
+
def volume_up(driver: BaseDriver):
|
|
124
|
+
driver.volume_up()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@register(Command.VOLUME_DOWN)
|
|
128
|
+
def volume_down(driver: BaseDriver):
|
|
129
|
+
driver.volume_down()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@register(Command.VOLUME_MUTE)
|
|
133
|
+
def volume_mute(driver: BaseDriver):
|
|
134
|
+
driver.volume_mute()
|
|
135
|
+
|
|
136
|
+
|
|
108
137
|
@register(Command.DUMP)
|
|
109
138
|
def dump(driver: BaseDriver) -> DumpResponse:
|
|
110
139
|
source, _ = driver.dump_hierarchy()
|
|
@@ -152,3 +181,10 @@ def click_element(driver: BaseDriver, params: FindElementRequest):
|
|
|
152
181
|
center_x = (node.bounds[0] + node.bounds[2]) / 2
|
|
153
182
|
center_y = (node.bounds[1] + node.bounds[3]) / 2
|
|
154
183
|
tap(driver, TapRequest(x=center_x, y=center_y, isPercent=True))
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@register(Command.APP_LIST)
|
|
187
|
+
def app_list(driver: BaseDriver) -> List[AppInfo]:
|
|
188
|
+
# added in v0.5.0
|
|
189
|
+
return driver.app_list()
|
|
190
|
+
|
uiautodev/command_types.py
CHANGED
|
@@ -22,6 +22,7 @@ class Command(str, enum.Enum):
|
|
|
22
22
|
APP_CURRENT = "currentApp"
|
|
23
23
|
APP_LAUNCH = "appLaunch"
|
|
24
24
|
APP_TERMINATE = "appTerminate"
|
|
25
|
+
APP_LIST = "appList"
|
|
25
26
|
|
|
26
27
|
GET_WINDOW_SIZE = "getWindowSize"
|
|
27
28
|
HOME = "home"
|
|
@@ -32,6 +33,13 @@ class Command(str, enum.Enum):
|
|
|
32
33
|
|
|
33
34
|
LIST = "list"
|
|
34
35
|
|
|
36
|
+
# 0.4.0
|
|
37
|
+
BACK = "back"
|
|
38
|
+
APP_SWITCH = "appSwitch"
|
|
39
|
+
VOLUME_UP = "volumeUp"
|
|
40
|
+
VOLUME_DOWN = "volumeDown"
|
|
41
|
+
VOLUME_MUTE = "volumeMute"
|
|
42
|
+
|
|
35
43
|
|
|
36
44
|
class TapRequest(BaseModel):
|
|
37
45
|
x: Union[int, float]
|
uiautodev/driver/android.py
CHANGED
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
"""Created on Fri Mar 01 2024 14:19:29 by codeskyblue
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import json
|
|
8
7
|
import logging
|
|
9
8
|
import re
|
|
10
9
|
import time
|
|
11
10
|
from functools import cached_property, partial
|
|
12
|
-
from typing import List, Optional, Tuple
|
|
11
|
+
from typing import Iterator, List, Optional, Tuple
|
|
13
12
|
from xml.etree import ElementTree
|
|
14
13
|
|
|
15
14
|
import adbutils
|
|
@@ -18,9 +17,8 @@ from PIL import Image
|
|
|
18
17
|
|
|
19
18
|
from uiautodev.command_types import CurrentAppResponse
|
|
20
19
|
from uiautodev.driver.base_driver import BaseDriver
|
|
21
|
-
from uiautodev.driver.udt.udt import UDT, UDTError
|
|
22
20
|
from uiautodev.exceptions import AndroidDriverException, RequestError
|
|
23
|
-
from uiautodev.model import Node, Rect, ShellResponse, WindowSize
|
|
21
|
+
from uiautodev.model import Node, AppInfo, Rect, ShellResponse, WindowSize
|
|
24
22
|
from uiautodev.utils.common import fetch_through_socket
|
|
25
23
|
|
|
26
24
|
logger = logging.getLogger(__name__)
|
|
@@ -29,28 +27,15 @@ class AndroidDriver(BaseDriver):
|
|
|
29
27
|
def __init__(self, serial: str):
|
|
30
28
|
super().__init__(serial)
|
|
31
29
|
self.adb_device = adbutils.device(serial)
|
|
32
|
-
self._try_dump_list = [
|
|
33
|
-
self._get_u2_hierarchy,
|
|
34
|
-
self._get_udt_dump_hierarchy,
|
|
35
|
-
# self._get_appium_hierarchy,
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
@cached_property
|
|
39
|
-
def udt(self) -> UDT:
|
|
40
|
-
return UDT(self.adb_device)
|
|
41
30
|
|
|
42
31
|
@cached_property
|
|
43
32
|
def ud(self) -> u2.Device:
|
|
44
33
|
return u2.connect_usb(self.serial)
|
|
45
34
|
|
|
46
35
|
def screenshot(self, id: int) -> Image.Image:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
logger.warning("screenshot error: %s", str(e))
|
|
51
|
-
if id > 0:
|
|
52
|
-
raise AndroidDriverException("multi-display is not supported yet for uiautomator2")
|
|
53
|
-
return self.ud.screenshot()
|
|
36
|
+
if id > 0:
|
|
37
|
+
raise AndroidDriverException("multi-display is not supported yet for uiautomator2")
|
|
38
|
+
return self.ud.screenshot()
|
|
54
39
|
|
|
55
40
|
def shell(self, command: str) -> ShellResponse:
|
|
56
41
|
try:
|
|
@@ -82,38 +67,12 @@ class AndroidDriver(BaseDriver):
|
|
|
82
67
|
|
|
83
68
|
uiautomator dump errors:
|
|
84
69
|
- ERROR: could not get idle state.
|
|
85
|
-
|
|
86
70
|
"""
|
|
87
|
-
for dump_func in self._try_dump_list[:]:
|
|
88
|
-
try:
|
|
89
|
-
logger.debug(f"try to dump with %s", dump_func.__name__)
|
|
90
|
-
result = dump_func()
|
|
91
|
-
logger.debug("dump success")
|
|
92
|
-
self._try_dump_list.remove(dump_func)
|
|
93
|
-
self._try_dump_list.insert(0, dump_func)
|
|
94
|
-
return result
|
|
95
|
-
except Exception as e:
|
|
96
|
-
logger.exception("unexpected dump error: %s", e)
|
|
97
|
-
raise AndroidDriverException("Failed to dump hierarchy")
|
|
98
|
-
|
|
99
|
-
def _get_u2_hierarchy(self) -> str:
|
|
100
|
-
d = u2.connect_usb(self.serial)
|
|
101
|
-
return d.dump_hierarchy()
|
|
102
|
-
|
|
103
|
-
def _get_appium_hierarchy(self) -> str:
|
|
104
|
-
c = self.adb_device.create_connection(adbutils.Network.TCP, 6790)
|
|
105
71
|
try:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
raise AndroidDriverException(
|
|
110
|
-
f"Failed to get hierarchy from appium server: {str(e)}"
|
|
111
|
-
)
|
|
112
|
-
finally:
|
|
113
|
-
c.close()
|
|
114
|
-
|
|
115
|
-
def _get_udt_dump_hierarchy(self) -> str:
|
|
116
|
-
return self.udt.dump_hierarchy()
|
|
72
|
+
return self.ud.dump_hierarchy()
|
|
73
|
+
except Exception as e:
|
|
74
|
+
logger.exception("unexpected dump error: %s", e)
|
|
75
|
+
raise AndroidDriverException("Failed to dump hierarchy")
|
|
117
76
|
|
|
118
77
|
def tap(self, x: int, y: int):
|
|
119
78
|
self.adb_device.click(x, y)
|
|
@@ -144,6 +103,37 @@ class AndroidDriver(BaseDriver):
|
|
|
144
103
|
|
|
145
104
|
def wake_up(self):
|
|
146
105
|
self.adb_device.keyevent("WAKEUP")
|
|
106
|
+
|
|
107
|
+
def back(self):
|
|
108
|
+
self.adb_device.keyevent("BACK")
|
|
109
|
+
|
|
110
|
+
def app_switch(self):
|
|
111
|
+
self.adb_device.keyevent("APP_SWITCH")
|
|
112
|
+
|
|
113
|
+
def volume_up(self):
|
|
114
|
+
self.adb_device.keyevent("VOLUME_UP")
|
|
115
|
+
|
|
116
|
+
def volume_down(self):
|
|
117
|
+
self.adb_device.keyevent("VOLUME_DOWN")
|
|
118
|
+
|
|
119
|
+
def volume_mute(self):
|
|
120
|
+
self.adb_device.keyevent("VOLUME_MUTE")
|
|
121
|
+
|
|
122
|
+
def app_list(self) -> List[AppInfo]:
|
|
123
|
+
results = []
|
|
124
|
+
output = self.adb_device.shell(["pm", "list", "packages", '-3'])
|
|
125
|
+
for m in re.finditer(r"^package:([^\s]+)\r?$", output, re.M):
|
|
126
|
+
packageName = m.group(1)
|
|
127
|
+
results.append(AppInfo(packageName=packageName))
|
|
128
|
+
return results
|
|
129
|
+
|
|
130
|
+
def open_app_file(self, package: str) -> Iterator[bytes]:
|
|
131
|
+
line = self.adb_device.shell(f"pm path {package}")
|
|
132
|
+
if not line.startswith("package:"):
|
|
133
|
+
raise AndroidDriverException(f"Failed to get package path: {line}")
|
|
134
|
+
remote_path = line.split(':', 1)[1]
|
|
135
|
+
yield from self.adb_device.sync.iter_content(remote_path)
|
|
136
|
+
|
|
147
137
|
|
|
148
138
|
|
|
149
139
|
def parse_xml(xml_data: str, wsize: WindowSize, display_id: Optional[int] = None) -> Node:
|
uiautodev/driver/base_driver.py
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"""Created on Fri Mar 01 2024 14:18:30 by codeskyblue
|
|
5
5
|
"""
|
|
6
6
|
import abc
|
|
7
|
-
import
|
|
8
|
-
from typing import Tuple
|
|
7
|
+
from io import FileIO
|
|
8
|
+
from typing import Iterator, List, Tuple
|
|
9
9
|
|
|
10
10
|
from PIL import Image
|
|
11
11
|
from pydantic import BaseModel
|
|
12
12
|
|
|
13
13
|
from uiautodev.command_types import CurrentAppResponse
|
|
14
|
-
from uiautodev.model import Node, ShellResponse, WindowSize
|
|
14
|
+
from uiautodev.model import Node, AppInfo, ShellResponse, WindowSize
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class BaseDriver(abc.ABC):
|
|
@@ -70,7 +70,36 @@ class BaseDriver(abc.ABC):
|
|
|
70
70
|
def home(self):
|
|
71
71
|
""" press home button """
|
|
72
72
|
raise NotImplementedError()
|
|
73
|
+
|
|
74
|
+
def back(self):
|
|
75
|
+
""" press back button """
|
|
76
|
+
raise NotImplementedError()
|
|
77
|
+
|
|
78
|
+
def app_switch(self):
|
|
79
|
+
""" switch app """
|
|
80
|
+
raise NotImplementedError()
|
|
81
|
+
|
|
82
|
+
def volume_up(self):
|
|
83
|
+
""" volume up """
|
|
84
|
+
raise NotImplementedError()
|
|
85
|
+
|
|
86
|
+
def volume_down(self):
|
|
87
|
+
""" volume down """
|
|
88
|
+
raise NotImplementedError()
|
|
89
|
+
|
|
90
|
+
def volume_mute(self):
|
|
91
|
+
""" volume mute """
|
|
92
|
+
raise NotImplementedError()
|
|
73
93
|
|
|
74
94
|
def wake_up(self):
|
|
75
95
|
""" wake up the device """
|
|
76
|
-
raise NotImplementedError()
|
|
96
|
+
raise NotImplementedError()
|
|
97
|
+
|
|
98
|
+
def app_list(self) -> List[AppInfo]:
|
|
99
|
+
""" list installed packages """
|
|
100
|
+
raise NotImplementedError()
|
|
101
|
+
|
|
102
|
+
def open_app_file(self, package: str) -> Iterator[bytes]:
|
|
103
|
+
""" open app file """
|
|
104
|
+
raise NotImplementedError()
|
|
105
|
+
|
uiautodev/driver/ios.py
CHANGED
|
@@ -5,21 +5,19 @@
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
import base64
|
|
9
|
-
import io
|
|
10
8
|
import json
|
|
11
|
-
import re
|
|
12
9
|
from functools import partial
|
|
13
10
|
from typing import List, Optional, Tuple
|
|
14
11
|
from xml.etree import ElementTree
|
|
15
12
|
|
|
13
|
+
import wdapy
|
|
16
14
|
from PIL import Image
|
|
17
15
|
|
|
18
16
|
from uiautodev.command_types import CurrentAppResponse
|
|
19
17
|
from uiautodev.driver.base_driver import BaseDriver
|
|
20
18
|
from uiautodev.exceptions import IOSDriverException
|
|
21
19
|
from uiautodev.model import Node, WindowSize
|
|
22
|
-
from uiautodev.utils.usbmux import
|
|
20
|
+
from uiautodev.utils.usbmux import select_device
|
|
23
21
|
|
|
24
22
|
|
|
25
23
|
class IOSDriver(BaseDriver):
|
|
@@ -27,6 +25,7 @@ class IOSDriver(BaseDriver):
|
|
|
27
25
|
""" serial is the udid of the ios device """
|
|
28
26
|
super().__init__(serial)
|
|
29
27
|
self.device = select_device(serial)
|
|
28
|
+
self.wda = wdapy.AppiumUSBClient(self.device.serial)
|
|
30
29
|
|
|
31
30
|
def _request(self, method: str, path: str, payload: Optional[dict] = None) -> bytes:
|
|
32
31
|
conn = self.device.make_http_connection(port=8100)
|
|
@@ -56,29 +55,36 @@ class IOSDriver(BaseDriver):
|
|
|
56
55
|
return self._request_json("GET", "/status")
|
|
57
56
|
|
|
58
57
|
def screenshot(self, id: int = 0) -> Image.Image:
|
|
59
|
-
|
|
60
|
-
png_data = base64.b64decode(png_base64)
|
|
61
|
-
return Image.open(io.BytesIO(png_data))
|
|
58
|
+
return self.wda.screenshot()
|
|
62
59
|
|
|
63
60
|
def window_size(self):
|
|
64
|
-
return self.
|
|
61
|
+
return self.wda.window_size()
|
|
65
62
|
|
|
66
63
|
def dump_hierarchy(self) -> Tuple[str, Node]:
|
|
67
64
|
"""returns xml string and hierarchy object"""
|
|
68
|
-
|
|
65
|
+
t = self.wda.sourcetree()
|
|
66
|
+
xml_data = t.value
|
|
69
67
|
root = ElementTree.fromstring(xml_data)
|
|
70
68
|
return xml_data, parse_xml_element(root, WindowSize(width=1, height=1))
|
|
71
69
|
|
|
72
70
|
def tap(self, x: int, y: int):
|
|
73
|
-
self.
|
|
71
|
+
self.wda.tap(x, y)
|
|
74
72
|
|
|
75
73
|
def app_current(self) -> CurrentAppResponse:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return CurrentAppResponse(package=value["bundleId"], pid=value["pid"])
|
|
74
|
+
info = self.wda.app_current()
|
|
75
|
+
return CurrentAppResponse(package=info.bundle_id, pid=info.pid)
|
|
79
76
|
|
|
80
77
|
def home(self):
|
|
81
|
-
self.
|
|
78
|
+
self.wda.homescreen()
|
|
79
|
+
|
|
80
|
+
def app_switch(self):
|
|
81
|
+
raise NotImplementedError()
|
|
82
|
+
|
|
83
|
+
def volume_up(self):
|
|
84
|
+
self.wda.volume_up()
|
|
85
|
+
|
|
86
|
+
def volume_down(self):
|
|
87
|
+
self.wda.volume_down()
|
|
82
88
|
|
|
83
89
|
|
|
84
90
|
def parse_xml_element(element, wsize: WindowSize, indexes: List[int]=[0]) -> Node:
|
uiautodev/model.py
CHANGED
uiautodev/router/device.py
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import io
|
|
8
8
|
import logging
|
|
9
|
-
from typing import Any, List
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
10
|
|
|
11
11
|
from fastapi import APIRouter, Response
|
|
12
|
+
from fastapi.responses import StreamingResponse
|
|
12
13
|
from pydantic import BaseModel
|
|
13
14
|
|
|
14
15
|
from uiautodev import command_proxy
|
|
@@ -102,14 +103,25 @@ def make_router(provider: BaseProvider) -> APIRouter:
|
|
|
102
103
|
return command_proxy.app_current(driver)
|
|
103
104
|
|
|
104
105
|
@router.post('/{serial}/command/{command}')
|
|
105
|
-
def _command_proxy_other(serial: str, command: Command, params: Any = None):
|
|
106
|
+
def _command_proxy_other(serial: str, command: Command, params: Dict[str, Any] = None):
|
|
106
107
|
"""Run a command on the device"""
|
|
107
108
|
driver = provider.get_device_driver(serial)
|
|
108
|
-
|
|
109
|
-
if params is None:
|
|
110
|
-
response = func(driver)
|
|
111
|
-
else:
|
|
112
|
-
response = func(driver, params)
|
|
109
|
+
response = command_proxy.send_command(driver, command, params)
|
|
113
110
|
return response
|
|
111
|
+
|
|
112
|
+
@router.get('/{serial}/backupApp')
|
|
113
|
+
def _backup_app(serial: str, packageName: str):
|
|
114
|
+
"""Backup app
|
|
115
|
+
|
|
116
|
+
Added in 0.5.0
|
|
117
|
+
"""
|
|
118
|
+
driver = provider.get_device_driver(serial)
|
|
119
|
+
file_name = f"{packageName}.apk"
|
|
120
|
+
headers = {
|
|
121
|
+
'Content-Disposition': f'attachment; filename="{file_name}"'
|
|
122
|
+
}
|
|
123
|
+
return StreamingResponse(driver.open_app_file(packageName), headers=headers)
|
|
124
|
+
|
|
125
|
+
|
|
114
126
|
|
|
115
127
|
return router
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: uiautodev
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Mobile UI Automation, include UI hierarchy inspector, script recorder
|
|
5
5
|
Home-page: https://uiauto.dev
|
|
6
6
|
License: MIT
|
|
@@ -14,13 +14,10 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
-
|
|
18
|
-
Requires-Dist: adbutils (>=2.6.0,<3.0.0)
|
|
19
|
-
Requires-Dist: appium-python-client (>=4.0.0,<5.0.0) ; extra == "appium"
|
|
17
|
+
Requires-Dist: adbutils (>=2.7.0,<3.0.0)
|
|
20
18
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
21
19
|
Requires-Dist: construct
|
|
22
20
|
Requires-Dist: fastapi (>=0.111.0,<0.112.0)
|
|
23
|
-
Requires-Dist: httpretty (>=1.1.4,<2.0.0)
|
|
24
21
|
Requires-Dist: httpx
|
|
25
22
|
Requires-Dist: lxml
|
|
26
23
|
Requires-Dist: pillow
|
|
@@ -29,6 +26,7 @@ Requires-Dist: pydantic (>=2.6,<3.0)
|
|
|
29
26
|
Requires-Dist: pygments (>=2)
|
|
30
27
|
Requires-Dist: uiautomator2 (>=2)
|
|
31
28
|
Requires-Dist: uvicorn[standard]
|
|
29
|
+
Requires-Dist: wdapy (>=0.2.2,<0.3.0)
|
|
32
30
|
Description-Content-Type: text/markdown
|
|
33
31
|
|
|
34
32
|
# uiautodev
|
|
@@ -37,6 +35,8 @@ Description-Content-Type: text/markdown
|
|
|
37
35
|
|
|
38
36
|
https://uiauto.dev
|
|
39
37
|
|
|
38
|
+
> backup site: https://uiauto.devsleep.com
|
|
39
|
+
|
|
40
40
|
UI Inspector for Android and iOS, help inspector element properties, and auto generate XPath, script.
|
|
41
41
|
|
|
42
42
|
# Install
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
uiautodev/__init__.py,sha256=
|
|
1
|
+
uiautodev/__init__.py,sha256=uBLcbZ_b1lvAbHh0kXPeO4VWJvl-Zc4XvUMhg6PmzyY,164
|
|
2
2
|
uiautodev/__main__.py,sha256=0WZHyHW-M7FG5RexANNoIB5pkCX8xwQbTnmaOA9Y1kg,176
|
|
3
3
|
uiautodev/app.py,sha256=R7AV5uuh4VLkrF9Kl_JJWUiPQnuIeJ02CN1W7tNGPKE,2498
|
|
4
4
|
uiautodev/appium_proxy.py,sha256=yMzPnIDo50hYSaq0g5bXUpgRrFa_849wNa2o7ZpxGNY,1773
|
|
5
5
|
uiautodev/case.py,sha256=Jk2_5X2F-XIPnGuYTCqOVQiwwchwOhF7uKK5oKv5shg,3919
|
|
6
|
-
uiautodev/cli.py,sha256=
|
|
7
|
-
uiautodev/command_proxy.py,sha256=
|
|
8
|
-
uiautodev/command_types.py,sha256=
|
|
6
|
+
uiautodev/cli.py,sha256=K4CEvGJSDWLAFR5tvls2Qp4evQ2lApLoUxA-4DI2-Sc,6235
|
|
7
|
+
uiautodev/command_proxy.py,sha256=gP4oTCjA1uKteWq5NOcHQLrI34el0ag5LUHNEq_j7Ko,5280
|
|
8
|
+
uiautodev/command_types.py,sha256=pWdnCS4FRnEIiR1ynd4cjXX8zeFndjPztacBlukt61E,1761
|
|
9
9
|
uiautodev/common.py,sha256=t1jmG7S0LVXAigtg86J3vM2XXf1xYPfDV_HwSwyl3OI,552
|
|
10
|
-
uiautodev/driver/android.py,sha256=
|
|
10
|
+
uiautodev/driver/android.py,sha256=aKx6mW0eUMejv2uItkvDQg6o5nxtAOJ3m0gqomRXC_g,6394
|
|
11
11
|
uiautodev/driver/appium.py,sha256=U3TGpOXmu3tEa3E1ttTFoXehOfFyjavJQ3XA4CtqeBE,5308
|
|
12
|
-
uiautodev/driver/base_driver.py,sha256=
|
|
13
|
-
uiautodev/driver/ios.py,sha256=
|
|
12
|
+
uiautodev/driver/base_driver.py,sha256=8uo7DgEKfgW_wf-HpkmFxjNRkElpFEDjjg45Q2pgiWA,2816
|
|
13
|
+
uiautodev/driver/ios.py,sha256=EOi9k-Y4qQS6Htdz_ycBf5jYCnOkruB-mR0Sc8J-coo,4204
|
|
14
14
|
uiautodev/driver/mock.py,sha256=0VtxBkZRMbHiQGHjqm8Ih2Ld6baXiVxX8yUTwWJQlnE,2422
|
|
15
15
|
uiautodev/driver/udt/appium-uiautomator2-v5.12.4-light.apk,sha256=cKUVKpqEiGRXODeqpwzVWllyjdSLyowFm94a6jDTvhI,3675062
|
|
16
16
|
uiautodev/driver/udt/udt.py,sha256=p6opbUtYxEGTINIX83F6m2CtzB42iSSBYRv1SjXCEFg,8351
|
|
17
17
|
uiautodev/exceptions.py,sha256=TuRD5SWQk5N2_KjrcDuXG_p84LBhLa2QEEXyFNFm0yQ,465
|
|
18
|
-
uiautodev/model.py,sha256=
|
|
18
|
+
uiautodev/model.py,sha256=ij9Ct_OboSygyU_cQHoXzQ9czcwGogoezwXjyY-Cr0U,876
|
|
19
19
|
uiautodev/provider.py,sha256=HDD_Jj-cJVfBceunzCYU9zJvGVya7Jd35GG9h85BY-0,2370
|
|
20
|
-
uiautodev/router/device.py,sha256=
|
|
20
|
+
uiautodev/router/device.py,sha256=9lLN7L1lExWUZ39uKz3fd56s3dkgdTfrKgcs9jQDD0I,4846
|
|
21
21
|
uiautodev/router/xml.py,sha256=MKVLhjMBqE4qbEraQxvdrVp_OBnylEL9Wti5lnmBDk4,891
|
|
22
22
|
uiautodev/static/demo.html,sha256=qC7qUZP5Af9T3V5EuFGbovzv8mArwiGMWsX_vcs_Bt0,1240
|
|
23
23
|
uiautodev/utils/common.py,sha256=HuXJvipkg1QQg6vCD7OxH6JQtqbSVbXNzI1X2OVcEcU,4785
|
|
24
24
|
uiautodev/utils/exceptions.py,sha256=lL_G_E41KWvfXnl32-E4Vgr3_HyTboxq_EwzdQMuvK4,637
|
|
25
25
|
uiautodev/utils/usbmux.py,sha256=LYupLDn7U4KFKhYQJrmIroS-3040gqZQVDRDB_FNDJM,17386
|
|
26
|
-
uiautodev-0.
|
|
27
|
-
uiautodev-0.
|
|
28
|
-
uiautodev-0.
|
|
29
|
-
uiautodev-0.
|
|
30
|
-
uiautodev-0.
|
|
26
|
+
uiautodev-0.5.0.dist-info/LICENSE,sha256=RyeW676gBYO7AVVP2zQgfEx5rPSt46vR47xXZe7TlX4,1068
|
|
27
|
+
uiautodev-0.5.0.dist-info/METADATA,sha256=jcCkmA85d8iUEKD7yO-JbHnykMP-gkiSy6zHHCULv34,2310
|
|
28
|
+
uiautodev-0.5.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
29
|
+
uiautodev-0.5.0.dist-info/entry_points.txt,sha256=zBY8GgseYAAzPFA5Cf4rCCS9ivdyWsNxMVVYIaGAHJU,88
|
|
30
|
+
uiautodev-0.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|