pydoll-python 2.6.0__tar.gz → 2.7.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 (86) hide show
  1. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/PKG-INFO +38 -4
  2. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/README.md +37 -3
  3. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/chromium/chrome.py +1 -0
  4. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/tab.py +10 -2
  5. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/constants.py +33 -5
  6. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/elements/web_element.py +56 -10
  7. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/browser/methods.py +14 -14
  8. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/dom/methods.py +22 -22
  9. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/fetch/methods.py +7 -7
  10. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/input/methods.py +16 -14
  11. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/network/methods.py +18 -18
  12. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/page/methods.py +42 -38
  13. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/runtime/methods.py +14 -12
  14. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/storage/methods.py +38 -26
  15. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/target/methods.py +9 -9
  16. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/utils.py +1 -1
  17. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pyproject.toml +1 -1
  18. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/LICENSE +0 -0
  19. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/__init__.py +0 -0
  20. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/__init__.py +0 -0
  21. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/chromium/__init__.py +0 -0
  22. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/chromium/base.py +0 -0
  23. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/chromium/edge.py +0 -0
  24. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/interfaces.py +0 -0
  25. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/managers/__init__.py +0 -0
  26. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/managers/browser_options_manager.py +0 -0
  27. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/managers/browser_process_manager.py +0 -0
  28. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/managers/proxy_manager.py +0 -0
  29. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/managers/temp_dir_manager.py +0 -0
  30. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/options.py +0 -0
  31. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/requests/__init__.py +0 -0
  32. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/requests/request.py +0 -0
  33. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/browser/requests/response.py +0 -0
  34. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/__init__.py +0 -0
  35. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/browser_commands.py +0 -0
  36. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/dom_commands.py +0 -0
  37. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/fetch_commands.py +0 -0
  38. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/input_commands.py +0 -0
  39. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/network_commands.py +0 -0
  40. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/page_commands.py +0 -0
  41. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/runtime_commands.py +0 -0
  42. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/storage_commands.py +0 -0
  43. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/commands/target_commands.py +0 -0
  44. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/connection/__init__.py +0 -0
  45. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/connection/connection_handler.py +0 -0
  46. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/connection/managers/__init__.py +0 -0
  47. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/connection/managers/commands_manager.py +0 -0
  48. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/connection/managers/events_manager.py +0 -0
  49. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/elements/__init__.py +0 -0
  50. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/elements/mixins/__init__.py +0 -0
  51. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/elements/mixins/find_elements_mixin.py +0 -0
  52. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/exceptions.py +0 -0
  53. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/__init__.py +0 -0
  54. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/base.py +0 -0
  55. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/browser/__init__.py +0 -0
  56. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/browser/events.py +0 -0
  57. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/browser/types.py +0 -0
  58. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/debugger/types.py +0 -0
  59. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/dom/__init__.py +0 -0
  60. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/dom/events.py +0 -0
  61. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/dom/types.py +0 -0
  62. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/emulation/types.py +0 -0
  63. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/fetch/__init__.py +0 -0
  64. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/fetch/events.py +0 -0
  65. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/fetch/types.py +0 -0
  66. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/input/__init__.py +0 -0
  67. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/input/events.py +0 -0
  68. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/input/types.py +0 -0
  69. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/io/types.py +0 -0
  70. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/network/__init__.py +0 -0
  71. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/network/events.py +0 -0
  72. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/network/types.py +0 -0
  73. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/page/__init__.py +0 -0
  74. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/page/events.py +0 -0
  75. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/page/types.py +0 -0
  76. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/runtime/__init__.py +0 -0
  77. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/runtime/events.py +0 -0
  78. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/runtime/types.py +0 -0
  79. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/security/types.py +0 -0
  80. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/storage/__init__.py +0 -0
  81. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/storage/events.py +0 -0
  82. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/storage/types.py +0 -0
  83. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/target/__init__.py +0 -0
  84. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/target/events.py +0 -0
  85. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/protocol/target/types.py +0 -0
  86. {pydoll_python-2.6.0 → pydoll_python-2.7.0}/pydoll/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pydoll-python
3
- Version: 2.6.0
3
+ Version: 2.7.0
4
4
  Summary: Pydoll is a library for automating chromium-based browsers without a WebDriver, offering realistic interactions.
5
5
  Author: Thalison Fernandes
6
6
  Author-email: thalissfernandes99@gmail.com
@@ -26,9 +26,9 @@ Description-Content-Type: text/markdown
26
26
  <a href="https://codecov.io/gh/autoscrape-labs/pydoll" >
27
27
  <img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
28
28
  </a>
29
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
30
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
31
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/mypy.yml/badge.svg" alt="MyPy CI">
29
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
30
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
31
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/mypy.yml/badge.svg" alt="MyPy CI">
32
32
  <img src="https://img.shields.io/badge/python-%3E%3D3.10-blue" alt="Python >= 3.10">
33
33
  <a href="https://deepwiki.com/autoscrape-labs/pydoll"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
34
34
  </p>
@@ -65,6 +65,40 @@ We believe that powerful automation shouldn't require you to become an expert in
65
65
 
66
66
  ## What's New
67
67
 
68
+ ### WebElement: state waiting and new public APIs
69
+
70
+ - New `wait_until(...)` on `WebElement` to await element states with minimal code:
71
+
72
+ ```python
73
+ # Wait until it becomes visible OR the timeout expires
74
+ await element.wait_until(is_visible=True, timeout=5)
75
+
76
+ # Wait until it becomes interactable (visible, on top, receiving pointer events)
77
+ await element.wait_until(is_interactable=True, timeout=10)
78
+ ```
79
+
80
+ - Methods now public on `WebElement`:
81
+ - `is_visible()`
82
+ - Checks that the element has a visible area (> 0), isn’t hidden by CSS and is in the viewport (after `scroll_into_view()` when needed). Useful pre-check before interactions.
83
+ - `is_interactable()`
84
+ - “Click-ready” state: combines visibility, enabledness and pointer-event hit testing. Ideal for robust flows that avoid lost clicks.
85
+ - `is_on_top()`
86
+ - Verifies the element is the top hit-test target at the intended click point, avoiding overlays.
87
+ - `execute_script(script: str, return_by_value: bool = False)`
88
+ - Executes JavaScript in the element’s own context (where `this` is the element). Great for fine-tuning and quick inspections.
89
+
90
+ ```python
91
+ # Visually outline the element via JS
92
+ await element.execute_script("this.style.outline='2px solid #22d3ee'")
93
+
94
+ # Confirm states
95
+ visible = await element.is_visible()
96
+ interactable = await element.is_interactable()
97
+ on_top = await element.is_on_top()
98
+ ```
99
+
100
+ These additions simplify waiting and state validation before clicking/typing, reducing flakiness and making automations more predictable.
101
+
68
102
  ### Browser-context HTTP requests - game changer for hybrid automation!
69
103
  Ever wished you could make HTTP requests that automatically inherit all your browser's session state? **Now you can!**<br>
70
104
  The `tab.request` property gives you a beautiful `requests`-like interface that executes HTTP calls directly in the browser's JavaScript context. This means every request automatically gets cookies, authentication headers, CORS policies, and session state, just as if the browser made the request itself.
@@ -8,9 +8,9 @@
8
8
  <a href="https://codecov.io/gh/autoscrape-labs/pydoll" >
9
9
  <img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
10
10
  </a>
11
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
12
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
13
- <img src="https://github.com/thalissonvs/pydoll/actions/workflows/mypy.yml/badge.svg" alt="MyPy CI">
11
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
12
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
13
+ <img src="https://github.com/autoscrape-labs/pydoll/actions/workflows/mypy.yml/badge.svg" alt="MyPy CI">
14
14
  <img src="https://img.shields.io/badge/python-%3E%3D3.10-blue" alt="Python >= 3.10">
15
15
  <a href="https://deepwiki.com/autoscrape-labs/pydoll"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
16
16
  </p>
@@ -47,6 +47,40 @@ We believe that powerful automation shouldn't require you to become an expert in
47
47
 
48
48
  ## What's New
49
49
 
