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.
- osn_selenium/_base_models.py +41 -0
- osn_selenium/_cdp_import.py +253 -0
- osn_selenium/abstract/executors/cdp.py +63 -0
- osn_selenium/browsers_handler/models.py +1 -1
- osn_selenium/dev_tools/_decorators.py +19 -10
- osn_selenium/dev_tools/_typehints.py +5 -2
- osn_selenium/dev_tools/_wrappers.py +0 -3
- osn_selenium/dev_tools/domains/__init__.py +2 -2
- osn_selenium/dev_tools/domains/abstract.py +1 -1
- osn_selenium/dev_tools/domains/fetch.py +1 -1
- osn_selenium/dev_tools/domains_default/fetch.py +1 -1
- osn_selenium/dev_tools/filters.py +1 -1
- osn_selenium/dev_tools/logger/main.py +0 -12
- osn_selenium/dev_tools/logger/models.py +1 -1
- osn_selenium/dev_tools/logger/target.py +42 -22
- osn_selenium/dev_tools/manager/base.py +0 -23
- osn_selenium/dev_tools/manager/lifecycle.py +1 -1
- osn_selenium/dev_tools/models.py +1 -1
- osn_selenium/dev_tools/settings.py +5 -1
- osn_selenium/dev_tools/target/base.py +12 -23
- osn_selenium/dev_tools/target/lifecycle.py +6 -1
- osn_selenium/dev_tools/target/logging.py +10 -2
- osn_selenium/exceptions/dependencies.py +60 -0
- osn_selenium/executors/sync/cdp.py +100 -0
- osn_selenium/executors/trio_threads/cdp.py +104 -0
- osn_selenium/executors/trio_threads/javascript.py +1 -1
- osn_selenium/executors/unified/javascript.py +0 -4
- osn_selenium/flags/base.py +1 -9
- osn_selenium/flags/blink.py +0 -6
- osn_selenium/flags/models/base.py +4 -4
- osn_selenium/flags/models/blink.py +1 -1
- osn_selenium/flags/models/values.py +1 -1
- osn_selenium/instances/sync/action_chains/__init__.py +6 -0
- osn_selenium/instances/sync/shadow_root.py +30 -8
- osn_selenium/instances/trio_threads/action_chains/__init__.py +6 -0
- osn_selenium/instances/trio_threads/action_chains/base.py +1 -1
- osn_selenium/instances/trio_threads/alert.py +1 -1
- osn_selenium/instances/trio_threads/browser.py +1 -1
- osn_selenium/instances/trio_threads/browsing_context.py +1 -1
- osn_selenium/instances/trio_threads/dialog.py +1 -1
- osn_selenium/instances/trio_threads/fedcm.py +1 -1
- osn_selenium/instances/trio_threads/mobile.py +1 -1
- osn_selenium/instances/trio_threads/network.py +1 -1
- osn_selenium/instances/trio_threads/permissions.py +1 -1
- osn_selenium/instances/trio_threads/script.py +1 -1
- osn_selenium/instances/trio_threads/shadow_root.py +46 -15
- osn_selenium/instances/trio_threads/storage.py +1 -1
- osn_selenium/instances/trio_threads/switch_to.py +1 -1
- osn_selenium/instances/trio_threads/web_driver_wait.py +1 -1
- osn_selenium/instances/trio_threads/web_element.py +1 -1
- osn_selenium/instances/trio_threads/web_extension.py +1 -1
- osn_selenium/javascript/fingerprint/__init__.py +1 -1
- osn_selenium/javascript/fingerprint/registry/models.py +1 -1
- osn_selenium/javascript/fingerprint/spoof/core_rules.py +1 -1
- osn_selenium/javascript/fingerprint/spoof/noise.py +1 -1
- osn_selenium/javascript/models.py +1 -1
- osn_selenium/models.py +2 -47
- osn_selenium/trio_threads_mixin.py +159 -0
- osn_selenium/webdrivers/_args_helpers.py +2 -2
- osn_selenium/webdrivers/_bridges.py +2 -2
- osn_selenium/webdrivers/_executable_tables/models.py +1 -1
- osn_selenium/webdrivers/sync/blink/__init__.py +11 -1
- osn_selenium/webdrivers/sync/blink/base.py +13 -1
- osn_selenium/webdrivers/sync/chrome/__init__.py +36 -1
- osn_selenium/webdrivers/sync/chrome/base.py +13 -1
- osn_selenium/webdrivers/sync/core/__init__.py +10 -1
- osn_selenium/webdrivers/sync/core/base.py +16 -8
- osn_selenium/webdrivers/sync/edge/__init__.py +36 -1
- osn_selenium/webdrivers/sync/edge/base.py +13 -1
- osn_selenium/webdrivers/sync/yandex/__init__.py +36 -1
- osn_selenium/webdrivers/sync/yandex/base.py +13 -1
- osn_selenium/webdrivers/trio_threads/blink/__init__.py +11 -1
- osn_selenium/webdrivers/trio_threads/blink/base.py +11 -1
- osn_selenium/webdrivers/trio_threads/blink/casting.py +1 -1
- osn_selenium/webdrivers/trio_threads/blink/features.py +1 -1
- osn_selenium/webdrivers/trio_threads/blink/logging.py +1 -1
- osn_selenium/webdrivers/trio_threads/blink/network.py +1 -1
- osn_selenium/webdrivers/trio_threads/chrome/__init__.py +34 -1
- osn_selenium/webdrivers/trio_threads/chrome/base.py +14 -2
- osn_selenium/webdrivers/trio_threads/core/__init__.py +10 -4
- osn_selenium/webdrivers/trio_threads/core/actions.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/auth.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/base.py +15 -7
- osn_selenium/webdrivers/trio_threads/core/capture.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/comonents.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/devtools.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/element.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/file.py +2 -2
- osn_selenium/webdrivers/trio_threads/core/lifecycle.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/navigation.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/script.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/settings.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/storage.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/timeouts.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/window.py +3 -3
- osn_selenium/webdrivers/trio_threads/edge/__init__.py +34 -1
- osn_selenium/webdrivers/trio_threads/edge/base.py +14 -2
- osn_selenium/webdrivers/trio_threads/yandex/__init__.py +34 -1
- osn_selenium/webdrivers/trio_threads/yandex/base.py +14 -2
- osn_selenium/webdrivers/unified/blink/base.py +5 -1
- osn_selenium/webdrivers/unified/chrome/base.py +5 -1
- osn_selenium/webdrivers/unified/core/base.py +9 -2
- osn_selenium/webdrivers/unified/edge/base.py +5 -1
- osn_selenium/webdrivers/unified/yandex/base.py +5 -1
- {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/METADATA +22 -9
- {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/RECORD +108 -101
- {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/WHEEL +1 -1
- {osn_selenium-1.0.0.dist-info → osn_selenium-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import trio
|
|
2
2
|
from typing import List, Self, Union
|
|
3
|
-
from osn_selenium.
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import trio
|
|
2
2
|
from typing import Any, Callable, Self
|
|
3
|
-
from osn_selenium.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
77
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,6 +1,6 @@
|
|
|
1
1
|
from pydantic import Field
|
|
2
2
|
from typing import Dict, List, Literal
|
|
3
|
-
from osn_selenium.
|
|
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.
|
|
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
|
|
osn_selenium/models.py
CHANGED
|
@@ -1,36 +1,8 @@
|
|
|
1
1
|
from typing import Self
|
|
2
|
-
from
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
51
|
+
result = driver.driver.execute_cdp_cmd(cmd, cmd_args)
|
|
52
52
|
|
|
53
53
|
return wrapper_function(result)
|
|
54
54
|
|
|
@@ -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
|
)
|