pydoll-python 2.15.0__tar.gz → 2.16.0__tar.gz

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.
Files changed (91) hide show
  1. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/PKG-INFO +24 -1
  2. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/README.md +23 -0
  3. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/chromium/base.py +3 -3
  4. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/tab.py +25 -4
  5. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/constants.py +25 -0
  6. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/elements/mixins/find_elements_mixin.py +5 -5
  7. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/elements/web_element.py +24 -0
  8. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pyproject.toml +1 -1
  9. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/LICENSE +0 -0
  10. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/__init__.py +0 -0
  11. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/__init__.py +0 -0
  12. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/chromium/__init__.py +0 -0
  13. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/chromium/chrome.py +0 -0
  14. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/chromium/edge.py +0 -0
  15. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/interfaces.py +0 -0
  16. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/managers/__init__.py +0 -0
  17. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/managers/browser_options_manager.py +0 -0
  18. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/managers/browser_process_manager.py +0 -0
  19. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/managers/proxy_manager.py +0 -0
  20. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/managers/temp_dir_manager.py +0 -0
  21. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/options.py +0 -0
  22. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/requests/__init__.py +0 -0
  23. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/requests/request.py +0 -0
  24. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/browser/requests/response.py +0 -0
  25. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/__init__.py +0 -0
  26. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/browser_commands.py +0 -0
  27. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/dom_commands.py +0 -0
  28. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/fetch_commands.py +0 -0
  29. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/input_commands.py +0 -0
  30. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/network_commands.py +0 -0
  31. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/page_commands.py +0 -0
  32. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/runtime_commands.py +0 -0
  33. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/storage_commands.py +0 -0
  34. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/commands/target_commands.py +0 -0
  35. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/connection/__init__.py +0 -0
  36. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/connection/connection_handler.py +0 -0
  37. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/connection/managers/__init__.py +0 -0
  38. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/connection/managers/commands_manager.py +0 -0
  39. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/connection/managers/events_manager.py +0 -0
  40. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/decorators.py +0 -0
  41. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/elements/__init__.py +0 -0
  42. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/elements/mixins/__init__.py +0 -0
  43. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/exceptions.py +0 -0
  44. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/interactions/__init__.py +0 -0
  45. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/interactions/iframe.py +0 -0
  46. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/interactions/keyboard.py +0 -0
  47. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/interactions/scroll.py +0 -0
  48. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/__init__.py +0 -0
  49. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/base.py +0 -0
  50. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/browser/__init__.py +0 -0
  51. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/browser/events.py +0 -0
  52. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/browser/methods.py +0 -0
  53. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/browser/types.py +0 -0
  54. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/debugger/types.py +0 -0
  55. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/dom/__init__.py +0 -0
  56. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/dom/events.py +0 -0
  57. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/dom/methods.py +0 -0
  58. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/dom/types.py +0 -0
  59. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/emulation/types.py +0 -0
  60. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/fetch/__init__.py +0 -0
  61. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/fetch/events.py +0 -0
  62. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/fetch/methods.py +0 -0
  63. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/fetch/types.py +0 -0
  64. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/input/__init__.py +0 -0
  65. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/input/events.py +0 -0
  66. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/input/methods.py +0 -0
  67. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/input/types.py +0 -0
  68. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/io/types.py +0 -0
  69. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/network/__init__.py +0 -0
  70. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/network/events.py +0 -0
  71. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/network/methods.py +0 -0
  72. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/network/types.py +0 -0
  73. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/page/__init__.py +0 -0
  74. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/page/events.py +0 -0
  75. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/page/methods.py +0 -0
  76. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/page/types.py +0 -0
  77. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/runtime/__init__.py +0 -0
  78. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/runtime/events.py +0 -0
  79. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/runtime/methods.py +0 -0
  80. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/runtime/types.py +0 -0
  81. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/security/types.py +0 -0
  82. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/storage/__init__.py +0 -0
  83. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/storage/events.py +0 -0
  84. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/storage/methods.py +0 -0
  85. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/storage/types.py +0 -0
  86. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/target/__init__.py +0 -0
  87. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/target/events.py +0 -0
  88. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/target/methods.py +0 -0
  89. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/protocol/target/types.py +0 -0
  90. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/py.typed +0 -0
  91. {pydoll_python-2.15.0 → pydoll_python-2.16.0}/pydoll/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydoll-python
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: Pydoll is a library for automating chromium-based browsers without a WebDriver, offering realistic interactions.
5
5
  License-File: LICENSE
