pymobiledevice3 5.3.2__py3-none-any.whl → 6.0.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.
@@ -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 = '5.3.2'
32
- __version_tuple__ = version_tuple = (5, 3, 2)
31
+ __version__ = version = '6.0.0'
32
+ __version_tuple__ = version_tuple = (6, 0, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -2,14 +2,16 @@ import asyncio
2
2
  import logging
3
3
  import re
4
4
  from abc import ABC, abstractmethod
5
- from collections.abc import Iterable
5
+ from asyncio import CancelledError
6
+ from collections.abc import AsyncIterator, Iterable
6
7
  from contextlib import asynccontextmanager
7
8
  from functools import update_wrapper
8
- from typing import Optional
9
+ from typing import Optional, Union
9
10
 
10
11
  import click
11
12
  import inquirer3
12
13
  import IPython
14
+ import nest_asyncio
13
15
  import uvicorn
14
16
  from inquirer3.themes import GreenPassion
15
17
  from prompt_toolkit import HTML, PromptSession
@@ -161,13 +163,22 @@ def reload_pages(inspector: WebinspectorService):
161
163
  inspector.flush_input(2)
162
164
 
163
165
 
164
- def create_webinspector_and_launch_app(lockdown: LockdownClient, timeout: float, app: str):
166
+ async def create_webinspector_and_launch_app(lockdown: LockdownClient, timeout: float, app: str):
165
167
  inspector = WebinspectorService(lockdown=lockdown)
166
- inspector.connect(timeout)
167
- application = inspector.open_app(app)
168
+ await inspector.connect(timeout)
169
+ application = await inspector.open_app(app)
168
170
  return inspector, application
169
171
 
170
172
 
173
+ async def opened_tabs_task(service_provider: LockdownClient, timeout):
174
+ inspector = WebinspectorService(lockdown=service_provider)
175
+ await inspector.connect(timeout)
176
+ application_pages = await inspector.get_open_application_pages(timeout=timeout)
177
+ for application_page in application_pages:
178
+ print(application_page)
179
+ await inspector.close()
180
+
181
+
171
182
  @webinspector.command(cls=Command)
172
183
  @click.option("-t", "--timeout", default=3, show_default=True, type=float)
173
184
  @catch_errors
@@ -181,12 +192,21 @@ def opened_tabs(service_provider: LockdownClient, timeout):
181
192
 
182
193
  iOS < 18: Settings -> Safari -> Advanced -> Web Inspector
183
194
  """
184
- inspector = WebinspectorService(lockdown=service_provider)
185
- inspector.connect(timeout)
186
- application_pages = inspector.get_open_application_pages(timeout=timeout)
187
- for application_page in application_pages:
188
- print(application_page)
189
- inspector.close()
195
+ asyncio.run(opened_tabs_task(service_provider, timeout), debug=True)
196
+
197
+
198
+ @catch_errors
199
+ async def launch_task(service_provider: LockdownClient, url, timeout):
200
+ inspector, safari = await create_webinspector_and_launch_app(service_provider, timeout, SAFARI)
201
+ session = await inspector.automation_session(safari)
202
+ driver = WebDriver(session)
203
+ print("Starting session")
204
+ await driver.start_session()
205
+ print("Getting URL")
206
+ await driver.get(url)
207
+ OSUTILS.wait_return()
208
+ await session.stop_session()
209
+ await inspector.close()
190
210
 
191
211
 
192
212
  @webinspector.command(cls=Command)
@@ -207,16 +227,7 @@ def launch(service_provider: LockdownClient, url, timeout):
207
227
  Settings -> Safari -> Advanced -> Remote Automation
208
228
 
209
229
  """
210
- inspector, safari = create_webinspector_and_launch_app(service_provider, timeout, SAFARI)
211
- session = inspector.automation_session(safari)
212
- driver = WebDriver(session)
213
- print("Starting session")
214
- driver.start_session()
215
- print("Getting URL")
216
- driver.get(url)
217
- OSUTILS.wait_return()
218
- session.stop_session()
219
- inspector.close()
230
+ asyncio.run(launch_task(service_provider, url, timeout), debug=True)
220
231
 
221
232
 
222
233
  SHELL_USAGE = """
@@ -240,9 +251,28 @@ driver.add_cookie(
240
251
  """
241
252
 
242
253
 
254
+ @catch_errors
255
+ async def shell_task(service_provider: LockdownClient, timeout):
256
+ inspector, safari = await create_webinspector_and_launch_app(service_provider, timeout, SAFARI)
257
+ session = await inspector.automation_session(safari)
258
+ driver = WebDriver(session)
259
+ try:
260
+ nest_asyncio.apply()
261
+ IPython.embed(
262
+ header=highlight(SHELL_USAGE, lexers.PythonLexer(), formatters.Terminal256Formatter(style="native")),
263
+ user_ns={
264
+ "driver": driver,
265
+ "Cookie": Cookie,
266
+ "By": By,
267
+ },
268
+ )
269
+ finally:
270
+ await session.stop_session()
271
+ await inspector.close()
272
+
273
+
243
274
  @webinspector.command(cls=Command)
244
275
  @click.option("-t", "--timeout", default=3, show_default=True, type=float)
245
- @catch_errors
246
276
  def shell(service_provider: LockdownClient, timeout):
247
277
  """
248
278
  Create an IPython shell for interacting with a WebView.
@@ -256,21 +286,7 @@ def shell(service_provider: LockdownClient, timeout):
256
286
  Settings -> Safari -> Advanced -> Web Inspector
257
287
  Settings -> Safari -> Advanced -> Remote Automation
258
288
  """
259
- inspector, safari = create_webinspector_and_launch_app(service_provider, timeout, SAFARI)
260
- session = inspector.automation_session(safari)
261
- driver = WebDriver(session)
262
- try:
263
- IPython.embed(
264
- header=highlight(SHELL_USAGE, lexers.PythonLexer(), formatters.Terminal256Formatter(style="native")),
265
- user_ns={
266
- "driver": driver,
267
- "Cookie": Cookie,
268
- "By": By,
269
- },
270
- )
271
- finally:
272
- session.stop_session()
273
- inspector.close()
289
+ asyncio.run(shell_task(service_provider, timeout), debug=True)
274
290
 
275
291
 
276
292
  @webinspector.command(cls=Command)
@@ -333,42 +349,56 @@ def cdp(service_provider: LockdownClient, host, port):
333
349
  )