50
+ ### WebElement: state waiting and new public APIs
51
+
52
+ - New `wait_until(...)` on `WebElement` to await element states with minimal code:
53
+
54
+ ```python
55
+ # Wait until it becomes visible OR the timeout expires
56
+ await element.wait_until(is_visible=True, timeout=5)
57
+
58
+ # Wait until it becomes interactable (visible, on top, receiving pointer events)
59
+ await element.wait_until(is_interactable=True, timeout=10)
60
+ ```
61
+
62
+ - Methods now public on `WebElement`:
63
+ - `is_visible()`
64
+ - Checks that the element has a visible area (> 0), isn’t hidden by CSS and is in the viewport (after `scroll_into_view()` when needed). Useful pre-check before interactions.
65
+ - `is_interactable()`
66
+ - “Click-ready” state: combines visibility, enabledness and pointer-event hit testing. Ideal for robust flows that avoid lost clicks.
67
+ - `is_on_top()`
68
+ - Verifies the element is the top hit-test target at the intended click point, avoiding overlays.
69
+ - `execute_script(script: str, return_by_value: bool = False)`
70
+ - Executes JavaScript in the element’s own context (where `this` is the element). Great for fine-tuning and quick inspections.
71
+
72
+ ```python
73
+ # Visually outline the element via JS
74
+ await element.execute_script("this.style.outline='2px solid #22d3ee'")
75
+
76
+ # Confirm states
77
+ visible = await element.is_visible()
78
+ interactable = await element.is_interactable()
79
+ on_top = await element.is_on_top()
80
+ ```
81
+
82
+ These additions simplify waiting and state validation before clicking/typing, reducing flakiness and making automations more predictable.
83
+
50
84
  ### Browser-context HTTP requests - game changer for hybrid automation!
51
85
  Ever wished you could make HTTP requests that automatically inherit all your browser's session state? **Now you can!**<br>
52
86
  The `tab.request` property gives you a beautiful `requests`-like interface that executes HTTP calls directly in the browser's JavaScript context. This means every request automatically gets cookies, authentication headers, CORS policies, and session state, just as if the browser made the request itself.
@@ -47,6 +47,7 @@ class Chrome(Browser):
47
47
  ],
48
48
  'Linux': [
49
49
  '/usr/bin/google-chrome',
50
+ '/usr/bin/google-chrome-stable',
50
51
  ],