6
6
  Author: Thalison Fernandes
@@ -44,6 +44,29 @@ Forget broken `webdrivers`, compatibility issues, or being blocked by `navigator
44
44
 
45
45
  It's designed for modern scraping, combining an **intuitive high-level API** (for productivity) with **deep-level control** over the network and browser behavior (for evasion), allowing you to bypass complex anti-bot defenses.
46
46
 
47
+ ### Sponsors
48
+
49
+ <a href="https://www.thordata.com/?ls=github&lk=pydoll">
50
+ <img alt="Thordata" src="public/images/thordata.png" />
51
+ </a>
52
+
53
+ Pydoll is proudly sponsored by **[Thordata](https://www.thordata.com/?ls=github&lk=pydoll)**: a residential proxy network built for serious web scraping and automation. With **190+ real residential and ISP locations**, fully encrypted connections, and infrastructure optimized for high-performance workflows, Thordata is an excellent choice for scaling your Pydoll automations.
54
+
55
+ **[Sign up through our link](https://www.thordata.com/?ls=github&lk=pydoll)** to support the project and get **1GB free** to get started.
56
+
57
+ ---
58
+
59
+
60
+ <a href="https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc">
61
+ <img alt="CapSolver" src="public/images/capsolver.jpeg" />
62
+ </a>
63
+
64
+ Pydoll excels at behavioral evasion, but it doesn't solve captchas. That's where **[CapSolver](https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc)** comes in. An AI-powered service that handles reCAPTCHA, Cloudflare challenges, and more, seamlessly integrating with your automation workflows.
65
+
66
+ **[Register with our invite code](https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc)** and use code **PYDOLL** to get an extra **6% balance bonus**.
67
+
68
+ ---
69
+
47
70
  ### The Pydoll Philosophy
48
71
 
49
72
  * **Stealth-by-Design:** Pydoll is built for evasion. Our [human-like interactions](https://pydoll.tech/docs/features/automation/human-interactions/) simulate real user clicks, typing, and scrolling to pass behavioral analysis, while granular [Browser Preferences](https://pydoll.tech/docs/features/configuration/browser-preferences/) control lets you patch your browser fingerprint.
@@ -24,6 +24,29 @@ Forget broken `webdrivers`, compatibility issues, or being blocked by `navigator
24
24
 
25
25
  It's designed for modern scraping, combining an **intuitive high-level API** (for productivity) with **deep-level control** over the network and browser behavior (for evasion), allowing you to bypass complex anti-bot defenses.
26
26
 