334
350
 
335
351
 
336
- def get_js_completions(jsshell: "JsShell", obj: str, prefix: str) -> list[Completion]:
352
+ async def get_js_completions(jsshell: "JsShell", obj: str, prefix: str) -> AsyncIterator[Completion]:
337
353
  if obj in JS_RESERVED_WORDS:
338
- return []
354
+ return
339
355
 
340
- completions = []
341
356
  try:
342
- for key in asyncio.get_running_loop().run_until_complete(
343
- jsshell.evaluate_expression(SCRIPT.format(object=obj), return_by_value=True)
344
- ):
357
+ for key in await jsshell.evaluate_expression(SCRIPT.format(object=obj), return_by_value=True):
345
358
  if not key.startswith(prefix):
346
359
  continue
347
- completions.append(Completion(key.removeprefix(prefix), display=key))
348
- except Exception:
360
+ yield Completion(key.removeprefix(prefix), display=key)
361
+ except (Exception, CancelledError):
349
362
  # ignore every possible exception
350
363
  pass
351
- return completions
352
364
 
353
365
 
354
366
  class JsShellCompleter(Completer):
355
367
  def __init__(self, jsshell: "JsShell"):
356
368
  self.jsshell = jsshell
357
369
 
358
- def get_completions(self, document: Document, complete_event: CompleteEvent) -> Iterable[Completion]:
370
+ def get_completions_async(
371
+ self,
372
+ document: Document,
373
+ complete_event: CompleteEvent,
374
+ ) -> Union[AsyncIterator[Completion], Iterable[Completion]]:
375
+ # Build the JS expression we want to inspect
359
376
  text = f"globalThis.{document.text_before_cursor}"
