osn-selenium 1.1.0__py3-none-any.whl → 1.2.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/_decorators.py +57 -0
- osn_selenium/_trio_threads_helpers.py +157 -0
- osn_selenium/_typehints.py +1 -1
- osn_selenium/abstract/webdriver/blink/base.py +14 -0
- osn_selenium/abstract/webdriver/blink/lifecycle.py +8 -8
- osn_selenium/abstract/webdriver/core/base.py +0 -14
- osn_selenium/abstract/webdriver/core/capture.py +4 -3
- osn_selenium/abstract/webdriver/core/lifecycle.py +8 -8
- osn_selenium/abstract/webdriver/core/script.py +5 -4
- osn_selenium/abstract/webdriver/core/window.py +11 -11
- osn_selenium/dev_tools/_decorators.py +1 -42
- osn_selenium/dev_tools/_functions.py +2 -4
- osn_selenium/dev_tools/domains/__init__.py +1 -1
- osn_selenium/dev_tools/domains/fetch.py +5 -7
- osn_selenium/dev_tools/domains_default/fetch.py +1 -1
- osn_selenium/dev_tools/logger/main.py +9 -9
- osn_selenium/dev_tools/logger/target.py +7 -7
- osn_selenium/dev_tools/manager/base.py +10 -19
- osn_selenium/dev_tools/manager/lifecycle.py +83 -74
- osn_selenium/dev_tools/manager/logging.py +1 -1
- osn_selenium/dev_tools/manager/targets.py +13 -5
- osn_selenium/dev_tools/settings.py +4 -4
- osn_selenium/dev_tools/target/base.py +18 -11
- osn_selenium/dev_tools/target/discovery.py +1 -1
- osn_selenium/dev_tools/target/events.py +2 -2
- osn_selenium/dev_tools/target/fingerprint.py +1 -1
- osn_selenium/dev_tools/target/lifecycle.py +103 -43
- osn_selenium/dev_tools/target/logging.py +1 -1
- osn_selenium/exceptions/__init__.py +0 -1
- osn_selenium/exceptions/base.py +28 -1
- osn_selenium/exceptions/bidi_bridge.py +59 -0
- osn_selenium/exceptions/configuration.py +1 -8
- osn_selenium/exceptions/dependencies.py +2 -2
- osn_selenium/exceptions/devtools.py +9 -39
- osn_selenium/exceptions/experimental.py +26 -0
- osn_selenium/exceptions/flags.py +0 -2
- osn_selenium/exceptions/instance.py +1 -9
- osn_selenium/exceptions/javascript.py +0 -2
- osn_selenium/exceptions/logic.py +0 -2
- osn_selenium/exceptions/path.py +1 -9
- osn_selenium/exceptions/platform.py +0 -2
- osn_selenium/exceptions/protocol.py +0 -3
- osn_selenium/exceptions/webdriver.py +1 -7
- osn_selenium/exceptions/window.py +1 -8
- osn_selenium/executors/sync/cdp.py +0 -5
- osn_selenium/executors/trio_bidi/cdp.py +101 -0
- osn_selenium/executors/trio_bidi/javascript.py +101 -0
- osn_selenium/executors/trio_threads/cdp.py +0 -5
- osn_selenium/flags/base.py +6 -4
- osn_selenium/flags/blink.py +2 -2
- osn_selenium/flags/chrome.py +6 -6
- osn_selenium/flags/edge.py +6 -6
- osn_selenium/instances/convert.py +44 -3
- osn_selenium/instances/protocols.py +47 -1
- osn_selenium/instances/sync/browsing_context.py +2 -2
- osn_selenium/instances/sync/script.py +7 -2
- osn_selenium/instances/sync/web_element.py +1 -1
- osn_selenium/instances/trio_bidi/__init__.py +1 -0
- osn_selenium/instances/trio_bidi/shadow_root.py +180 -0
- osn_selenium/instances/trio_bidi/switch_to.py +143 -0
- osn_selenium/instances/trio_bidi/web_driver_wait.py +124 -0
- osn_selenium/instances/trio_bidi/web_element.py +239 -0
- osn_selenium/instances/trio_threads/browsing_context.py +2 -2
- osn_selenium/instances/trio_threads/fedcm.py +1 -1
- osn_selenium/instances/trio_threads/network.py +1 -1
- osn_selenium/instances/trio_threads/script.py +7 -2
- osn_selenium/instances/trio_threads/web_extension.py +1 -1
- osn_selenium/instances/unified/browsing_context.py +2 -2
- osn_selenium/instances/unified/script.py +2 -2
- osn_selenium/instances/unified/web_element.py +3 -5
- osn_selenium/javascript/fingerprint/__init__.py +2 -1
- osn_selenium/trio_bidi/__init__.py +1 -0
- osn_selenium/trio_bidi/_context_vars.py +12 -0
- osn_selenium/trio_bidi/_error_mappings.py +123 -0
- osn_selenium/trio_bidi/_error_redirects.py +194 -0
- osn_selenium/trio_bidi/_file_functions.py +28 -0
- osn_selenium/trio_bidi/_internal_mappings.py +10 -0
- osn_selenium/trio_bidi/_models.py +199 -0
- osn_selenium/trio_bidi/_typehints.py +20 -0
- osn_selenium/trio_bidi/connection_pool.py +587 -0
- osn_selenium/trio_bidi/mapping/__init__.py +1 -0
- osn_selenium/trio_bidi/mapping/_constants.py +14 -0
- osn_selenium/trio_bidi/mapping/_js_snippets.py +285 -0
- osn_selenium/trio_bidi/mapping/_utils.py +4 -0
- osn_selenium/trio_bidi/mapping/request_functions/__init__.py +87 -0
- osn_selenium/trio_bidi/mapping/request_functions/_alert.py +102 -0
- osn_selenium/trio_bidi/mapping/request_functions/_args_helpers.py +225 -0
- osn_selenium/trio_bidi/mapping/request_functions/_capture.py +71 -0
- osn_selenium/trio_bidi/mapping/request_functions/_cdp.py +40 -0
- osn_selenium/trio_bidi/mapping/request_functions/_element.py +55 -0
- osn_selenium/trio_bidi/mapping/request_functions/_file.py +32 -0
- osn_selenium/trio_bidi/mapping/request_functions/_navigation.py +147 -0
- osn_selenium/trio_bidi/mapping/request_functions/_script.py +85 -0
- osn_selenium/trio_bidi/mapping/request_functions/_shadow_root.py +65 -0
- osn_selenium/trio_bidi/mapping/request_functions/_switch_to.py +59 -0
- osn_selenium/trio_bidi/mapping/request_functions/_web_element.py +448 -0
- osn_selenium/trio_bidi/mapping/request_functions/_window.py +125 -0
- osn_selenium/trio_bidi/mapping/response_functions/__init__.py +86 -0
- osn_selenium/trio_bidi/mapping/response_functions/_alert.py +81 -0
- osn_selenium/trio_bidi/mapping/response_functions/_args_helpers.py +183 -0
- osn_selenium/trio_bidi/mapping/response_functions/_args_validators.py +153 -0
- osn_selenium/trio_bidi/mapping/response_functions/_capture.py +71 -0
- osn_selenium/trio_bidi/mapping/response_functions/_cdp.py +26 -0
- osn_selenium/trio_bidi/mapping/response_functions/_element.py +58 -0
- osn_selenium/trio_bidi/mapping/response_functions/_file.py +30 -0
- osn_selenium/trio_bidi/mapping/response_functions/_navigation.py +120 -0
- osn_selenium/trio_bidi/mapping/response_functions/_script.py +57 -0
- osn_selenium/trio_bidi/mapping/response_functions/_shadow_root.py +58 -0
- osn_selenium/trio_bidi/mapping/response_functions/_switch_to.py +57 -0
- osn_selenium/trio_bidi/mapping/response_functions/_web_element.py +368 -0
- osn_selenium/trio_bidi/mapping/response_functions/_window.py +119 -0
- osn_selenium/trio_bidi/mixin.py +186 -0
- osn_selenium/trio_bidi/remote_connection.py +164 -0
- osn_selenium/trio_threads_mixin.py +22 -68
- osn_selenium/webdrivers/_args_helpers.py +118 -5
- osn_selenium/webdrivers/_typehints.py +9 -3
- osn_selenium/webdrivers/protocols.py +81 -1
- osn_selenium/webdrivers/sync/blink/base.py +10 -0
- osn_selenium/webdrivers/sync/blink/lifecycle.py +26 -8
- osn_selenium/webdrivers/sync/chrome/lifecycle.py +23 -5
- osn_selenium/webdrivers/sync/chrome/settings.py +6 -1
- osn_selenium/webdrivers/sync/core/base.py +3 -11
- osn_selenium/webdrivers/sync/core/capture.py +3 -2
- osn_selenium/webdrivers/sync/core/file.py +3 -2
- osn_selenium/webdrivers/sync/core/lifecycle.py +44 -10
- osn_selenium/webdrivers/sync/core/script.py +3 -2
- osn_selenium/webdrivers/sync/core/window.py +3 -3
- osn_selenium/webdrivers/sync/edge/lifecycle.py +23 -5
- osn_selenium/webdrivers/sync/edge/settings.py +6 -1
- osn_selenium/webdrivers/sync/yandex/lifecycle.py +23 -5
- osn_selenium/webdrivers/sync/yandex/settings.py +6 -1
- osn_selenium/webdrivers/trio_bidi/__init__.py +1 -0
- osn_selenium/webdrivers/trio_bidi/blink/__init__.py +132 -0
- osn_selenium/webdrivers/trio_bidi/blink/base.py +167 -0
- osn_selenium/webdrivers/trio_bidi/blink/lifecycle.py +89 -0
- osn_selenium/webdrivers/trio_bidi/blink/settings.py +63 -0
- osn_selenium/webdrivers/trio_bidi/chrome/__init__.py +114 -0
- osn_selenium/webdrivers/trio_bidi/chrome/base.py +127 -0
- osn_selenium/webdrivers/trio_bidi/chrome/lifecycle.py +85 -0
- osn_selenium/webdrivers/trio_bidi/chrome/settings.py +63 -0
- osn_selenium/webdrivers/trio_bidi/core/__init__.py +95 -0
- osn_selenium/webdrivers/trio_bidi/core/actions.py +70 -0
- osn_selenium/webdrivers/trio_bidi/core/base.py +200 -0
- osn_selenium/webdrivers/trio_bidi/core/capture.py +39 -0
- osn_selenium/webdrivers/trio_bidi/core/devtools.py +49 -0
- osn_selenium/webdrivers/trio_bidi/core/element.py +64 -0
- osn_selenium/webdrivers/trio_bidi/core/lifecycle.py +135 -0
- osn_selenium/webdrivers/trio_bidi/core/navigation.py +37 -0
- osn_selenium/webdrivers/trio_bidi/core/script.py +56 -0
- osn_selenium/webdrivers/trio_bidi/core/settings.py +36 -0
- osn_selenium/webdrivers/trio_bidi/core/window.py +134 -0
- osn_selenium/webdrivers/trio_bidi/edge/__init__.py +114 -0
- osn_selenium/webdrivers/trio_bidi/edge/base.py +123 -0
- osn_selenium/webdrivers/trio_bidi/edge/lifecycle.py +85 -0
- osn_selenium/webdrivers/trio_bidi/edge/settings.py +63 -0
- osn_selenium/webdrivers/trio_bidi/yandex/__init__.py +114 -0
- osn_selenium/webdrivers/trio_bidi/yandex/base.py +120 -0
- osn_selenium/webdrivers/trio_bidi/yandex/lifecycle.py +85 -0
- osn_selenium/webdrivers/trio_bidi/yandex/settings.py +63 -0
- osn_selenium/webdrivers/trio_threads/blink/__init__.py +7 -1
- osn_selenium/webdrivers/trio_threads/blink/base.py +14 -0
- osn_selenium/webdrivers/trio_threads/blink/lifecycle.py +26 -8
- osn_selenium/webdrivers/trio_threads/chrome/lifecycle.py +23 -5
- osn_selenium/webdrivers/trio_threads/chrome/settings.py +1 -1
- osn_selenium/webdrivers/trio_threads/core/__init__.py +0 -10
- 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 +4 -16
- osn_selenium/webdrivers/trio_threads/core/capture.py +3 -2
- osn_selenium/webdrivers/trio_threads/core/file.py +3 -2
- osn_selenium/webdrivers/trio_threads/core/lifecycle.py +44 -10
- osn_selenium/webdrivers/trio_threads/core/script.py +3 -2
- 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 +4 -4
- osn_selenium/webdrivers/trio_threads/edge/lifecycle.py +23 -5
- osn_selenium/webdrivers/trio_threads/edge/settings.py +1 -1
- osn_selenium/webdrivers/trio_threads/yandex/lifecycle.py +23 -5
- osn_selenium/webdrivers/trio_threads/yandex/settings.py +1 -1
- osn_selenium/webdrivers/unified/blink/base.py +5 -1
- osn_selenium/webdrivers/unified/blink/lifecycle.py +4 -2
- osn_selenium/webdrivers/unified/chrome/base.py +5 -1
- osn_selenium/webdrivers/unified/core/auth.py +4 -2
- osn_selenium/webdrivers/unified/core/base.py +16 -10
- osn_selenium/webdrivers/unified/core/capture.py +3 -2
- osn_selenium/webdrivers/unified/core/components.py +12 -7
- osn_selenium/webdrivers/unified/core/devtools.py +2 -1
- osn_selenium/webdrivers/unified/core/file.py +3 -2
- osn_selenium/webdrivers/unified/core/lifecycle.py +5 -3
- osn_selenium/webdrivers/unified/core/script.py +5 -3
- osn_selenium/webdrivers/unified/core/storage.py +2 -1
- osn_selenium/webdrivers/unified/core/window.py +9 -8
- osn_selenium/webdrivers/unified/edge/base.py +5 -1
- osn_selenium/webdrivers/unified/yandex/base.py +5 -1
- {osn_selenium-1.1.0.dist-info → osn_selenium-1.2.0.dist-info}/METADATA +3 -2
- osn_selenium-1.2.0.dist-info/RECORD +480 -0
- osn_selenium/abstract/executors/cdp/__init__.py +0 -435
- osn_selenium/abstract/executors/cdp/accessibility.py +0 -62
- osn_selenium/abstract/executors/cdp/animation.py +0 -47
- osn_selenium/abstract/executors/cdp/audits.py +0 -39
- osn_selenium/abstract/executors/cdp/autofill.py +0 -34
- osn_selenium/abstract/executors/cdp/background_service.py +0 -22
- osn_selenium/abstract/executors/cdp/bluetooth_emulation.py +0 -95
- osn_selenium/abstract/executors/cdp/browser.py +0 -122
- osn_selenium/abstract/executors/cdp/cache_storage.py +0 -49
- osn_selenium/abstract/executors/cdp/cast.py +0 -31
- osn_selenium/abstract/executors/cdp/console.py +0 -18
- osn_selenium/abstract/executors/cdp/css.py +0 -197
- osn_selenium/abstract/executors/cdp/debugger.py +0 -198
- osn_selenium/abstract/executors/cdp/device_access.py +0 -22
- osn_selenium/abstract/executors/cdp/device_orientation.py +0 -14
- osn_selenium/abstract/executors/cdp/dom.py +0 -305
- osn_selenium/abstract/executors/cdp/dom_debugger.py +0 -57
- osn_selenium/abstract/executors/cdp/dom_snapshot.py +0 -42
- osn_selenium/abstract/executors/cdp/dom_storage.py +0 -31
- osn_selenium/abstract/executors/cdp/emulation.py +0 -259
- osn_selenium/abstract/executors/cdp/event_breakpoints.py +0 -18
- osn_selenium/abstract/executors/cdp/extensions.py +0 -31
- osn_selenium/abstract/executors/cdp/fed_cm.py +0 -35
- osn_selenium/abstract/executors/cdp/fetch.py +0 -76
- osn_selenium/abstract/executors/cdp/file_system.py +0 -11
- osn_selenium/abstract/executors/cdp/headless_experimental.py +0 -30
- osn_selenium/abstract/executors/cdp/heap_profiler.py +0 -73
- osn_selenium/abstract/executors/cdp/indexed_db.py +0 -99
- osn_selenium/abstract/executors/cdp/input.py +0 -158
- osn_selenium/abstract/executors/cdp/inspector.py +0 -14
- osn_selenium/abstract/executors/cdp/io.py +0 -24
- osn_selenium/abstract/executors/cdp/layer_tree.py +0 -61
- osn_selenium/abstract/executors/cdp/log.py +0 -27
- osn_selenium/abstract/executors/cdp/media.py +0 -14
- osn_selenium/abstract/executors/cdp/memory.py +0 -61
- osn_selenium/abstract/executors/cdp/network.py +0 -252
- osn_selenium/abstract/executors/cdp/overlay.py +0 -166
- osn_selenium/abstract/executors/cdp/page.py +0 -347
- osn_selenium/abstract/executors/cdp/performance.py +0 -28
- osn_selenium/abstract/executors/cdp/performance_timeline.py +0 -11
- osn_selenium/abstract/executors/cdp/preload.py +0 -14
- osn_selenium/abstract/executors/cdp/profiler.py +0 -54
- osn_selenium/abstract/executors/cdp/pwa.py +0 -46
- osn_selenium/abstract/executors/cdp/runtime.py +0 -176
- osn_selenium/abstract/executors/cdp/schema.py +0 -11
- osn_selenium/abstract/executors/cdp/security.py +0 -26
- osn_selenium/abstract/executors/cdp/service_worker.py +0 -54
- osn_selenium/abstract/executors/cdp/storage.py +0 -175
- osn_selenium/abstract/executors/cdp/system_info.py +0 -24
- osn_selenium/abstract/executors/cdp/target.py +0 -125
- osn_selenium/abstract/executors/cdp/tethering.py +0 -14
- osn_selenium/abstract/executors/cdp/tracing.py +0 -48
- osn_selenium/abstract/executors/cdp/web_audio.py +0 -19
- osn_selenium/abstract/executors/cdp/web_authn.py +0 -76
- osn_selenium/base_mixin.py +0 -122
- osn_selenium/executors/sync/cdp/__init__.py +0 -550
- osn_selenium/executors/sync/cdp/accessibility.py +0 -74
- osn_selenium/executors/sync/cdp/animation.py +0 -50
- osn_selenium/executors/sync/cdp/audits.py +0 -48
- osn_selenium/executors/sync/cdp/autofill.py +0 -39
- osn_selenium/executors/sync/cdp/background_service.py +0 -30
- osn_selenium/executors/sync/cdp/bluetooth_emulation.py +0 -101
- osn_selenium/executors/sync/cdp/browser.py +0 -131
- osn_selenium/executors/sync/cdp/cache_storage.py +0 -66
- osn_selenium/executors/sync/cdp/cast.py +0 -38
- osn_selenium/executors/sync/cdp/console.py +0 -24
- osn_selenium/executors/sync/cdp/css.py +0 -187
- osn_selenium/executors/sync/cdp/debugger.py +0 -206
- osn_selenium/executors/sync/cdp/device_access.py +0 -27
- osn_selenium/executors/sync/cdp/device_orientation.py +0 -24
- osn_selenium/executors/sync/cdp/dom.py +0 -310
- osn_selenium/executors/sync/cdp/dom_debugger.py +0 -56
- osn_selenium/executors/sync/cdp/dom_snapshot.py +0 -58
- osn_selenium/executors/sync/cdp/dom_storage.py +0 -38
- osn_selenium/executors/sync/cdp/emulation.py +0 -270
- osn_selenium/executors/sync/cdp/event_breakpoints.py +0 -27
- osn_selenium/executors/sync/cdp/extensions.py +0 -39
- osn_selenium/executors/sync/cdp/fed_cm.py +0 -45
- osn_selenium/executors/sync/cdp/fetch.py +0 -96
- osn_selenium/executors/sync/cdp/file_system.py +0 -18
- osn_selenium/executors/sync/cdp/headless_experimental.py +0 -44
- osn_selenium/executors/sync/cdp/heap_profiler.py +0 -89
- osn_selenium/executors/sync/cdp/indexed_db.py +0 -142
- osn_selenium/executors/sync/cdp/input.py +0 -233
- osn_selenium/executors/sync/cdp/inspector.py +0 -21
- osn_selenium/executors/sync/cdp/io.py +0 -33
- osn_selenium/executors/sync/cdp/layer_tree.py +0 -71
- osn_selenium/executors/sync/cdp/log.py +0 -35
- osn_selenium/executors/sync/cdp/media.py +0 -21
- osn_selenium/executors/sync/cdp/memory.py +0 -62
- osn_selenium/executors/sync/cdp/network.py +0 -287
- osn_selenium/executors/sync/cdp/overlay.py +0 -174
- osn_selenium/executors/sync/cdp/page.py +0 -365
- osn_selenium/executors/sync/cdp/performance.py +0 -33
- osn_selenium/executors/sync/cdp/performance_timeline.py +0 -26
- osn_selenium/executors/sync/cdp/preload.py +0 -21
- osn_selenium/executors/sync/cdp/profiler.py +0 -58
- osn_selenium/executors/sync/cdp/pwa.py +0 -55
- osn_selenium/executors/sync/cdp/runtime.py +0 -221
- osn_selenium/executors/sync/cdp/schema.py +0 -23
- osn_selenium/executors/sync/cdp/security.py +0 -30
- osn_selenium/executors/sync/cdp/service_worker.py +0 -56
- osn_selenium/executors/sync/cdp/storage.py +0 -151
- osn_selenium/executors/sync/cdp/system_info.py +0 -30
- osn_selenium/executors/sync/cdp/target.py +0 -147
- osn_selenium/executors/sync/cdp/tethering.py +0 -21
- osn_selenium/executors/sync/cdp/tracing.py +0 -62
- osn_selenium/executors/sync/cdp/web_audio.py +0 -24
- osn_selenium/executors/sync/cdp/web_authn.py +0 -82
- osn_selenium/executors/trio_threads/cdp/__init__.py +0 -771
- osn_selenium/executors/trio_threads/cdp/accessibility.py +0 -87
- osn_selenium/executors/trio_threads/cdp/animation.py +0 -63
- osn_selenium/executors/trio_threads/cdp/audits.py +0 -57
- osn_selenium/executors/trio_threads/cdp/autofill.py +0 -52
- osn_selenium/executors/trio_threads/cdp/background_service.py +0 -40
- osn_selenium/executors/trio_threads/cdp/bluetooth_emulation.py +0 -111
- osn_selenium/executors/trio_threads/cdp/browser.py +0 -140
- osn_selenium/executors/trio_threads/cdp/cache_storage.py +0 -79
- osn_selenium/executors/trio_threads/cdp/cast.py +0 -47
- osn_selenium/executors/trio_threads/cdp/console.py +0 -33
- osn_selenium/executors/trio_threads/cdp/css.py +0 -196
- osn_selenium/executors/trio_threads/cdp/debugger.py +0 -219
- osn_selenium/executors/trio_threads/cdp/device_access.py +0 -40
- osn_selenium/executors/trio_threads/cdp/device_orientation.py +0 -34
- osn_selenium/executors/trio_threads/cdp/dom.py +0 -319
- osn_selenium/executors/trio_threads/cdp/dom_debugger.py +0 -69
- osn_selenium/executors/trio_threads/cdp/dom_snapshot.py +0 -71
- osn_selenium/executors/trio_threads/cdp/dom_storage.py +0 -51
- osn_selenium/executors/trio_threads/cdp/emulation.py +0 -283
- osn_selenium/executors/trio_threads/cdp/event_breakpoints.py +0 -37
- osn_selenium/executors/trio_threads/cdp/extensions.py +0 -52
- osn_selenium/executors/trio_threads/cdp/fed_cm.py +0 -54
- osn_selenium/executors/trio_threads/cdp/fetch.py +0 -105
- osn_selenium/executors/trio_threads/cdp/file_system.py +0 -31
- osn_selenium/executors/trio_threads/cdp/headless_experimental.py +0 -54
- osn_selenium/executors/trio_threads/cdp/heap_profiler.py +0 -102
- osn_selenium/executors/trio_threads/cdp/indexed_db.py +0 -155
- osn_selenium/executors/trio_threads/cdp/input.py +0 -242
- osn_selenium/executors/trio_threads/cdp/inspector.py +0 -34
- osn_selenium/executors/trio_threads/cdp/io.py +0 -42
- osn_selenium/executors/trio_threads/cdp/layer_tree.py +0 -84
- osn_selenium/executors/trio_threads/cdp/log.py +0 -44
- osn_selenium/executors/trio_threads/cdp/media.py +0 -30
- osn_selenium/executors/trio_threads/cdp/memory.py +0 -71
- osn_selenium/executors/trio_threads/cdp/network.py +0 -296
- osn_selenium/executors/trio_threads/cdp/overlay.py +0 -183
- osn_selenium/executors/trio_threads/cdp/page.py +0 -374
- osn_selenium/executors/trio_threads/cdp/performance.py +0 -46
- osn_selenium/executors/trio_threads/cdp/performance_timeline.py +0 -36
- osn_selenium/executors/trio_threads/cdp/preload.py +0 -30
- osn_selenium/executors/trio_threads/cdp/profiler.py +0 -71
- osn_selenium/executors/trio_threads/cdp/pwa.py +0 -64
- osn_selenium/executors/trio_threads/cdp/runtime.py +0 -230
- osn_selenium/executors/trio_threads/cdp/schema.py +0 -32
- osn_selenium/executors/trio_threads/cdp/security.py +0 -43
- osn_selenium/executors/trio_threads/cdp/service_worker.py +0 -69
- osn_selenium/executors/trio_threads/cdp/storage.py +0 -162
- osn_selenium/executors/trio_threads/cdp/system_info.py +0 -43
- osn_selenium/executors/trio_threads/cdp/target.py +0 -156
- osn_selenium/executors/trio_threads/cdp/tethering.py +0 -34
- osn_selenium/executors/trio_threads/cdp/tracing.py +0 -71
- osn_selenium/executors/trio_threads/cdp/web_audio.py +0 -37
- osn_selenium/executors/trio_threads/cdp/web_authn.py +0 -95
- osn_selenium/executors/unified/cdp/accessibility.py +0 -81
- osn_selenium/executors/unified/cdp/animation.py +0 -50
- osn_selenium/executors/unified/cdp/audits.py +0 -45
- osn_selenium/executors/unified/cdp/autofill.py +0 -41
- osn_selenium/executors/unified/cdp/background_service.py +0 -24
- osn_selenium/executors/unified/cdp/bluetooth_emulation.py +0 -132
- osn_selenium/executors/unified/cdp/browser.py +0 -143
- osn_selenium/executors/unified/cdp/cache_storage.py +0 -69
- osn_selenium/executors/unified/cdp/cast.py +0 -32
- osn_selenium/executors/unified/cdp/console.py +0 -18
- osn_selenium/executors/unified/cdp/css.py +0 -237
- osn_selenium/executors/unified/cdp/debugger.py +0 -243
- osn_selenium/executors/unified/cdp/device_access.py +0 -21
- osn_selenium/executors/unified/cdp/device_orientation.py +0 -18
- osn_selenium/executors/unified/cdp/dom.py +0 -380
- osn_selenium/executors/unified/cdp/dom_debugger.py +0 -65
- osn_selenium/executors/unified/cdp/dom_snapshot.py +0 -58
- osn_selenium/executors/unified/cdp/dom_storage.py +0 -38
- osn_selenium/executors/unified/cdp/emulation.py +0 -312
- osn_selenium/executors/unified/cdp/event_breakpoints.py +0 -24
- osn_selenium/executors/unified/cdp/extensions.py +0 -45
- osn_selenium/executors/unified/cdp/fed_cm.py +0 -51
- osn_selenium/executors/unified/cdp/fetch.py +0 -111
- osn_selenium/executors/unified/cdp/file_system.py +0 -15
- osn_selenium/executors/unified/cdp/headless_experimental.py +0 -38
- osn_selenium/executors/unified/cdp/heap_profiler.py +0 -101
- osn_selenium/executors/unified/cdp/indexed_db.py +0 -157
- osn_selenium/executors/unified/cdp/input.py +0 -254
- osn_selenium/executors/unified/cdp/inspector.py +0 -15
- osn_selenium/executors/unified/cdp/io.py +0 -29
- osn_selenium/executors/unified/cdp/layer_tree.py +0 -71
- osn_selenium/executors/unified/cdp/log.py +0 -29
- osn_selenium/executors/unified/cdp/media.py +0 -15
- osn_selenium/executors/unified/cdp/memory.py +0 -59
- osn_selenium/executors/unified/cdp/network.py +0 -323
- osn_selenium/executors/unified/cdp/overlay.py +0 -209
- osn_selenium/executors/unified/cdp/page.py +0 -410
- osn_selenium/executors/unified/cdp/performance.py +0 -27
- osn_selenium/executors/unified/cdp/performance_timeline.py +0 -17
- osn_selenium/executors/unified/cdp/preload.py +0 -15
- osn_selenium/executors/unified/cdp/profiler.py +0 -55
- osn_selenium/executors/unified/cdp/pwa.py +0 -55
- osn_selenium/executors/unified/cdp/runtime.py +0 -245
- osn_selenium/executors/unified/cdp/schema.py +0 -17
- osn_selenium/executors/unified/cdp/security.py +0 -27
- osn_selenium/executors/unified/cdp/service_worker.py +0 -62
- osn_selenium/executors/unified/cdp/storage.py +0 -178
- osn_selenium/executors/unified/cdp/system_info.py +0 -24
- osn_selenium/executors/unified/cdp/target.py +0 -165
- osn_selenium/executors/unified/cdp/tethering.py +0 -15
- osn_selenium/executors/unified/cdp/tracing.py +0 -62
- osn_selenium/executors/unified/cdp/web_audio.py +0 -18
- osn_selenium/executors/unified/cdp/web_authn.py +0 -103
- osn_selenium-1.1.0.dist-info/RECORD +0 -615
- /osn_selenium/{dev_tools/_exception_helpers.py → _exception_helpers.py} +0 -0
- /osn_selenium/executors/{unified/cdp → trio_bidi}/__init__.py +0 -0
- {osn_selenium-1.1.0.dist-info → osn_selenium-1.2.0.dist-info}/WHEEL +0 -0
- {osn_selenium-1.1.0.dist-info → osn_selenium-1.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
from selenium.webdriver.remote.command import Command
|
|
3
|
+
from osn_selenium.trio_bidi.mapping.response_functions._args_helpers import map_void_response
|
|
4
|
+
from osn_selenium.trio_bidi._typehints import (
|
|
5
|
+
MAP_RESPONSE_FUNCTION_TYPEHINT,
|
|
6
|
+
REQUEST_PARAMS_TYPEHINT
|
|
7
|
+
)
|
|
8
|
+
from osn_selenium.trio_bidi.mapping.response_functions._args_validators import (
|
|
9
|
+
validate_javascript_error
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = ["MAPPED_RESPONSE_WINDOW_COMMANDS"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _map_w3c_get_window_handles_response(bidi_result: Dict[str, Any], request_params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
17
|
+
"""
|
|
18
|
+
Maps BiDi context tree into a list of W3C window handles.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
bidi_result (Dict[str, Any]): BiDi result containing 'contexts'.
|
|
22
|
+
request_params (REQUEST_PARAMS_TYPEHINT): Original request parameters.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Dict[str, Any]: W3C response with a list of handles.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
contexts = bidi_result.get("contexts", [])
|
|
29
|
+
handles = [ctx["context"] for ctx in contexts]
|
|
30
|
+
|
|
31
|
+
return {"value": handles}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _map_w3c_get_current_window_handle_response(bidi_result: Dict[str, Any], request_params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
35
|
+
"""
|
|
36
|
+
Maps specific BiDi context ID to W3C window handle response.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
bidi_result (Dict[str, Any]): BiDi result containing single context info.
|
|
40
|
+
request_params (REQUEST_PARAMS_TYPEHINT): Original request parameters.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Dict[str, Any]: W3C response with the handle string.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return {"value": bidi_result["contexts"][0]["context"]}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _map_set_screen_orientation_response(bidi_result: Dict[str, Any], request_params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
50
|
+
"""
|
|
51
|
+
Maps screen orientation script execution result to void response.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
bidi_result (Dict[str, Any]): BiDi response.
|
|
55
|
+
request_params (REQUEST_PARAMS_TYPEHINT): Original request parameters.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Dict[str, Any]: W3C void response.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
javascript_error_validation = validate_javascript_error(bidi_result=bidi_result, request_params=request_params)
|
|
62
|
+
if javascript_error_validation is not None:
|
|
63
|
+
return javascript_error_validation
|
|
64
|
+
|
|
65
|
+
return map_void_response(bidi_result=bidi_result, request_params=request_params)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _map_get_screen_orientation_response(bidi_result: Dict[str, Any], request_params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
69
|
+
"""
|
|
70
|
+
Maps BiDi screen orientation script result into W3C orientation dictionary.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
bidi_result (Dict[str, Any]): BiDi result containing raw orientation string.
|
|
74
|
+
request_params (REQUEST_PARAMS_TYPEHINT): Original request parameters.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Dict[str, Any]: W3C response with orientation info.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
javascript_error_validation = validate_javascript_error(bidi_result=bidi_result, request_params=request_params)
|
|
81
|
+
if javascript_error_validation is not None:
|
|
82
|
+
return javascript_error_validation
|
|
83
|
+
|
|
84
|
+
raw_value = bidi_result.get("result", {}).get("value", "").upper()
|
|
85
|
+
|
|
86
|
+
if "LANDSCAPE" in raw_value:
|
|
87
|
+
orientation = "LANDSCAPE"
|
|
88
|
+
elif "PORTRAIT" in raw_value:
|
|
89
|
+
orientation = "PORTRAIT"
|
|
90
|
+
else:
|
|
91
|
+
orientation = "LANDSCAPE"
|
|
92
|
+
|
|
93
|
+
return {"value": {"orientation": orientation}}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _map_close_response(bidi_result: Dict[str, Any], request_params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
97
|
+
"""
|
|
98
|
+
Maps window closing result to W3C void response.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
bidi_result (Dict[str, Any]): BiDi response.
|
|
102
|
+
request_params (REQUEST_PARAMS_TYPEHINT): Original request parameters.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Dict[str, Any]: W3C void response.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
return map_void_response(bidi_result=bidi_result, request_params=request_params)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
MAPPED_RESPONSE_WINDOW_COMMANDS: Dict[str, MAP_RESPONSE_FUNCTION_TYPEHINT] = {
|
|
112
|
+
Command.W3C_GET_WINDOW_HANDLES: _map_w3c_get_window_handles_response,
|
|
113
|
+
Command.W3C_GET_CURRENT_WINDOW_HANDLE: _map_w3c_get_current_window_handle_response,
|
|
114
|
+
Command.CLOSE: _map_close_response,
|
|
115
|
+
Command.GET_SCREEN_ORIENTATION: _map_get_screen_orientation_response,
|
|
116
|
+
Command.SET_SCREEN_ORIENTATION: _map_set_screen_orientation_response,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# TODO create mappings for Command.GET_WINDOW_RECT, Command.SET_WINDOW_RECT, Command.W3C_MAXIMIZE_WINDOW, Command.MINIMIZE_WINDOW, Command.FULLSCREEN_WINDOW
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import trio
|
|
2
|
+
from contextlib import asynccontextmanager
|
|
3
|
+
from osn_selenium.trio_threads_mixin import TrioThreadMixin
|
|
4
|
+
from osn_selenium.trio_bidi.connection_pool import BiDiConnectionPool
|
|
5
|
+
from osn_selenium.trio_bidi._context_vars import (
|
|
6
|
+
CURRENT_BROWSING_CONTEXT
|
|
7
|
+
)
|
|
8
|
+
from osn_selenium.trio_bidi.remote_connection import (
|
|
9
|
+
BiDiBridgeRemoteConnection
|
|
10
|
+
)
|
|
11
|
+
from osn_selenium.trio_bidi._typehints import (
|
|
12
|
+
CURRENT_BROWSING_CONTEXT_TYPEHINT
|
|
13
|
+
)
|
|
14
|
+
from osn_selenium._trio_threads_helpers import (
|
|
15
|
+
sync_to_trio,
|
|
16
|
+
sync_to_trio_context
|
|
17
|
+
)
|
|
18
|
+
from typing import (
|
|
19
|
+
Any,
|
|
20
|
+
AsyncContextManager,
|
|
21
|
+
AsyncGenerator,
|
|
22
|
+
Callable,
|
|
23
|
+
ContextManager,
|
|
24
|
+
Coroutine,
|
|
25
|
+
Optional,
|
|
26
|
+
ParamSpec,
|
|
27
|
+
TypeVar,
|
|
28
|
+
Union
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
__all__ = ["TrioBiDiMixin"]
|
|
33
|
+
|
|
34
|
+
_METHOD_INPUT = ParamSpec("_METHOD_INPUT")
|
|
35
|
+
_METHOD_OUTPUT = TypeVar("_METHOD_OUTPUT")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TrioBiDiMixin(TrioThreadMixin):
|
|
39
|
+
"""
|
|
40
|
+
Mixin that provides WebDriver with Trio-based BiDi context switching capabilities.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
lock: trio.Lock,
|
|
46
|
+
limiter: trio.CapacityLimiter,
|
|
47
|
+
token: Optional[trio.lowlevel.TrioToken],
|
|
48
|
+
buffer_size: Union[int, float],
|
|
49
|
+
) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Initializes the TrioBiDiMixin.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
lock (trio.Lock): Trio lock for synchronization.
|
|
55
|
+
limiter (trio.CapacityLimiter): Limiter for concurrent operations.
|
|
56
|
+
token (Optional[trio.lowlevel.TrioToken]): The Trio token for the current event loop.
|
|
57
|
+
buffer_size (Union[int, float]): Buffer size for the BiDi task channel.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
super().__init__(lock=lock, limiter=limiter)
|
|
61
|
+
|
|
62
|
+
self._trio_token = token if token is not None else trio.lowlevel.current_trio_token()
|
|
63
|
+
|
|
64
|
+
self._trio_bidi_buffer_size = buffer_size
|
|
65
|
+
self._bidi_bridge_connection_pool: Optional[BiDiConnectionPool] = None
|
|
66
|
+
self._bidi_bridge_remote_connection: Optional[BiDiBridgeRemoteConnection] = None
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def current_context_id(self) -> CURRENT_BROWSING_CONTEXT_TYPEHINT:
|
|
70
|
+
"""
|
|
71
|
+
Returns the browsing context ID (tab ID) associated with the current Trio task.
|
|
72
|
+
This operation is instant and does not require a driver call.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
CURRENT_BROWSING_CONTEXT_TYPEHINT: The current context ID.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
return CURRENT_BROWSING_CONTEXT.get()
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def switch_context(context_id: CURRENT_BROWSING_CONTEXT_TYPEHINT) -> None:
|
|
82
|
+
"""
|
|
83
|
+
Updates the target context for the CURRENT task only.
|
|
84
|
+
Equivalent to `driver.switch_to.window` but strictly local to the coroutine.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
context_id (CURRENT_BROWSING_CONTEXT_TYPEHINT): The ID of the browsing context to switch to.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
CURRENT_BROWSING_CONTEXT.set(context_id)
|
|
91
|
+
|
|
92
|
+
def sync_to_trio(
|
|
93
|
+
self,
|
|
94
|
+
sync_function: Callable[_METHOD_INPUT, _METHOD_OUTPUT],
|
|
95
|
+
lock: bool = False,
|
|
96
|
+
exchange_context:bool = True,
|
|
97
|
+
) -> Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]:
|
|
98
|
+
"""
|
|
99
|
+
Wraps a synchronous function to run within a Trio thread pool using a lock and limiter.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
sync_function (Callable[_METHOD_INPUT, _METHOD_OUTPUT]): The synchronous function to wrap.
|
|
103
|
+
lock (bool): Whether to use the internal lock for synchronization.
|
|
104
|
+
exchange_context (bool): Whether to synchronize context variables between threads.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]: An async wrapper for the sync function.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
return sync_to_trio(
|
|
111
|
+
sync_function=sync_function,
|
|
112
|
+
lock_object=self._lock,
|
|
113
|
+
capacity_limiter_object=self._capacity_limiter,
|
|
114
|
+
lock=lock,
|
|
115
|
+
exchange_context=exchange_context,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def sync_to_trio_context(
|
|
119
|
+
self,
|
|
120
|
+
context_manager_factory: Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]],
|
|
121
|
+
lock: bool = False,
|
|
122
|
+
exchange_context: bool = True,
|
|
123
|
+
) -> Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]:
|
|
124
|
+
"""
|
|
125
|
+
Converts a synchronous context manager factory to an asynchronous Trio-compatible context manager.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
context_manager_factory (Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]]): Factory function returning a context manager.
|
|
129
|
+
lock (bool): Whether to use the internal lock for synchronization.
|
|
130
|
+
exchange_context (bool): Whether to synchronize context variables between threads.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]: An async function returning an async context manager.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
return sync_to_trio_context(
|
|
137
|
+
context_manager_factory=context_manager_factory,
|
|
138
|
+
lock_object=self._lock,
|
|
139
|
+
capacity_limiter_object=self._capacity_limiter,
|
|
140
|
+
lock=lock,
|
|
141
|
+
exchange_context=exchange_context,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def trio_bidi_buffer_size(self) -> Union[int, float]:
|
|
146
|
+
"""
|
|
147
|
+
Returns the configured buffer size for BiDi operations.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Union[int, float]: The buffer size.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
return self._trio_bidi_buffer_size
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def trio_token(self) -> trio.lowlevel.TrioToken:
|
|
157
|
+
"""
|
|
158
|
+
Returns the Trio token associated with this driver.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
trio.lowlevel.TrioToken: The event loop token.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
return self._trio_token
|
|
165
|
+
|
|
166
|
+
@asynccontextmanager
|
|
167
|
+
async def use_context(self, context_id: CURRENT_BROWSING_CONTEXT_TYPEHINT) -> AsyncGenerator[None, Any]:
|
|
168
|
+
"""
|
|
169
|
+
Context manager for temporary context switching.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
context_id (CURRENT_BROWSING_CONTEXT_TYPEHINT): The ID of the browsing context to switch to.
|
|
173
|
+
|
|
174
|
+
EXAMPLES
|
|
175
|
+
________
|
|
176
|
+
>>> async with driver.use_context(tab_id):
|
|
177
|
+
... await driver.get("https://example.com")
|
|
178
|
+
... # Context automatically reverts here
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
token = CURRENT_BROWSING_CONTEXT.set(context_id)
|
|
182
|
+
|
|
183
|
+
try:
|
|
184
|
+
yield
|
|
185
|
+
finally:
|
|
186
|
+
CURRENT_BROWSING_CONTEXT.reset(token)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import trio
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
from selenium.webdriver.remote.command import Command
|
|
4
|
+
from selenium.webdriver.remote.client_config import ClientConfig
|
|
5
|
+
from selenium.webdriver.remote.remote_connection import RemoteConnection
|
|
6
|
+
from osn_selenium.trio_bidi._typehints import (
|
|
7
|
+
REQUEST_PARAMS_TYPEHINT
|
|
8
|
+
)
|
|
9
|
+
from osn_selenium.trio_bidi._models import (
|
|
10
|
+
W3CTask,
|
|
11
|
+
W3CTaskContainer
|
|
12
|
+
)
|
|
13
|
+
from osn_selenium.trio_bidi._context_vars import (
|
|
14
|
+
CURRENT_BROWSING_CONTEXT
|
|
15
|
+
)
|
|
16
|
+
from osn_selenium.trio_bidi._internal_mappings import (
|
|
17
|
+
OSN_SWITCH_CONTEXT_KEY
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__all__ = ["BiDiBridgeRemoteConnection"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _processing_in_trio_loop() -> bool:
|
|
25
|
+
"""
|
|
26
|
+
Checks if the current code is executing within a Trio event loop.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
bool: True if in a Trio loop, False otherwise.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
is_in_trio = False
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
trio.lowlevel.current_task()
|
|
36
|
+
is_in_trio = True
|
|
37
|
+
except RuntimeError:
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
return is_in_trio
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _handle_response(w3c_task_container: W3CTaskContainer) -> Dict[str, Any]:
|
|
44
|
+
"""
|
|
45
|
+
Processes the result of a W3C task, handling errors and context switching.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
w3c_task_container (W3CTaskContainer): The container holding the task result.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Dict[str, Any]: The processed W3C response.
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
Exception: The error received from the BiDi bridge if the task failed.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
if w3c_task_container.response["error"]:
|
|
58
|
+
raise w3c_task_container.response["error"]
|
|
59
|
+
|
|
60
|
+
osn_switch_context_value = w3c_task_container.response["response"].get(OSN_SWITCH_CONTEXT_KEY, None)
|
|
61
|
+
if osn_switch_context_value is not None:
|
|
62
|
+
CURRENT_BROWSING_CONTEXT.set(osn_switch_context_value)
|
|
63
|
+
|
|
64
|
+
return w3c_task_container.response["response"]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class BiDiBridgeRemoteConnection(RemoteConnection):
|
|
68
|
+
"""
|
|
69
|
+
Remote connection implementation that bridges W3C commands to a BiDi-capable backend via Trio.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
send_channel: trio.MemorySendChannel[W3CTaskContainer],
|
|
75
|
+
trio_token: trio.lowlevel.TrioToken,
|
|
76
|
+
legacy_remote_connection: RemoteConnection,
|
|
77
|
+
remote_server_addr: Optional[str] = "http://localhost:9999",
|
|
78
|
+
keep_alive: bool = True,
|
|
79
|
+
ignore_proxy: bool = False,
|
|
80
|
+
ignore_certificates: Optional[bool] = False,
|
|
81
|
+
init_args_for_pool_manager: Optional[Dict] = None,
|
|
82
|
+
client_config: Optional[ClientConfig] = None,
|
|
83
|
+
):
|
|
84
|
+
"""
|
|
85
|
+
Initializes the BiDiBridgeRemoteConnection.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
send_channel (trio.MemorySendChannel[W3CTaskContainer]): The channel to send W3C tasks to.
|
|
89
|
+
trio_token (trio.lowlevel.TrioToken): The token for the Trio event loop.
|
|
90
|
+
legacy_remote_connection (RemoteConnection): The underlying legacy connection.
|
|
91
|
+
remote_server_addr (Optional[str]): The address of the remote Selenium server.
|
|
92
|
+
keep_alive (bool): Whether to keep the connection alive.
|
|
93
|
+
ignore_proxy (bool): Whether to ignore proxy settings.
|
|
94
|
+
ignore_certificates (Optional[bool]): Whether to ignore SSL certificate errors.
|
|
95
|
+
init_args_for_pool_manager (Optional[Dict]): Additional arguments for the pool manager.
|
|
96
|
+
client_config (Optional[ClientConfig]): Configuration object for the client.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
super().__init__(
|
|
100
|
+
remote_server_addr=remote_server_addr,
|
|
101
|
+
keep_alive=keep_alive,
|
|
102
|
+
ignore_proxy=ignore_proxy,
|
|
103
|
+
ignore_certificates=ignore_certificates,
|
|
104
|
+
init_args_for_pool_manager=init_args_for_pool_manager,
|
|
105
|
+
client_config=client_config,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
self._legacy_remote_connection = legacy_remote_connection
|
|
109
|
+
self._trio_send_channel = send_channel
|
|
110
|
+
self._trio_token = trio_token
|
|
111
|
+
|
|
112
|
+
def _OSN_GET_CURRENT_WINDOW_HANDLE(self, command: str, params: REQUEST_PARAMS_TYPEHINT) -> Optional[str]:
|
|
113
|
+
"""
|
|
114
|
+
Internal method to manage browsing context handle via local cache or legacy call.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
command (str): Current command name.
|
|
118
|
+
params (Optional[Dict[str, Any]]): Current command parameters.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Optional[str]: The browsing context ID.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
context_id = CURRENT_BROWSING_CONTEXT.get()
|
|
125
|
+
|
|
126
|
+
if context_id is not None:
|
|
127
|
+
return context_id
|
|
128
|
+
|
|
129
|
+
context_id = self._legacy_remote_connection.execute(command, params)["value"]
|
|
130
|
+
CURRENT_BROWSING_CONTEXT.set(context_id)
|
|
131
|
+
|
|
132
|
+
return context_id
|
|
133
|
+
|
|
134
|
+
def execute(self, command: str, params: REQUEST_PARAMS_TYPEHINT) -> Dict[str, Any]:
|
|
135
|
+
"""
|
|
136
|
+
Executes a W3C command by sending it through the BiDi bridge or legacy connection.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
command (str): The name of the command to execute.
|
|
140
|
+
params (Optional[Dict[str, Any]]): The parameters for the command.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Dict[str, Any]: The response from the remote end.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
if _processing_in_trio_loop():
|
|
147
|
+
return self._legacy_remote_connection.execute(command, params)
|
|
148
|
+
|
|
149
|
+
context_id = self._OSN_GET_CURRENT_WINDOW_HANDLE(command=command, params=params)
|
|
150
|
+
|
|
151
|
+
if command == Command.W3C_GET_CURRENT_WINDOW_HANDLE:
|
|
152
|
+
return {"value": context_id}
|
|
153
|
+
|
|
154
|
+
w3c_task_container = W3CTaskContainer(task=W3CTask(command=command, params=params, context_id=context_id))
|
|
155
|
+
|
|
156
|
+
trio.from_thread.run(
|
|
157
|
+
self._trio_send_channel.send,
|
|
158
|
+
w3c_task_container,
|
|
159
|
+
trio_token=self._trio_token
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
w3c_task_container.pending_event.wait()
|
|
163
|
+
|
|
164
|
+
return _handle_response(w3c_task_container=w3c_task_container)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
import trio
|
|
3
|
-
from
|
|
2
|
+
from osn_selenium._trio_threads_helpers import (
|
|
3
|
+
sync_to_trio,
|
|
4
|
+
sync_to_trio_context
|
|
5
|
+
)
|
|
4
6
|
from typing import (
|
|
5
7
|
Any,
|
|
6
8
|
AsyncContextManager,
|
|
7
|
-
AsyncIterator,
|
|
8
9
|
Callable,
|
|
9
10
|
ContextManager,
|
|
10
11
|
Coroutine,
|
|
@@ -63,6 +64,7 @@ class TrioThreadMixin:
|
|
|
63
64
|
self,
|
|
64
65
|
sync_function: Callable[_METHOD_INPUT, _METHOD_OUTPUT],
|
|
65
66
|
lock: bool = True,
|
|
67
|
+
exchange_context:bool = True,
|
|
66
68
|
) -> Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]:
|
|
67
69
|
"""
|
|
68
70
|
Wraps a synchronous function to run within a Trio thread pool using a lock and limiter.
|
|
@@ -70,50 +72,25 @@ class TrioThreadMixin:
|
|
|
70
72
|
Args:
|
|
71
73
|
sync_function (Callable[_METHOD_INPUT, _METHOD_OUTPUT]): The synchronous function to wrap.
|
|
72
74
|
lock (bool): Whether to use the internal lock for synchronization.
|
|
75
|
+
exchange_context (bool): Whether to synchronize context variables between threads.
|
|
73
76
|
|
|
74
77
|
Returns:
|
|
75
78
|
Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]: An async wrapper for the sync function.
|
|
76
79
|
"""
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
81
|
+
return sync_to_trio(
|
|
82
|
+
sync_function=sync_function,
|
|
83
|
+
lock_object=self._lock,
|
|
84
|
+
capacity_limiter_object=self._capacity_limiter,
|
|
85
|
+
lock=lock,
|
|
86
|
+
exchange_context=exchange_context,
|
|
87
|
+
)
|
|
112
88
|
|
|
113
89
|
def sync_to_trio_context(
|
|
114
90
|
self,
|
|
115
91
|
context_manager_factory: Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]],
|
|
116
92
|
lock: bool = True,
|
|
93
|
+
exchange_context:bool = True,
|
|
117
94
|
) -> Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]:
|
|
118
95
|
"""
|
|
119
96
|
Converts a synchronous context manager factory to an asynchronous Trio-compatible context manager.
|
|
@@ -121,39 +98,16 @@ class TrioThreadMixin:
|
|
|
121
98
|
Args:
|
|
122
99
|
context_manager_factory (Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]]): A factory function returning a context manager.
|
|
123
100
|
lock (bool): Whether to use the internal lock for synchronization.
|
|
101
|
+
exchange_context (bool): Whether to synchronize context variables between threads.
|
|
124
102
|
|
|
125
103
|
Returns:
|
|
126
104
|
Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]: An async function returning an async context manager.
|
|
127
105
|
"""
|
|
128
106
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
|
107
|
+
return sync_to_trio_context(
|
|
108
|
+
context_manager_factory=context_manager_factory,
|
|
109
|
+
lock_object=self._lock,
|
|
110
|
+
capacity_limiter_object=self._capacity_limiter,
|
|
111
|
+
lock=lock,
|
|
112
|
+
exchange_context=exchange_context,
|
|
113
|
+
)
|