osn-selenium 1.0.0__py3-none-any.whl → 1.1.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.
Files changed (108) hide show
  1. osn_selenium/_base_models.py +41 -0
  2. osn_selenium/_cdp_import.py +253 -0
  3. osn_selenium/abstract/executors/cdp.py +63 -0
  4. osn_selenium/browsers_handler/models.py +1 -1
  5. osn_selenium/dev_tools/_decorators.py +19 -10
  6. osn_selenium/dev_tools/_typehints.py +5 -2
  7. osn_selenium/dev_tools/_wrappers.py +0 -3
  8. osn_selenium/dev_tools/domains/__init__.py +2 -2
  9. osn_selenium/dev_tools/domains/abstract.py +1 -1
  10. osn_selenium/dev_tools/domains/fetch.py +1 -1
  11. osn_selenium/dev_tools/domains_default/fetch.py +1 -1
  12. osn_selenium/dev_tools/filters.py +1 -1
  13. osn_selenium/dev_tools/logger/main.py +0 -12
  14. osn_selenium/dev_tools/logger/models.py +1 -1
  15. osn_selenium/dev_tools/logger/target.py +42 -22
  16. osn_selenium/dev_tools/manager/base.py +0 -23
  17. osn_selenium/dev_tools/manager/lifecycle.py +1 -1
  18. osn_selenium/dev_tools/models.py +1 -1
  19. osn_selenium/dev_tools/settings.py +5 -1
  20. osn_selenium/dev_tools/target/base.py +12 -23
  21. osn_selenium/dev_tools/target/lifecycle.py +6 -1
  22. osn_selenium/dev_tools/target/logging.py +10 -2
  23. osn_selenium/exceptions/dependencies.py +60 -0
  24. osn_selenium/executors/sync/cdp.py +100 -0
  25. osn_selenium/executors/trio_threads/cdp.py +104 -0
  26. osn_selenium/executors/trio_threads/javascript.py +1 -1
  27. osn_selenium/executors/unified/javascript.py +0 -4
  28. osn_selenium/flags/base.py +1 -9
  29. osn_selenium/flags/blink.py +0 -6
  30. osn_selenium/flags/models/base.py +4 -4
  31. osn_selenium/flags/models/blink.py +1 -1
  32. osn_selenium/flags/models/values.py +1 -1
  33. osn_selenium/instances/sync/action_chains/__init__.py +6 -0
  34. osn_selenium/instances/sync/shadow_root.py +30 -8
  35. osn_selenium/instances/trio_threads/action_chains/__init__.py +6 -0
  36. osn_selenium/instances/trio_threads/action_chains/base.py +1 -1
  37. osn_selenium/instances/trio_threads/alert.py +1 -1
  38. osn_selenium/instances/trio_threads/browser.py +1 -1
  39. osn_selenium/instances/trio_threads/browsing_context.py +1 -1
  40. osn_selenium/instances/trio_threads/dialog.py +1 -1
  41. osn_selenium/instances/trio_threads/fedcm.py +1 -1
  42. osn_selenium/instances/trio_threads/mobile.py +1 -1
  43. osn_selenium/instances/trio_threads/network.py +1 -1
  44. osn_selenium/instances/trio_threads/permissions.py +1 -1
  45. osn_selenium/instances/trio_threads/script.py +1 -1
  46. osn_selenium/instances/trio_threads/shadow_root.py +46 -15
  47. osn_selenium/instances/trio_threads/storage.py +1 -1
  48. osn_selenium/instances/trio_threads/switch_to.py +1 -1
  49. osn_selenium/instances/trio_threads/web_driver_wait.py +1 -1
  50. osn_selenium/instances/trio_threads/web_element.py +1 -1
  51. osn_selenium/instances/trio_threads/web_extension.py +1 -1
  52. osn_selenium/javascript/fingerprint/__init__.py +1 -1
  53. osn_selenium/javascript/fingerprint/registry/models.py +1 -1
  54. osn_selenium/javascript/fingerprint/spoof/core_rules.py +1 -1
  55. osn_selenium/javascript/fingerprint/spoof/noise.py +1 -1
  56. osn_selenium/javascript/models.py +1 -1
  57. osn_selenium/models.py +2 -47
  58. osn_selenium/trio_threads_mixin.py +159 -0
  59. osn_selenium/webdrivers/_args_helpers.py +2 -2
  60. osn_selenium/webdrivers/_bridges.py +2 -2
  61. osn_selenium/webdrivers/_executable_tables/models.py +1 -1
  62. osn_selenium/webdrivers/sync/blink/__init__.py +11 -1
  63. osn_selenium/webdrivers/sync/blink/base.py +13 -1
  64. osn_selenium/webdrivers/sync/chrome/__init__.py +36 -1
  65. osn_selenium/webdrivers/sync/chrome/base.py +13 -1
  66. osn_selenium/webdrivers/sync/core/__init__.py +10 -1
  67. osn_selenium/webdrivers/sync/core/base.py +16 -8
  68. osn_selenium/webdrivers/sync/edge/__init__.py +36 -1
  69. osn_selenium/webdrivers/sync/edge/base.py +13 -1
  70. osn_selenium/webdrivers/sync/yandex/__init__.py +36 -1
  71. osn_selenium/webdrivers/sync/yandex/base.py +13 -1
  72. osn_selenium/webdrivers/trio_threads/blink/__init__.py +11 -1
  73. osn_selenium/webdrivers/trio_threads/blink/base.py +11 -1
  74. osn_selenium/webdrivers/trio_threads/blink/casting.py +1 -1
  75. osn_selenium/webdrivers/trio_threads/blink/features.py +1 -1
  76. osn_selenium/webdrivers/trio_threads/blink/logging.py +1 -1
  77. osn_selenium/webdrivers/trio_threads/blink/network.py +1 -1
  78. osn_selenium/webdrivers/trio_threads/chrome/__init__.py +34 -1
  79. osn_selenium/webdrivers/trio_threads/chrome/base.py +14 -2
  80. osn_selenium/webdrivers/trio_threads/core/__init__.py +10 -4
  81. osn_selenium/webdrivers/trio_threads/core/actions.py +1 -1
  82. osn_selenium/webdrivers/trio_threads/core/auth.py +1 -1
  83. osn_selenium/webdrivers/trio_threads/core/base.py +15 -7
  84. osn_selenium/webdrivers/trio_threads/core/capture.py +1 -1
  85. osn_selenium/webdrivers/trio_threads/core/comonents.py +1 -1
  86. osn_selenium/webdrivers/trio_threads/core/devtools.py +1 -1
  87. osn_selenium/webdrivers/trio_threads/core/element.py +1 -1
  88. osn_selenium/webdrivers/trio_threads/core/file.py +2 -2
  89. osn_selenium/webdrivers/trio_threads/core/lifecycle.py +1 -1
  90. osn_selenium/webdrivers/trio_threads/core/navigation.py +1 -1
  91. osn_selenium/webdrivers/trio_threads/core/script.py +1 -1
  92. osn_selenium/webdrivers/trio_threads/core/settings.py +1 -1
  93. osn_selenium/webdrivers/trio_threads/core/storage.py +1 -1
  94. osn_selenium/webdrivers/trio_threads/core/timeouts.py +1 -1
  95. osn_selenium/webdrivers/trio_threads/core/window.py +3 -3
  96. osn_selenium/webdrivers/trio_threads/edge/__init__.py +34 -1
  97. osn_selenium/webdrivers/trio_threads/edge/base.py +14 -2
  98. osn_selenium/webdrivers/trio_threads/yandex/__init__.py +34 -1
  99. osn_selenium/webdrivers/trio_threads/yandex/base.py +14 -2
  100. osn_selenium/webdrivers/unified/blink/base.py +5 -1
  101. osn_selenium/webdrivers/unified/chrome/base.py +5 -1
  102. osn_selenium/webdrivers/unified/core/base.py +9 -2
  103. osn_selenium/webdrivers/unified/edge/base.py +5 -1
  104. osn_selenium/webdrivers/unified/yandex/base.py +5 -1
  105. {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/METADATA +22 -9
  106. {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/RECORD +108 -101
  107. {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/WHEEL +1 -1
  108. {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  import trio
2
- from osn_selenium.base_mixin import TrioThreadMixin
2
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
3
3
  from typing import (
4
4
  Dict,
5
5
  List,
@@ -1,6 +1,6 @@
1
1
  import trio
2
2
  from typing import List, Self, Union
3
- from osn_selenium.base_mixin import TrioThreadMixin
3
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
4
4
  from osn_selenium.instances._typehints import MOBILE_TYPEHINT
5
5
  from osn_selenium.instances.convert import get_legacy_instance
6
6
  from osn_selenium.instances.unified.mobile import UnifiedMobile
@@ -1,5 +1,5 @@
1
1
  import trio
2
- from osn_selenium.base_mixin import TrioThreadMixin
2
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
3
3
  from typing import (
4
4
  Callable,
5
5
  List,
@@ -1,5 +1,5 @@
1
1
  import trio
2
- from osn_selenium.base_mixin import TrioThreadMixin
2
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
3
3
  from typing import (
4
4
  Any,
5
5
  Dict,
@@ -1,6 +1,6 @@
1
1
  import trio
2
2
  from typing import Any, Callable, Self
3
- from osn_selenium.base_mixin import TrioThreadMixin
3
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
4
4
  from osn_selenium.instances._typehints import SCRIPT_TYPEHINT
5
5
  from osn_selenium.instances.convert import get_legacy_instance
6
6
  from osn_selenium.instances.unified.script import UnifiedScript
@@ -1,13 +1,14 @@
1
1
  import trio
2
2
  from selenium.webdriver.common.by import By
3
- from osn_selenium.base_mixin import TrioThreadMixin
3
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
4
+ from osn_selenium.instances._typehints import SHADOW_ROOT_TYPEHINT
4
5
  from typing import (
5
6
  List,
6
7
  Optional,
7
8
  Self,
8
- TYPE_CHECKING
9
+ TYPE_CHECKING,
10
+ Type
9
11
  )
10
- from osn_selenium.instances._typehints import SHADOW_ROOT_TYPEHINT
11
12
  from osn_selenium.exceptions.instance import (
12
13
  CannotConvertTypeError
13
14
  )
@@ -16,6 +17,9 @@ from osn_selenium.abstract.instances.shadow_root import AbstractShadowRoot
16
17
  from selenium.webdriver.remote.shadowroot import (
17
18
  ShadowRoot as legacyShadowRoot
18
19
  )
20
+ from selenium.webdriver.remote.webelement import (
21
+ WebElement as legacyWebElement
22
+ )
19
23
  from osn_selenium.instances.convert import (
20
24
  get_legacy_instance,
21
25
  get_trio_thread_instance_wrapper
@@ -27,6 +31,39 @@ __all__ = ["ShadowRoot"]
27
31
  if TYPE_CHECKING:
28
32
  from osn_selenium.instances.trio_threads.web_element import WebElement
29
33
 
34
+ _WEB_ELEMENT_TYPE: Optional[Type["WebElement"]] = None
35
+
36
+
37
+ def _build_web_element(
38
+ legacy_element: legacyWebElement,
39
+ lock: trio.Lock,
40
+ limiter: trio.CapacityLimiter,
41
+ ):
42
+ """
43
+ Builds a wrapped WebElement from a legacy element.
44
+
45
+ Args:
46
+ legacy_element (legacyWebElement): The legacy Selenium WebElement instance.
47
+ lock (trio.Lock): A Trio lock for managing concurrent access.
48
+ limiter (trio.CapacityLimiter): A Trio capacity limiter for rate limiting.
49
+
50
+ Returns:
51
+ WebElement: The wrapped WebElement instance.
52
+ """
53
+
54
+ global _WEB_ELEMENT_TYPE
55
+
56
+ if _WEB_ELEMENT_TYPE is None:
57
+ from osn_selenium.instances.trio_threads.web_element import WebElement
58
+ _WEB_ELEMENT_TYPE = WebElement
59
+
60
+ return get_trio_thread_instance_wrapper(
61
+ wrapper_class=_WEB_ELEMENT_TYPE,
62
+ legacy_object=legacy_element,
63
+ lock=lock,
64
+ limiter=limiter,
65
+ )
66
+
30
67
 
31
68
  class ShadowRoot(UnifiedShadowRoot, TrioThreadMixin, AbstractShadowRoot):
32
69
  """
@@ -58,26 +95,20 @@ class ShadowRoot(UnifiedShadowRoot, TrioThreadMixin, AbstractShadowRoot):
58
95
  async def find_element(self, by: str = By.ID, value: Optional[str] = None) -> "WebElement":
59
96
  legacy_element = await self.sync_to_trio(sync_function=self._find_element_impl)(by=by, value=value)
60
97
 
61
- from osn_selenium.instances.trio_threads.web_element import WebElement
62
-
63
- return get_trio_thread_instance_wrapper(
64
- wrapper_class=WebElement,
65
- legacy_object=legacy_element,
98
+ return _build_web_element(
99
+ legacy_element=legacy_element,
66
100
  lock=self._lock,
67
- limiter=self._capacity_limiter
101
+ limiter=self._capacity_limiter,
68
102
  )
69
103
 
70
104
  async def find_elements(self, by: str = By.ID, value: Optional[str] = None) -> List["WebElement"]:
71
105
  legacy_elements = await self.sync_to_trio(sync_function=self._find_elements_impl)(by=by, value=value)
72
106
 
73
- from osn_selenium.instances.trio_threads.web_element import WebElement
74
-
75
107
  return [
76
- get_trio_thread_instance_wrapper(
77
- wrapper_class=WebElement,
78
- legacy_object=legacy_element,
108
+ _build_web_element(
109
+ legacy_element=legacy_element,
79
110
  lock=self._lock,
80
- limiter=self._capacity_limiter
111
+ limiter=self._capacity_limiter,
81
112
  )
82
113
  for legacy_element in legacy_elements
83
114
  ]
@@ -4,7 +4,7 @@ from typing import (
4
4
  Self,
5
5
  Union
6
6
  )
7
- from osn_selenium.base_mixin import TrioThreadMixin
7
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
8
8
  from osn_selenium.instances._typehints import STORAGE_TYPEHINT
9
9
  from osn_selenium.instances.convert import get_legacy_instance
10
10
  from osn_selenium.instances.unified.storage import UnifiedStorage
@@ -4,7 +4,7 @@ from typing import (
4
4
  Self,
5
5
  Union
6
6
  )
7
- from osn_selenium.base_mixin import TrioThreadMixin
7
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
8
8
  from osn_selenium.instances.trio_threads.alert import Alert
9
9
  from osn_selenium.instances.unified.switch_to import UnifiedSwitchTo
10
10
  from osn_selenium.abstract.instances.switch_to import AbstractSwitchTo
@@ -4,7 +4,7 @@ from typing import (
4
4
  Self,
5
5
  TypeVar
6
6
  )
7
- from osn_selenium.base_mixin import TrioThreadMixin
7
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
8
8
  from osn_selenium.instances.convert import get_legacy_instance
9
9
  from osn_selenium.exceptions.instance import (
10
10
  CannotConvertTypeError
@@ -1,6 +1,6 @@
1
1
  import trio
2
2
  from selenium.webdriver.common.by import By
3
- from osn_selenium.base_mixin import TrioThreadMixin
3
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
4
4
  from osn_selenium.instances._typehints import WEB_ELEMENT_TYPEHINT
5
5
  from typing import (
6
6
  Any,
@@ -1,5 +1,5 @@
1
1
  import trio
2
- from osn_selenium.base_mixin import TrioThreadMixin
2
+ from osn_selenium.trio_threads_mixin import TrioThreadMixin
3
3
  from typing import (
4
4
  Dict,
5
5
  Optional,
@@ -1,6 +1,6 @@
1
1
  from pydantic import Field
2
2
  from typing import Dict, List, Literal
3
- from osn_selenium.models import DictModel
3
+ from osn_selenium._base_models import DictModel
4
4
  from osn_selenium.javascript.functions import get_js_scripts
5
5
  from osn_selenium.javascript.fingerprint._functions import add_code_level
6
6
  from osn_selenium.javascript.fingerprint.registry.models import RegistryItem
@@ -1,6 +1,6 @@
1
1
  from pydantic import Field
2
2
  from typing import Any, Dict, Optional
3
- from osn_selenium.models import DictModel
3
+ from osn_selenium._base_models import DictModel
4
4
  from osn_selenium.javascript.fingerprint._typehints import SPOOF_RULE_TYPEHINT
5
5
  from osn_selenium.javascript.fingerprint.registry._typehints import ITEM_TYPE_TYPEHINT
6
6
 
@@ -1,4 +1,4 @@
1
- from osn_selenium.models import DictModel
1
+ from osn_selenium._base_models import DictModel
2
2
  from pydantic import (
3
3
  Field,
4
4
  model_validator
@@ -1,6 +1,6 @@
1
1
  from pydantic import Field
2
2
  from typing import Any, Literal
3
- from osn_selenium.models import DictModel
3
+ from osn_selenium._base_models import DictModel
4
4
  from osn_selenium.javascript.fingerprint.spoof._typehints import (
5
5
  NOISE_TYPEHINT,
6
6
  RANDOM_NOISE_TYPEHINT
@@ -1,4 +1,4 @@
1
- from osn_selenium.models import DictModel
1
+ from osn_selenium._base_models import DictModel
2
2
 
3
3
 
4
4
  __all__ = ["JS_Scripts"]
osn_selenium/models.py CHANGED
@@ -1,36 +1,8 @@
1
1
  from typing import Self
2
- from pydantic import (
3
- BaseModel,
4
- ConfigDict
5
- )
2
+ from osn_selenium._base_models import DictModel
6
3
 
7
4
 
8
- __all__ = [
9
- "DictModel",
10
- "ExtraDictModel",
11
- "Point",
12
- "Position",
13
- "Rectangle",
14
- "Size",
15
- "WindowRect"
16
- ]
17
-
18
-
19
- class DictModel(BaseModel):
20
- """
21
- Base class for Pydantic models with a predefined configuration.
22
-
23
- This configuration enforces strict validation rules such as forbidding extra
24
- fields and stripping whitespace from string inputs.
25
- """
26
-
27
- model_config = ConfigDict(
28
- populate_by_name=True,
29
- extra="forbid",
30
- use_enum_values=True,
31
- str_strip_whitespace=True,
32
- validate_assignment=True,
33
- )
5
+ __all__ = ["Point", "Position", "Rectangle", "Size", "WindowRect"]
34
6
 
35
7
 
36
8
  class WindowRect(DictModel):
@@ -120,20 +92,3 @@ class Point:
120
92
 
121
93
  def __ne__(self, other: Self) -> bool:
122
94
  return not self.__eq__(other)
123
-
124
-
125
- class ExtraDictModel(BaseModel):
126
- """
127
- Base class for Pydantic models that allows extra fields.
128
-
129
- This configuration allows the model to accept fields that are not
130
- explicitly defined in the model's schema.
131
- """
132
-
133
- model_config = ConfigDict(
134
- populate_by_name=True,
135
- extra="allow",
136
- use_enum_values=True,
137
- str_strip_whitespace=True,
138
- validate_assignment=True,
139
- )
@@ -0,0 +1,159 @@
1
+ import sys
2
+ import trio
3
+ from contextlib import asynccontextmanager
4
+ from typing import (
5
+ Any,
6
+ AsyncContextManager,
7
+ AsyncIterator,
8
+ Callable,
9
+ ContextManager,
10
+ Coroutine,
11
+ ParamSpec,
12
+ TypeVar
13
+ )
14
+
15
+
16
+ __all__ = ["TrioThreadMixin"]
17
+
18
+ _METHOD_INPUT = ParamSpec("_METHOD_INPUT")
19
+ _METHOD_OUTPUT = TypeVar("_METHOD_OUTPUT")
20
+
21
+
22
+ class TrioThreadMixin:
23
+ """
24
+ Provides utilities for running synchronous functions in a Trio event loop
25
+ with a controlled concurrency, ensuring thread safety and resource limits.
26
+ """
27
+
28
+ def __init__(self, lock: trio.Lock, limiter: trio.CapacityLimiter) -> None:
29
+ """
30
+ Initializes the TrioThreadMixin with a Trio Lock and CapacityLimiter.
31
+
32
+ Args:
33
+ lock (trio.Lock): A Trio Lock for synchronization.
34
+ limiter (trio.CapacityLimiter): A limiter to control thread pool concurrency.
35
+ """
36
+
37
+ self._lock = lock
38
+ self._capacity_limiter = limiter
39
+
40
+ @property
41
+ def capacity_limiter(self) -> trio.CapacityLimiter:
42
+ """
43
+ The Trio CapacityLimiter used for concurrency control.
44
+
45
+ Returns:
46
+ trio.CapacityLimiter: The limiter instance.
47
+ """
48
+
49
+ return self._capacity_limiter
50
+
51
+ @property
52
+ def lock(self) -> trio.Lock:
53
+ """
54
+ The Trio Lock used for synchronization.
55
+
56
+ Returns:
57
+ trio.Lock: The lock instance.
58
+ """
59
+
60
+ return self._lock
61
+
62
+ def sync_to_trio(
63
+ self,
64
+ sync_function: Callable[_METHOD_INPUT, _METHOD_OUTPUT],
65
+ lock: bool = True,
66
+ ) -> Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]:
67
+ """
68
+ Wraps a synchronous function to run within a Trio thread pool using a lock and limiter.
69
+
70
+ Args:
71
+ sync_function (Callable[_METHOD_INPUT, _METHOD_OUTPUT]): The synchronous function to wrap.
72
+ lock (bool): Whether to use the internal lock for synchronization.
73
+
74
+ Returns:
75
+ Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]: An async wrapper for the sync function.
76
+ """
77
+
78
+ async def wrapper(*args: _METHOD_INPUT.args, **kwargs: _METHOD_INPUT.kwargs) -> _METHOD_OUTPUT:
79
+ """
80
+ Internal async wrapper for the synchronous function.
81
+
82
+ Args:
83
+ *args (_METHOD_INPUT.args): Positional arguments for the sync function.
84
+ **kwargs (_METHOD_INPUT.kwargs): Keyword arguments for the sync function.
85
+
86
+ Returns:
87
+ _METHOD_OUTPUT: The result of the synchronous function execution.
88
+ """
89
+
90
+ def function_with_kwargs(*args_) -> _METHOD_OUTPUT:
91
+ """
92
+ Helper to pass keyword arguments to trio.to_thread.run_sync.
93
+
94
+ Args:
95
+ *args_: Positional arguments passed from the outer scope.
96
+
97
+ Returns:
98
+ _METHOD_OUTPUT: Result of the original sync function.
99
+ """
100
+
101
+ return sync_function(*args_, **kwargs)
102
+
103
+ if lock:
104
+ async with self._lock:
105
+ result = await trio.to_thread.run_sync(function_with_kwargs, *args, limiter=self._capacity_limiter)
106
+ else:
107
+ result = await trio.to_thread.run_sync(function_with_kwargs, *args, limiter=self._capacity_limiter)
108
+
109
+ return result
110
+
111
+ return wrapper
112
+
113
+ def sync_to_trio_context(
114
+ self,
115
+ context_manager_factory: Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]],
116
+ lock: bool = True,
117
+ ) -> Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]:
118
+ """
119
+ Converts a synchronous context manager factory to an asynchronous Trio-compatible context manager.
120
+
121
+ Args:
122
+ context_manager_factory (Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]]): A factory function returning a context manager.
123
+ lock (bool): Whether to use the internal lock for synchronization.
124
+
125
+ Returns:
126
+ Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]: An async function returning an async context manager.
127
+ """
128
+
129
+ @asynccontextmanager
130
+ async def wrapper(*args: _METHOD_INPUT.args, **kwargs: _METHOD_INPUT.kwargs) -> AsyncIterator[_METHOD_OUTPUT]:
131
+ """
132
+ Internal async context manager wrapper.
133
+
134
+ Args:
135
+ *args (_METHOD_INPUT.args): Positional arguments for the factory.
136
+ **kwargs (_METHOD_INPUT.kwargs): Keyword arguments for the factory.
137
+
138
+ Returns:
139
+ AsyncIterator[_METHOD_OUTPUT]: An async iterator yielding the context resource.
140
+ """
141
+
142
+ sync_context_manager = await self.sync_to_trio(sync_function=context_manager_factory, lock=lock)(*args, **kwargs)
143
+
144
+ enter_ = self.sync_to_trio(sync_function=sync_context_manager.__enter__, lock=lock)
145
+ exit_ = self.sync_to_trio(sync_function=sync_context_manager.__exit__, lock=lock)
146
+
147
+ try:
148
+ result = await enter_()
149
+
150
+ yield result
151
+ except Exception as e:
152
+ exc_type, exc_val, exc_tb = sys.exc_info()
153
+
154
+ if not await exit_(exc_type, exc_val, exc_tb):
155
+ raise e
156
+ else:
157
+ await exit_(None, None, None)
158
+
159
+ return wrapper
@@ -146,13 +146,13 @@ def get_wrap_args_function(driver: ANY_WEBDRIVER_PROTOCOL_TYPEHINT) -> Callable[
146
146
  ExpectedTypeError: If the driver instance type is not supported.
147
147
  """
148
148
 
149
- if isinstance(driver, SyncWebDriver) and driver._architecture_impl == "sync":
149
+ if isinstance(driver, SyncWebDriver) and driver.architecture == "sync":
150
150
  def wrapper(args: Any) -> Any:
151
151
  return wrap_sync_args(args)
152
152
 
153
153
  return wrapper
154
154
 
155
- if isinstance(driver, TrioThreadWebDriver) and driver._architecture_impl == "trio_threads":
155
+ if isinstance(driver, TrioThreadWebDriver) and driver.architecture == "trio_threads":
156
156
  def wrapper(args: Any) -> Any:
157
157
  return wrap_trio_thread_args(args, lock=driver.lock, limiter=driver.capacity_limiter)
158
158
 
@@ -25,7 +25,7 @@ def get_js_executor_bridge(driver: ANY_WEBDRIVER_PROTOCOL_TYPEHINT) -> Callable[
25
25
  def wrapper(script: str, *args: Any) -> Any:
26
26
  args = unwrap_args(args)
27
27
 
28
- result = driver._driver_impl.execute_script(script, *args)
28
+ result = driver.driver.execute_script(script, *args)
29
29
 
30
30
  return wrapper_function(result)
31
31
 
@@ -48,7 +48,7 @@ def get_cdp_executor_bridge(driver: ANY_WEBDRIVER_PROTOCOL_TYPEHINT) -> Callable
48
48
  def wrapper(cmd: str, cmd_args: Dict[str, Any]) -> Any:
49
49
  cmd_args = unwrap_args(cmd_args)
50
50
 
51
- result = driver._driver_impl.execute_cdp_cmd(cmd, cmd_args)
51
+ result = driver.driver.execute_cdp_cmd(cmd, cmd_args)
52
52
 
53
53
  return wrapper_function(result)
54
54
 
@@ -1,4 +1,4 @@
1
- from osn_selenium.models import DictModel
1
+ from osn_selenium._base_models import DictModel
2
2
 
3
3
 
4
4
  __all__ = ["ExecutablesTableRow"]
@@ -1,5 +1,9 @@
1
- from typing import Optional, Type
2
1
  from osn_selenium.models import WindowRect
2
+ from typing import (
3
+ Mapping,
4
+ Optional,
5
+ Type
6
+ )
3
7
  from osn_selenium._typehints import PATH_TYPEHINT
4
8
  from osn_selenium.flags.blink import BlinkFlagsManager
5
9
  from osn_selenium.flags.models.blink import BlinkFlags
@@ -50,6 +54,8 @@ class BlinkWebDriver(
50
54
  page_load_timeout: int = 5,
51
55
  script_timeout: int = 5,
52
56
  window_rect: Optional[WindowRect] = None,
57
+ cdp_versioned_packages_paths: Optional[Mapping[int, PATH_TYPEHINT]] = None,
58
+ ignore_cdp_version_package_missing: bool = True,
53
59
  ):
54
60
  """
55
61
  Initializes the BlinkWebDriver instance.
@@ -95,6 +101,8 @@ class BlinkWebDriver(
95
101
  page_load_timeout=page_load_timeout,
96
102
  script_timeout=script_timeout,
97
103
  window_rect=window_rect,
104
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
105
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
98
106
  )
99
107
 
100
108
  BlinkBaseMixin.__init__(
@@ -111,4 +119,6 @@ class BlinkWebDriver(
111
119
  page_load_timeout=page_load_timeout,
112
120
  script_timeout=script_timeout,
113
121
  window_rect=window_rect,
122
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
123
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
114
124
  )
@@ -1,6 +1,10 @@
1
1
  import pathlib
2
- from typing import Optional, Type
3
2
  from osn_selenium.models import WindowRect
3
+ from typing import (
4
+ Mapping,
5
+ Optional,
6
+ Type
7
+ )
4
8
  from osn_selenium.flags.blink import BlinkFlagsManager
5
9
  from osn_selenium.flags.models.blink import BlinkFlags
6
10
  from osn_selenium.webdrivers.sync.core.base import CoreBaseMixin
@@ -45,6 +49,8 @@ class BlinkBaseMixin(UnifiedBlinkBaseMixin, CoreBaseMixin, AbstractBlinkBaseMixi
45
49
  page_load_timeout: int = 5,
46
50
  script_timeout: int = 5,
47
51
  window_rect: Optional[WindowRect] = None,
52
+ cdp_versioned_packages_paths: Optional[Mapping[int, PATH_TYPEHINT]] = None,
53
+ ignore_cdp_version_package_missing: bool = True,
48
54
  ):
49
55
  """
50
56
  Initializes the BlinkWebDriver instance.
@@ -79,6 +85,8 @@ class BlinkBaseMixin(UnifiedBlinkBaseMixin, CoreBaseMixin, AbstractBlinkBaseMixi
79
85
  script_timeout (int): The default asynchronous script timeout in seconds. Defaults to 5.
80
86
  window_rect (Optional[WindowRect]): The initial window size and position. If None,
81
87
  the browser's default window size will be used. Defaults to None.
88
+ cdp_versioned_packages_paths (Optional[Mapping[int, PATH_TYPEHINT]]): Custom local paths for specific CDP versions packages.
89
+ ignore_cdp_version_package_missing (bool): Whether to ignore missing CDP package errors.
82
90
  """
83
91
 
84
92
  CoreBaseMixin.__init__(
@@ -90,6 +98,8 @@ class BlinkBaseMixin(UnifiedBlinkBaseMixin, CoreBaseMixin, AbstractBlinkBaseMixi
90
98
  page_load_timeout=page_load_timeout,
91
99
  script_timeout=script_timeout,
92
100
  window_rect=window_rect,
101
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
102
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
93
103
  )
94
104
 
95
105
  UnifiedBlinkBaseMixin.__init__(
@@ -106,6 +116,8 @@ class BlinkBaseMixin(UnifiedBlinkBaseMixin, CoreBaseMixin, AbstractBlinkBaseMixi
106
116
  page_load_timeout=page_load_timeout,
107
117
  script_timeout=script_timeout,
108
118
  window_rect=window_rect,
119
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
120
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
109
121
  )
110
122
 
111
123
  @property
@@ -1,5 +1,9 @@
1
- from typing import Optional, Type
2
1
  from osn_selenium.models import WindowRect
2
+ from typing import (
3
+ Mapping,
4
+ Optional,
5
+ Type
6
+ )
3
7
  from osn_selenium._typehints import PATH_TYPEHINT
4
8
  from osn_selenium.flags.chrome import ChromeFlagsManager
5
9
  from osn_selenium.flags.models.chrome import ChromeFlags
@@ -35,7 +39,34 @@ class ChromeWebDriver(
35
39
  page_load_timeout: int = 5,
36
40
  script_timeout: int = 5,
37
41
  window_rect: Optional[WindowRect] = None,
42
+ cdp_versioned_packages_paths: Optional[Mapping[int, PATH_TYPEHINT]] = None,
43
+ ignore_cdp_version_package_missing: bool = True,
38
44
  ):
45
+ """
46
+ Initializes the synchronous Chrome WebDriver with specified configuration.
47
+
48
+ Args:
49
+ webdriver_path (str): Path to the ChromeDriver executable.
50
+ flags_manager_type (Type[ChromeFlagsManager]): The class type used for managing Chrome flags.
51
+ Defaults to ChromeFlagsManager.
52
+ use_browser_exe (bool): Whether to use a specific browser executable path or auto-detect.
53
+ Defaults to True.
54
+ browser_name_in_system (str): The name of the browser in the system registry or path.
55
+ Defaults to "Google Chrome".
56
+ browser_exe (Optional[PATH_TYPEHINT]): Explicit path to the Chrome browser executable.
57
+ If None, it may be auto-detected based on other parameters.
58
+ flags (Optional[ChromeFlags]): Initial set of flags to configure the Chrome instance.
59
+ start_page_url (str): The URL to navigate to immediately upon startup.
60
+ Defaults to "about:blank".
61
+ implicitly_wait (int): Default implicit wait time in seconds. Defaults to 5.
62
+ page_load_timeout (int): Default page load timeout in seconds. Defaults to 5.
63
+ script_timeout (int): Default script execution timeout in seconds. Defaults to 5.
64
+ window_rect (Optional[WindowRect]): Initial window dimensions and position.
65
+ If None, browser defaults are used.
66
+ cdp_versioned_packages_paths (Optional[Mapping[int, PATH_TYPEHINT]]): Custom local paths for specific CDP versions packages.
67
+ ignore_cdp_version_package_missing (bool): Whether to ignore missing CDP package errors.
68
+ """
69
+
39
70
  BlinkWebDriver.__init__(
40
71
  self,
41
72
  browser_exe=browser_exe,
@@ -48,6 +79,8 @@ class ChromeWebDriver(
48
79
  page_load_timeout=page_load_timeout,
49
80
  script_timeout=script_timeout,
50
81
  window_rect=window_rect,
82
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
83
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
51
84
  )
52
85
 
53
86
  ChromeBaseMixin.__init__(
@@ -64,4 +97,6 @@ class ChromeWebDriver(
64
97
  page_load_timeout=page_load_timeout,
65
98
  script_timeout=script_timeout,
66
99
  window_rect=window_rect,
100
+ cdp_versioned_packages_paths=cdp_versioned_packages_paths,
101
+ ignore_cdp_version_package_missing=ignore_cdp_version_package_missing,
67
102
  )