360
- text = re.findall("[a-zA-Z_][a-zA-Z_0-9.]+", text)
361
- if len(text) == 0:
362
- return []
363
- text = text[-1]
377
+
378
+ # Extract identifiers / dotted paths
379
+ matches = re.findall(r"[a-zA-Z_][a-zA-Z_0-9.]+", text)
380
+ if not matches:
381
+ # async *generator*: just end, don't return a list
382
+ return iter(())
383
+
384
+ text = matches[-1]
364
385
  if "." in text:
365
386
  js_obj, prefix = text.rsplit(".", 1)
366
387
  else:
367
388
  js_obj = text
368
389
  prefix = ""
369
390
 
391
+ # This should return an iterable of Completion (or something we can wrap)
370
392
  return get_js_completions(self.jsshell, js_obj, prefix)
371
393
 
394
+ # Optional: keep sync completions empty so PTK knows we prefer async
395
+ def get_completions(
396
+ self,
397
+ document: Document,
398
+ complete_event: CompleteEvent,
399
+ ) -> Iterable[Completion]:
400
+ return []
401
+
372
402
 
373
403
  class JsShell(ABC):
374
404
  def __init__(self) -> None:
@@ -436,7 +466,7 @@ class AutomationJsShell(JsShell):
436
466
  inspector, application = create_webinspector_and_launch_app(lockdown, timeout, SAFARI)
437
467
  automation_session = inspector.automation_session(application)
438
468
  driver = WebDriver(automation_session)
439
- driver.start_session()
469
+ await driver.start_session()
440
470
  try:
441
471
  yield cls(driver)
442
472
  finally:
@@ -444,10 +474,10 @@ class AutomationJsShell(JsShell):
444
474
  inspector.close()
445
475
 
446
476
  async def evaluate_expression(self, exp: str, return_by_value: bool = False):
447
- return self.driver.execute_script(f"return {exp}")
477
+ return await self.driver.execute_script(f"return {exp}")
448
478
 
449
479
  async def navigate(self, url: str):
450
- self.driver.get(url)
480
+ await self.driver.get(url)
451
481
 
452
482
 
453
483
  class InspectorJsShell(JsShell):
@@ -459,10 +489,10 @@ class InspectorJsShell(JsShell):
459
489
  @asynccontextmanager
460
490
  async def create(cls, lockdown: LockdownClient, timeout: float, open_safari: bool) -> "InspectorJsShell":
461
491
  inspector = WebinspectorService(lockdown=lockdown)
462
- inspector.connect(timeout)
492
+ await inspector.connect(timeout)
463
493
  if open_safari:
464
- _ = inspector.open_app(SAFARI)
465
- application_page = cls.query_page(inspector, bundle_identifier=SAFARI if open_safari else None)
494
+ _ = await inspector.open_app(SAFARI)
495
+ application_page = await cls.query_page(inspector, bundle_identifier=SAFARI if open_safari else None)
466
496
  if application_page is None:
467
497
  raise click.exceptions.Exit()
468
498
 
@@ -473,7 +503,7 @@ class InspectorJsShell(JsShell):
473
503
  try:
474
504
  yield cls(inspector_session)
475
505
  finally:
476
- inspector.close()
506
+ await inspector.close()
477
507
 
478
508
  async def evaluate_expression(self, exp: str, return_by_value: bool = False):
479
509
  return await self.inspector_session.runtime_evaluate(exp, return_by_value=return_by_value)
@@ -482,10 +512,10 @@ class InspectorJsShell(JsShell):
482
512
  await self.inspector_session.navigate_to_url(url)
483
513
 
484
514
  @staticmethod
