pymobiledevice3 6.0.0__py3-none-any.whl → 6.1.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.
- pymobiledevice3/_version.py +2 -2
- pymobiledevice3/cli/syslog.py +21 -5
- pymobiledevice3/services/os_trace.py +8 -2
- pymobiledevice3/services/web_protocol/alert.py +8 -8
- pymobiledevice3/services/web_protocol/driver.py +2 -2
- pymobiledevice3/services/web_protocol/element.py +3 -3
- pymobiledevice3/services/web_protocol/selenium_api.py +47 -47
- pymobiledevice3/services/web_protocol/switch_to.py +23 -19
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/METADATA +1 -1
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/RECORD +14 -14
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/WHEEL +0 -0
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/licenses/LICENSE +0 -0
- {pymobiledevice3-6.0.0.dist-info → pymobiledevice3-6.1.0.dist-info}/top_level.txt +0 -0
pymobiledevice3/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '6.
|
|
32
|
-
__version_tuple__ = version_tuple = (6,
|
|
31
|
+
__version__ = version = '6.1.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (6, 1, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
pymobiledevice3/cli/syslog.py
CHANGED
|
@@ -33,7 +33,7 @@ def syslog_live_old(service_provider: LockdownClient):
|
|
|
33
33
|
print(line)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def format_line(color, pid, syslog_entry, include_label):
|
|
36
|
+
def format_line(color, pid, syslog_entry, include_label: bool, image_offset: bool = False) -> Optional[str]:
|
|
37
37
|
log_level_colors = {
|
|
38
38
|
SyslogLogLevel.NOTICE.name: "white",
|
|
39
39
|
SyslogLogLevel.INFO.name: "white",
|
|
@@ -50,6 +50,7 @@ def format_line(color, pid, syslog_entry, include_label):
|
|
|
50
50
|
image_name = posixpath.basename(syslog_entry.image_name)
|
|
51
51
|
message = syslog_entry.message
|
|
52
52
|
process_name = posixpath.basename(filename)
|
|
53
|
+
image_offset_str = f"+0x{syslog_entry.image_offset:x}" if image_offset else ""
|
|
53
54
|
label = ""
|
|
54
55
|
|
|
55
56
|
if (pid != -1) and (syslog_pid != pid):
|
|
@@ -63,13 +64,15 @@ def format_line(color, pid, syslog_entry, include_label):
|
|
|
63
64
|
process_name = click.style(process_name, "magenta")
|
|
64
65
|
if len(image_name) > 0:
|
|
65
66
|
image_name = click.style(image_name, "magenta")
|
|
67
|
+
if image_offset:
|
|
68
|
+
image_offset_str = click.style(image_offset_str, "blue")
|
|
66
69
|
syslog_pid = click.style(syslog_pid, "cyan")
|
|
67
70
|
log_level_color = log_level_colors[level]
|
|
68
71
|
level = click.style(level, log_level_color)
|
|
69
72
|
label = click.style(label, "cyan")
|
|
70
73
|
message = click.style(message, log_level_color)
|
|
71
74
|
|
|
72
|
-
line_format = "{timestamp} {process_name}{{{image_name}}}[{pid}] <{level}>: {message}"
|
|
75
|
+
line_format = "{timestamp} {process_name}{{{image_name}{image_offset_str}}}[{pid}] <{level}>: {message}"
|
|
73
76
|
|
|
74
77
|
if include_label:
|
|
75
78
|
line_format += f" {label}"
|
|
@@ -81,6 +84,7 @@ def format_line(color, pid, syslog_entry, include_label):
|
|
|
81
84
|
pid=syslog_pid,
|
|
82
85
|
level=level,
|
|
83
86
|
message=message,
|
|
87
|
+
image_offset_str=image_offset_str,
|
|
84
88
|
)
|
|
85
89
|
|
|
86
90
|
return line
|
|
@@ -96,6 +100,7 @@ def syslog_live(
|
|
|
96
100
|
include_label: bool,
|
|
97
101
|
regex: list[str],
|
|
98
102
|
insensitive_regex: list[str],
|
|
103
|
+
image_offset: bool = False,
|
|
99
104
|
) -> None:
|
|
100
105
|
match_regex = [re.compile(f".*({r}).*", re.DOTALL) for r in regex]
|
|
101
106
|
match_regex += [re.compile(f".*({r}).*", re.IGNORECASE | re.DOTALL) for r in insensitive_regex]
|
|
@@ -109,8 +114,8 @@ def syslog_live(
|
|
|
109
114
|
if process_name and posixpath.basename(syslog_entry.filename) != process_name:
|
|
110
115
|
continue
|
|
111
116
|
|
|
112
|
-
line_no_style = format_line(False, pid, syslog_entry, include_label)
|
|
113
|
-
line = format_line(user_requested_colored_output(), pid, syslog_entry, include_label)
|
|
117
|
+
line_no_style = format_line(False, pid, syslog_entry, include_label, image_offset)
|
|
118
|
+
line = format_line(user_requested_colored_output(), pid, syslog_entry, include_label, image_offset)
|
|
114
119
|
|
|
115
120
|
skip = False
|
|
116
121
|
|
|
@@ -172,6 +177,7 @@ def syslog_live(
|
|
|
172
177
|
@click.option("include_label", "--label", is_flag=True, help="should include label")
|
|
173
178
|
@click.option("-e", "--regex", multiple=True, help="filter only lines matching given regex")
|
|
174
179
|
@click.option("-ei", "--insensitive-regex", multiple=True, help="filter only lines matching given regex (insensitive)")
|
|
180
|
+
@click.option("-im", "--image-offset", is_flag=True, help="Include image offset in log line")
|
|
175
181
|
def cli_syslog_live(
|
|
176
182
|
service_provider: LockdownServiceProvider,
|
|
177
183
|
out: Optional[TextIO],
|
|
@@ -182,11 +188,21 @@ def cli_syslog_live(
|
|
|
182
188
|
include_label: bool,
|
|
183
189
|
regex: list[str],
|
|
184
190
|
insensitive_regex: list[str],
|
|
191
|
+
image_offset: bool,
|
|
185
192
|
) -> None:
|
|
186
193
|
"""view live syslog lines"""
|
|
187
194
|
|
|
188
195
|
syslog_live(
|
|
189
|
-
service_provider,
|
|
196
|
+
service_provider,
|
|
197
|
+
out,
|
|
198
|
+
pid,
|
|
199
|
+
process_name,
|
|
200
|
+
match,
|
|
201
|
+
match_insensitive,
|
|
202
|
+
include_label,
|
|
203
|
+
regex,
|
|
204
|
+
insensitive_regex,
|
|
205
|
+
image_offset,
|
|
190
206
|
)
|
|
191
207
|
|
|
192
208
|
|
|
@@ -43,6 +43,7 @@ class SyslogEntry:
|
|
|
43
43
|
timestamp: datetime
|
|
44
44
|
level: SyslogLogLevel
|
|
45
45
|
image_name: str
|
|
46
|
+
image_offset: int
|
|
46
47
|
filename: str
|
|
47
48
|
message: str
|
|
48
49
|
label: typing.Optional[SyslogLabel] = None
|
|
@@ -93,8 +94,12 @@ def parse_syslog_entry(data: bytes) -> SyslogEntry:
|
|
|
93
94
|
message_size = struct.unpack("<H", data[offset : offset + 2])[0]
|
|
94
95
|
offset += 2
|
|
95
96
|
|
|
96
|
-
# Skip
|
|
97
|
-
offset +=
|
|
97
|
+
# Skip 2 bytes
|
|
98
|
+
offset += 2
|
|
99
|
+
|
|
100
|
+
# Parse sender_image_offset (4 bytes, little-endian unsigned int)
|
|
101
|
+
sender_image_offset = struct.unpack("<I", data[offset : offset + 4])[0]
|
|
102
|
+
offset += 4
|
|
98
103
|
|
|
99
104
|
# Parse subsystem_size (4 bytes, little-endian unsigned int)
|
|
100
105
|
subsystem_size = struct.unpack("<I", data[offset : offset + 4])[0]
|
|
@@ -134,6 +139,7 @@ def parse_syslog_entry(data: bytes) -> SyslogEntry:
|
|
|
134
139
|
timestamp=timestamp,
|
|
135
140
|
level=SyslogLogLevel(level),
|
|
136
141
|
image_name=image_name,
|
|
142
|
+
image_offset=sender_image_offset,
|
|
137
143
|
filename=filename,
|
|
138
144
|
message=message,
|
|
139
145
|
label=label,
|
|
@@ -5,22 +5,22 @@ class Alert:
|
|
|
5
5
|
"""
|
|
6
6
|
self.session = session
|
|
7
7
|
|
|
8
|
-
def accept(self):
|
|
8
|
+
async def accept(self):
|
|
9
9
|
"""Accepts the alert available."""
|
|
10
|
-
self.session.accept_current_javascript_dialog()
|
|
10
|
+
await self.session.accept_current_javascript_dialog()
|
|
11
11
|
|
|
12
|
-
def dismiss(self):
|
|
12
|
+
async def dismiss(self):
|
|
13
13
|
"""Dismisses the alert available."""
|
|
14
|
-
self.session.dismiss_current_javascript_dialog()
|
|
14
|
+
await self.session.dismiss_current_javascript_dialog()
|
|
15
15
|
|
|
16
|
-
def send_keys(self, text: str):
|
|
16
|
+
async def send_keys(self, text: str):
|
|
17
17
|
"""
|
|
18
18
|
Send Keys to the Alert.
|
|
19
19
|
:param text: Text to send to prompts.
|
|
20
20
|
"""
|
|
21
|
-
self.session.set_user_input_for_current_javascript_prompt(text)
|
|
21
|
+
await self.session.set_user_input_for_current_javascript_prompt(text)
|
|
22
22
|
|
|
23
23
|
@property
|
|
24
|
-
def text(self) -> str:
|
|
24
|
+
async def text(self) -> str:
|
|
25
25
|
"""Gets the text of the Alert."""
|
|
26
|
-
return self.session.message_of_current_javascript_dialog()
|
|
26
|
+
return await self.session.message_of_current_javascript_dialog()
|
|
@@ -127,9 +127,9 @@ class WebDriver(SeleniumApi):
|
|
|
127
127
|
"""Gets the screenshot of the current window as a base64 encoded string."""
|
|
128
128
|
return await self.session.screenshot_as_base64()
|
|
129
129
|
|
|
130
|
-
def get_window_position(self) -> Point:
|
|
130
|
+
async def get_window_position(self) -> Point:
|
|
131
131
|
"""Gets the x,y position of the current window."""
|
|
132
|
-
rect = self.get_window_rect()
|
|
132
|
+
rect = await self.get_window_rect()
|
|
133
133
|
return Point(x=rect.x, y=rect.y)
|
|
134
134
|
|
|
135
135
|
async def get_window_rect(self) -> Rect:
|
|
@@ -54,7 +54,7 @@ class WebElement(SeleniumApi):
|
|
|
54
54
|
|
|
55
55
|
async def find_element(self, by=By.ID, value=None):
|
|
56
56
|
"""Find an element given a By strategy and locator."""
|
|
57
|
-
elem = self.session.find_elements(by, value, root=self.id_)
|
|
57
|
+
elem = await self.session.find_elements(by, value, root=self.id_)
|
|
58
58
|
return None if elem is None else WebElement(self.session, elem)
|
|
59
59
|
|
|
60
60
|
async def find_elements(self, by=By.ID, value=None):
|
|
@@ -180,9 +180,9 @@ class WebElement(SeleniumApi):
|
|
|
180
180
|
"}"
|
|
181
181
|
)
|
|
182
182
|
|
|
183
|
-
def is_editable(self) -> bool:
|
|
183
|
+
async def is_editable(self) -> bool:
|
|
184
184
|
"""Returns whether the element is editable."""
|
|
185
|
-
return self._evaluate_js_function(IS_EDITABLE)
|
|
185
|
+
return await self._evaluate_js_function(IS_EDITABLE)
|
|
186
186
|
|
|
187
187
|
async def _compute_layout(self, scroll_if_needed=True, use_viewport=False):
|
|
188
188
|
try:
|
|
@@ -6,68 +6,68 @@ from pymobiledevice3.services.web_protocol.automation_session import By
|
|
|
6
6
|
|
|
7
7
|
class SeleniumApi(ABC):
|
|
8
8
|
@abstractmethod
|
|
9
|
-
def find_element(self, by=By.ID, value=None):
|
|
9
|
+
async def find_element(self, by=By.ID, value=None):
|
|
10
10
|
pass
|
|
11
11
|
|
|
12
12
|
@abstractmethod
|
|
13
|
-
def find_elements(self, by=By.ID, value=None):
|
|
13
|
+
async def find_elements(self, by=By.ID, value=None):
|
|
14
14
|
pass
|
|
15
15
|
|
|
16
16
|
@property
|
|
17
17
|
@abstractmethod
|
|
18
|
-
def screenshot_as_base64(self):
|
|
18
|
+
async def screenshot_as_base64(self) -> str:
|
|
19
19
|
pass
|
|
20
20
|
|
|
21
|
-
def find_element_by_class_name(self, name):
|
|
22
|
-
return self.find_element(By.CLASS_NAME, name)
|
|
21
|
+
async def find_element_by_class_name(self, name):
|
|
22
|
+
return await self.find_element(By.CLASS_NAME, name)
|
|
23
23
|
|
|
24
|
-
def find_element_by_css_selector(self, css_selector):
|
|
25
|
-
return self.find_element(By.CSS_SELECTOR, css_selector)
|
|
24
|
+
async def find_element_by_css_selector(self, css_selector):
|
|
25
|
+
return await self.find_element(By.CSS_SELECTOR, css_selector)
|
|
26
26
|
|
|
27
|
-
def find_element_by_id(self, id_):
|
|
28
|
-
return self.find_element(value=id_)
|
|
27
|
+
async def find_element_by_id(self, id_):
|
|
28
|
+
return await self.find_element(value=id_)
|
|
29
29
|
|
|
30
|
-
def find_element_by_link_text(self, link_text):
|
|
31
|
-
return self.find_element(By.LINK_TEXT, link_text)
|
|
30
|
+
async def find_element_by_link_text(self, link_text):
|
|
31
|
+
return await self.find_element(By.LINK_TEXT, link_text)
|
|
32
32
|
|
|
33
|
-
def find_element_by_name(self, name):
|
|
34
|
-
return self.find_element(By.NAME, name)
|
|
33
|
+
async def find_element_by_name(self, name):
|
|
34
|
+
return await self.find_element(By.NAME, name)
|
|
35
35
|
|
|
36
|
-
def find_element_by_partial_link_text(self, link_text):
|
|
37
|
-
return self.find_element(By.PARTIAL_LINK_TEXT, link_text)
|
|
36
|
+
async def find_element_by_partial_link_text(self, link_text):
|
|
37
|
+
return await self.find_element(By.PARTIAL_LINK_TEXT, link_text)
|
|
38
38
|
|
|
39
|
-
def find_element_by_tag_name(self, name):
|
|
40
|
-
return self.find_element(By.TAG_NAME, name)
|
|
39
|
+
async def find_element_by_tag_name(self, name):
|
|
40
|
+
return await self.find_element(By.TAG_NAME, name)
|
|
41
41
|
|
|
42
|
-
def find_element_by_xpath(self, xpath):
|
|
43
|
-
return self.find_element(By.XPATH, xpath)
|
|
42
|
+
async def find_element_by_xpath(self, xpath):
|
|
43
|
+
return await self.find_element(By.XPATH, xpath)
|
|
44
44
|
|
|
45
|
-
def find_elements_by_class_name(self, name):
|
|
46
|
-
return self.find_elements(By.CLASS_NAME, name)
|
|
45
|
+
async def find_elements_by_class_name(self, name):
|
|
46
|
+
return await self.find_elements(By.CLASS_NAME, name)
|
|
47
47
|
|
|
48
|
-
def find_elements_by_css_selector(self, css_selector):
|
|
49
|
-
return self.find_elements(By.CSS_SELECTOR, css_selector)
|
|
48
|
+
async def find_elements_by_css_selector(self, css_selector):
|
|
49
|
+
return await self.find_elements(By.CSS_SELECTOR, css_selector)
|
|
50
50
|
|
|
51
|
-
def find_elements_by_id(self, id_):
|
|
52
|
-
return self.find_elements(value=id_)
|
|
51
|
+
async def find_elements_by_id(self, id_):
|
|
52
|
+
return await self.find_elements(value=id_)
|
|
53
53
|
|
|
54
|
-
def find_elements_by_link_text(self, link_text):
|
|
55
|
-
return self.find_elements(By.LINK_TEXT, link_text)
|
|
54
|
+
async def find_elements_by_link_text(self, link_text):
|
|
55
|
+
return await self.find_elements(By.LINK_TEXT, link_text)
|
|
56
56
|
|
|
57
|
-
def find_elements_by_name(self, name):
|
|
58
|
-
return self.find_elements(By.NAME, name)
|
|
57
|
+
async def find_elements_by_name(self, name):
|
|
58
|
+
return await self.find_elements(By.NAME, name)
|
|
59
59
|
|
|
60
|
-
def find_elements_by_partial_link_text(self, link_text):
|
|
61
|
-
return self.find_elements(By.PARTIAL_LINK_TEXT, link_text)
|
|
60
|
+
async def find_elements_by_partial_link_text(self, link_text):
|
|
61
|
+
return await self.find_elements(By.PARTIAL_LINK_TEXT, link_text)
|
|
62
62
|
|
|
63
|
-
def find_elements_by_tag_name(self, name):
|
|
64
|
-
return self.find_elements(By.TAG_NAME, name)
|
|
63
|
+
async def find_elements_by_tag_name(self, name):
|
|
64
|
+
return await self.find_elements(By.TAG_NAME, name)
|
|
65
65
|
|
|
66
|
-
def find_elements_by_xpath(self, xpath):
|
|
67
|
-
return self.find_elements(By.XPATH, xpath)
|
|
66
|
+
async def find_elements_by_xpath(self, xpath):
|
|
67
|
+
return await self.find_elements(By.XPATH, xpath)
|
|
68
68
|
|
|
69
|
-
def screenshot(self, filename):
|
|
70
|
-
png = self.screenshot_as_png()
|
|
69
|
+
async def screenshot(self, filename):
|
|
70
|
+
png = await self.screenshot_as_png()
|
|
71
71
|
try:
|
|
72
72
|
with open(filename, "wb") as f:
|
|
73
73
|
f.write(png)
|
|
@@ -75,17 +75,17 @@ class SeleniumApi(ABC):
|
|
|
75
75
|
return False
|
|
76
76
|
return True
|
|
77
77
|
|
|
78
|
-
def screenshot_as_png(self):
|
|
79
|
-
return b64decode(self.screenshot_as_base64.encode("ascii"))
|
|
78
|
+
async def screenshot_as_png(self) -> bytes:
|
|
79
|
+
return b64decode((await self.screenshot_as_base64).encode("ascii"))
|
|
80
80
|
|
|
81
|
-
def get_screenshot_as_base64(self):
|
|
82
|
-
return self.screenshot_as_base64
|
|
81
|
+
async def get_screenshot_as_base64(self) -> str:
|
|
82
|
+
return await self.screenshot_as_base64
|
|
83
83
|
|
|
84
|
-
def get_screenshot_as_file(self, filename):
|
|
85
|
-
return self.screenshot(filename)
|
|
84
|
+
async def get_screenshot_as_file(self, filename):
|
|
85
|
+
return await self.screenshot(filename)
|
|
86
86
|
|
|
87
|
-
def get_screenshot_as_png(self):
|
|
88
|
-
return self.screenshot_as_png()
|
|
87
|
+
async def get_screenshot_as_png(self):
|
|
88
|
+
return await self.screenshot_as_png()
|
|
89
89
|
|
|
90
|
-
def save_screenshot(self, filename) -> bool:
|
|
91
|
-
return self.screenshot(filename)
|
|
90
|
+
async def save_screenshot(self, filename) -> bool:
|
|
91
|
+
return await self.screenshot(filename)
|
|
@@ -11,10 +11,12 @@ class SwitchTo:
|
|
|
11
11
|
self.session = session
|
|
12
12
|
|
|
13
13
|
@property
|
|
14
|
-
def active_element(self) -> WebElement:
|
|
14
|
+
async def active_element(self) -> WebElement:
|
|
15
15
|
"""Returns the element with focus, or BODY if nothing has focus."""
|
|
16
|
-
self.session.wait_for_navigation_to_complete()
|
|
17
|
-
elem = self.session.evaluate_js_function(
|
|
16
|
+
await self.session.wait_for_navigation_to_complete()
|
|
17
|
+
elem = await self.session.evaluate_js_function(
|
|
18
|
+
"function() { return document.activeElement; }", include_frame=False
|
|
19
|
+
)
|
|
18
20
|
return WebElement(self.session, elem)
|
|
19
21
|
|
|
20
22
|
@property
|
|
@@ -22,11 +24,11 @@ class SwitchTo:
|
|
|
22
24
|
"""Switches focus to an alert on the page."""
|
|
23
25
|
return Alert(self.session)
|
|
24
26
|
|
|
25
|
-
def default_content(self):
|
|
27
|
+
async def default_content(self):
|
|
26
28
|
"""Switch focus to the default frame."""
|
|
27
|
-
self.session.switch_to_browsing_context("")
|
|
29
|
+
await self.session.switch_to_browsing_context("")
|
|
28
30
|
|
|
29
|
-
def frame(self, frame_reference):
|
|
31
|
+
async def frame(self, frame_reference):
|
|
30
32
|
"""
|
|
31
33
|
Switches focus to the specified frame, by index, name, or web element.
|
|
32
34
|
:param frame_reference: The name of the window to switch to, an integer representing the index,
|
|
@@ -35,32 +37,34 @@ class SwitchTo:
|
|
|
35
37
|
if isinstance(frame_reference, (int, WebElement)):
|
|
36
38
|
frame = frame_reference
|
|
37
39
|
elif isinstance(frame_reference, str):
|
|
38
|
-
elem = self.session.find_elements(By.ID, frame_reference)
|
|
40
|
+
elem = await self.session.find_elements(By.ID, frame_reference)
|
|
39
41
|
if elem is None:
|
|
40
|
-
elem = self.session.find_elements(By.NAME, frame_reference)
|
|
42
|
+
elem = await self.session.find_elements(By.NAME, frame_reference)
|
|
41
43
|
frame = WebElement(self.session, elem)
|
|
42
44
|
else:
|
|
43
45
|
raise TypeError()
|
|
44
46
|
|
|
45
|
-
self.session.wait_for_navigation_to_complete()
|
|
47
|
+
await self.session.wait_for_navigation_to_complete()
|
|
46
48
|
if isinstance(frame, int):
|
|
47
|
-
self.session.switch_to_frame(frame_ordinal=frame)
|
|
49
|
+
await self.session.switch_to_frame(frame_ordinal=frame)
|
|
48
50
|
else:
|
|
49
|
-
self.session.switch_to_frame(frame_handle=frame)
|
|
51
|
+
await self.session.switch_to_frame(frame_handle=frame)
|
|
50
52
|
|
|
51
|
-
def new_window(self, type_=""):
|
|
53
|
+
async def new_window(self, type_=""):
|
|
52
54
|
"""Switches to a new top-level browsing context."""
|
|
53
|
-
self.session.switch_to_window(self.session.create_window(type_))
|
|
55
|
+
await self.session.switch_to_window(self.session.create_window(type_))
|
|
54
56
|
|
|
55
|
-
def parent_frame(self):
|
|
57
|
+
async def parent_frame(self):
|
|
56
58
|
"""
|
|
57
59
|
Switches focus to the parent context. If the current context is the top
|
|
58
60
|
level browsing context, the context remains unchanged.
|
|
59
61
|
"""
|
|
60
|
-
self.session.wait_for_navigation_to_complete()
|
|
61
|
-
self.session.switch_to_browsing_context_frame(
|
|
62
|
-
|
|
62
|
+
await self.session.wait_for_navigation_to_complete()
|
|
63
|
+
await self.session.switch_to_browsing_context_frame(
|
|
64
|
+
self.session.top_level_handle, self.session.current_parent_handle
|
|
65
|
+
)
|
|
66
|
+
await self.session.switch_to_browsing_context(self.session.current_parent_handle)
|
|
63
67
|
|
|
64
|
-
def window(self, window_name):
|
|
68
|
+
async def window(self, window_name):
|
|
65
69
|
"""Switches focus to the specified window."""
|
|
66
|
-
self.session.switch_to_window(window_name)
|
|
70
|
+
await self.session.switch_to_window(window_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pymobiledevice3
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Pure python3 implementation for working with iDevices (iPhone, etc...)
|
|
5
5
|
Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
6
6
|
Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
@@ -8,7 +8,7 @@ misc/understanding_idevice_protocol_layers.md,sha256=8tEqRXWOUPoxOJLZVh7C7H9JGCh
|
|
|
8
8
|
misc/usbmux_sniff.sh,sha256=iWtbucOEQ9_UEFXk9x-2VNt48Jg5zrPsnUbZ_LfZxwA,212
|
|
9
9
|
pymobiledevice3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
pymobiledevice3/__main__.py,sha256=hpLgWH1Pmwkf1pX-JvYkfJUkphpEb4YhoRV3qQUwbOs,12718
|
|
11
|
-
pymobiledevice3/_version.py,sha256=
|
|
11
|
+
pymobiledevice3/_version.py,sha256=oi6TX3BV_lJKewictnXlp6Z_C5gyJqyHQKAhpLK1dSk,704
|
|
12
12
|
pymobiledevice3/bonjour.py,sha256=y1Zd-__GnvK2ShxmvqFpNfi5NGF6PEWGcuKp8mJVFNA,13419
|
|
13
13
|
pymobiledevice3/ca.py,sha256=5_Y4F-zDFX_KeDL-M_TRCKKyrRRb9h1lBE8MGTWv91o,10606
|
|
14
14
|
pymobiledevice3/common.py,sha256=FZzF0BQYV5fCEUPbLo6jbt2Ig9s5YwR8AvX_iR124Ew,329
|
|
@@ -47,7 +47,7 @@ pymobiledevice3/cli/provision.py,sha256=SofHAYdmxb54n9KSRyPKol6jOMUXN1hBACr2VBQr
|
|
|
47
47
|
pymobiledevice3/cli/remote.py,sha256=xkIVR4bu1Vdpw-sswH1b-pekBM6rV6AS7YUeYQU5UyY,12375
|
|
48
48
|
pymobiledevice3/cli/restore.py,sha256=xwiUIofoyCMxDSgRq4bndAn5GNUq1P-RcC446M_6I7Y,8085
|
|
49
49
|
pymobiledevice3/cli/springboard.py,sha256=hVoLqLU_gHxXa6q17ar61lc2ovmWejeu-rvxQpHXWD0,3094
|
|
50
|
-
pymobiledevice3/cli/syslog.py,sha256
|
|
50
|
+
pymobiledevice3/cli/syslog.py,sha256=-1qdNTMj_eRynv2-fbjOXOtxuftTznv_xkLERV-wjK8,8097
|
|
51
51
|
pymobiledevice3/cli/usbmux.py,sha256=Bx-5OSxEbHBhLeYaRt9LvZzp3RIazn49Q86pFi-EtpQ,2354
|
|
52
52
|
pymobiledevice3/cli/version.py,sha256=N7UY328WNR6FpQ2w7aACyL74XQxkRmi53WV5SVlCgCo,345
|
|
53
53
|
pymobiledevice3/cli/webinspector.py,sha256=dUsaaZZBV2OQPaYCj8C809ElO0O-G-NSSLvj7x26L94,16705
|
|
@@ -121,7 +121,7 @@ pymobiledevice3/services/mobile_config.py,sha256=2UmdqYNikznxI6bA2lkyIWS3NcHg3pT
|
|
|
121
121
|
pymobiledevice3/services/mobile_image_mounter.py,sha256=PZEN9O7XtLW9VH1qNTJ19zo_tFZhX68bTX0O-Uy9sck,15034
|
|
122
122
|
pymobiledevice3/services/mobilebackup2.py,sha256=M2sVY-vXl6f25QFom-z5bUkeTdA4Twbiw1tH-4Tb79M,18303
|
|
123
123
|
pymobiledevice3/services/notification_proxy.py,sha256=mk4kxLRi6aDTXKOazgldliZG4q0bME7jBcxPyJsSpDw,2125
|
|
124
|
-
pymobiledevice3/services/os_trace.py,sha256=
|
|
124
|
+
pymobiledevice3/services/os_trace.py,sha256=nTODlyWvb10fpqWHDU3m7i9sADIMF0ezfyo9Ql2BZa8,7422
|
|
125
125
|
pymobiledevice3/services/pcapd.py,sha256=Gd6xN9eBHnLIQ5M2LM-y4Z-eCquxVEnSKuyBECwZlRs,11960
|
|
126
126
|
pymobiledevice3/services/power_assertion.py,sha256=hh-9tpPbNctAegsV0IYE3ilikT-o4t758-y3u0Td9wM,1212
|
|
127
127
|
pymobiledevice3/services/preboard.py,sha256=QJ1miS0e2lY9y4sS4GxsMZh-uxKDeDi6upgPTyqTpfs,894
|
|
@@ -153,23 +153,23 @@ pymobiledevice3/services/dvt/instruments/screenshot.py,sha256=JKz8UFWTkroMTIEnXB
|
|
|
153
153
|
pymobiledevice3/services/dvt/instruments/sysmontap.py,sha256=Tscf05j2xNfTKcYsBL1KEXHkrs0I1sS7YAKt-AtlcFU,1594
|
|
154
154
|
pymobiledevice3/services/dvt/testmanaged/xcuitest.py,sha256=nv3wtZi5INXGanIzun-5HLAGccXeOAEDKk8HiMeVFqA,12267
|
|
155
155
|
pymobiledevice3/services/web_protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
156
|
-
pymobiledevice3/services/web_protocol/alert.py,sha256=
|
|
156
|
+
pymobiledevice3/services/web_protocol/alert.py,sha256=yN_P-S2XnqIDGRGdpRgdEOBWkqa5P0hcby8W7N7i_I4,878
|
|
157
157
|
pymobiledevice3/services/web_protocol/automation_session.py,sha256=I3fnHYn1njczBk_5kKMNga7KZruLLhgHVAAaW-z824U,15051
|
|
158
158
|
pymobiledevice3/services/web_protocol/cdp_screencast.py,sha256=zCTKYXaly1v4DODooTZHZDp5qyeXiQ0JkYxMrh2SeCs,5908
|
|
159
159
|
pymobiledevice3/services/web_protocol/cdp_server.py,sha256=NwwtrBco9iOynJaoXTNM9lamNYZ-t7pLvU1vswKwKsU,2554
|
|
160
160
|
pymobiledevice3/services/web_protocol/cdp_target.py,sha256=dtJ5I59Q--yZ9_0dwDm7BMV4_tbTDiZaqLFWxSlYaxM,32393
|
|
161
|
-
pymobiledevice3/services/web_protocol/driver.py,sha256=
|
|
162
|
-
pymobiledevice3/services/web_protocol/element.py,sha256=
|
|
161
|
+
pymobiledevice3/services/web_protocol/driver.py,sha256=opdQwObQkDE5rh0m4pmfSGEKsVmLZCXg3ow5q7NHGcU,7996
|
|
162
|
+
pymobiledevice3/services/web_protocol/element.py,sha256=YROMv_Q4hjj9pnvcMEzG8rK9wU4usjmGChq9KmGBdpI,8858
|
|
163
163
|
pymobiledevice3/services/web_protocol/inspector_session.py,sha256=ep4YWu9Pm9IQfkRZ8AYVUCWDV1-BPRz0DQHKTGwj-JE,10625
|
|
164
|
-
pymobiledevice3/services/web_protocol/selenium_api.py,sha256=
|
|
164
|
+
pymobiledevice3/services/web_protocol/selenium_api.py,sha256=RmiY260usm7Pa45IQLzx2jO0kC8r0VnxKM8SHJ3-Y_s,3079
|
|
165
165
|
pymobiledevice3/services/web_protocol/session_protocol.py,sha256=CMqFeIjsse0qkFqh8va_AJDkybjurtIjALLSUo7BfR4,1981
|
|
166
|
-
pymobiledevice3/services/web_protocol/switch_to.py,sha256=
|
|
166
|
+
pymobiledevice3/services/web_protocol/switch_to.py,sha256=TCdVrMfsvd18o-vZ0owVrEFYeoGbwF3jZ1iDaPslV9U,2944
|
|
167
167
|
pymobiledevice3/tunneld/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
168
168
|
pymobiledevice3/tunneld/api.py,sha256=Lwl1OdhPTgX6Zqezy8T4dEcXRfaEPwyGNClioTx3fUc,2338
|
|
169
169
|
pymobiledevice3/tunneld/server.py,sha256=dMEZAv_X-76l0vSalpq4x0IVkbE-MNGR77T-u1TiHuE,25752
|
|
170
|
-
pymobiledevice3-6.
|
|
171
|
-
pymobiledevice3-6.
|
|
172
|
-
pymobiledevice3-6.
|
|
173
|
-
pymobiledevice3-6.
|
|
174
|
-
pymobiledevice3-6.
|
|
175
|
-
pymobiledevice3-6.
|
|
170
|
+
pymobiledevice3-6.1.0.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
171
|
+
pymobiledevice3-6.1.0.dist-info/METADATA,sha256=Kc1aB01LI303p-FzJbxI_232-MeLu_CM-ZMla141-eU,17416
|
|
172
|
+
pymobiledevice3-6.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
173
|
+
pymobiledevice3-6.1.0.dist-info/entry_points.txt,sha256=jJMlOanHlVwUxcY__JwvKeWPrvBJr_wJyEq4oHIZNKE,66
|
|
174
|
+
pymobiledevice3-6.1.0.dist-info/top_level.txt,sha256=MjZoRqcWPOh5banG-BbDOnKEfsS3kCxqV9cv-nzyg2Q,21
|
|
175
|
+
pymobiledevice3-6.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|