27
+ ### Sponsors
28
+
29
+ <a href="https://www.thordata.com/?ls=github&lk=pydoll">
30
+ <img alt="Thordata" src="public/images/thordata.png" />
31
+ </a>
32
+
33
+ Pydoll is proudly sponsored by **[Thordata](https://www.thordata.com/?ls=github&lk=pydoll)**: a residential proxy network built for serious web scraping and automation. With **190+ real residential and ISP locations**, fully encrypted connections, and infrastructure optimized for high-performance workflows, Thordata is an excellent choice for scaling your Pydoll automations.
34
+
35
+ **[Sign up through our link](https://www.thordata.com/?ls=github&lk=pydoll)** to support the project and get **1GB free** to get started.
36
+
37
+ ---
38
+
39
+
40
+ <a href="https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc">
41
+ <img alt="CapSolver" src="public/images/capsolver.jpeg" />
42
+ </a>
43
+
44
+ Pydoll excels at behavioral evasion, but it doesn't solve captchas. That's where **[CapSolver](https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc)** comes in. An AI-powered service that handles reCAPTCHA, Cloudflare challenges, and more, seamlessly integrating with your automation workflows.
45
+
46
+ **[Register with our invite code](https://dashboard.capsolver.com/passport/register?inviteCode=WPhTbOsbXEpc)** and use code **PYDOLL** to get an extra **6% balance bonus**.
47
+
48
+ ---
49
+
27
50
  ### The Pydoll Philosophy
28
51
 
29
52
  * **Stealth-by-Design:** Pydoll is built for evasion. Our [human-like interactions](https://pydoll.tech/docs/features/automation/human-interactions/) simulate real user clicks, typing, and scrolling to pass behavioral analysis, while granular [Browser Preferences](https://pydoll.tech/docs/features/configuration/browser-preferences/) control lets you patch your browser fingerprint.
@@ -906,9 +906,9 @@ class Browser(ABC): # noqa: PLR0904
906
906
  def _validate_ws_address(ws_address: str):
907
907
  """Validate WebSocket address."""
908
908
  min_slashes = 4
909
- if not ws_address.startswith('ws://'):
910
- logger.error('Invalid WebSocket address: missing ws:// prefix')
911
- raise InvalidWebSocketAddress('WebSocket address must start with ws://')
909
+ if not ws_address.startswith(('ws://', 'wss://')):
910
+ logger.error('Invalid WebSocket address: missing ws:// or wss:// prefix')
911
+ raise InvalidWebSocketAddress('WebSocket address must start with ws:// or wss://')
912
912
  if len(ws_address.split('/')) < min_slashes:
913
913
  logger.error('Invalid WebSocket address: not enough slashes')
914
914
  raise InvalidWebSocketAddress(
@@ -34,7 +34,7 @@ from pydoll.commands import (
34
34
  StorageCommands,
35
35
  )
36
36
  from pydoll.connection import ConnectionHandler
37
- from pydoll.constants import By
37
+ from pydoll.constants import By, PageLoadState
38
38
  from pydoll.elements.mixins import FindElementsMixin
39
39
  from pydoll.exceptions import (
40
40
  DownloadTimeout,
@@ -104,6 +104,8 @@ class Tab(FindElementsMixin):
104
104
  like Cloudflare bypass.
105
105
  """
106
106
 
107
+ _READY_STATE_ORDER = (PageLoadState.LOADING, PageLoadState.INTERACTIVE, PageLoadState.COMPLETE)
108
+
107
109
  def __init__(
108
110
  self,
109
111
  browser: Browser,
@@ -231,6 +233,14 @@ class Tab(FindElementsMixin):
231
233
  )
232
234
  return response['result']['result']['value']
233
235
 
236
+ @property
237
+ async def title(self) -> str:
238
+ """Get current page title."""
239
+ response: EvaluateResponse = await self._execute_command(
240
+ RuntimeCommands.evaluate('document.title')
241
+ )
242
+ return response['result']['result'].get('value', '')
243
+
234
244
  async def enable_page_events(self):
235
245
  """Enable CDP Page domain events (load, navigation, dialogs, etc.)."""
236
246
  logger.debug('Enabling Page events')
@@ -1409,17 +1419,28 @@ class Tab(FindElementsMixin):
1409
1419
  """
1410
1420
  Wait for page to finish loading.
1411
1421
 
1422
+ Waits until ``document.readyState`` reaches **at least** the level
1423
+ configured in ``browser.options.page_load_state``. For example, when
1424
+ the target state is ``interactive``, both ``"interactive"`` and
1425
+ ``"complete"`` satisfy the condition — this prevents an infinite
1426
+ polling loop when the page transitions past ``interactive`` before the
1427
+ first check runs.
1428
+
1412
1429
  Raises:
1413
- asyncio.TimeoutError: If page doesn't load within timeout.
1430
+ WaitElementTimeout: If page doesn't load within *timeout* seconds.
1414
1431
  """
1432
+ target_state = self._browser.options.page_load_state.value
1433
+ target_index = self._READY_STATE_ORDER.index(target_state)
1415
1434
  start_time = asyncio.get_event_loop().time()
1416
1435
  logger.debug(f'Waiting for page load (timeout={timeout}s)')
1417
1436
  while True:
1418
1437
  response: EvaluateResponse = await self._execute_command(
1419
1438
  RuntimeCommands.evaluate(expression='document.readyState')
1420
1439
  )
1421
- if response['result']['result']['value'] == self._browser.options.page_load_state.value:
1422
- logger.debug(f'Page load state reached: {self._browser.options.page_load_state}')
1440
+ current_state = response['result']['result']['value']
1441
+ current_index = self._READY_STATE_ORDER.index(current_state)
1442
+ if current_index >= target_index:
1443
+ logger.debug(f'Page load state reached: {current_state} (target: {target_state})')
1423
1444
  break
1424
1445
  if asyncio.get_event_loop().time() - start_time > timeout:
1425
1446
  raise WaitElementTimeout('Page load timed out')
@@ -13,6 +13,7 @@ class By(str, Enum):
13
13
  class PageLoadState(str, Enum):
14
14
  COMPLETE = 'complete'
15
15
  INTERACTIVE = 'interactive'
16
+ LOADING = 'loading'
16
17
 
17
18
 
18
19
  class ScrollPosition(str, Enum):
@@ -436,6 +437,30 @@ new Promise((resolve) => {{
436
437
  }
437
438
  """
438
439
 
440
+ CLEAR_INPUT = """
441
+ function() {
442
+ const el = this;
443
+
444
+ // Standard input/textarea
445
+ if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {
446
+ el.value = '';
447
+ el.dispatchEvent(new Event('input', { bubbles: true }));
448
+ el.dispatchEvent(new Event('change', { bubbles: true }));
449
+ return true;
450
+ }
451
+
452
+ // ContentEditable elements
453
+ if (el.isContentEditable) {
454
+ el.focus();
455
+ el.innerHTML = '';
456
+ el.dispatchEvent(new Event('input', { bubbles: true }));
457
+ return true;
458
+ }
459
+
460
+ return false;
461
+ }
462
+ """
463
+
439
464
  IS_EDITABLE = """
440
465
  function() {
441
466
  const el = this;
@@ -463,9 +463,9 @@ class FindElementsMixin:
463
463
  )
464
464
  response: list[str] = []
465
465
  for query in query_response['result']['result']:
466
- query_value = query.get('value', {})
467
- if query_value and query_value['type'] == 'object':
468
- response.append(query_value['objectId'])
466
+ if not (query['name'].isdigit() and 'objectId' in query['value']):
467
+ continue
468
+ response.append(query['value']['objectId'])
469
469
 
470
470
  elements = []
471
471
  for object_id in response:
@@ -646,11 +646,11 @@ class FindElementsMixin:
646
646
  async def _execute_command(
647
647
  self, command: Command[T_CommandParams, T_CommandResponse]
648
648
  ) -> T_CommandResponse:
649
- """Execute CDP command via resolved handler (60s timeout)."""
649
+ """Execute CDP command via resolved handler (10s timeout)."""
650
650
  handler, session_id = self._resolve_routing()
651
651
  if session_id:
652
652
  command['sessionId'] = session_id
653
- return await handler.execute_command(command, timeout=60)
653
+ return await handler.execute_command(command, timeout=10)
654
654
 
655
655
  def _get_find_element_command(
656
656
  self,
@@ -123,6 +123,11 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
123
123
  self._iframe_resolver = IFrameContextResolver(self)
124
124
  return self._iframe_resolver
125
125
 
126
+ @property
127
+ def attributes(self) -> dict[str, str]:
128
+ """Read-only copy of the element's cached attributes."""
129
+ return dict(self._attributes)
130
+
126
131
  @property
127
132
  def value(self) -> Optional[str]:
128
133
  """Element's value attribute (for form elements)."""
@@ -530,6 +535,25 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
530
535
  await asyncio.sleep(hold_time)
531
536
  await self._connection_handler.execute_command(release_command)
532
537
 
538
+ async def clear(self):
539
+ """
540
+ Clear the current value of the element.
541
+
542
+ Supports standard inputs, textareas, and contenteditable elements.
543
+ Dispatches ``input`` and ``change`` events so frameworks detect the update.
544
+
545
+ Raises:
546
+ ElementNotInteractable: If the element does not accept text input.
547
+ """
548
+ logger.info('Clearing element value')
549
+ result = await self.execute_script(Scripts.CLEAR_INPUT, return_by_value=True)
550
+ success = result['result'].get('result', {}).get('value', False)
551
+ if not success:
552
+ logger.error('Element does not accept text input')
553
+ raise ElementNotInteractable('Element does not accept text input')
554
+ if self._attributes.get('tag_name', '').lower() in {'input', 'textarea'}:
555
+ self._attributes['value'] = ''
556
+
533
557
  async def insert_text(self, text: str):
534
558
  """
535
559
  Insert text into element using JavaScript.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pydoll-python"
3
- version = "2.15.0"
3
+ version = "2.16.0"
4
4
  description = "Pydoll is a library for automating chromium-based browsers without a WebDriver, offering realistic interactions."
5
5
  authors = ["Thalison Fernandes <thalissfernandes99@gmail.com>"]
6
6
  readme = "README.md"
File without changes