osn-selenium 1.0.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.
Files changed (475) hide show
  1. osn_selenium/_base_models.py +41 -0
  2. osn_selenium/_cdp_import.py +253 -0
  3. osn_selenium/_decorators.py +57 -0
  4. osn_selenium/_trio_threads_helpers.py +157 -0
  5. osn_selenium/_typehints.py +1 -1
  6. osn_selenium/abstract/executors/cdp.py +63 -0
  7. osn_selenium/abstract/webdriver/blink/base.py +14 -0
  8. osn_selenium/abstract/webdriver/blink/lifecycle.py +8 -8
  9. osn_selenium/abstract/webdriver/core/base.py +0 -14
  10. osn_selenium/abstract/webdriver/core/capture.py +4 -3
  11. osn_selenium/abstract/webdriver/core/lifecycle.py +8 -8
  12. osn_selenium/abstract/webdriver/core/script.py +5 -4
  13. osn_selenium/abstract/webdriver/core/window.py +11 -11
  14. osn_selenium/browsers_handler/models.py +1 -1
  15. osn_selenium/dev_tools/_decorators.py +19 -51
  16. osn_selenium/dev_tools/_functions.py +2 -4
  17. osn_selenium/dev_tools/_typehints.py +5 -2
  18. osn_selenium/dev_tools/_wrappers.py +0 -3
  19. osn_selenium/dev_tools/domains/__init__.py +2 -2
  20. osn_selenium/dev_tools/domains/abstract.py +1 -1
  21. osn_selenium/dev_tools/domains/fetch.py +6 -8
  22. osn_selenium/dev_tools/domains_default/fetch.py +2 -2
  23. osn_selenium/dev_tools/filters.py +1 -1
  24. osn_selenium/dev_tools/logger/main.py +9 -21
  25. osn_selenium/dev_tools/logger/models.py +1 -1
  26. osn_selenium/dev_tools/logger/target.py +49 -29
  27. osn_selenium/dev_tools/manager/base.py +10 -42
  28. osn_selenium/dev_tools/manager/lifecycle.py +84 -75
  29. osn_selenium/dev_tools/manager/logging.py +1 -1
  30. osn_selenium/dev_tools/manager/targets.py +13 -5
  31. osn_selenium/dev_tools/models.py +1 -1
  32. osn_selenium/dev_tools/settings.py +9 -5
  33. osn_selenium/dev_tools/target/base.py +30 -34
  34. osn_selenium/dev_tools/target/discovery.py +1 -1
  35. osn_selenium/dev_tools/target/events.py +2 -2
  36. osn_selenium/dev_tools/target/fingerprint.py +1 -1
  37. osn_selenium/dev_tools/target/lifecycle.py +103 -38
  38. osn_selenium/dev_tools/target/logging.py +11 -3
  39. osn_selenium/exceptions/__init__.py +0 -1
  40. osn_selenium/exceptions/base.py +28 -1
  41. osn_selenium/exceptions/bidi_bridge.py +59 -0
  42. osn_selenium/exceptions/configuration.py +1 -8
  43. osn_selenium/exceptions/dependencies.py +60 -0
  44. osn_selenium/exceptions/devtools.py +9 -39
  45. osn_selenium/exceptions/experimental.py +26 -0
  46. osn_selenium/exceptions/flags.py +0 -2
  47. osn_selenium/exceptions/instance.py +1 -9
  48. osn_selenium/exceptions/javascript.py +0 -2
  49. osn_selenium/exceptions/logic.py +0 -2
  50. osn_selenium/exceptions/path.py +1 -9
  51. osn_selenium/exceptions/platform.py +0 -2
  52. osn_selenium/exceptions/protocol.py +0 -3
  53. osn_selenium/exceptions/webdriver.py +1 -7
  54. osn_selenium/exceptions/window.py +1 -8
  55. osn_selenium/executors/sync/cdp.py +95 -0
  56. osn_selenium/executors/trio_bidi/cdp.py +101 -0
  57. osn_selenium/executors/trio_bidi/javascript.py +101 -0
  58. osn_selenium/executors/trio_threads/cdp.py +99 -0
  59. osn_selenium/executors/trio_threads/javascript.py +1 -1
  60. osn_selenium/executors/unified/javascript.py +0 -4
  61. osn_selenium/flags/base.py +7 -13
  62. osn_selenium/flags/blink.py +2 -8
  63. osn_selenium/flags/chrome.py +6 -6
  64. osn_selenium/flags/edge.py +6 -6
  65. osn_selenium/flags/models/base.py +4 -4
  66. osn_selenium/flags/models/blink.py +1 -1
  67. osn_selenium/flags/models/values.py +1 -1
  68. osn_selenium/instances/convert.py +44 -3
  69. osn_selenium/instances/protocols.py +47 -1
  70. osn_selenium/instances/sync/action_chains/__init__.py +6 -0
  71. osn_selenium/instances/sync/browsing_context.py +2 -2
  72. osn_selenium/instances/sync/script.py +7 -2
  73. osn_selenium/instances/sync/shadow_root.py +30 -8
  74. osn_selenium/instances/sync/web_element.py +1 -1
  75. osn_selenium/instances/trio_bidi/__init__.py +1 -0
  76. osn_selenium/instances/trio_bidi/shadow_root.py +180 -0
  77. osn_selenium/instances/trio_bidi/switch_to.py +143 -0
  78. osn_selenium/instances/trio_bidi/web_driver_wait.py +124 -0
  79. osn_selenium/instances/trio_bidi/web_element.py +239 -0
  80. osn_selenium/instances/trio_threads/action_chains/__init__.py +6 -0
  81. osn_selenium/instances/trio_threads/action_chains/base.py +1 -1
  82. osn_selenium/instances/trio_threads/alert.py +1 -1
  83. osn_selenium/instances/trio_threads/browser.py +1 -1
  84. osn_selenium/instances/trio_threads/browsing_context.py +3 -3
  85. osn_selenium/instances/trio_threads/dialog.py +1 -1
  86. osn_selenium/instances/trio_threads/fedcm.py +1 -1
  87. osn_selenium/instances/trio_threads/mobile.py +1 -1
  88. osn_selenium/instances/trio_threads/network.py +1 -1
  89. osn_selenium/instances/trio_threads/permissions.py +1 -1
  90. osn_selenium/instances/trio_threads/script.py +8 -3
  91. osn_selenium/instances/trio_threads/shadow_root.py +46 -15
  92. osn_selenium/instances/trio_threads/storage.py +1 -1
  93. osn_selenium/instances/trio_threads/switch_to.py +1 -1
  94. osn_selenium/instances/trio_threads/web_driver_wait.py +1 -1
  95. osn_selenium/instances/trio_threads/web_element.py +1 -1
  96. osn_selenium/instances/trio_threads/web_extension.py +1 -1
  97. osn_selenium/instances/unified/browsing_context.py +2 -2
  98. osn_selenium/instances/unified/script.py +2 -2
  99. osn_selenium/instances/unified/web_element.py +3 -5
  100. osn_selenium/javascript/fingerprint/__init__.py +3 -2
  101. osn_selenium/javascript/fingerprint/registry/models.py +1 -1
  102. osn_selenium/javascript/fingerprint/spoof/core_rules.py +1 -1
  103. osn_selenium/javascript/fingerprint/spoof/noise.py +1 -1
  104. osn_selenium/javascript/models.py +1 -1
  105. osn_selenium/models.py +2 -47
  106. osn_selenium/trio_bidi/__init__.py +1 -0
  107. osn_selenium/trio_bidi/_context_vars.py +12 -0
  108. osn_selenium/trio_bidi/_error_mappings.py +123 -0
  109. osn_selenium/trio_bidi/_error_redirects.py +194 -0
  110. osn_selenium/trio_bidi/_file_functions.py +28 -0
  111. osn_selenium/trio_bidi/_internal_mappings.py +10 -0
  112. osn_selenium/trio_bidi/_models.py +199 -0
  113. osn_selenium/trio_bidi/_typehints.py +20 -0
  114. osn_selenium/trio_bidi/connection_pool.py +587 -0
  115. osn_selenium/trio_bidi/mapping/__init__.py +1 -0
  116. osn_selenium/trio_bidi/mapping/_constants.py +14 -0
  117. osn_selenium/trio_bidi/mapping/_js_snippets.py +285 -0
  118. osn_selenium/trio_bidi/mapping/_utils.py +4 -0
  119. osn_selenium/trio_bidi/mapping/request_functions/__init__.py +87 -0
  120. osn_selenium/trio_bidi/mapping/request_functions/_alert.py +102 -0
  121. osn_selenium/trio_bidi/mapping/request_functions/_args_helpers.py +225 -0
  122. osn_selenium/trio_bidi/mapping/request_functions/_capture.py +71 -0
  123. osn_selenium/trio_bidi/mapping/request_functions/_cdp.py +40 -0
  124. osn_selenium/trio_bidi/mapping/request_functions/_element.py +55 -0
  125. osn_selenium/trio_bidi/mapping/request_functions/_file.py +32 -0
  126. osn_selenium/trio_bidi/mapping/request_functions/_navigation.py +147 -0
  127. osn_selenium/trio_bidi/mapping/request_functions/_script.py +85 -0
  128. osn_selenium/trio_bidi/mapping/request_functions/_shadow_root.py +65 -0
  129. osn_selenium/trio_bidi/mapping/request_functions/_switch_to.py +59 -0
  130. osn_selenium/trio_bidi/mapping/request_functions/_web_element.py +448 -0
  131. osn_selenium/trio_bidi/mapping/request_functions/_window.py +125 -0
  132. osn_selenium/trio_bidi/mapping/response_functions/__init__.py +86 -0
  133. osn_selenium/trio_bidi/mapping/response_functions/_alert.py +81 -0
  134. osn_selenium/trio_bidi/mapping/response_functions/_args_helpers.py +183 -0
  135. osn_selenium/trio_bidi/mapping/response_functions/_args_validators.py +153 -0
  136. osn_selenium/trio_bidi/mapping/response_functions/_capture.py +71 -0
  137. osn_selenium/trio_bidi/mapping/response_functions/_cdp.py +26 -0
  138. osn_selenium/trio_bidi/mapping/response_functions/_element.py +58 -0
  139. osn_selenium/trio_bidi/mapping/response_functions/_file.py +30 -0
  140. osn_selenium/trio_bidi/mapping/response_functions/_navigation.py +120 -0
  141. osn_selenium/trio_bidi/mapping/response_functions/_script.py +57 -0
  142. osn_selenium/trio_bidi/mapping/response_functions/_shadow_root.py +58 -0
  143. osn_selenium/trio_bidi/mapping/response_functions/_switch_to.py +57 -0
  144. osn_selenium/trio_bidi/mapping/response_functions/_web_element.py +368 -0
  145. osn_selenium/trio_bidi/mapping/response_functions/_window.py +119 -0
  146. osn_selenium/trio_bidi/mixin.py +186 -0
  147. osn_selenium/trio_bidi/remote_connection.py +164 -0
  148. osn_selenium/{base_mixin.py → trio_threads_mixin.py} +31 -40
  149. osn_selenium/webdrivers/_args_helpers.py +120 -7
  150. osn_selenium/webdrivers/_bridges.py +2 -2
  151. osn_selenium/webdrivers/_executable_tables/models.py +1 -1
  152. osn_selenium/webdrivers/_typehints.py +9 -3
  153. osn_selenium/webdrivers/protocols.py +81 -1
  154. osn_selenium/webdrivers/sync/blink/__init__.py +11 -1
  155. osn_selenium/webdrivers/sync/blink/base.py +23 -1
  156. osn_selenium/webdrivers/sync/blink/lifecycle.py +26 -8
  157. osn_selenium/webdrivers/sync/chrome/__init__.py +36 -1
  158. osn_selenium/webdrivers/sync/chrome/base.py +13 -1
  159. osn_selenium/webdrivers/sync/chrome/lifecycle.py +23 -5
  160. osn_selenium/webdrivers/sync/chrome/settings.py +6 -1
  161. osn_selenium/webdrivers/sync/core/__init__.py +10 -1
  162. osn_selenium/webdrivers/sync/core/base.py +18 -18
  163. osn_selenium/webdrivers/sync/core/capture.py +3 -2
  164. osn_selenium/webdrivers/sync/core/file.py +3 -2
  165. osn_selenium/webdrivers/sync/core/lifecycle.py +44 -10
  166. osn_selenium/webdrivers/sync/core/script.py +3 -2
  167. osn_selenium/webdrivers/sync/core/window.py +3 -3
  168. osn_selenium/webdrivers/sync/edge/__init__.py +36 -1
  169. osn_selenium/webdrivers/sync/edge/base.py +13 -1
  170. osn_selenium/webdrivers/sync/edge/lifecycle.py +23 -5
  171. osn_selenium/webdrivers/sync/edge/settings.py +6 -1
  172. osn_selenium/webdrivers/sync/yandex/__init__.py +36 -1
  173. osn_selenium/webdrivers/sync/yandex/base.py +13 -1
  174. osn_selenium/webdrivers/sync/yandex/lifecycle.py +23 -5
  175. osn_selenium/webdrivers/sync/yandex/settings.py +6 -1
  176. osn_selenium/webdrivers/trio_bidi/__init__.py +1 -0
  177. osn_selenium/webdrivers/trio_bidi/blink/__init__.py +132 -0
  178. osn_selenium/webdrivers/trio_bidi/blink/base.py +167 -0
  179. osn_selenium/webdrivers/trio_bidi/blink/lifecycle.py +89 -0
  180. osn_selenium/webdrivers/trio_bidi/blink/settings.py +63 -0
  181. osn_selenium/webdrivers/trio_bidi/chrome/__init__.py +114 -0
  182. osn_selenium/webdrivers/trio_bidi/chrome/base.py +127 -0
  183. osn_selenium/webdrivers/trio_bidi/chrome/lifecycle.py +85 -0
  184. osn_selenium/webdrivers/trio_bidi/chrome/settings.py +63 -0
  185. osn_selenium/webdrivers/trio_bidi/core/__init__.py +95 -0
  186. osn_selenium/webdrivers/trio_bidi/core/actions.py +70 -0
  187. osn_selenium/webdrivers/trio_bidi/core/base.py +200 -0
  188. osn_selenium/webdrivers/trio_bidi/core/capture.py +39 -0
  189. osn_selenium/webdrivers/trio_bidi/core/devtools.py +49 -0
  190. osn_selenium/webdrivers/trio_bidi/core/element.py +64 -0
  191. osn_selenium/webdrivers/trio_bidi/core/lifecycle.py +135 -0
  192. osn_selenium/webdrivers/trio_bidi/core/navigation.py +37 -0
  193. osn_selenium/webdrivers/trio_bidi/core/script.py +56 -0
  194. osn_selenium/webdrivers/trio_bidi/core/settings.py +36 -0
  195. osn_selenium/webdrivers/trio_bidi/core/window.py +134 -0
  196. osn_selenium/webdrivers/trio_bidi/edge/__init__.py +114 -0
  197. osn_selenium/webdrivers/trio_bidi/edge/base.py +123 -0
  198. osn_selenium/webdrivers/trio_bidi/edge/lifecycle.py +85 -0
  199. osn_selenium/webdrivers/trio_bidi/edge/settings.py +63 -0
  200. osn_selenium/webdrivers/trio_bidi/yandex/__init__.py +114 -0
  201. osn_selenium/webdrivers/trio_bidi/yandex/base.py +120 -0
  202. osn_selenium/webdrivers/trio_bidi/yandex/lifecycle.py +85 -0
  203. osn_selenium/webdrivers/trio_bidi/yandex/settings.py +63 -0
  204. osn_selenium/webdrivers/trio_threads/blink/__init__.py +18 -2
  205. osn_selenium/webdrivers/trio_threads/blink/base.py +25 -1
  206. osn_selenium/webdrivers/trio_threads/blink/casting.py +1 -1
  207. osn_selenium/webdrivers/trio_threads/blink/features.py +1 -1
  208. osn_selenium/webdrivers/trio_threads/blink/lifecycle.py +26 -8
  209. osn_selenium/webdrivers/trio_threads/blink/logging.py +1 -1
  210. osn_selenium/webdrivers/trio_threads/blink/network.py +1 -1
  211. osn_selenium/webdrivers/trio_threads/chrome/__init__.py +34 -1
  212. osn_selenium/webdrivers/trio_threads/chrome/base.py +14 -2
  213. osn_selenium/webdrivers/trio_threads/chrome/lifecycle.py +23 -5
  214. osn_selenium/webdrivers/trio_threads/chrome/settings.py +1 -1
  215. osn_selenium/webdrivers/trio_threads/core/__init__.py +10 -14
  216. osn_selenium/webdrivers/trio_threads/core/actions.py +1 -1
  217. osn_selenium/webdrivers/trio_threads/core/auth.py +1 -1
  218. osn_selenium/webdrivers/trio_threads/core/base.py +18 -22
  219. osn_selenium/webdrivers/trio_threads/core/capture.py +4 -3
  220. osn_selenium/webdrivers/trio_threads/core/comonents.py +1 -1
  221. osn_selenium/webdrivers/trio_threads/core/devtools.py +1 -1
  222. osn_selenium/webdrivers/trio_threads/core/element.py +1 -1
  223. osn_selenium/webdrivers/trio_threads/core/file.py +5 -4
  224. osn_selenium/webdrivers/trio_threads/core/lifecycle.py +45 -11
  225. osn_selenium/webdrivers/trio_threads/core/navigation.py +1 -1
  226. osn_selenium/webdrivers/trio_threads/core/script.py +4 -3
  227. osn_selenium/webdrivers/trio_threads/core/settings.py +1 -1
  228. osn_selenium/webdrivers/trio_threads/core/storage.py +1 -1
  229. osn_selenium/webdrivers/trio_threads/core/timeouts.py +1 -1
  230. osn_selenium/webdrivers/trio_threads/core/window.py +6 -6
  231. osn_selenium/webdrivers/trio_threads/edge/__init__.py +34 -1
  232. osn_selenium/webdrivers/trio_threads/edge/base.py +14 -2
  233. osn_selenium/webdrivers/trio_threads/edge/lifecycle.py +23 -5
  234. osn_selenium/webdrivers/trio_threads/edge/settings.py +1 -1
  235. osn_selenium/webdrivers/trio_threads/yandex/__init__.py +34 -1
  236. osn_selenium/webdrivers/trio_threads/yandex/base.py +14 -2
  237. osn_selenium/webdrivers/trio_threads/yandex/lifecycle.py +23 -5
  238. osn_selenium/webdrivers/trio_threads/yandex/settings.py +1 -1
  239. osn_selenium/webdrivers/unified/blink/base.py +9 -1
  240. osn_selenium/webdrivers/unified/blink/lifecycle.py +4 -2
  241. osn_selenium/webdrivers/unified/chrome/base.py +9 -1
  242. osn_selenium/webdrivers/unified/core/auth.py +4 -2
  243. osn_selenium/webdrivers/unified/core/base.py +19 -6
  244. osn_selenium/webdrivers/unified/core/capture.py +3 -2
  245. osn_selenium/webdrivers/unified/core/components.py +12 -7
  246. osn_selenium/webdrivers/unified/core/devtools.py +2 -1
  247. osn_selenium/webdrivers/unified/core/file.py +3 -2
  248. osn_selenium/webdrivers/unified/core/lifecycle.py +5 -3
  249. osn_selenium/webdrivers/unified/core/script.py +5 -3
  250. osn_selenium/webdrivers/unified/core/storage.py +2 -1
  251. osn_selenium/webdrivers/unified/core/window.py +9 -8
  252. osn_selenium/webdrivers/unified/edge/base.py +9 -1
  253. osn_selenium/webdrivers/unified/yandex/base.py +9 -1
  254. {osn_selenium-1.0.0.dist-info → osn_selenium-1.2.0.dist-info}/METADATA +24 -10
  255. osn_selenium-1.2.0.dist-info/RECORD +480 -0
  256. {osn_selenium-1.0.0.dist-info → osn_selenium-1.2.0.dist-info}/WHEEL +1 -1
  257. osn_selenium/abstract/executors/cdp/__init__.py +0 -435
  258. osn_selenium/abstract/executors/cdp/accessibility.py +0 -62
  259. osn_selenium/abstract/executors/cdp/animation.py +0 -47
  260. osn_selenium/abstract/executors/cdp/audits.py +0 -39
  261. osn_selenium/abstract/executors/cdp/autofill.py +0 -34
  262. osn_selenium/abstract/executors/cdp/background_service.py +0 -22
  263. osn_selenium/abstract/executors/cdp/bluetooth_emulation.py +0 -95
  264. osn_selenium/abstract/executors/cdp/browser.py +0 -122
  265. osn_selenium/abstract/executors/cdp/cache_storage.py +0 -49
  266. osn_selenium/abstract/executors/cdp/cast.py +0 -31
  267. osn_selenium/abstract/executors/cdp/console.py +0 -18
  268. osn_selenium/abstract/executors/cdp/css.py +0 -197
  269. osn_selenium/abstract/executors/cdp/debugger.py +0 -198
  270. osn_selenium/abstract/executors/cdp/device_access.py +0 -22
  271. osn_selenium/abstract/executors/cdp/device_orientation.py +0 -14
  272. osn_selenium/abstract/executors/cdp/dom.py +0 -305
  273. osn_selenium/abstract/executors/cdp/dom_debugger.py +0 -57
  274. osn_selenium/abstract/executors/cdp/dom_snapshot.py +0 -42
  275. osn_selenium/abstract/executors/cdp/dom_storage.py +0 -31
  276. osn_selenium/abstract/executors/cdp/emulation.py +0 -259
  277. osn_selenium/abstract/executors/cdp/event_breakpoints.py +0 -18
  278. osn_selenium/abstract/executors/cdp/extensions.py +0 -31
  279. osn_selenium/abstract/executors/cdp/fed_cm.py +0 -35
  280. osn_selenium/abstract/executors/cdp/fetch.py +0 -76
  281. osn_selenium/abstract/executors/cdp/file_system.py +0 -11
  282. osn_selenium/abstract/executors/cdp/headless_experimental.py +0 -30
  283. osn_selenium/abstract/executors/cdp/heap_profiler.py +0 -73
  284. osn_selenium/abstract/executors/cdp/indexed_db.py +0 -99
  285. osn_selenium/abstract/executors/cdp/input.py +0 -158
  286. osn_selenium/abstract/executors/cdp/inspector.py +0 -14
  287. osn_selenium/abstract/executors/cdp/io.py +0 -24
  288. osn_selenium/abstract/executors/cdp/layer_tree.py +0 -61
  289. osn_selenium/abstract/executors/cdp/log.py +0 -27
  290. osn_selenium/abstract/executors/cdp/media.py +0 -14
  291. osn_selenium/abstract/executors/cdp/memory.py +0 -61
  292. osn_selenium/abstract/executors/cdp/network.py +0 -252
  293. osn_selenium/abstract/executors/cdp/overlay.py +0 -166
  294. osn_selenium/abstract/executors/cdp/page.py +0 -347
  295. osn_selenium/abstract/executors/cdp/performance.py +0 -28
  296. osn_selenium/abstract/executors/cdp/performance_timeline.py +0 -11
  297. osn_selenium/abstract/executors/cdp/preload.py +0 -14
  298. osn_selenium/abstract/executors/cdp/profiler.py +0 -54
  299. osn_selenium/abstract/executors/cdp/pwa.py +0 -46
  300. osn_selenium/abstract/executors/cdp/runtime.py +0 -176
  301. osn_selenium/abstract/executors/cdp/schema.py +0 -11
  302. osn_selenium/abstract/executors/cdp/security.py +0 -26
  303. osn_selenium/abstract/executors/cdp/service_worker.py +0 -54
  304. osn_selenium/abstract/executors/cdp/storage.py +0 -175
  305. osn_selenium/abstract/executors/cdp/system_info.py +0 -24
  306. osn_selenium/abstract/executors/cdp/target.py +0 -125
  307. osn_selenium/abstract/executors/cdp/tethering.py +0 -14
  308. osn_selenium/abstract/executors/cdp/tracing.py +0 -48
  309. osn_selenium/abstract/executors/cdp/web_audio.py +0 -19
  310. osn_selenium/abstract/executors/cdp/web_authn.py +0 -76
  311. osn_selenium/executors/sync/cdp/__init__.py +0 -550
  312. osn_selenium/executors/sync/cdp/accessibility.py +0 -74
  313. osn_selenium/executors/sync/cdp/animation.py +0 -50
  314. osn_selenium/executors/sync/cdp/audits.py +0 -48
  315. osn_selenium/executors/sync/cdp/autofill.py +0 -39
  316. osn_selenium/executors/sync/cdp/background_service.py +0 -30
  317. osn_selenium/executors/sync/cdp/bluetooth_emulation.py +0 -101
  318. osn_selenium/executors/sync/cdp/browser.py +0 -131
  319. osn_selenium/executors/sync/cdp/cache_storage.py +0 -66
  320. osn_selenium/executors/sync/cdp/cast.py +0 -38
  321. osn_selenium/executors/sync/cdp/console.py +0 -24
  322. osn_selenium/executors/sync/cdp/css.py +0 -187
  323. osn_selenium/executors/sync/cdp/debugger.py +0 -206
  324. osn_selenium/executors/sync/cdp/device_access.py +0 -27
  325. osn_selenium/executors/sync/cdp/device_orientation.py +0 -24
  326. osn_selenium/executors/sync/cdp/dom.py +0 -310
  327. osn_selenium/executors/sync/cdp/dom_debugger.py +0 -56
  328. osn_selenium/executors/sync/cdp/dom_snapshot.py +0 -58
  329. osn_selenium/executors/sync/cdp/dom_storage.py +0 -38
  330. osn_selenium/executors/sync/cdp/emulation.py +0 -270
  331. osn_selenium/executors/sync/cdp/event_breakpoints.py +0 -27
  332. osn_selenium/executors/sync/cdp/extensions.py +0 -39
  333. osn_selenium/executors/sync/cdp/fed_cm.py +0 -45
  334. osn_selenium/executors/sync/cdp/fetch.py +0 -96
  335. osn_selenium/executors/sync/cdp/file_system.py +0 -18
  336. osn_selenium/executors/sync/cdp/headless_experimental.py +0 -44
  337. osn_selenium/executors/sync/cdp/heap_profiler.py +0 -89
  338. osn_selenium/executors/sync/cdp/indexed_db.py +0 -142
  339. osn_selenium/executors/sync/cdp/input.py +0 -233
  340. osn_selenium/executors/sync/cdp/inspector.py +0 -21
  341. osn_selenium/executors/sync/cdp/io.py +0 -33
  342. osn_selenium/executors/sync/cdp/layer_tree.py +0 -71
  343. osn_selenium/executors/sync/cdp/log.py +0 -35
  344. osn_selenium/executors/sync/cdp/media.py +0 -21
  345. osn_selenium/executors/sync/cdp/memory.py +0 -62
  346. osn_selenium/executors/sync/cdp/network.py +0 -287
  347. osn_selenium/executors/sync/cdp/overlay.py +0 -174
  348. osn_selenium/executors/sync/cdp/page.py +0 -365
  349. osn_selenium/executors/sync/cdp/performance.py +0 -33
  350. osn_selenium/executors/sync/cdp/performance_timeline.py +0 -26
  351. osn_selenium/executors/sync/cdp/preload.py +0 -21
  352. osn_selenium/executors/sync/cdp/profiler.py +0 -58
  353. osn_selenium/executors/sync/cdp/pwa.py +0 -55
  354. osn_selenium/executors/sync/cdp/runtime.py +0 -221
  355. osn_selenium/executors/sync/cdp/schema.py +0 -23
  356. osn_selenium/executors/sync/cdp/security.py +0 -30
  357. osn_selenium/executors/sync/cdp/service_worker.py +0 -56
  358. osn_selenium/executors/sync/cdp/storage.py +0 -151
  359. osn_selenium/executors/sync/cdp/system_info.py +0 -30
  360. osn_selenium/executors/sync/cdp/target.py +0 -147
  361. osn_selenium/executors/sync/cdp/tethering.py +0 -21
  362. osn_selenium/executors/sync/cdp/tracing.py +0 -62
  363. osn_selenium/executors/sync/cdp/web_audio.py +0 -24
  364. osn_selenium/executors/sync/cdp/web_authn.py +0 -82
  365. osn_selenium/executors/trio_threads/cdp/__init__.py +0 -771
  366. osn_selenium/executors/trio_threads/cdp/accessibility.py +0 -87
  367. osn_selenium/executors/trio_threads/cdp/animation.py +0 -63
  368. osn_selenium/executors/trio_threads/cdp/audits.py +0 -57
  369. osn_selenium/executors/trio_threads/cdp/autofill.py +0 -52
  370. osn_selenium/executors/trio_threads/cdp/background_service.py +0 -40
  371. osn_selenium/executors/trio_threads/cdp/bluetooth_emulation.py +0 -111
  372. osn_selenium/executors/trio_threads/cdp/browser.py +0 -140
  373. osn_selenium/executors/trio_threads/cdp/cache_storage.py +0 -79
  374. osn_selenium/executors/trio_threads/cdp/cast.py +0 -47
  375. osn_selenium/executors/trio_threads/cdp/console.py +0 -33
  376. osn_selenium/executors/trio_threads/cdp/css.py +0 -196
  377. osn_selenium/executors/trio_threads/cdp/debugger.py +0 -219
  378. osn_selenium/executors/trio_threads/cdp/device_access.py +0 -40
  379. osn_selenium/executors/trio_threads/cdp/device_orientation.py +0 -34
  380. osn_selenium/executors/trio_threads/cdp/dom.py +0 -319
  381. osn_selenium/executors/trio_threads/cdp/dom_debugger.py +0 -69
  382. osn_selenium/executors/trio_threads/cdp/dom_snapshot.py +0 -71
  383. osn_selenium/executors/trio_threads/cdp/dom_storage.py +0 -51
  384. osn_selenium/executors/trio_threads/cdp/emulation.py +0 -283
  385. osn_selenium/executors/trio_threads/cdp/event_breakpoints.py +0 -37
  386. osn_selenium/executors/trio_threads/cdp/extensions.py +0 -52
  387. osn_selenium/executors/trio_threads/cdp/fed_cm.py +0 -54
  388. osn_selenium/executors/trio_threads/cdp/fetch.py +0 -105
  389. osn_selenium/executors/trio_threads/cdp/file_system.py +0 -31
  390. osn_selenium/executors/trio_threads/cdp/headless_experimental.py +0 -54
  391. osn_selenium/executors/trio_threads/cdp/heap_profiler.py +0 -102
  392. osn_selenium/executors/trio_threads/cdp/indexed_db.py +0 -155
  393. osn_selenium/executors/trio_threads/cdp/input.py +0 -242
  394. osn_selenium/executors/trio_threads/cdp/inspector.py +0 -34
  395. osn_selenium/executors/trio_threads/cdp/io.py +0 -42
  396. osn_selenium/executors/trio_threads/cdp/layer_tree.py +0 -84
  397. osn_selenium/executors/trio_threads/cdp/log.py +0 -44
  398. osn_selenium/executors/trio_threads/cdp/media.py +0 -30
  399. osn_selenium/executors/trio_threads/cdp/memory.py +0 -71
  400. osn_selenium/executors/trio_threads/cdp/network.py +0 -296
  401. osn_selenium/executors/trio_threads/cdp/overlay.py +0 -183
  402. osn_selenium/executors/trio_threads/cdp/page.py +0 -374
  403. osn_selenium/executors/trio_threads/cdp/performance.py +0 -46
  404. osn_selenium/executors/trio_threads/cdp/performance_timeline.py +0 -36
  405. osn_selenium/executors/trio_threads/cdp/preload.py +0 -30
  406. osn_selenium/executors/trio_threads/cdp/profiler.py +0 -71
  407. osn_selenium/executors/trio_threads/cdp/pwa.py +0 -64
  408. osn_selenium/executors/trio_threads/cdp/runtime.py +0 -230
  409. osn_selenium/executors/trio_threads/cdp/schema.py +0 -32
  410. osn_selenium/executors/trio_threads/cdp/security.py +0 -43
  411. osn_selenium/executors/trio_threads/cdp/service_worker.py +0 -69
  412. osn_selenium/executors/trio_threads/cdp/storage.py +0 -162
  413. osn_selenium/executors/trio_threads/cdp/system_info.py +0 -43
  414. osn_selenium/executors/trio_threads/cdp/target.py +0 -156
  415. osn_selenium/executors/trio_threads/cdp/tethering.py +0 -34
  416. osn_selenium/executors/trio_threads/cdp/tracing.py +0 -71
  417. osn_selenium/executors/trio_threads/cdp/web_audio.py +0 -37
  418. osn_selenium/executors/trio_threads/cdp/web_authn.py +0 -95
  419. osn_selenium/executors/unified/cdp/accessibility.py +0 -81
  420. osn_selenium/executors/unified/cdp/animation.py +0 -50
  421. osn_selenium/executors/unified/cdp/audits.py +0 -45
  422. osn_selenium/executors/unified/cdp/autofill.py +0 -41
  423. osn_selenium/executors/unified/cdp/background_service.py +0 -24
  424. osn_selenium/executors/unified/cdp/bluetooth_emulation.py +0 -132
  425. osn_selenium/executors/unified/cdp/browser.py +0 -143
  426. osn_selenium/executors/unified/cdp/cache_storage.py +0 -69
  427. osn_selenium/executors/unified/cdp/cast.py +0 -32
  428. osn_selenium/executors/unified/cdp/console.py +0 -18
  429. osn_selenium/executors/unified/cdp/css.py +0 -237
  430. osn_selenium/executors/unified/cdp/debugger.py +0 -243
  431. osn_selenium/executors/unified/cdp/device_access.py +0 -21
  432. osn_selenium/executors/unified/cdp/device_orientation.py +0 -18
  433. osn_selenium/executors/unified/cdp/dom.py +0 -380
  434. osn_selenium/executors/unified/cdp/dom_debugger.py +0 -65
  435. osn_selenium/executors/unified/cdp/dom_snapshot.py +0 -58
  436. osn_selenium/executors/unified/cdp/dom_storage.py +0 -38
  437. osn_selenium/executors/unified/cdp/emulation.py +0 -312
  438. osn_selenium/executors/unified/cdp/event_breakpoints.py +0 -24
  439. osn_selenium/executors/unified/cdp/extensions.py +0 -45
  440. osn_selenium/executors/unified/cdp/fed_cm.py +0 -51
  441. osn_selenium/executors/unified/cdp/fetch.py +0 -111
  442. osn_selenium/executors/unified/cdp/file_system.py +0 -15
  443. osn_selenium/executors/unified/cdp/headless_experimental.py +0 -38
  444. osn_selenium/executors/unified/cdp/heap_profiler.py +0 -101
  445. osn_selenium/executors/unified/cdp/indexed_db.py +0 -157
  446. osn_selenium/executors/unified/cdp/input.py +0 -254
  447. osn_selenium/executors/unified/cdp/inspector.py +0 -15
  448. osn_selenium/executors/unified/cdp/io.py +0 -29
  449. osn_selenium/executors/unified/cdp/layer_tree.py +0 -71
  450. osn_selenium/executors/unified/cdp/log.py +0 -29
  451. osn_selenium/executors/unified/cdp/media.py +0 -15
  452. osn_selenium/executors/unified/cdp/memory.py +0 -59
  453. osn_selenium/executors/unified/cdp/network.py +0 -323
  454. osn_selenium/executors/unified/cdp/overlay.py +0 -209
  455. osn_selenium/executors/unified/cdp/page.py +0 -410
  456. osn_selenium/executors/unified/cdp/performance.py +0 -27
  457. osn_selenium/executors/unified/cdp/performance_timeline.py +0 -17
  458. osn_selenium/executors/unified/cdp/preload.py +0 -15
  459. osn_selenium/executors/unified/cdp/profiler.py +0 -55
  460. osn_selenium/executors/unified/cdp/pwa.py +0 -55
  461. osn_selenium/executors/unified/cdp/runtime.py +0 -245
  462. osn_selenium/executors/unified/cdp/schema.py +0 -17
  463. osn_selenium/executors/unified/cdp/security.py +0 -27
  464. osn_selenium/executors/unified/cdp/service_worker.py +0 -62
  465. osn_selenium/executors/unified/cdp/storage.py +0 -178
  466. osn_selenium/executors/unified/cdp/system_info.py +0 -24
  467. osn_selenium/executors/unified/cdp/target.py +0 -165
  468. osn_selenium/executors/unified/cdp/tethering.py +0 -15
  469. osn_selenium/executors/unified/cdp/tracing.py +0 -62
  470. osn_selenium/executors/unified/cdp/web_audio.py +0 -18
  471. osn_selenium/executors/unified/cdp/web_authn.py +0 -103
  472. osn_selenium-1.0.0.dist-info/RECORD +0 -608
  473. /osn_selenium/{dev_tools/_exception_helpers.py → _exception_helpers.py} +0 -0
  474. /osn_selenium/executors/{unified/cdp → trio_bidi}/__init__.py +0 -0
  475. {osn_selenium-1.0.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 contextlib import asynccontextmanager
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,
@@ -23,11 +24,6 @@ class TrioThreadMixin:
23
24
  """
24
25
  Provides utilities for running synchronous functions in a Trio event loop
25
26
  with a controlled concurrency, ensuring thread safety and resource limits.
26
-
27
- Attributes:
28
- _lock (trio.Lock): A Trio Lock to ensure exclusive access for certain operations.
29
- _capacity_limiter (trio.CapacityLimiter): A Trio CapacityLimiter to control the number
30
- of concurrent synchronous operations.
31
27
  """
32
28
 
33
29
  def __init__(self, lock: trio.Lock, limiter: trio.CapacityLimiter) -> None:
@@ -64,59 +60,54 @@ class TrioThreadMixin:
64
60
 
65
61
  return self._lock
66
62
 
67
- def sync_to_trio(self, sync_function: Callable[_METHOD_INPUT, _METHOD_OUTPUT]) -> Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]:
63
+ def sync_to_trio(
64
+ self,
65
+ sync_function: Callable[_METHOD_INPUT, _METHOD_OUTPUT],
66
+ lock: bool = True,
67
+ exchange_context:bool = True,
68
+ ) -> Callable[_METHOD_INPUT, Coroutine[Any, Any, _METHOD_OUTPUT]]:
68
69
  """
69
70
  Wraps a synchronous function to run within a Trio thread pool using a lock and limiter.
70
71
 
71
72
  Args:
72
73
  sync_function (Callable[_METHOD_INPUT, _METHOD_OUTPUT]): The synchronous function to wrap.
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
- async def wrapper(*args: _METHOD_INPUT.args, **kwargs: _METHOD_INPUT.kwargs) -> _METHOD_OUTPUT:
79
- def function_with_kwargs(*args_) -> _METHOD_OUTPUT:
80
- return sync_function(*args_, **kwargs)
81
-
82
- async with self._lock:
83
- result = await trio.to_thread.run_sync(function_with_kwargs, *args, limiter=self._capacity_limiter)
84
-
85
- return result
86
-
87
- 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
+ )
88
88
 
89
89
  def sync_to_trio_context(
90
90
  self,
91
- context_manager_factory: Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]]
91
+ context_manager_factory: Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]],
92
+ lock: bool = True,
93
+ exchange_context:bool = True,
92
94
  ) -> Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]:
93
95
  """
