pymobiledevice3 4.14.6__py3-none-any.whl → 7.0.6__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.
- misc/plist_sniffer.py +15 -15
- misc/remotexpc_sniffer.py +29 -28
- misc/understanding_idevice_protocol_layers.md +15 -10
- pymobiledevice3/__main__.py +317 -127
- pymobiledevice3/_version.py +22 -4
- pymobiledevice3/bonjour.py +358 -113
- pymobiledevice3/ca.py +253 -16
- pymobiledevice3/cli/activation.py +31 -23
- pymobiledevice3/cli/afc.py +49 -40
- pymobiledevice3/cli/amfi.py +16 -21
- pymobiledevice3/cli/apps.py +87 -42
- pymobiledevice3/cli/backup.py +160 -90
- pymobiledevice3/cli/bonjour.py +44 -40
- pymobiledevice3/cli/cli_common.py +204 -198
- pymobiledevice3/cli/companion_proxy.py +14 -14
- pymobiledevice3/cli/crash.py +105 -56
- pymobiledevice3/cli/developer/__init__.py +62 -0
- pymobiledevice3/cli/developer/accessibility/__init__.py +65 -0
- pymobiledevice3/cli/developer/accessibility/settings.py +43 -0
- pymobiledevice3/cli/developer/arbitration.py +50 -0
- pymobiledevice3/cli/developer/condition.py +33 -0
- pymobiledevice3/cli/developer/core_device.py +294 -0
- pymobiledevice3/cli/developer/debugserver.py +244 -0
- pymobiledevice3/cli/developer/dvt/__init__.py +438 -0
- pymobiledevice3/cli/developer/dvt/core_profile_session.py +295 -0
- pymobiledevice3/cli/developer/dvt/simulate_location.py +56 -0
- pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +69 -0
- pymobiledevice3/cli/developer/dvt/sysmon/process.py +188 -0
- pymobiledevice3/cli/developer/fetch_symbols.py +108 -0
- pymobiledevice3/cli/developer/simulate_location.py +51 -0
- pymobiledevice3/cli/diagnostics/__init__.py +75 -0
- pymobiledevice3/cli/diagnostics/battery.py +47 -0
- pymobiledevice3/cli/idam.py +42 -0
- pymobiledevice3/cli/lockdown.py +108 -103
- pymobiledevice3/cli/mounter.py +158 -99
- pymobiledevice3/cli/notification.py +38 -26
- pymobiledevice3/cli/pcap.py +45 -24
- pymobiledevice3/cli/power_assertion.py +18 -17
- pymobiledevice3/cli/processes.py +17 -23
- pymobiledevice3/cli/profile.py +165 -109
- pymobiledevice3/cli/provision.py +35 -34
- pymobiledevice3/cli/remote.py +217 -129
- pymobiledevice3/cli/restore.py +159 -143
- pymobiledevice3/cli/springboard.py +63 -53
- pymobiledevice3/cli/syslog.py +193 -86
- pymobiledevice3/cli/usbmux.py +73 -33
- pymobiledevice3/cli/version.py +5 -7
- pymobiledevice3/cli/webinspector.py +376 -214
- pymobiledevice3/common.py +3 -1
- pymobiledevice3/exceptions.py +182 -58
- pymobiledevice3/irecv.py +52 -53
- pymobiledevice3/irecv_devices.py +1489 -464
- pymobiledevice3/lockdown.py +473 -275
- pymobiledevice3/lockdown_service_provider.py +15 -8
- pymobiledevice3/osu/os_utils.py +27 -9
- pymobiledevice3/osu/posix_util.py +34 -15
- pymobiledevice3/osu/win_util.py +14 -8
- pymobiledevice3/pair_records.py +102 -21
- pymobiledevice3/remote/common.py +8 -4
- pymobiledevice3/remote/core_device/app_service.py +94 -67
- pymobiledevice3/remote/core_device/core_device_service.py +17 -14
- pymobiledevice3/remote/core_device/device_info.py +5 -5
- pymobiledevice3/remote/core_device/diagnostics_service.py +19 -4
- pymobiledevice3/remote/core_device/file_service.py +53 -23
- pymobiledevice3/remote/remote_service_discovery.py +79 -45
- pymobiledevice3/remote/remotexpc.py +73 -44
- pymobiledevice3/remote/tunnel_service.py +442 -317
- pymobiledevice3/remote/utils.py +14 -13
- pymobiledevice3/remote/xpc_message.py +145 -125
- pymobiledevice3/resources/dsc_uuid_map.py +19 -19
- pymobiledevice3/resources/firmware_notifications.py +20 -16
- pymobiledevice3/resources/notifications.txt +144 -0
- pymobiledevice3/restore/asr.py +27 -27
- pymobiledevice3/restore/base_restore.py +110 -21
- pymobiledevice3/restore/consts.py +87 -66
- pymobiledevice3/restore/device.py +59 -12
- pymobiledevice3/restore/fdr.py +46 -48
- pymobiledevice3/restore/ftab.py +19 -19
- pymobiledevice3/restore/img4.py +163 -0
- pymobiledevice3/restore/mbn.py +587 -0
- pymobiledevice3/restore/recovery.py +151 -151
- pymobiledevice3/restore/restore.py +562 -544
- pymobiledevice3/restore/restore_options.py +131 -110
- pymobiledevice3/restore/restored_client.py +51 -31
- pymobiledevice3/restore/tss.py +385 -267
- pymobiledevice3/service_connection.py +252 -59
- pymobiledevice3/services/accessibilityaudit.py +202 -120
- pymobiledevice3/services/afc.py +962 -365
- pymobiledevice3/services/amfi.py +24 -30
- pymobiledevice3/services/companion.py +23 -19
- pymobiledevice3/services/crash_reports.py +71 -47
- pymobiledevice3/services/debugserver_applist.py +3 -3
- pymobiledevice3/services/device_arbitration.py +8 -8
- pymobiledevice3/services/device_link.py +101 -79
- pymobiledevice3/services/diagnostics.py +973 -967
- pymobiledevice3/services/dtfetchsymbols.py +8 -8
- pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
- pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
- pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
- pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
- pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
- pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +466 -384
- pymobiledevice3/services/dvt/instruments/device_info.py +20 -11
- pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
- pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
- pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
- pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
- pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
- pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
- pymobiledevice3/services/dvt/instruments/process_control.py +35 -10
- pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
- pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
- pymobiledevice3/services/dvt/testmanaged/xcuitest.py +42 -52
- pymobiledevice3/services/file_relay.py +10 -10
- pymobiledevice3/services/heartbeat.py +9 -8
- pymobiledevice3/services/house_arrest.py +16 -15
- pymobiledevice3/services/idam.py +20 -0
- pymobiledevice3/services/installation_proxy.py +173 -81
- pymobiledevice3/services/lockdown_service.py +20 -10
- pymobiledevice3/services/misagent.py +22 -19
- pymobiledevice3/services/mobile_activation.py +147 -64
- pymobiledevice3/services/mobile_config.py +331 -294
- pymobiledevice3/services/mobile_image_mounter.py +141 -113
- pymobiledevice3/services/mobilebackup2.py +203 -145
- pymobiledevice3/services/notification_proxy.py +11 -11
- pymobiledevice3/services/os_trace.py +134 -74
- pymobiledevice3/services/pcapd.py +314 -302
- pymobiledevice3/services/power_assertion.py +10 -9
- pymobiledevice3/services/preboard.py +4 -4
- pymobiledevice3/services/remote_fetch_symbols.py +21 -14
- pymobiledevice3/services/remote_server.py +176 -146
- pymobiledevice3/services/restore_service.py +16 -16
- pymobiledevice3/services/screenshot.py +15 -12
- pymobiledevice3/services/simulate_location.py +7 -7
- pymobiledevice3/services/springboard.py +15 -15
- pymobiledevice3/services/syslog.py +5 -5
- pymobiledevice3/services/web_protocol/alert.py +11 -11
- pymobiledevice3/services/web_protocol/automation_session.py +251 -239
- pymobiledevice3/services/web_protocol/cdp_screencast.py +46 -37
- pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
- pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
- pymobiledevice3/services/web_protocol/driver.py +114 -111
- pymobiledevice3/services/web_protocol/element.py +124 -111
- pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
- pymobiledevice3/services/web_protocol/selenium_api.py +49 -49
- pymobiledevice3/services/web_protocol/session_protocol.py +18 -12
- pymobiledevice3/services/web_protocol/switch_to.py +30 -27
- pymobiledevice3/services/webinspector.py +189 -155
- pymobiledevice3/tcp_forwarder.py +87 -69
- pymobiledevice3/tunneld/__init__.py +0 -0
- pymobiledevice3/tunneld/api.py +63 -0
- pymobiledevice3/tunneld/server.py +603 -0
- pymobiledevice3/usbmux.py +198 -147
- pymobiledevice3/utils.py +14 -11
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/METADATA +55 -28
- pymobiledevice3-7.0.6.dist-info/RECORD +188 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/WHEEL +1 -1
- pymobiledevice3/cli/developer.py +0 -1215
- pymobiledevice3/cli/diagnostics.py +0 -99
- pymobiledevice3/tunneld.py +0 -524
- pymobiledevice3-4.14.6.dist-info/RECORD +0 -168
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info/licenses}/LICENSE +0 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/top_level.txt +0 -0
|
@@ -1,131 +1,134 @@
|
|
|
1
|
+
import importlib.resources
|
|
1
2
|
import json
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from enum import Enum
|
|
4
|
-
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import pymobiledevice3.resources
|
|
7
|
+
|
|
8
|
+
RESOURCES = importlib.resources.files(pymobiledevice3.resources) / "webinspector"
|
|
9
|
+
FIND_NODES = (RESOURCES / "find_nodes.js").read_text()
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class By(Enum):
|
|
11
13
|
"""
|
|
12
14
|
Set of supported locator strategies.
|
|
13
15
|
"""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
|
|
17
|
+
ID = "id"
|
|
18
|
+
XPATH = "xpath"
|
|
19
|
+
LINK_TEXT = "link text"
|
|
20
|
+
PARTIAL_LINK_TEXT = "partial link text"
|
|
21
|
+
NAME = "name"
|
|
22
|
+
TAG_NAME = "tag name"
|
|
23
|
+
CLASS_NAME = "class name"
|
|
24
|
+
CSS_SELECTOR = "css selector"
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
class MouseButton(Enum):
|
|
25
|
-
NONE =
|
|
26
|
-
LEFT =
|
|
27
|
-
MIDDLE =
|
|
28
|
-
RIGHT =
|
|
28
|
+
NONE = "None"
|
|
29
|
+
LEFT = "Left"
|
|
30
|
+
MIDDLE = "Middle"
|
|
31
|
+
RIGHT = "Right"
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
class MouseInteraction(Enum):
|
|
32
|
-
MOVE =
|
|
33
|
-
DOWN =
|
|
34
|
-
UP =
|
|
35
|
-
SINGLE_CLICK =
|
|
36
|
-
DOUBLE_CLICK =
|
|
35
|
+
MOVE = "Move"
|
|
36
|
+
DOWN = "Down"
|
|
37
|
+
UP = "Up"
|
|
38
|
+
SINGLE_CLICK = "SingleClick"
|
|
39
|
+
DOUBLE_CLICK = "DoubleClick"
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
class KeyboardInteractionType(Enum):
|
|
40
|
-
KEY_PRESS =
|
|
41
|
-
KEY_RELEASE =
|
|
42
|
-
INSERT_BY_KEY =
|
|
43
|
+
KEY_PRESS = "KeyPress"
|
|
44
|
+
KEY_RELEASE = "KeyRelease"
|
|
45
|
+
INSERT_BY_KEY = "InsertByKey"
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
class KeyModifier(Enum):
|
|
46
|
-
CAPS_LOCK =
|
|
47
|
-
CONTROL =
|
|
48
|
-
SHIFT =
|
|
49
|
-
META =
|
|
50
|
-
ALT =
|
|
49
|
+
CAPS_LOCK = "CapsLock"
|
|
50
|
+
CONTROL = "Control"
|
|
51
|
+
SHIFT = "Shift"
|
|
52
|
+
META = "Meta"
|
|
53
|
+
ALT = "Alt"
|
|
51
54
|
|
|
52
55
|
|
|
53
56
|
VIRTUAL_KEYS = {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
57
|
+
"\ue001": ("Cancel", None),
|
|
58
|
+
"\ue002": ("Help", None),
|
|
59
|
+
"\ue003": ("Backspace", None),
|
|
60
|
+
"\ue004": ("Tab", None),
|
|
61
|
+
"\ue005": ("Clear", None),
|
|
62
|
+
"\ue006": ("Return", None),
|
|
63
|
+
"\ue007": ("Enter", None),
|
|
64
|
+
"\ue008": ("Shift", KeyModifier.SHIFT),
|
|
65
|
+
"\ue050": ("Shift", KeyModifier.SHIFT),
|
|
66
|
+
"\ue009": ("Control", KeyModifier.CONTROL),
|
|
67
|
+
"\ue051": ("Control", KeyModifier.CONTROL),
|
|
68
|
+
"\ue00a": ("Alternate", KeyModifier.ALT),
|
|
69
|
+
"\ue052": ("Alternate", KeyModifier.ALT),
|
|
70
|
+
"\ue00b": ("Pause", None),
|
|
71
|
+
"\ue00c": ("Escape", None),
|
|
72
|
+
"\ue00d": ("Space", None),
|
|
73
|
+
"\ue00e": ("PageUp", None),
|
|
74
|
+
"\ue054": ("PageUp", None),
|
|
75
|
+
"\ue00f": ("PageDown", None),
|
|
76
|
+
"\ue055": ("PageDown", None),
|
|
77
|
+
"\ue010": ("End", None),
|
|
78
|
+
"\ue056": ("End", None),
|
|
79
|
+
"\ue011": ("Home", None),
|
|
80
|
+
"\ue057": ("Home", None),
|
|
81
|
+
"\ue012": ("LeftArrow", None),
|
|
82
|
+
"\ue058": ("LeftArrow", None),
|
|
83
|
+
"\ue013": ("UpArrow", None),
|
|
84
|
+
"\ue059": ("UpArrow", None),
|
|
85
|
+
"\ue014": ("RightArrow", None),
|
|
86
|
+
"\ue05a": ("RightArrow", None),
|
|
87
|
+
"\ue015": ("DownArrow", None),
|
|
88
|
+
"\ue05b": ("DownArrow", None),
|
|
89
|
+
"\ue016": ("Insert", None),
|
|
90
|
+
"\ue05c": ("Insert", None),
|
|
91
|
+
"\ue017": ("Delete", None),
|
|
92
|
+
"\ue05d": ("Delete", None),
|
|
93
|
+
"\ue018": ("Semicolon", None),
|
|
94
|
+
"\ue019": ("Equals", None),
|
|
95
|
+
"\ue01a": ("NumberPad0", None),
|
|
96
|
+
"\ue01b": ("NumberPad1", None),
|
|
97
|
+
"\ue01c": ("NumberPad2", None),
|
|
98
|
+
"\ue01d": ("NumberPad3", None),
|
|
99
|
+
"\ue01e": ("NumberPad4", None),
|
|
100
|
+
"\ue01f": ("NumberPad5", None),
|
|
101
|
+
"\ue020": ("NumberPad6", None),
|
|
102
|
+
"\ue021": ("NumberPad7", None),
|
|
103
|
+
"\ue022": ("NumberPad8", None),
|
|
104
|
+
"\ue023": ("NumberPad9", None),
|
|
105
|
+
"\ue024": ("NumberPadMultiply", None),
|
|
106
|
+
"\ue025": ("NumberPadAdd", None),
|
|
107
|
+
"\ue026": ("NumberPadSeparator", None),
|
|
108
|
+
"\ue027": ("NumberPadSubtract", None),
|
|
109
|
+
"\ue028": ("NumberPadDecimal", None),
|
|
110
|
+
"\ue029": ("NumberPadDivide", None),
|
|
111
|
+
"\ue031": ("Function1", None),
|
|
112
|
+
"\ue032": ("Function2", None),
|
|
113
|
+
"\ue033": ("Function3", None),
|
|
114
|
+
"\ue034": ("Function4", None),
|
|
115
|
+
"\ue035": ("Function5", None),
|
|
116
|
+
"\ue036": ("Function6", None),
|
|
117
|
+
"\ue037": ("Function7", None),
|
|
118
|
+
"\ue038": ("Function8", None),
|
|
119
|
+
"\ue039": ("Function9", None),
|
|
120
|
+
"\ue03a": ("Function10", None),
|
|
121
|
+
"\ue03b": ("Function11", None),
|
|
122
|
+
"\ue03c": ("Function12", None),
|
|
123
|
+
"\ue03d": ("Meta", KeyModifier.META),
|
|
124
|
+
"\ue053": ("Meta", KeyModifier.META),
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
MODIFIER_TO_KEY = {
|
|
125
|
-
KeyModifier.SHIFT:
|
|
126
|
-
KeyModifier.CONTROL:
|
|
127
|
-
KeyModifier.ALT:
|
|
128
|
-
KeyModifier.META:
|
|
128
|
+
KeyModifier.SHIFT: "Shift",
|
|
129
|
+
KeyModifier.CONTROL: "Control",
|
|
130
|
+
KeyModifier.ALT: "Alternate",
|
|
131
|
+
KeyModifier.META: "Meta",
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
|
|
@@ -155,9 +158,9 @@ class AutomationSession:
|
|
|
155
158
|
:param pymobiledevice3.services.web_protocol.session_protocol.SessionProtocol protocol: Session protocol.
|
|
156
159
|
"""
|
|
157
160
|
self.protocol = protocol
|
|
158
|
-
self.top_level_handle =
|
|
159
|
-
self.current_handle =
|
|
160
|
-
self.current_parent_handle =
|
|
161
|
+
self.top_level_handle = ""
|
|
162
|
+
self.current_handle = ""
|
|
163
|
+
self.current_parent_handle = ""
|
|
161
164
|
self.implicit_wait_timeout = 0
|
|
162
165
|
self.page_load_timeout = 3000000
|
|
163
166
|
self.script_timeout = -1
|
|
@@ -166,234 +169,243 @@ class AutomationSession:
|
|
|
166
169
|
def id_(self):
|
|
167
170
|
return self.protocol.id_
|
|
168
171
|
|
|
169
|
-
def start_session(self):
|
|
170
|
-
handle = self.protocol.createBrowsingContext()[
|
|
171
|
-
self.switch_to_top_level_browsing_context(handle)
|
|
172
|
+
async def start_session(self):
|
|
173
|
+
handle = (await self.protocol.createBrowsingContext())["handle"]
|
|
174
|
+
await self.switch_to_top_level_browsing_context(handle)
|
|
172
175
|
|
|
173
|
-
def stop_session(self):
|
|
174
|
-
self.top_level_handle =
|
|
175
|
-
self.current_handle =
|
|
176
|
-
self.current_parent_handle =
|
|
177
|
-
for handle in self.get_window_handles():
|
|
178
|
-
self.protocol.closeBrowsingContext(handle=handle)
|
|
176
|
+
async def stop_session(self):
|
|
177
|
+
self.top_level_handle = ""
|
|
178
|
+
self.current_handle = ""
|
|
179
|
+
self.current_parent_handle = ""
|
|
180
|
+
for handle in await self.get_window_handles():
|
|
181
|
+
await self.protocol.closeBrowsingContext(handle=handle)
|
|
179
182
|
|
|
180
|
-
def create_window(self, type_):
|
|
183
|
+
async def create_window(self, type_):
|
|
181
184
|
type_ = type_.capitalize()
|
|
182
|
-
params = {
|
|
183
|
-
return self.protocol.createBrowsingContext(**params)[
|
|
185
|
+
params = {"presentationHint": type_} if type_ else {}
|
|
186
|
+
return (await self.protocol.createBrowsingContext(**params))["handle"]
|
|
184
187
|
|
|
185
|
-
def close_window(self):
|
|
188
|
+
async def close_window(self):
|
|
186
189
|
if not self.top_level_handle:
|
|
187
190
|
return
|
|
188
191
|
handle = self.top_level_handle
|
|
189
|
-
self.protocol.closeBrowsingContext(handle=handle)
|
|
192
|
+
await self.protocol.closeBrowsingContext(handle=handle)
|
|
190
193
|
|
|
191
|
-
def maximize_window(self):
|
|
192
|
-
self.protocol.maximizeWindowOfBrowsingContext(handle=self.top_level_handle)
|
|
194
|
+
async def maximize_window(self):
|
|
195
|
+
await self.protocol.maximizeWindowOfBrowsingContext(handle=self.top_level_handle)
|
|
193
196
|
|
|
194
|
-
def hide_window(self):
|
|
195
|
-
self.protocol.hideWindowOfBrowsingContext(handle=self.top_level_handle)
|
|
197
|
+
async def hide_window(self):
|
|
198
|
+
await self.protocol.hideWindowOfBrowsingContext(handle=self.top_level_handle)
|
|
196
199
|
|
|
197
|
-
def get_browsing_context(self):
|
|
198
|
-
return self.protocol.getBrowsingContext(handle=self.top_level_handle)[
|
|
200
|
+
async def get_browsing_context(self):
|
|
201
|
+
return (await self.protocol.getBrowsingContext(handle=self.top_level_handle))["context"]
|
|
199
202
|
|
|
200
|
-
def get_window_handles(self):
|
|
201
|
-
contexts = self.protocol.getBrowsingContexts()
|
|
202
|
-
return [c[
|
|
203
|
+
async def get_window_handles(self):
|
|
204
|
+
contexts = await self.protocol.getBrowsingContexts()
|
|
205
|
+
return [c["handle"] for c in contexts["contexts"]]
|
|
203
206
|
|
|
204
|
-
def set_window_frame(self, x=None, y=None, width=None, height=None):
|
|
207
|
+
async def set_window_frame(self, x=None, y=None, width=None, height=None):
|
|
205
208
|
params = {}
|
|
206
209
|
if x is not None and y is not None:
|
|
207
|
-
params[
|
|
210
|
+
params["origin"] = {"x": x, "y": y}
|
|
208
211
|
if width is not None and height is not None:
|
|
209
|
-
params[
|
|
210
|
-
self.protocol.setWindowFrameOfBrowsingContext(handle=self.top_level_handle, **params)
|
|
212
|
+
params["size"] = {"width": width, "height": height}
|
|
213
|
+
await self.protocol.setWindowFrameOfBrowsingContext(handle=self.top_level_handle, **params)
|
|
211
214
|
|
|
212
|
-
def add_single_cookie(self, cookie):
|
|
213
|
-
self.protocol.addSingleCookie(browsingContextHandle=self.top_level_handle, cookie=cookie)
|
|
215
|
+
async def add_single_cookie(self, cookie):
|
|
216
|
+
await self.protocol.addSingleCookie(browsingContextHandle=self.top_level_handle, cookie=cookie)
|
|
214
217
|
|
|
215
|
-
def delete_all_cookies(self):
|
|
216
|
-
self.protocol.deleteAllCookies(browsingContextHandle=self.top_level_handle)
|
|
218
|
+
async def delete_all_cookies(self):
|
|
219
|
+
await self.protocol.deleteAllCookies(browsingContextHandle=self.top_level_handle)
|
|
217
220
|
|
|
218
|
-
def delete_single_cookie(self, name):
|
|
219
|
-
self.protocol.deleteSingleCookie(browsingContextHandle=self.top_level_handle, cookieName=name)
|
|
221
|
+
async def delete_single_cookie(self, name):
|
|
222
|
+
await self.protocol.deleteSingleCookie(browsingContextHandle=self.top_level_handle, cookieName=name)
|
|
220
223
|
|
|
221
|
-
def get_all_cookies(self):
|
|
222
|
-
return self.protocol.getAllCookies(browsingContextHandle=self.top_level_handle)[
|
|
224
|
+
async def get_all_cookies(self):
|
|
225
|
+
return (await self.protocol.getAllCookies(browsingContextHandle=self.top_level_handle))["cookies"]
|
|
223
226
|
|
|
224
|
-
def execute_script(self, script, args, async_=False):
|
|
227
|
+
async def execute_script(self, script, args, async_=False):
|
|
225
228
|
parameters = {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
+
"browsingContextHandle": self.top_level_handle,
|
|
230
|
+
"function": "function(){\n" + script + "\n}",
|
|
231
|
+
"arguments": list(map(json.dumps, args)),
|
|
229
232
|
}
|
|
230
233
|
if self.current_handle:
|
|
231
|
-
parameters[
|
|
234
|
+
parameters["frameHandle"] = self.current_handle
|
|
232
235
|
if async_:
|
|
233
|
-
parameters[
|
|
236
|
+
parameters["expectsImplicitCallbackArgument"] = True
|
|
234
237
|
if self.script_timeout != -1:
|
|
235
|
-
parameters[
|
|
236
|
-
result = self.protocol.evaluateJavaScriptFunction(**parameters, wait_for_response=not async_)
|
|
238
|
+
parameters["callbackTimeout"] = self.script_timeout
|
|
239
|
+
result = await self.protocol.evaluateJavaScriptFunction(**parameters, wait_for_response=not async_)
|
|
237
240
|
if async_:
|
|
238
241
|
return result
|
|
239
242
|
else:
|
|
240
|
-
return json.loads(result[
|
|
243
|
+
return json.loads(result["result"])
|
|
241
244
|
|
|
242
|
-
def evaluate_js_function(self, function, *args, implicit_callback=False, include_frame=True):
|
|
245
|
+
async def evaluate_js_function(self, function, *args, implicit_callback=False, include_frame=True):
|
|
243
246
|
params = {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
+
"browsingContextHandle": self.top_level_handle,
|
|
248
|
+
"function": function,
|
|
249
|
+
"arguments": list(map(json.dumps, args)),
|
|
247
250
|
}
|
|
248
251
|
if include_frame and self.current_handle:
|
|
249
|
-
params[
|
|
252
|
+
params["frameHandle"] = self.current_handle
|
|
250
253
|
if implicit_callback:
|
|
251
|
-
params[
|
|
252
|
-
result = self.protocol.evaluateJavaScriptFunction(**params)
|
|
253
|
-
return json.loads(result[
|
|
254
|
+
params["expectsImplicitCallbackArgument"] = True
|
|
255
|
+
result = await self.protocol.evaluateJavaScriptFunction(**params)
|
|
256
|
+
return json.loads(result["result"])
|
|
254
257
|
|
|
255
|
-
def find_elements(self, by, value, single: bool = True, root=None):
|
|
256
|
-
self.wait_for_navigation_to_complete()
|
|
258
|
+
async def find_elements(self, by, value, single: bool = True, root=None):
|
|
259
|
+
await self.wait_for_navigation_to_complete()
|
|
257
260
|
by = by.value if isinstance(by, By) else by
|
|
258
261
|
if by == By.ID.value:
|
|
259
262
|
by = By.CSS_SELECTOR.value
|
|
260
|
-
value = '[id="
|
|
263
|
+
value = f'[id="{value}"]'
|
|
261
264
|
elif by == By.TAG_NAME.value:
|
|
262
265
|
by = By.CSS_SELECTOR.value
|
|
263
266
|
elif by == By.CLASS_NAME.value:
|
|
264
267
|
by = By.CSS_SELECTOR.value
|
|
265
|
-
value = "
|
|
268
|
+
value = f".{value}"
|
|
266
269
|
elif by == By.NAME.value:
|
|
267
270
|
by = By.CSS_SELECTOR.value
|
|
268
|
-
value = '[name="
|
|
271
|
+
value = f'[name="{value}"]'
|
|
269
272
|
|
|
270
273
|
parameters = {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
"browsingContextHandle": self.top_level_handle,
|
|
275
|
+
"function": FIND_NODES,
|
|
276
|
+
"arguments": list(map(json.dumps, [by, root, value, single, self.implicit_wait_timeout])),
|
|
277
|
+
"expectsImplicitCallbackArgument": True,
|
|
275
278
|
}
|
|
276
279
|
if self.current_handle:
|
|
277
|
-
parameters[
|
|
280
|
+
parameters["frameHandle"] = self.current_handle
|
|
278
281
|
if self.implicit_wait_timeout:
|
|
279
|
-
parameters[
|
|
280
|
-
result = json.loads(self.protocol.evaluateJavaScriptFunction(**parameters)[
|
|
282
|
+
parameters["callbackTimeout"] = self.implicit_wait_timeout + 1000
|
|
283
|
+
result = json.loads((await self.protocol.evaluateJavaScriptFunction(**parameters))["result"])
|
|
281
284
|
return result
|
|
282
285
|
|
|
283
|
-
def screenshot_as_base64(self, scroll=False, node_id=
|
|
284
|
-
params = {
|
|
286
|
+
async def screenshot_as_base64(self, scroll=False, node_id="", clip=True):
|
|
287
|
+
params = {"handle": self.top_level_handle, "clipToViewport": clip}
|
|
285
288
|
if self.current_handle:
|
|
286
|
-
params[
|
|
289
|
+
params["frameHandle"] = self.current_handle
|
|
287
290
|
if scroll:
|
|
288
|
-
params[
|
|
291
|
+
params["scrollIntoViewIfNeeded"] = True
|
|
289
292
|
if node_id:
|
|
290
|
-
params[
|
|
291
|
-
return self.protocol.takeScreenshot(**params)[
|
|
293
|
+
params["nodeHandle"] = node_id
|
|
294
|
+
return (await self.protocol.takeScreenshot(**params))["data"]
|
|
292
295
|
|
|
293
|
-
def switch_to_top_level_browsing_context(self, top_level_handle):
|
|
296
|
+
async def switch_to_top_level_browsing_context(self, top_level_handle):
|
|
294
297
|
self.top_level_handle = top_level_handle
|
|
295
|
-
self.current_handle =
|
|
296
|
-
self.current_parent_handle =
|
|
298
|
+
self.current_handle = ""
|
|
299
|
+
self.current_parent_handle = ""
|
|
297
300
|
|
|
298
|
-
def switch_to_browsing_context(self, handle):
|
|
301
|
+
async def switch_to_browsing_context(self, handle):
|
|
299
302
|
self.current_handle = handle
|
|
300
303
|
if not self.current_handle:
|
|
301
|
-
self.current_parent_handle =
|
|
304
|
+
self.current_parent_handle = ""
|
|
302
305
|
return
|
|
303
306
|
|
|
304
|
-
resp = self.protocol.resolveParentFrameHandle(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
+
resp = await self.protocol.resolveParentFrameHandle(
|
|
308
|
+
browsingContextHandle=self.top_level_handle, frameHandle=self.current_handle
|
|
309
|
+
)
|
|
310
|
+
self.current_parent_handle = resp["result"]
|
|
307
311
|
|
|
308
|
-
def switch_to_browsing_context_frame(self, context, frame):
|
|
309
|
-
self.protocol.switchToBrowsingContext(browsingContextHandle=context, frameHandle=frame)
|
|
312
|
+
async def switch_to_browsing_context_frame(self, context, frame):
|
|
313
|
+
await self.protocol.switchToBrowsingContext(browsingContextHandle=context, frameHandle=frame)
|
|
310
314
|
|
|
311
|
-
def navigate_broswing_context(self, url):
|
|
312
|
-
self.protocol.navigateBrowsingContext(
|
|
315
|
+
async def navigate_broswing_context(self, url):
|
|
316
|
+
await self.protocol.navigateBrowsingContext(
|
|
313
317
|
handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout, url=url
|
|
314
318
|
)
|
|
315
319
|
|
|
316
|
-
def go_back_in_browsing_context(self):
|
|
317
|
-
self.protocol.goBackInBrowsingContext(
|
|
320
|
+
async def go_back_in_browsing_context(self):
|
|
321
|
+
await self.protocol.goBackInBrowsingContext(
|
|
318
322
|
handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout
|
|
319
323
|
)
|
|
320
324
|
|
|
321
|
-
def go_forward_in_browsing_context(self):
|
|
322
|
-
self.protocol.goForwardInBrowsingContext(
|
|
325
|
+
async def go_forward_in_browsing_context(self):
|
|
326
|
+
await self.protocol.goForwardInBrowsingContext(
|
|
323
327
|
handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout
|
|
324
328
|
)
|
|
325
329
|
|
|
326
|
-
def reload_browsing_context(self):
|
|
327
|
-
self.protocol.reloadBrowsingContext(
|
|
328
|
-
handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout
|
|
329
|
-
)
|
|
330
|
+
async def reload_browsing_context(self):
|
|
331
|
+
await self.protocol.reloadBrowsingContext(handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout)
|
|
330
332
|
|
|
331
|
-
def switch_to_frame(self, frame_ordinal=None, frame_handle=None):
|
|
332
|
-
params = {
|
|
333
|
+
async def switch_to_frame(self, frame_ordinal=None, frame_handle=None):
|
|
334
|
+
params = {"browsingContextHandle": self.top_level_handle}
|
|
333
335
|
if self.current_handle:
|
|
334
|
-
params[
|
|
336
|
+
params["frameHandle"] = self.current_handle
|
|
335
337
|
if frame_ordinal is not None:
|
|
336
|
-
params[
|
|
338
|
+
params["ordinal"] = frame_ordinal
|
|
337
339
|
elif frame_handle is not None:
|
|
338
|
-
params[
|
|
339
|
-
resp = self.protocol.resolveChildFrameHandle(**params)[
|
|
340
|
-
self.switch_to_browsing_context_frame(self.top_level_handle, resp)
|
|
341
|
-
self.switch_to_browsing_context(resp)
|
|
340
|
+
params["nodeHandle"] = frame_handle.node_id
|
|
341
|
+
resp = (await self.protocol.resolveChildFrameHandle(**params))["result"]
|
|
342
|
+
await self.switch_to_browsing_context_frame(self.top_level_handle, resp)
|
|
343
|
+
await self.switch_to_browsing_context(resp)
|
|
342
344
|
|
|
343
|
-
def switch_to_window(self, handle):
|
|
344
|
-
self.switch_to_browsing_context_frame(handle,
|
|
345
|
-
self.switch_to_top_level_browsing_context(handle)
|
|
345
|
+
async def switch_to_window(self, handle):
|
|
346
|
+
await self.switch_to_browsing_context_frame(handle, "")
|
|
347
|
+
await self.switch_to_top_level_browsing_context(handle)
|
|
346
348
|
|
|
347
|
-
def perform_keyboard_interactions(self, interactions):
|
|
349
|
+
async def perform_keyboard_interactions(self, interactions):
|
|
348
350
|
for interaction in interactions:
|
|
349
|
-
type_ = interaction[
|
|
350
|
-
interaction[
|
|
351
|
-
self.protocol.performKeyboardInteractions(handle=self.top_level_handle, interactions=interactions)
|
|
351
|
+
type_ = interaction["type"]
|
|
352
|
+
interaction["type"] = type_.value if isinstance(type_, KeyboardInteractionType) else type_
|
|
353
|
+
await self.protocol.performKeyboardInteractions(handle=self.top_level_handle, interactions=interactions)
|
|
352
354
|
|
|
353
|
-
def perform_mouse_interaction(self, x, y, button: MouseButton, interaction: MouseInteraction, modifiers=None):
|
|
355
|
+
async def perform_mouse_interaction(self, x, y, button: MouseButton, interaction: MouseInteraction, modifiers=None):
|
|
354
356
|
modifiers = [] if modifiers is None else modifiers
|
|
355
|
-
self.protocol.performMouseInteraction(
|
|
356
|
-
|
|
357
|
+
await self.protocol.performMouseInteraction(
|
|
358
|
+
handle=self.top_level_handle,
|
|
359
|
+
position={"x": x, "y": y},
|
|
360
|
+
button=button.value,
|
|
361
|
+
interaction=interaction.value,
|
|
362
|
+
modifiers=modifiers,
|
|
363
|
+
)
|
|
357
364
|
|
|
358
|
-
def perform_interaction_sequence(self, sources, steps):
|
|
365
|
+
async def perform_interaction_sequence(self, sources, steps):
|
|
359
366
|
params = {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
367
|
+
"handle": self.top_level_handle,
|
|
368
|
+
"inputSources": sources,
|
|
369
|
+
"steps": steps,
|
|
363
370
|
}
|
|
364
371
|
if self.current_handle:
|
|
365
|
-
params[
|
|
366
|
-
self.protocol.performInteractionSequence(**params)
|
|
372
|
+
params["frameHandle"] = self.current_handle
|
|
373
|
+
await self.protocol.performInteractionSequence(**params)
|
|
367
374
|
|
|
368
|
-
def wait_for_navigation_to_complete(self):
|
|
369
|
-
params = {
|
|
375
|
+
async def wait_for_navigation_to_complete(self):
|
|
376
|
+
params = {"browsingContextHandle": self.top_level_handle, "pageLoadTimeout": self.page_load_timeout}
|
|
370
377
|
if self.current_handle:
|
|
371
|
-
params[
|
|
372
|
-
self.protocol.waitForNavigationToComplete(**params)
|
|
378
|
+
params["frameHandle"] = self.current_handle
|
|
379
|
+
await self.protocol.waitForNavigationToComplete(**params)
|
|
373
380
|
|
|
374
|
-
def accept_current_javascript_dialog(self):
|
|
375
|
-
self.protocol.acceptCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
|
|
381
|
+
async def accept_current_javascript_dialog(self):
|
|
382
|
+
await self.protocol.acceptCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
|
|
376
383
|
|
|
377
|
-
def dismiss_current_javascript_dialog(self):
|
|
378
|
-
self.protocol.dismissCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
|
|
384
|
+
async def dismiss_current_javascript_dialog(self):
|
|
385
|
+
await self.protocol.dismissCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
|
|
379
386
|
|
|
380
|
-
def set_user_input_for_current_javascript_prompt(self, user_input):
|
|
381
|
-
self.protocol.setUserInputForCurrentJavaScriptPrompt(
|
|
387
|
+
async def set_user_input_for_current_javascript_prompt(self, user_input):
|
|
388
|
+
await self.protocol.setUserInputForCurrentJavaScriptPrompt(
|
|
382
389
|
browsingContextHandle=self.top_level_handle, userInput=user_input
|
|
383
390
|
)
|
|
384
391
|
|
|
385
|
-
def message_of_current_javascript_dialog(self):
|
|
386
|
-
return self.protocol.messageOfCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)[
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
392
|
+
async def message_of_current_javascript_dialog(self):
|
|
393
|
+
return (await self.protocol.messageOfCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle))[
|
|
394
|
+
"message"
|
|
395
|
+
]
|
|
396
|
+
|
|
397
|
+
async def compute_element_layout(self, node_id, scroll_if_needed, coordinate_system):
|
|
398
|
+
return await self.protocol.computeElementLayout(
|
|
399
|
+
browsingContextHandle=self.top_level_handle,
|
|
400
|
+
nodeHandle=node_id,
|
|
401
|
+
scrollIntoViewIfNeeded=scroll_if_needed,
|
|
402
|
+
coordinateSystem=coordinate_system,
|
|
403
|
+
frameHandle="" if self.current_handle is None else self.current_handle,
|
|
393
404
|
)
|
|
394
405
|
|
|
395
|
-
def select_option_element(self, node_id):
|
|
396
|
-
self.protocol.selectOptionElement(
|
|
397
|
-
browsingContextHandle=self.top_level_handle,
|
|
398
|
-
|
|
406
|
+
async def select_option_element(self, node_id):
|
|
407
|
+
await self.protocol.selectOptionElement(
|
|
408
|
+
browsingContextHandle=self.top_level_handle,
|
|
409
|
+
nodeHandle=node_id,
|
|
410
|
+
frameHandle="" if self.current_handle is None else self.current_handle,
|
|
399
411
|
)
|