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