94
96
  Converts a synchronous context manager factory to an asynchronous Trio-compatible context manager.
95
97
 
96
98
  Args:
97
99
  context_manager_factory (Callable[_METHOD_INPUT, ContextManager[_METHOD_OUTPUT]]): A factory function returning a context manager.
100
+ lock (bool): Whether to use the internal lock for synchronization.
101
+ exchange_context (bool): Whether to synchronize context variables between threads.
98
102
 
99
103
  Returns:
100
104
  Callable[_METHOD_INPUT, AsyncContextManager[_METHOD_OUTPUT]]: An async function returning an async context manager.
101
105
  """
102
106
 
103
- @asynccontextmanager
104
- async def wrapper(*args: _METHOD_INPUT.args, **kwargs: _METHOD_INPUT.kwargs) -> AsyncIterator[_METHOD_OUTPUT]:
105
- sync_context_manager = await self.sync_to_trio(sync_function=context_manager_factory)(*args, **kwargs)
106
-
107
- enter_ = self.sync_to_trio(sync_function=sync_context_manager.__enter__)
108
- exit_ = self.sync_to_trio(sync_function=sync_context_manager.__exit__)
109
-
110
- try:
111
- result = await enter_()
112
-
113
- yield result
114
- except Exception as e:
115
- exc_type, exc_val, exc_tb = sys.exc_info()
116
-
117
- if not await exit_(exc_type, exc_val, exc_tb):
118
- raise e
119
- else:
120
- await exit_(None, None, None)
121
-
122
- 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
+ )