51
52
  'Darwin': [
52
53
  '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
@@ -46,7 +46,7 @@ from pydoll.exceptions import (
46
46
  PageLoadTimeout,
47
47
  WaitElementTimeout,
48
48
  )
49
- from pydoll.protocol.base import EmptyResponse
49
+ from pydoll.protocol.base import EmptyResponse, Response
50
50
  from pydoll.protocol.browser.events import (
51
51
  BrowserEvent,
52
52
  DownloadProgressEvent,
@@ -282,7 +282,7 @@ class Tab(FindElementsMixin):
282
282
  Note:
283
283
  Intercepted requests must be explicitly continued or timeout.
284
284
  """
285
- response: EmptyResponse = await self._execute_command(
285
+ response: Response[EmptyResponse] = await self._execute_command(
286
286
  FetchCommands.enable(
287
287
  handle_auth_requests=handle_auth,
288
288
  resource_type=resource_type,
@@ -424,6 +424,10 @@ class Tab(FindElementsMixin):
424
424
 
425
425
  return Tab(self._browser, self._connection_port, iframe_target['targetId'])
426
426
 
427
+ async def bring_to_front(self):
428
+ """Brings the page to front."""
429
+ return await self._execute_command(PageCommands.bring_to_front())
430
+
427
431
  async def get_cookies(self) -> list[Cookie]:
428
432
  """Get all cookies accessible from current page."""
429
433
  response: GetCookiesResponse = await self._execute_command(
@@ -545,6 +549,7 @@ class Tab(FindElementsMixin):
545
549
  self,
546
550
  path: Optional[str] = None,
547
551
  quality: int = 100,
552
+ beyond_viewport: bool = False,
548
553
  as_base64: bool = False,
549
554
  ) -> Optional[str]:
550
555
  """
@@ -553,6 +558,8 @@ class Tab(FindElementsMixin):
553
558
  Args:
554
559
  path: File path for screenshot (extension determines format).
555
560
  quality: Image quality 0-100 (default 100).
561
+ beyond_viewport: The page will be scrolled to the bottom and the screenshot will
562
+ include the entire page
556
563
  as_base64: Return as base64 string instead of saving file.
557
564
 
558
565
  Returns:
@@ -573,6 +580,7 @@ class Tab(FindElementsMixin):
573
580
  PageCommands.capture_screenshot(
574
581
  format=ScreenshotFormat.get_value(output_extension),
575
582
  quality=quality,
583
+ capture_beyond_viewport=beyond_viewport,
576
584
  )
577
585
  )
578
586
  screenshot_data = response['result']['data']
@@ -25,11 +25,39 @@ class Scripts:
25
25
  ELEMENT_ON_TOP = """
26
26
  function() {
27
27
  const rect = this.getBoundingClientRect();
28
- const elementFromPoint = document.elementFromPoint(
29
- rect.x + rect.width / 2,
30
- rect.y + rect.height / 2
31
- );
32
- return elementFromPoint === this;
28
+ const x = rect.x + rect.width / 2;
29
+ const y = rect.y + rect.height / 2;
30
+ const elementFromPoint = document.elementFromPoint(x, y);
31
+ if (!elementFromPoint) {
32
+ return false;
33
+ }
34
+ return elementFromPoint === this || this.contains(elementFromPoint);
35
+ }
36
+ """
37
+
38
+ ELEMENT_INTERACTIVE = """
39
+ function() {
40
+ const style = window.getComputedStyle(this);
41
+ const rect = this.getBoundingClientRect();
42
+ if (
43
+ rect.width <= 0 ||
44
+ rect.height <= 0 ||
45
+ style.visibility === 'hidden' ||
46
+ style.display === 'none' ||
47
+ style.pointerEvents === 'none'
48
+ ) {
49
+ return false;
50
+ }
51
+ const x = rect.x + rect.width / 2;
52
+ const y = rect.y + rect.height / 2;
53
+ const elementFromPoint = document.elementFromPoint(x, y);
54
+ if (!elementFromPoint || (elementFromPoint !== this && !this.contains(elementFromPoint))) {
55
+ return false;
56
+ }
57
+ if (this.disabled) {
58
+ return false;
59
+ }
60
+ return true;
33
61
  }
34
62
  """
35
63
 
@@ -21,6 +21,7 @@ from pydoll.exceptions import (
21
21
  ElementNotFound,
22
22
  ElementNotInteractable,
23
23
  ElementNotVisible,
24
+ WaitElementTimeout,
24
25
  )
25
26
  from pydoll.protocol.dom.methods import (
26
27
  GetBoxModelResponse,
@@ -129,12 +130,12 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
129
130
 
130
131
  Returns coordinates relative to viewport (alternative to bounds property).
131
132
  """
132
- response = await self._execute_script(Scripts.BOUNDS, return_by_value=True)
133
+ response = await self.execute_script(Scripts.BOUNDS, return_by_value=True)
133
134
  return json.loads(response['result']['result']['value'])
134
135
 
135
136
  async def get_parent_element(self) -> 'WebElement':
136
137
  """Element's parent element."""
137
- result = await self._execute_script(Scripts.GET_PARENT_NODE)
138
+ result = await self.execute_script(Scripts.GET_PARENT_NODE)
138
139
  if not self._has_object_id_key(result):
139
140
  raise ElementNotFound(f'Parent element not found for element: {self}')
140
141
 
@@ -180,6 +181,46 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
180
181
  command = DomCommands.scroll_into_view_if_needed(object_id=self._object_id)
181
182
  await self._execute_command(command)
182
183
 
184
+ async def wait_until(
185
+ self,
186
+ *,
187
+ is_visible: bool = False,
188
+ is_interactable: bool = False,
189
+ timeout: int = 0,
190
+ ):
191
+ """Wait for element to meet specified conditions.
192
+
193
+ Raises:
194
+ ValueError: If neither ``is_visible`` nor ``is_interactable`` is True.
195
+ WaitElementTimeout: If the condition is not met within ``timeout``.
196
+ """
197
+ checks_map = [
198
+ (is_visible, self.is_visible),
199
+ (is_interactable, self.is_interactable),
200
+ ]
201
+ checks = [func for flag, func in checks_map if flag]
202
+ if not checks:
203
+ raise ValueError('At least one of is_visible or is_interactable must be True')
204
+
205
+ condition_parts = []
206
+ if is_visible:
207
+ condition_parts.append('visible')
208
+ if is_interactable:
209
+ condition_parts.append('interactable')
210
+ condition_msg = ' and '.join(condition_parts)
211
+
212
+ loop = asyncio.get_event_loop()
213
+ start_time = loop.time()
214
+ while True:
215
+ results = await asyncio.gather(*(check() for check in checks))
216
+ if all(results):
217
+ return
218
+
219
+ if timeout and loop.time() - start_time > timeout:
220
+ raise WaitElementTimeout(f'Timed out waiting for element to become {condition_msg}')
221
+
222
+ await asyncio.sleep(0.5)
223
+
183
224
  async def click_using_js(self):
184
225
  """
185
226
  Click element using JavaScript click() method.
@@ -197,10 +238,10 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
197
238
 
198
239
  await self.scroll_into_view()
199
240
 
200
- if not await self._is_element_visible():
241
+ if not await self.is_visible():
201
242
  raise ElementNotVisible()
202
243
 
203
- result = await self._execute_script(Scripts.CLICK, return_by_value=True)
244
+ result = await self.execute_script(Scripts.CLICK, return_by_value=True)
204
245
  clicked = result['result']['result']['value']
205
246
  if not clicked:
206
247
  raise ElementNotInteractable()
@@ -229,7 +270,7 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
229
270
  if self._is_option_tag():
230
271
  return await self._click_option_tag()
231
272
 
232
- if not await self._is_element_visible():
273
+ if not await self.is_visible():
233
274
  raise ElementNotVisible()
234
275
 
235
276
  await self.scroll_into_view()
@@ -365,17 +406,22 @@ class WebElement(FindElementsMixin): # noqa: PLR0904
365
406
  )
366
407
  )
367
408
 
368
- async def _is_element_visible(self):
409
+ async def is_visible(self):
369
410
  """Check if element is visible using comprehensive JavaScript visibility test."""
370
- result = await self._execute_script(Scripts.ELEMENT_VISIBLE, return_by_value=True)
411
+ result = await self.execute_script(Scripts.ELEMENT_VISIBLE, return_by_value=True)
371
412
  return result['result']['result']['value']
372
413
 
373
- async def _is_element_on_top(self):
414
+ async def is_on_top(self):
374
415
  """Check if element is topmost at its center point (not covered by overlays)."""
375
- result = await self._execute_script(Scripts.ELEMENT_ON_TOP, return_by_value=True)
416
+ result = await self.execute_script(Scripts.ELEMENT_ON_TOP, return_by_value=True)
417
+ return result['result']['result']['value']
418
+
419
+ async def is_interactable(self):
420
+ """Check if element is interactable based on visibility and position."""
421
+ result = await self.execute_script(Scripts.ELEMENT_INTERACTIVE, return_by_value=True)
376
422
  return result['result']['result']['value']
377
423
 
378
- async def _execute_script(self, script: str, return_by_value: bool = False):
424
+ async def execute_script(self, script: str, return_by_value: bool = False):
379
425
  """
380
426
  Execute JavaScript in element context.
381
427
 
@@ -203,26 +203,26 @@ GetWindowForTargetResponse = Response[GetWindowForTargetResult]
203
203
 
204
204
  # Command types
205
205
  AddPrivacySandboxCoordinatorKeyConfigCommand = Command[
206
- AddPrivacySandboxCoordinatorKeyConfigParams, EmptyResponse
206
+ AddPrivacySandboxCoordinatorKeyConfigParams, Response[EmptyResponse]
207
207
  ]
208
208
  AddPrivacySandboxEnrollmentOverrideCommand = Command[
209
- AddPrivacySandboxEnrollmentOverrideParams, EmptyResponse
209
+ AddPrivacySandboxEnrollmentOverrideParams, Response[EmptyResponse]
210
210
  ]
211
- CancelDownloadCommand = Command[CancelDownloadParams, EmptyResponse]
212
- CloseCommand = Command[EmptyParams, EmptyResponse]
213
- CrashCommand = Command[EmptyParams, EmptyResponse]
214
- CrashGpuProcessCommand = Command[EmptyParams, EmptyResponse]
215
- ExecuteBrowserCommandCommand = Command[ExecuteBrowserCommandParams, EmptyResponse]
211
+ CancelDownloadCommand = Command[CancelDownloadParams, Response[EmptyResponse]]
212
+ CloseCommand = Command[EmptyParams, Response[EmptyResponse]]
213
+ CrashCommand = Command[EmptyParams, Response[EmptyResponse]]
214
+ CrashGpuProcessCommand = Command[EmptyParams, Response[EmptyResponse]]
215
+ ExecuteBrowserCommandCommand = Command[ExecuteBrowserCommandParams, Response[EmptyResponse]]
216
216
  GetBrowserCommandLineCommand = Command[EmptyParams, GetBrowserCommandLineResponse]
217
217
  GetHistogramCommand = Command[GetHistogramParams, GetHistogramResponse]
218
218
  GetHistogramsCommand = Command[GetHistogramsParams, GetHistogramsResponse]
219
219
  GetVersionCommand = Command[EmptyParams, GetVersionResponse]
220
220
  GetWindowBoundsCommand = Command[GetWindowBoundsParams, GetWindowBoundsResponse]
221
221
  GetWindowForTargetCommand = Command[GetWindowForTargetParams, GetWindowForTargetResponse]
222
- GrantPermissionsCommand = Command[GrantPermissionsParams, EmptyResponse]
223
- ResetPermissionsCommand = Command[ResetPermissionsParams, EmptyResponse]
224
- SetContentsSizeCommand = Command[SetContentsSizeParams, EmptyResponse]
225
- SetDockTileCommand = Command[SetDockTileParams, EmptyResponse]
226
- SetDownloadBehaviorCommand = Command[SetDownloadBehaviorParams, EmptyResponse]
227
- SetPermissionCommand = Command[SetPermissionParams, EmptyResponse]
228
- SetWindowBoundsCommand = Command[SetWindowBoundsParams, EmptyResponse]
222
+ GrantPermissionsCommand = Command[GrantPermissionsParams, Response[EmptyResponse]]
223
+ ResetPermissionsCommand = Command[ResetPermissionsParams, Response[EmptyResponse]]
224
+ SetContentsSizeCommand = Command[SetContentsSizeParams, Response[EmptyResponse]]
225
+ SetDockTileCommand = Command[SetDockTileParams, Response[EmptyResponse]]
226
+ SetDownloadBehaviorCommand = Command[SetDownloadBehaviorParams, Response[EmptyResponse]]
227
+ SetPermissionCommand = Command[SetPermissionParams, Response[EmptyResponse]]
228
+ SetWindowBoundsCommand = Command[SetWindowBoundsParams, Response[EmptyResponse]]
@@ -642,17 +642,17 @@ CollectClassNamesFromSubtreeCommand = Command[
642
642
  ]
643
643
  CopyToCommand = Command[CopyToParams, CopyToResponse]
644
644
  DescribeNodeCommand = Command[DescribeNodeParams, DescribeNodeResponse]
645
- DisableCommand = Command[EmptyParams, EmptyResponse]
646
- DiscardSearchResultsCommand = Command[DiscardSearchResultsParams, EmptyResponse]
647
- EnableCommand = Command[EnableParams, EmptyResponse]
648
- FocusCommand = Command[FocusParams, EmptyResponse]
645
+ DisableCommand = Command[EmptyParams, Response[EmptyResponse]]
646
+ DiscardSearchResultsCommand = Command[DiscardSearchResultsParams, Response[EmptyResponse]]
647
+ EnableCommand = Command[EnableParams, Response[EmptyResponse]]
648
+ FocusCommand = Command[FocusParams, Response[EmptyResponse]]
649
649
  ForceShowPopoverCommand = Command[ForceShowPopoverParams, ForceShowPopoverResponse]
650
650
  GetAnchorElementCommand = Command[GetAnchorElementParams, GetAnchorElementResponse]
651
651
  GetAttributesCommand = Command[GetAttributesParams, GetAttributesResponse]
652
652
  GetBoxModelCommand = Command[GetBoxModelParams, GetBoxModelResponse]
653
653
  GetContainerForNodeCommand = Command[GetContainerForNodeParams, GetContainerForNodeResponse]
654
654
  GetContentQuadsCommand = Command[GetContentQuadsParams, GetContentQuadsResponse]
655
- GetDetachedDomNodesCommand = Command[EmptyParams, GetDetachedDomNodesResponse]
655
+ GetDetachedDomNodesCommand = Command[EmptyParams, Response[GetDetachedDomNodesResponse]]
656
656
  GetDocumentCommand = Command[GetDocumentParams, GetDocumentResponse]
657
657
  GetElementByRelationCommand = Command[GetElementByRelationParams, GetElementByRelationResponse]
658
658
  GetFileInfoCommand = Command[GetFileInfoParams, GetFileInfoResponse]
@@ -670,10 +670,10 @@ GetQueryingDescendantsForContainerCommand = Command[
670
670
  GetRelayoutBoundaryCommand = Command[GetRelayoutBoundaryParams, GetRelayoutBoundaryResponse]
671
671
  GetSearchResultsCommand = Command[GetSearchResultsParams, GetSearchResultsResponse]
672
672
  GetTopLayerElementsCommand = Command[EmptyParams, GetTopLayerElementsResponse]
673
- HideHighlightCommand = Command[EmptyParams, EmptyResponse]
674
- HighlightNodeCommand = Command[EmptyParams, EmptyResponse] # redirect to Overlay
675
- HighlightRectCommand = Command[EmptyParams, EmptyResponse] # redirect to Overlay
676
- MarkUndoableStateCommand = Command[EmptyParams, EmptyResponse]
673
+ HideHighlightCommand = Command[EmptyParams, Response[EmptyResponse]]
674
+ HighlightNodeCommand = Command[EmptyParams, Response[EmptyResponse]] # redirect to Overlay
675
+ HighlightRectCommand = Command[EmptyParams, Response[EmptyResponse]] # redirect to Overlay
676
+ MarkUndoableStateCommand = Command[EmptyParams, Response[EmptyResponse]]
677
677
  MoveToCommand = Command[MoveToParams, MoveToResponse]
678
678
  PerformSearchCommand = Command[PerformSearchParams, PerformSearchResponse]
679
679
  PushNodeByPathToFrontendCommand = Command[
@@ -684,19 +684,19 @@ PushNodesByBackendIdsToFrontendCommand = Command[
684
684
  ]
685
685
  QuerySelectorCommand = Command[QuerySelectorParams, QuerySelectorResponse]
686
686
  QuerySelectorAllCommand = Command[QuerySelectorAllParams, QuerySelectorAllResponse]
687
- RedoCommand = Command[EmptyParams, EmptyResponse]
688
- RemoveAttributeCommand = Command[RemoveAttributeParams, EmptyResponse]
689
- RemoveNodeCommand = Command[RemoveNodeParams, EmptyResponse]
690
- RequestChildNodesCommand = Command[RequestChildNodesParams, EmptyResponse]
687
+ RedoCommand = Command[EmptyParams, Response[EmptyResponse]]
688
+ RemoveAttributeCommand = Command[RemoveAttributeParams, Response[EmptyResponse]]
689
+ RemoveNodeCommand = Command[RemoveNodeParams, Response[EmptyResponse]]
690
+ RequestChildNodesCommand = Command[RequestChildNodesParams, Response[EmptyResponse]]
691
691
  RequestNodeCommand = Command[RequestNodeParams, RequestNodeResponse]
692
692
  ResolveNodeCommand = Command[ResolveNodeParams, ResolveNodeResponse]
693
- ScrollIntoViewIfNeededCommand = Command[ScrollIntoViewIfNeededParams, EmptyResponse]
694
- SetAttributeValueCommand = Command[SetAttributeValueParams, EmptyResponse]
695
- SetAttributesAsTextCommand = Command[SetAttributesAsTextParams, EmptyResponse]
696
- SetFileInputFilesCommand = Command[SetFileInputFilesParams, EmptyResponse]
697
- SetInspectedNodeCommand = Command[SetInspectedNodeParams, EmptyResponse]
693
+ ScrollIntoViewIfNeededCommand = Command[ScrollIntoViewIfNeededParams, Response[EmptyResponse]]
694
+ SetAttributeValueCommand = Command[SetAttributeValueParams, Response[EmptyResponse]]
695
+ SetAttributesAsTextCommand = Command[SetAttributesAsTextParams, Response[EmptyResponse]]
696
+ SetFileInputFilesCommand = Command[SetFileInputFilesParams, Response[EmptyResponse]]
697
+ SetInspectedNodeCommand = Command[SetInspectedNodeParams, Response[EmptyResponse]]
698
698
  SetNodeNameCommand = Command[SetNodeNameParams, SetNodeNameResponse]
699
- SetNodeStackTracesEnabledCommand = Command[SetNodeStackTracesEnabledParams, EmptyResponse]
700
- SetNodeValueCommand = Command[SetNodeValueParams, EmptyResponse]
701
- SetOuterHTMLCommand = Command[SetOuterHTMLParams, EmptyResponse]
702
- UndoCommand = Command[EmptyParams, EmptyResponse]
699
+ SetNodeStackTracesEnabledCommand = Command[SetNodeStackTracesEnabledParams, Response[EmptyResponse]]
700
+ SetNodeValueCommand = Command[SetNodeValueParams, Response[EmptyResponse]]
701
+ SetOuterHTMLCommand = Command[SetOuterHTMLParams, Response[EmptyResponse]]
702
+ UndoCommand = Command[EmptyParams, Response[EmptyResponse]]
@@ -115,13 +115,13 @@ TakeResponseBodyAsStreamResponse = Response[TakeResponseBodyAsStreamResult]
115
115
 
116
116
 
117
117
  # Command types
118
- ContinueRequestCommand = Command[ContinueRequestParams, EmptyResponse]
119
- ContinueResponseCommand = Command[ContinueResponseParams, EmptyResponse]
120
- ContinueWithAuthCommand = Command[ContinueWithAuthParams, EmptyResponse]
121
- DisableCommand = Command[EmptyParams, EmptyResponse]
122
- EnableCommand = Command[EnableParams, EmptyResponse]
123
- FailRequestCommand = Command[FailRequestParams, EmptyResponse]
124
- FulfillRequestCommand = Command[FulfillRequestParams, EmptyResponse]
118
+ ContinueRequestCommand = Command[ContinueRequestParams, Response[EmptyResponse]]
119
+ ContinueResponseCommand = Command[ContinueResponseParams, Response[EmptyResponse]]
120
+ ContinueWithAuthCommand = Command[ContinueWithAuthParams, Response[EmptyResponse]]
121
+ DisableCommand = Command[EmptyParams, Response[EmptyResponse]]
122
+ EnableCommand = Command[EnableParams, Response[EmptyResponse]]
123
+ FailRequestCommand = Command[FailRequestParams, Response[EmptyResponse]]
124
+ FulfillRequestCommand = Command[FulfillRequestParams, Response[EmptyResponse]]
125
125
  GetResponseBodyCommand = Command[GetResponseBodyParams, GetResponseBodyResponse]
126
126
  TakeResponseBodyAsStreamCommand = Command[
127
127
  TakeResponseBodyAsStreamParams, TakeResponseBodyAsStreamResponse
@@ -2,7 +2,7 @@ from enum import Enum
2
2
 
3
3
  from typing_extensions import NotRequired, TypedDict
4
4
 
5
- from pydoll.protocol.base import Command, EmptyParams, EmptyResponse
5
+ from pydoll.protocol.base import Command, EmptyParams, EmptyResponse, Response
6
6
  from pydoll.protocol.input.types import (
7
7
  DragData,
8
8
  DragEventType,
@@ -179,16 +179,18 @@ class SynthesizeTapGestureParams(TypedDict):
179
179
 
180
180
 
181
181
  # Command types
182
- CancelDraggingCommand = Command[EmptyParams, EmptyResponse]
183
- DispatchDragEventCommand = Command[DispatchDragEventParams, EmptyResponse]
184
- DispatchKeyEventCommand = Command[DispatchKeyEventParams, EmptyResponse]
185
- DispatchMouseEventCommand = Command[DispatchMouseEventParams, EmptyResponse]
186
- DispatchTouchEventCommand = Command[DispatchTouchEventParams, EmptyResponse]
187
- EmulateTouchFromMouseEventCommand = Command[EmulateTouchFromMouseEventParams, EmptyResponse]
188
- ImeSetCompositionCommand = Command[ImeSetCompositionParams, EmptyResponse]
189
- InsertTextCommand = Command[InsertTextParams, EmptyResponse]
190
- SetIgnoreInputEventsCommand = Command[SetIgnoreInputEventsParams, EmptyResponse]
191
- SetInterceptDragsCommand = Command[SetInterceptDragsParams, EmptyResponse]
192
- SynthesizePinchGestureCommand = Command[SynthesizePinchGestureParams, EmptyResponse]
193
- SynthesizeScrollGestureCommand = Command[SynthesizeScrollGestureParams, EmptyResponse]
194
- SynthesizeTapGestureCommand = Command[SynthesizeTapGestureParams, EmptyResponse]
182
+ CancelDraggingCommand = Command[EmptyParams, Response[EmptyResponse]]
183
+ DispatchDragEventCommand = Command[DispatchDragEventParams, Response[EmptyResponse]]
184
+ DispatchKeyEventCommand = Command[DispatchKeyEventParams, Response[EmptyResponse]]
185
+ DispatchMouseEventCommand = Command[DispatchMouseEventParams, Response[EmptyResponse]]
186
+ DispatchTouchEventCommand = Command[DispatchTouchEventParams, Response[EmptyResponse]]
187
+ EmulateTouchFromMouseEventCommand = Command[
188
+ EmulateTouchFromMouseEventParams, Response[EmptyResponse]
189
+ ]
190
+ ImeSetCompositionCommand = Command[ImeSetCompositionParams, Response[EmptyResponse]]
191
+ InsertTextCommand = Command[InsertTextParams, Response[EmptyResponse]]
192
+ SetIgnoreInputEventsCommand = Command[SetIgnoreInputEventsParams, Response[EmptyResponse]]
193
+ SetInterceptDragsCommand = Command[SetInterceptDragsParams, Response[EmptyResponse]]
194
+ SynthesizePinchGestureCommand = Command[SynthesizePinchGestureParams, Response[EmptyResponse]]
195
+ SynthesizeScrollGestureCommand = Command[SynthesizeScrollGestureParams, Response[EmptyResponse]]
196
+ SynthesizeTapGestureCommand = Command[SynthesizeTapGestureParams, Response[EmptyResponse]]
@@ -360,32 +360,32 @@ GetSecurityIsolationStatusResponse = Response[GetSecurityIsolationStatusResult]
360
360
  LoadNetworkResourceResponse = Response[LoadNetworkResourceResult]
361
361
 
362
362
 
363
- ClearBrowserCacheCommand = Command[EmptyParams, EmptyResponse]
364
- ClearBrowserCookiesCommand = Command[EmptyParams, EmptyResponse]
365
- ClearCookiesCommand = Command[DeleteCookiesParams, EmptyResponse]
366
- DisableCommand = Command[EmptyParams, EmptyResponse]
367
- EmulateNetworkConditionsCommand = Command[EmulateNetworkConditionsParams, EmptyResponse]
368
- EnableCommand = Command[NetworkEnableParams, EmptyResponse]
363
+ ClearBrowserCacheCommand = Command[EmptyParams, Response[EmptyResponse]]
364
+ ClearBrowserCookiesCommand = Command[EmptyParams, Response[EmptyResponse]]
365
+ ClearCookiesCommand = Command[DeleteCookiesParams, Response[EmptyResponse]]
366
+ DisableCommand = Command[EmptyParams, Response[EmptyResponse]]
367
+ EmulateNetworkConditionsCommand = Command[EmulateNetworkConditionsParams, Response[EmptyResponse]]
368
+ EnableCommand = Command[NetworkEnableParams, Response[EmptyResponse]]
369
369
  GetCookiesCommand = Command[GetCookiesParams, GetCookiesResponse]
370
370
  GetRequestPostDataCommand = Command[GetRequestPostDataParams, GetRequestPostDataResponse]
371
371
  GetResponseBodyCommand = Command[GetResponseBodyParams, GetResponseBodyResponse]
372
- SetCacheDisabledCommand = Command[SetCacheDisabledParams, EmptyResponse]
372
+ SetCacheDisabledCommand = Command[SetCacheDisabledParams, Response[EmptyResponse]]
373
373
  SetCookieCommand = Command[SetCookieParams, SetCookieResponse]
374
- SetCookiesCommand = Command[SetCookiesParams, EmptyResponse]
375
- SetExtraHTTPHeadersCommand = Command[SetExtraHTTPHeadersParams, EmptyResponse]
376
- SetUserAgentOverrideCommand = Command[SetUserAgentOverrideParams, EmptyResponse]
377
- ClearAcceptedEncodingsOverrideCommand = Command[EmptyParams, EmptyResponse]
378
- EnableReportingApiCommand = Command[EnableReportingApiParams, EmptyResponse]
374
+ SetCookiesCommand = Command[SetCookiesParams, Response[EmptyResponse]]
375
+ SetExtraHTTPHeadersCommand = Command[SetExtraHTTPHeadersParams, Response[EmptyResponse]]
376
+ SetUserAgentOverrideCommand = Command[SetUserAgentOverrideParams, Response[EmptyResponse]]
377
+ ClearAcceptedEncodingsOverrideCommand = Command[EmptyParams, Response[EmptyResponse]]
378
+ EnableReportingApiCommand = Command[EnableReportingApiParams, Response[EmptyResponse]]
379
379
  SearchInResponseBodyCommand = Command[SearchInResponseBodyParams, SearchInResponseBodyResponse]
380
- SetBlockedURLsCommand = Command[SetBlockedURLsParams, EmptyResponse]
381
- SetBypassServiceWorkerCommand = Command[SetBypassServiceWorkerParams, EmptyResponse]
380
+ SetBlockedURLsCommand = Command[SetBlockedURLsParams, Response[EmptyResponse]]
381
+ SetBypassServiceWorkerCommand = Command[SetBypassServiceWorkerParams, Response[EmptyResponse]]
382
382
  GetCertificateCommand = Command[GetCertificateParams, GetCertificateResponse]
383
383
  GetResponseBodyForInterceptionCommand = Command[
384
384
  GetResponseBodyForInterceptionParams, GetResponseBodyForInterceptionResponse
385
385
  ]
386
- SetAcceptedEncodingsCommand = Command[SetAcceptedEncodingsParams, EmptyResponse]
387
- SetAttachDebugStackCommand = Command[SetAttachDebugStackParams, EmptyResponse]
388
- SetCookieControlsCommand = Command[SetCookieControlsParams, EmptyResponse]
386
+ SetAcceptedEncodingsCommand = Command[SetAcceptedEncodingsParams, Response[EmptyResponse]]
387
+ SetAttachDebugStackCommand = Command[SetAttachDebugStackParams, Response[EmptyResponse]]
388
+ SetCookieControlsCommand = Command[SetCookieControlsParams, Response[EmptyResponse]]
389
389
  StreamResourceContentCommand = Command[StreamResourceContentParams, StreamResourceContentResponse]
390
390
  TakeResponseBodyForInterceptionAsStreamCommand = Command[
391
391
  TakeResponseBodyForInterceptionAsStreamParams, TakeResponseBodyForInterceptionAsStreamResponse
@@ -394,4 +394,4 @@ GetSecurityIsolationStatusCommand = Command[
394
394
  GetSecurityIsolationStatusParams, GetSecurityIsolationStatusResponse
395
395
  ]
396
396
  LoadNetworkResourceCommand = Command[LoadNetworkResourceParams, LoadNetworkResourceResponse]
397
- ReplayXHRCommand = Command[ReplayXHRParams, EmptyResponse]
397
+ ReplayXHRCommand = Command[ReplayXHRParams, Response[EmptyResponse]]
@@ -499,65 +499,69 @@ PrintToPDFResponse = Response[PrintToPDFResult]
499
499
  SearchInResourceResponse = Response[SearchInResourceResult]
500
500
 
501
501
 
502
- AddCompilationCacheCommand = Command[AddCompilationCacheParams, EmptyResponse]
502
+ AddCompilationCacheCommand = Command[AddCompilationCacheParams, Response[EmptyResponse]]
503
503
  AddScriptToEvaluateOnLoadCommand = Command[
504
504
  AddScriptToEvaluateOnLoadParams, AddScriptToEvaluateOnLoadResponse
505
505
  ]
506
506
  AddScriptToEvaluateOnNewDocumentCommand = Command[
507
507
  AddScriptToEvaluateOnNewDocumentParams, AddScriptToEvaluateOnNewDocumentResponse
508
508
  ]
509
- BringToFrontCommand = Command[EmptyParams, EmptyResponse]
509
+ BringToFrontCommand = Command[EmptyParams, Response[EmptyResponse]]
510
510
  CaptureScreenshotCommand = Command[CaptureScreenshotParams, CaptureScreenshotResponse]
511
511
  CaptureSnapshotCommand = Command[CaptureSnapshotParams, CaptureSnapshotResponse]
512
- ClearCompilationCacheCommand = Command[EmptyParams, EmptyResponse]
513
- CloseCommand = Command[EmptyParams, EmptyResponse]
514
- CrashCommand = Command[EmptyParams, EmptyResponse]
512
+ ClearCompilationCacheCommand = Command[EmptyParams, Response[EmptyResponse]]
513
+ CloseCommand = Command[EmptyParams, Response[EmptyResponse]]
514
+ CrashCommand = Command[EmptyParams, Response[EmptyResponse]]
515
515
  CreateIsolatedWorldCommand = Command[CreateIsolatedWorldParams, CreateIsolatedWorldResponse]
516
- DisableCommand = Command[EmptyParams, EmptyResponse]
517
- EnableCommand = Command[EnableParams, EmptyResponse]
518
- GenerateTestReportCommand = Command[GenerateTestReportParams, EmptyResponse]
516
+ DisableCommand = Command[EmptyParams, Response[EmptyResponse]]
517
+ EnableCommand = Command[EnableParams, Response[EmptyResponse]]
518
+ GenerateTestReportCommand = Command[GenerateTestReportParams, Response[EmptyResponse]]
519
519
  GetAdScriptAncestryCommand = Command[GetAdScriptAncestryParams, GetAdScriptAncestryResponse]
520
520
  GetAdScriptAncestryIdsCommand = Command[
521
521
  GetAdScriptAncestryIdsParams, GetAdScriptAncestryIdsResponse
522
522
  ]
523
523
  GetAppIdCommand = Command[GetAppIdParams, GetAppIdResponse]
524
524
  GetAppManifestCommand = Command[GetAppManifestParams, GetAppManifestResponse]
525
- GetFrameTreeCommand = Command[EmptyParams, GetFrameTreeResponse]
526
- GetInstallabilityErrorsCommand = Command[EmptyParams, GetInstallabilityErrorsResponse]
527
- GetLayoutMetricsCommand = Command[EmptyParams, GetLayoutMetricsResponse]
528
- GetManifestIconsCommand = Command[EmptyParams, GetManifestIconsResponse]
529
- GetNavigationHistoryCommand = Command[EmptyParams, GetNavigationHistoryResponse]
530
- GetOriginTrialsCommand = Command[GetOriginTrialsParams, GetOriginTrialsResponse]
525
+ GetFrameTreeCommand = Command[EmptyParams, Response[GetFrameTreeResponse]]
526
+ GetInstallabilityErrorsCommand = Command[EmptyParams, Response[GetInstallabilityErrorsResponse]]
527
+ GetLayoutMetricsCommand = Command[EmptyParams, Response[GetLayoutMetricsResponse]]
528
+ GetManifestIconsCommand = Command[EmptyParams, Response[GetManifestIconsResponse]]
529
+ GetNavigationHistoryCommand = Command[EmptyParams, Response[GetNavigationHistoryResponse]]
530
+ GetOriginTrialsCommand = Command[GetOriginTrialsParams, Response[GetOriginTrialsResponse]]
531
531
  GetPermissionsPolicyStateCommand = Command[
532
532
  GetPermissionsPolicyStateParams, GetPermissionsPolicyStateResponse
533
533
  ]
534
534
  GetResourceContentCommand = Command[GetResourceContentParams, GetResourceContentResponse]
535
- GetResourceTreeCommand = Command[EmptyParams, GetResourceTreeResponse]
536
- HandleJavaScriptDialogCommand = Command[HandleJavaScriptDialogParams, EmptyResponse]
535
+ GetResourceTreeCommand = Command[EmptyParams, Response[GetResourceTreeResponse]]
536
+ HandleJavaScriptDialogCommand = Command[HandleJavaScriptDialogParams, Response[EmptyResponse]]
537
537
  NavigateCommand = Command[NavigateParams, NavigateResponse]
538
- NavigateToHistoryEntryCommand = Command[NavigateToHistoryEntryParams, EmptyResponse]
538
+ NavigateToHistoryEntryCommand = Command[NavigateToHistoryEntryParams, Response[EmptyResponse]]
539
539
  PrintToPDFCommand = Command[PrintToPDFParams, PrintToPDFResponse]
540
- ProduceCompilationCacheCommand = Command[ProduceCompilationCacheParams, EmptyResponse]
541
- ReloadCommand = Command[ReloadParams, EmptyResponse]
542
- RemoveScriptToEvaluateOnLoadCommand = Command[RemoveScriptToEvaluateOnLoadParams, EmptyResponse]
540
+ ProduceCompilationCacheCommand = Command[ProduceCompilationCacheParams, Response[EmptyResponse]]
541
+ ReloadCommand = Command[ReloadParams, Response[EmptyResponse]]
542
+ RemoveScriptToEvaluateOnLoadCommand = Command[
543
+ RemoveScriptToEvaluateOnLoadParams, Response[EmptyResponse]
544
+ ]
543
545
  RemoveScriptToEvaluateOnNewDocumentCommand = Command[
544
- RemoveScriptToEvaluateOnNewDocumentParams, EmptyResponse
546
+ RemoveScriptToEvaluateOnNewDocumentParams, Response[EmptyResponse]
545
547
  ]
546
- ResetNavigationHistoryCommand = Command[EmptyParams, EmptyResponse]
547
- ScreencastFrameAckCommand = Command[ScreencastFrameAckParams, EmptyResponse]
548
+ ResetNavigationHistoryCommand = Command[EmptyParams, Response[EmptyResponse]]
549
+ ScreencastFrameAckCommand = Command[ScreencastFrameAckParams, Response[EmptyResponse]]
548
550
  SearchInResourceCommand = Command[SearchInResourceParams, SearchInResourceResponse]
549
- SetAdBlockingEnabledCommand = Command[SetAdBlockingEnabledParams, EmptyResponse]
550
- SetBypassCSPCommand = Command[SetBypassCSPParams, EmptyResponse]
551
- SetDocumentContentCommand = Command[SetDocumentContentParams, EmptyResponse]
552
- SetFontFamiliesCommand = Command[SetFontFamiliesParams, EmptyResponse]
553
- SetFontSizesCommand = Command[SetFontSizesParams, EmptyResponse]
554
- SetInterceptFileChooserDialogCommand = Command[SetInterceptFileChooserDialogParams, EmptyResponse]
555
- SetLifecycleEventsEnabledCommand = Command[SetLifecycleEventsEnabledParams, EmptyResponse]
556
- SetPrerenderingAllowedCommand = Command[SetPrerenderingAllowedParams, EmptyResponse]
557
- SetRPHRegistrationModeCommand = Command[SetRPHRegistrationModeParams, EmptyResponse]
558
- SetSPCTransactionModeCommand = Command[SetSPCTransactionModeParams, EmptyResponse]
559
- SetWebLifecycleStateCommand = Command[SetWebLifecycleStateParams, EmptyResponse]
560
- StartScreencastCommand = Command[StartScreencastParams, EmptyResponse]
561
- StopLoadingCommand = Command[EmptyParams, EmptyResponse]
562
- StopScreencastCommand = Command[EmptyParams, EmptyResponse]
563
- WaitForDebuggerCommand = Command[EmptyParams, EmptyResponse]
551
+ SetAdBlockingEnabledCommand = Command[SetAdBlockingEnabledParams, Response[EmptyResponse]]
552
+ SetBypassCSPCommand = Command[SetBypassCSPParams, Response[EmptyResponse]]
553
+ SetDocumentContentCommand = Command[SetDocumentContentParams, Response[EmptyResponse]]
554
+ SetFontFamiliesCommand = Command[SetFontFamiliesParams, Response[EmptyResponse]]
555
+ SetFontSizesCommand = Command[SetFontSizesParams, Response[EmptyResponse]]
556
+ SetInterceptFileChooserDialogCommand = Command[
557
+ SetInterceptFileChooserDialogParams, Response[EmptyResponse]
558
+ ]
559
+ SetLifecycleEventsEnabledCommand = Command[SetLifecycleEventsEnabledParams, Response[EmptyResponse]]
560
+ SetPrerenderingAllowedCommand = Command[SetPrerenderingAllowedParams, Response[EmptyResponse]]
561
+ SetRPHRegistrationModeCommand = Command[SetRPHRegistrationModeParams, Response[EmptyResponse]]
562
+ SetSPCTransactionModeCommand = Command[SetSPCTransactionModeParams, Response[EmptyResponse]]
563
+ SetWebLifecycleStateCommand = Command[SetWebLifecycleStateParams, Response[EmptyResponse]]
564
+ StartScreencastCommand = Command[StartScreencastParams, Response[EmptyResponse]]
565
+ StopLoadingCommand = Command[EmptyParams, Response[EmptyResponse]]
566
+ StopScreencastCommand = Command[EmptyParams, Response[EmptyResponse]]
567
+ WaitForDebuggerCommand = Command[EmptyParams, Response[EmptyResponse]]
@@ -282,13 +282,13 @@ RunScriptResponse = Response[RunScriptResult]
282
282
 
283
283
 
284
284
  # Command types
285
- AddBindingCommand = Command[AddBindingParams, EmptyResponse]
285
+ AddBindingCommand = Command[AddBindingParams, Response[EmptyResponse]]
286
286
  AwaitPromiseCommand = Command[AwaitPromiseParams, AwaitPromiseResponse]
287
287
  CallFunctionOnCommand = Command[CallFunctionOnParams, CallFunctionOnResponse]
288
288
  CompileScriptCommand = Command[CompileScriptParams, CompileScriptResponse]
289
- DisableCommand = Command[EmptyParams, EmptyResponse]
290
- DiscardConsoleEntriesCommand = Command[EmptyParams, EmptyResponse]
291
- EnableCommand = Command[EmptyParams, EmptyResponse]
289
+ DisableCommand = Command[EmptyParams, Response[EmptyResponse]]
290
+ DiscardConsoleEntriesCommand = Command[EmptyParams, Response[EmptyResponse]]
291
+ EnableCommand = Command[EmptyParams, Response[EmptyResponse]]
292
292
  EvaluateCommand = Command[EvaluateParams, EvaluateResponse]
293
293
  GetExceptionDetailsCommand = Command[GetExceptionDetailsParams, GetExceptionDetailsResponse]
294
294
  GetHeapUsageCommand = Command[EmptyParams, GetHeapUsageResponse]
@@ -298,14 +298,16 @@ GlobalLexicalScopeNamesCommand = Command[
298
298
  GlobalLexicalScopeNamesParams, GlobalLexicalScopeNamesResponse
299
299
  ]
300
300
  QueryObjectsCommand = Command[QueryObjectsParams, QueryObjectsResponse]
301
- ReleaseObjectCommand = Command[ReleaseObjectParams, EmptyResponse]
302
- ReleaseObjectGroupCommand = Command[ReleaseObjectGroupParams, EmptyResponse]
303
- RemoveBindingCommand = Command[RemoveBindingParams, EmptyResponse]
304
- RunIfWaitingForDebuggerCommand = Command[EmptyParams, EmptyResponse]
301
+ ReleaseObjectCommand = Command[ReleaseObjectParams, Response[EmptyResponse]]
302
+ ReleaseObjectGroupCommand = Command[ReleaseObjectGroupParams, Response[EmptyResponse]]
303
+ RemoveBindingCommand = Command[RemoveBindingParams, Response[EmptyResponse]]
304
+ RunIfWaitingForDebuggerCommand = Command[EmptyParams, Response[EmptyResponse]]
305
305
  RunScriptCommand = Command[RunScriptParams, RunScriptResponse]
306
- SetAsyncCallStackDepthCommand = Command[SetAsyncCallStackDepthParams, EmptyResponse]
306
+ SetAsyncCallStackDepthCommand = Command[SetAsyncCallStackDepthParams, Response[EmptyResponse]]
307
307
  SetCustomObjectFormatterEnabledCommand = Command[
308
- SetCustomObjectFormatterEnabledParams, EmptyResponse
308
+ SetCustomObjectFormatterEnabledParams, Response[EmptyResponse]
309
309
  ]
310
- SetMaxCallStackSizeToCaptureCommand = Command[SetMaxCallStackSizeToCaptureParams, EmptyResponse]
311
- TerminateExecutionCommand = Command[EmptyParams, EmptyResponse]
310
+ SetMaxCallStackSizeToCaptureCommand = Command[
311
+ SetMaxCallStackSizeToCaptureParams, Response[EmptyResponse]
312
+ ]
313
+ TerminateExecutionCommand = Command[EmptyParams, Response[EmptyResponse]]
@@ -271,31 +271,41 @@ GetAffectedUrlsForThirdPartyCookieMetadataResponse = Response[
271
271
 
272
272
 
273
273
  GetStorageKeyForFrameCommand = Command[GetStorageKeyForFrameParams, GetStorageKeyForFrameResponse]
274
- ClearDataForOriginCommand = Command[ClearDataForOriginParams, EmptyResponse]
275
- ClearDataForStorageKeyCommand = Command[ClearDataForStorageKeyParams, EmptyResponse]
274
+ ClearDataForOriginCommand = Command[ClearDataForOriginParams, Response[EmptyResponse]]
275
+ ClearDataForStorageKeyCommand = Command[ClearDataForStorageKeyParams, Response[EmptyResponse]]
276
276
  GetCookiesCommand = Command[GetCookiesParams, GetCookiesResponse]
277
- SetCookiesCommand = Command[SetCookiesParams, EmptyResponse]
278
- ClearCookiesCommand = Command[ClearCookiesParams, EmptyResponse]
277
+ SetCookiesCommand = Command[SetCookiesParams, Response[EmptyResponse]]
278
+ ClearCookiesCommand = Command[ClearCookiesParams, Response[EmptyResponse]]
279
279
  GetUsageAndQuotaCommand = Command[GetUsageAndQuotaParams, GetUsageAndQuotaResponse]
280
- OverrideQuotaForOriginCommand = Command[OverrideQuotaForOriginParams, EmptyResponse]
281
- TrackCacheStorageForOriginCommand = Command[TrackCacheStorageForOriginParams, EmptyResponse]
282
- TrackCacheStorageForStorageKeyCommand = Command[TrackCacheStorageForStorageKeyParams, EmptyResponse]
283
- TrackIndexedDBForOriginCommand = Command[TrackIndexedDBForOriginParams, EmptyResponse]
284
- TrackIndexedDBForStorageKeyCommand = Command[TrackIndexedDBForStorageKeyParams, EmptyResponse]
285
- UntrackCacheStorageForOriginCommand = Command[UntrackCacheStorageForOriginParams, EmptyResponse]
280
+ OverrideQuotaForOriginCommand = Command[OverrideQuotaForOriginParams, Response[EmptyResponse]]
281
+ TrackCacheStorageForOriginCommand = Command[
282
+ TrackCacheStorageForOriginParams, Response[EmptyResponse]
283
+ ]
284
+ TrackCacheStorageForStorageKeyCommand = Command[
285
+ TrackCacheStorageForStorageKeyParams, Response[EmptyResponse]
286
+ ]
287
+ TrackIndexedDBForOriginCommand = Command[TrackIndexedDBForOriginParams, Response[EmptyResponse]]
288
+ TrackIndexedDBForStorageKeyCommand = Command[
289
+ TrackIndexedDBForStorageKeyParams, Response[EmptyResponse]
290
+ ]
291
+ UntrackCacheStorageForOriginCommand = Command[
292
+ UntrackCacheStorageForOriginParams, Response[EmptyResponse]
293
+ ]
286
294
  UntrackCacheStorageForStorageKeyCommand = Command[
287
- UntrackCacheStorageForStorageKeyParams, EmptyResponse
295
+ UntrackCacheStorageForStorageKeyParams, Response[EmptyResponse]
296
+ ]
297
+ UntrackIndexedDBForOriginCommand = Command[UntrackIndexedDBForOriginParams, Response[EmptyResponse]]
298
+ UntrackIndexedDBForStorageKeyCommand = Command[
299
+ UntrackIndexedDBForStorageKeyParams, Response[EmptyResponse]
288
300
  ]
289
- UntrackIndexedDBForOriginCommand = Command[UntrackIndexedDBForOriginParams, EmptyResponse]
290
- UntrackIndexedDBForStorageKeyCommand = Command[UntrackIndexedDBForStorageKeyParams, EmptyResponse]
291
301
  GetTrustTokensCommand = Command[EmptyParams, GetTrustTokensResponse]
292
- ClearTrustTokensCommand = Command[ClearTrustTokensParams, EmptyResponse]
302
+ ClearTrustTokensCommand = Command[ClearTrustTokensParams, Response[EmptyResponse]]
293
303
  GetInterestGroupDetailsCommand = Command[
294
304
  GetInterestGroupDetailsParams, GetInterestGroupDetailsResponse
295
305
  ]
296
- SetInterestGroupTrackingCommand = Command[SetInterestGroupTrackingParams, EmptyResponse]
306
+ SetInterestGroupTrackingCommand = Command[SetInterestGroupTrackingParams, Response[EmptyResponse]]
297
307
  SetInterestGroupAuctionTrackingCommand = Command[
298
- SetInterestGroupAuctionTrackingParams, EmptyResponse
308
+ SetInterestGroupAuctionTrackingParams, Response[EmptyResponse]
299
309
  ]
300
310
  GetSharedStorageMetadataCommand = Command[
301
311
  GetSharedStorageMetadataParams, GetSharedStorageMetadataResponse
@@ -303,19 +313,19 @@ GetSharedStorageMetadataCommand = Command[
303
313
  GetSharedStorageEntriesCommand = Command[
304
314
  GetSharedStorageEntriesParams, GetSharedStorageEntriesResponse
305
315
  ]
306
- SetSharedStorageEntryCommand = Command[SetSharedStorageEntryParams, EmptyResponse]
307
- DeleteSharedStorageEntryCommand = Command[DeleteSharedStorageEntryParams, EmptyResponse]
308
- ClearSharedStorageEntriesCommand = Command[ClearSharedStorageEntriesParams, EmptyResponse]
309
- ResetSharedStorageBudgetCommand = Command[ResetSharedStorageBudgetParams, EmptyResponse]
310
- SetSharedStorageTrackingCommand = Command[SetSharedStorageTrackingParams, EmptyResponse]
311
- SetStorageBucketTrackingCommand = Command[SetStorageBucketTrackingParams, EmptyResponse]
312
- DeleteStorageBucketCommand = Command[DeleteStorageBucketParams, EmptyResponse]
316
+ SetSharedStorageEntryCommand = Command[SetSharedStorageEntryParams, Response[EmptyResponse]]
317
+ DeleteSharedStorageEntryCommand = Command[DeleteSharedStorageEntryParams, Response[EmptyResponse]]
318
+ ClearSharedStorageEntriesCommand = Command[ClearSharedStorageEntriesParams, Response[EmptyResponse]]
319
+ ResetSharedStorageBudgetCommand = Command[ResetSharedStorageBudgetParams, Response[EmptyResponse]]
320
+ SetSharedStorageTrackingCommand = Command[SetSharedStorageTrackingParams, Response[EmptyResponse]]
321
+ SetStorageBucketTrackingCommand = Command[SetStorageBucketTrackingParams, Response[EmptyResponse]]
322
+ DeleteStorageBucketCommand = Command[DeleteStorageBucketParams, Response[EmptyResponse]]
313
323
  RunBounceTrackingMitigationsCommand = Command[EmptyParams, RunBounceTrackingMitigationsResponse]
314
324
  SetAttributionReportingLocalTestingModeCommand = Command[
315
- SetAttributionReportingLocalTestingModeParams, EmptyResponse
325
+ SetAttributionReportingLocalTestingModeParams, Response[EmptyResponse]
316
326
  ]
317
327
  SetAttributionReportingTrackingCommand = Command[
318
- SetAttributionReportingTrackingParams, EmptyResponse
328
+ SetAttributionReportingTrackingParams, Response[EmptyResponse]
319
329
  ]
320
330
  SendPendingAttributionReportsCommand = Command[EmptyParams, SendPendingAttributionReportsResponse]
321
331
  GetRelatedWebsiteSetsCommand = Command[EmptyParams, GetRelatedWebsiteSetsResponse]
@@ -323,4 +333,6 @@ GetAffectedUrlsForThirdPartyCookieMetadataCommand = Command[
323
333
  GetAffectedUrlsForThirdPartyCookieMetadataParams,
324
334
  GetAffectedUrlsForThirdPartyCookieMetadataResponse,
325
335
  ]
326
- SetProtectedAudienceKAnonymityCommand = Command[SetProtectedAudienceKAnonymityParams, EmptyResponse]
336
+ SetProtectedAudienceKAnonymityCommand = Command[
337
+ SetProtectedAudienceKAnonymityParams, Response[EmptyResponse]
338
+ ]
@@ -233,21 +233,21 @@ OpenDevToolsResponse = Response[OpenDevToolsResult]
233
233
 
234
234
 
235
235
  # Command types
236
- ActivateTargetCommand = Command[ActivateTargetParams, EmptyResponse]
236
+ ActivateTargetCommand = Command[ActivateTargetParams, Response[EmptyResponse]]
237
237
  AttachToTargetCommand = Command[AttachToTargetParams, AttachToTargetResponse]
238
238
  AttachToBrowserTargetCommand = Command[EmptyParams, AttachToBrowserTargetResponse]
239
239
  CloseTargetCommand = Command[CloseTargetParams, CloseTargetResponse]
240
- ExposeDevToolsProtocolCommand = Command[ExposeDevToolsProtocolParams, EmptyResponse]
240
+ ExposeDevToolsProtocolCommand = Command[ExposeDevToolsProtocolParams, Response[EmptyResponse]]
241
241
  CreateBrowserContextCommand = Command[CreateBrowserContextParams, CreateBrowserContextResponse]
242
242
  GetBrowserContextsCommand = Command[EmptyParams, GetBrowserContextsResponse]
243
243
  CreateTargetCommand = Command[CreateTargetParams, CreateTargetResponse]
244
- DetachFromTargetCommand = Command[DetachFromTargetParams, EmptyResponse]
245
- DisposeBrowserContextCommand = Command[DisposeBrowserContextParams, EmptyResponse]
244
+ DetachFromTargetCommand = Command[DetachFromTargetParams, Response[EmptyResponse]]
245
+ DisposeBrowserContextCommand = Command[DisposeBrowserContextParams, Response[EmptyResponse]]
246
246
  GetTargetInfoCommand = Command[GetTargetInfoParams, GetTargetInfoResponse]
247
247
  GetTargetsCommand = Command[GetTargetsParams, GetTargetsResponse]
248
- SendMessageToTargetCommand = Command[SendMessageToTargetParams, EmptyResponse]
249
- SetAutoAttachCommand = Command[SetAutoAttachParams, EmptyResponse]
250
- AutoAttachRelatedCommand = Command[AutoAttachRelatedParams, EmptyResponse]
251
- SetDiscoverTargetsCommand = Command[SetDiscoverTargetsParams, EmptyResponse]
252
- SetRemoteLocationsCommand = Command[SetRemoteLocationsParams, EmptyResponse]
248
+ SendMessageToTargetCommand = Command[SendMessageToTargetParams, Response[EmptyResponse]]
249
+ SetAutoAttachCommand = Command[SetAutoAttachParams, Response[EmptyResponse]]
250
+ AutoAttachRelatedCommand = Command[AutoAttachRelatedParams, Response[EmptyResponse]]
251
+ SetDiscoverTargetsCommand = Command[SetDiscoverTargetsParams, Response[EmptyResponse]]
252
+ SetRemoteLocationsCommand = Command[SetRemoteLocationsParams, Response[EmptyResponse]]
253
253
  OpenDevToolsCommand = Command[OpenDevToolsParams, OpenDevToolsResponse]
@@ -159,7 +159,7 @@ def validate_browser_paths(paths: list[str]) -> str:
159
159
  InvalidBrowserPath: If the browser executable is not found at the path.
160
160
  """
161
161
  for path in paths:
162
- if os.path.exists(path) and os.access(path, os.X_OK):
162
+ if os.path.isfile(path) and os.access(path, os.X_OK):
163
163
  return path
164
164
  raise InvalidBrowserPath(f'No valid browser path found in: {paths}')
165
165
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pydoll-python"
3
- version = "2.6.0"
3
+ version = "2.7.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