485
- def query_page(
515
+ async def query_page(
486
516
  inspector: WebinspectorService, bundle_identifier: Optional[str] = None
487
517
  ) -> Optional[ApplicationPage]:
488
- available_pages = inspector.get_open_application_pages(timeout=1)
518
+ available_pages = await inspector.get_open_application_pages(timeout=1)
489
519
  if bundle_identifier is not None:
490
520
  available_pages = [
491
521
  application_page
@@ -167,62 +167,62 @@ class AutomationSession:
167
167
  def id_(self):
168
168
  return self.protocol.id_
169
169
 
170
- def start_session(self):
171
- handle = self.protocol.createBrowsingContext()["handle"]
172
- self.switch_to_top_level_browsing_context(handle)
170
+ async def start_session(self):
171
+ handle = (await self.protocol.createBrowsingContext())["handle"]
172
+ await self.switch_to_top_level_browsing_context(handle)
173
173
 
174
- def stop_session(self):
174
+ async def stop_session(self):
175
175
  self.top_level_handle = ""
176
176
  self.current_handle = ""
177
177
  self.current_parent_handle = ""
178
- for handle in self.get_window_handles():
179
- self.protocol.closeBrowsingContext(handle=handle)
178
+ for handle in await self.get_window_handles():
179
+ await self.protocol.closeBrowsingContext(handle=handle)
180
180
 
181
- def create_window(self, type_):
181
+ async def create_window(self, type_):
182
182
  type_ = type_.capitalize()
183
183
  params = {"presentationHint": type_} if type_ else {}
184
- return self.protocol.createBrowsingContext(**params)["handle"]
184
+ return (await self.protocol.createBrowsingContext(**params))["handle"]
185
185
 
186
- def close_window(self):
186
+ async def close_window(self):
187
187
  if not self.top_level_handle:
188
188
  return
189
189
  handle = self.top_level_handle
190
- self.protocol.closeBrowsingContext(handle=handle)
190
+ await self.protocol.closeBrowsingContext(handle=handle)
191
191
 
192
- def maximize_window(self):
193
- self.protocol.maximizeWindowOfBrowsingContext(handle=self.top_level_handle)
192
+ async def maximize_window(self):
193
+ await self.protocol.maximizeWindowOfBrowsingContext(handle=self.top_level_handle)
194
194
 
195
- def hide_window(self):
196
- self.protocol.hideWindowOfBrowsingContext(handle=self.top_level_handle)
195
+ async def hide_window(self):
196
+ await self.protocol.hideWindowOfBrowsingContext(handle=self.top_level_handle)
197
197
 
198
- def get_browsing_context(self):
199
- return self.protocol.getBrowsingContext(handle=self.top_level_handle)["context"]
198
+ async def get_browsing_context(self):
199
+ return (await self.protocol.getBrowsingContext(handle=self.top_level_handle))["context"]
200
200
 
201
- def get_window_handles(self):
202
- contexts = self.protocol.getBrowsingContexts()
201
+ async def get_window_handles(self):
202
+ contexts = await self.protocol.getBrowsingContexts()
203
203
  return [c["handle"] for c in contexts["contexts"]]
204
204
 
205
- def set_window_frame(self, x=None, y=None, width=None, height=None):
205
+ async def set_window_frame(self, x=None, y=None, width=None, height=None):
206
206
  params = {}
207
207
  if x is not None and y is not None:
208
208
  params["origin"] = {"x": x, "y": y}
209
209
  if width is not None and height is not None:
210
210
  params["size"] = {"width": width, "height": height}
211
- self.protocol.setWindowFrameOfBrowsingContext(handle=self.top_level_handle, **params)
211
+ await self.protocol.setWindowFrameOfBrowsingContext(handle=self.top_level_handle, **params)
212
212
 
213
- def add_single_cookie(self, cookie):
214
- self.protocol.addSingleCookie(browsingContextHandle=self.top_level_handle, cookie=cookie)
213
+ async def add_single_cookie(self, cookie):
214
+ await self.protocol.addSingleCookie(browsingContextHandle=self.top_level_handle, cookie=cookie)
215
215
 
216
- def delete_all_cookies(self):
217
- self.protocol.deleteAllCookies(browsingContextHandle=self.top_level_handle)
216
+ async def delete_all_cookies(self):
217
+ await self.protocol.deleteAllCookies(browsingContextHandle=self.top_level_handle)
218
218
 
219
- def delete_single_cookie(self, name):
220
- self.protocol.deleteSingleCookie(browsingContextHandle=self.top_level_handle, cookieName=name)
219
+ async def delete_single_cookie(self, name):
220
+ await self.protocol.deleteSingleCookie(browsingContextHandle=self.top_level_handle, cookieName=name)
221
221
 
222
- def get_all_cookies(self):
223
- return self.protocol.getAllCookies(browsingContextHandle=self.top_level_handle)["cookies"]
222
+ async def get_all_cookies(self):
223
+ return (await self.protocol.getAllCookies(browsingContextHandle=self.top_level_handle))["cookies"]
224
224
 
225
- def execute_script(self, script, args, async_=False):
225
+ async def execute_script(self, script, args, async_=False):
226
226
  parameters = {
227
227
  "browsingContextHandle": self.top_level_handle,
228
228
  "function": "function(){\n" + script + "\n}",
@@ -234,13 +234,13 @@ class AutomationSession:
234
234
  parameters["expectsImplicitCallbackArgument"] = True
235
235
  if self.script_timeout != -1:
236
236
  parameters["callbackTimeout"] = self.script_timeout
237
- result = self.protocol.evaluateJavaScriptFunction(**parameters, wait_for_response=not async_)
237
+ result = await self.protocol.evaluateJavaScriptFunction(**parameters, wait_for_response=not async_)
238
238
  if async_:
239
239
  return result
240
240
  else:
241
241
  return json.loads(result["result"])
242
242
 
243
- def evaluate_js_function(self, function, *args, implicit_callback=False, include_frame=True):
243
+ async def evaluate_js_function(self, function, *args, implicit_callback=False, include_frame=True):
244
244
  params = {
245
245
  "browsingContextHandle": self.top_level_handle,
246
246
  "function": function,
@@ -250,11 +250,11 @@ class AutomationSession:
250
250
  params["frameHandle"] = self.current_handle
251
251
  if implicit_callback:
252
252
  params["expectsImplicitCallbackArgument"] = True
253
- result = self.protocol.evaluateJavaScriptFunction(**params)
253
+ result = await self.protocol.evaluateJavaScriptFunction(**params)
254
254
  return json.loads(result["result"])
255
255
 
256
- def find_elements(self, by, value, single: bool = True, root=None):
257
- self.wait_for_navigation_to_complete()
256
+ async def find_elements(self, by, value, single: bool = True, root=None):
257
+ await self.wait_for_navigation_to_complete()
258
258
  by = by.value if isinstance(by, By) else by
259
259
  if by == By.ID.value:
260
260
  by = By.CSS_SELECTOR.value
@@ -278,10 +278,10 @@ class AutomationSession:
278
278
  parameters["frameHandle"] = self.current_handle
279
279
  if self.implicit_wait_timeout:
280
280
  parameters["callbackTimeout"] = self.implicit_wait_timeout + 1000
281
- result = json.loads(self.protocol.evaluateJavaScriptFunction(**parameters)["result"])
281
+ result = json.loads((await self.protocol.evaluateJavaScriptFunction(**parameters))["result"])
282
282
  return result
283
283
 
284
- def screenshot_as_base64(self, scroll=False, node_id="", clip=True):
284
+ async def screenshot_as_base64(self, scroll=False, node_id="", clip=True):
285
285
  params = {"handle": self.top_level_handle, "clipToViewport": clip}
286
286
  if self.current_handle:
287
287
  params["frameHandle"] = self.current_handle
@@ -289,42 +289,46 @@ class AutomationSession:
289
289
  params["scrollIntoViewIfNeeded"] = True
290
290
  if node_id:
291
291
  params["nodeHandle"] = node_id
292
- return self.protocol.takeScreenshot(**params)["data"]
292
+ return (await self.protocol.takeScreenshot(**params))["data"]
293
293
 
294
- def switch_to_top_level_browsing_context(self, top_level_handle):
294
+ async def switch_to_top_level_browsing_context(self, top_level_handle):
295
295
  self.top_level_handle = top_level_handle
296
296
  self.current_handle = ""
297
297
  self.current_parent_handle = ""
298
298
 
299
- def switch_to_browsing_context(self, handle):
299
+ async def switch_to_browsing_context(self, handle):
300
300
  self.current_handle = handle
301
301
  if not self.current_handle:
302
302
  self.current_parent_handle = ""
303
303
  return
304
304
 
305
- resp = self.protocol.resolveParentFrameHandle(
305
+ resp = await self.protocol.resolveParentFrameHandle(
306
306
  browsingContextHandle=self.top_level_handle, frameHandle=self.current_handle
307
307
  )
308
308
  self.current_parent_handle = resp["result"]
309
309
 
310
- def switch_to_browsing_context_frame(self, context, frame):
311
- self.protocol.switchToBrowsingContext(browsingContextHandle=context, frameHandle=frame)
310
+ async def switch_to_browsing_context_frame(self, context, frame):
311
+ await self.protocol.switchToBrowsingContext(browsingContextHandle=context, frameHandle=frame)
312
312
 
313
- def navigate_broswing_context(self, url):
314
- self.protocol.navigateBrowsingContext(
313
+ async def navigate_broswing_context(self, url):
314
+ await self.protocol.navigateBrowsingContext(
315
315
  handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout, url=url
316
316
  )
317
317
 
318
- def go_back_in_browsing_context(self):
319
- self.protocol.goBackInBrowsingContext(handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout)
318
+ async def go_back_in_browsing_context(self):
319
+ await self.protocol.goBackInBrowsingContext(
320
+ handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout
321
+ )
320
322
 
321
- def go_forward_in_browsing_context(self):
322
- self.protocol.goForwardInBrowsingContext(handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout)
323
+ async def go_forward_in_browsing_context(self):
324
+ await self.protocol.goForwardInBrowsingContext(
325
+ handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout
326
+ )
323
327
 
324
- def reload_browsing_context(self):
325
- self.protocol.reloadBrowsingContext(handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout)
328
+ async def reload_browsing_context(self):
329
+ await self.protocol.reloadBrowsingContext(handle=self.top_level_handle, pageLoadTimeout=self.page_load_timeout)
326
330
 
327
- def switch_to_frame(self, frame_ordinal=None, frame_handle=None):
331
+ async def switch_to_frame(self, frame_ordinal=None, frame_handle=None):
328
332
  params = {"browsingContextHandle": self.top_level_handle}
329
333
  if self.current_handle:
330
334
  params["frameHandle"] = self.current_handle
@@ -332,23 +336,23 @@ class AutomationSession:
332
336
  params["ordinal"] = frame_ordinal
333
337
  elif frame_handle is not None:
334
338
  params["nodeHandle"] = frame_handle.node_id
335
- resp = self.protocol.resolveChildFrameHandle(**params)["result"]
336
- self.switch_to_browsing_context_frame(self.top_level_handle, resp)
337
- self.switch_to_browsing_context(resp)
339
+ resp = (await self.protocol.resolveChildFrameHandle(**params))["result"]
340
+ await self.switch_to_browsing_context_frame(self.top_level_handle, resp)
341
+ await self.switch_to_browsing_context(resp)
338
342
 
339
- def switch_to_window(self, handle):
340
- self.switch_to_browsing_context_frame(handle, "")
341
- self.switch_to_top_level_browsing_context(handle)
343
+ async def switch_to_window(self, handle):
344
+ await self.switch_to_browsing_context_frame(handle, "")
345
+ await self.switch_to_top_level_browsing_context(handle)
342
346
 
343
- def perform_keyboard_interactions(self, interactions):
347
+ async def perform_keyboard_interactions(self, interactions):
344
348
  for interaction in interactions:
345
349
  type_ = interaction["type"]
346
350
  interaction["type"] = type_.value if isinstance(type_, KeyboardInteractionType) else type_
347
- self.protocol.performKeyboardInteractions(handle=self.top_level_handle, interactions=interactions)
351
+ await self.protocol.performKeyboardInteractions(handle=self.top_level_handle, interactions=interactions)
348
352
 
349
- def perform_mouse_interaction(self, x, y, button: MouseButton, interaction: MouseInteraction, modifiers=None):
353
+ async def perform_mouse_interaction(self, x, y, button: MouseButton, interaction: MouseInteraction, modifiers=None):
350
354
  modifiers = [] if modifiers is None else modifiers
351
- self.protocol.performMouseInteraction(
355
+ await self.protocol.performMouseInteraction(
352
356
  handle=self.top_level_handle,
353
357
  position={"x": x, "y": y},
354
358
  button=button.value,
@@ -356,7 +360,7 @@ class AutomationSession:
356
360
  modifiers=modifiers,
357
361
  )
358
362
 
359
- def perform_interaction_sequence(self, sources, steps):
363
+ async def perform_interaction_sequence(self, sources, steps):
360
364
  params = {
361
365
  "handle": self.top_level_handle,
362
366
  "inputSources": sources,
@@ -364,30 +368,32 @@ class AutomationSession:
364
368
  }
365
369
  if self.current_handle:
366
370
  params["frameHandle"] = self.current_handle
367
- self.protocol.performInteractionSequence(**params)
371
+ await self.protocol.performInteractionSequence(**params)
368
372
 
369
- def wait_for_navigation_to_complete(self):
373
+ async def wait_for_navigation_to_complete(self):
370
374
  params = {"browsingContextHandle": self.top_level_handle, "pageLoadTimeout": self.page_load_timeout}
371
375
  if self.current_handle:
372
376
  params["frameHandle"] = self.current_handle
373
- self.protocol.waitForNavigationToComplete(**params)
377
+ await self.protocol.waitForNavigationToComplete(**params)
374
378
 
375
- def accept_current_javascript_dialog(self):
376
- self.protocol.acceptCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
379
+ async def accept_current_javascript_dialog(self):
380
+ await self.protocol.acceptCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
377
381
 
378
- def dismiss_current_javascript_dialog(self):
379
- self.protocol.dismissCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
382
+ async def dismiss_current_javascript_dialog(self):
383
+ await self.protocol.dismissCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)
380
384
 
381
- def set_user_input_for_current_javascript_prompt(self, user_input):
382
- self.protocol.setUserInputForCurrentJavaScriptPrompt(
385
+ async def set_user_input_for_current_javascript_prompt(self, user_input):
386
+ await self.protocol.setUserInputForCurrentJavaScriptPrompt(
383
387
  browsingContextHandle=self.top_level_handle, userInput=user_input
384
388
  )
385
389
 
386
- def message_of_current_javascript_dialog(self):
387
- return self.protocol.messageOfCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle)["message"]
390
+ async def message_of_current_javascript_dialog(self):
391
+ return (await self.protocol.messageOfCurrentJavaScriptDialog(browsingContextHandle=self.top_level_handle))[
392
+ "message"
393
+ ]
388
394
 
389
- def compute_element_layout(self, node_id, scroll_if_needed, coordinate_system):
390
- return self.protocol.computeElementLayout(
395
+ async def compute_element_layout(self, node_id, scroll_if_needed, coordinate_system):
396
+ return await self.protocol.computeElementLayout(
391
397
  browsingContextHandle=self.top_level_handle,
392
398
  nodeHandle=node_id,
393
399
  scrollIntoViewIfNeeded=scroll_if_needed,
@@ -395,8 +401,8 @@ class AutomationSession:
395
401
  frameHandle="" if self.current_handle is None else self.current_handle,
396
402
  )
397
403
 
398
- def select_option_element(self, node_id):
399
- self.protocol.selectOptionElement(
404
+ async def select_option_element(self, node_id):
405
+ await self.protocol.selectOptionElement(
400
406
  browsingContextHandle=self.top_level_handle,
401
407
  nodeHandle=node_id,
402
408
  frameHandle="" if self.current_handle is None else self.current_handle,