patchright 1.48.0__py3-none-win32.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 (406) hide show
  1. patchright/__init__.py +5 -0
  2. patchright/__main__.py +18 -0
  3. patchright/_impl/__init__.py +0 -0
  4. patchright/_impl/__pyinstaller/__init__.py +20 -0
  5. patchright/_impl/__pyinstaller/hook-playwright.async_api.py +17 -0
  6. patchright/_impl/__pyinstaller/hook-playwright.sync_api.py +17 -0
  7. patchright/_impl/_accessibility.py +50 -0
  8. patchright/_impl/_api_structures.py +271 -0
  9. patchright/_impl/_artifact.py +45 -0
  10. patchright/_impl/_assertions.py +779 -0
  11. patchright/_impl/_async_base.py +92 -0
  12. patchright/_impl/_browser.py +243 -0
  13. patchright/_impl/_browser_context.py +724 -0
  14. patchright/_impl/_browser_type.py +264 -0
  15. patchright/_impl/_cdp_session.py +21 -0
  16. patchright/_impl/_clock.py +57 -0
  17. patchright/_impl/_connection.py +554 -0
  18. patchright/_impl/_console_message.py +45 -0
  19. patchright/_impl/_dialog.py +40 -0
  20. patchright/_impl/_download.py +50 -0
  21. patchright/_impl/_driver.py +26 -0
  22. patchright/_impl/_element_handle.py +376 -0
  23. patchright/_impl/_errors.py +44 -0
  24. patchright/_impl/_event_context_manager.py +20 -0
  25. patchright/_impl/_fetch.py +511 -0
  26. patchright/_impl/_file_chooser.py +43 -0
  27. patchright/_impl/_frame.py +755 -0
  28. patchright/_impl/_glob.py +51 -0
  29. patchright/_impl/_greenlets.py +39 -0
  30. patchright/_impl/_har_router.py +99 -0
  31. patchright/_impl/_helper.py +421 -0
  32. patchright/_impl/_impl_to_api_mapping.py +123 -0
  33. patchright/_impl/_input.py +71 -0
  34. patchright/_impl/_js_handle.py +234 -0
  35. patchright/_impl/_json_pipe.py +56 -0
  36. patchright/_impl/_local_utils.py +73 -0
  37. patchright/_impl/_locator.py +784 -0
  38. patchright/_impl/_map.py +19 -0
  39. patchright/_impl/_network.py +934 -0
  40. patchright/_impl/_object_factory.py +91 -0
  41. patchright/_impl/_page.py +1446 -0
  42. patchright/_impl/_path_utils.py +11 -0
  43. patchright/_impl/_playwright.py +51 -0
  44. patchright/_impl/_selectors.py +62 -0
  45. patchright/_impl/_set_input_files_helpers.py +135 -0
  46. patchright/_impl/_str_utils.py +57 -0
  47. patchright/_impl/_stream.py +32 -0
  48. patchright/_impl/_sync_base.py +134 -0
  49. patchright/_impl/_tracing.py +103 -0
  50. patchright/_impl/_transport.py +150 -0
  51. patchright/_impl/_video.py +57 -0
  52. patchright/_impl/_waiter.py +142 -0
  53. patchright/_impl/_web_error.py +22 -0
  54. patchright/_impl/_writable_stream.py +27 -0
  55. patchright/_repo_version.py +12 -0
  56. patchright/async_api/__init__.py +177 -0
  57. patchright/async_api/_context_manager.py +39 -0
  58. patchright/async_api/_generated.py +19960 -0
  59. patchright/driver/LICENSE +2174 -0
  60. patchright/driver/README.md +1 -0
  61. patchright/driver/node.exe +0 -0
  62. patchright/driver/package/README.md +3 -0
  63. patchright/driver/package/ThirdPartyNotices.txt +1548 -0
  64. patchright/driver/package/api.json +1 -0
  65. patchright/driver/package/bin/PrintDeps.exe +0 -0
  66. patchright/driver/package/bin/README.md +2 -0
  67. patchright/driver/package/bin/install_media_pack.ps1 +5 -0
  68. patchright/driver/package/bin/reinstall_chrome_beta_linux.sh +40 -0
  69. patchright/driver/package/bin/reinstall_chrome_beta_mac.sh +13 -0
  70. patchright/driver/package/bin/reinstall_chrome_beta_win.ps1 +24 -0
  71. patchright/driver/package/bin/reinstall_chrome_stable_linux.sh +40 -0
  72. patchright/driver/package/bin/reinstall_chrome_stable_mac.sh +12 -0
  73. patchright/driver/package/bin/reinstall_chrome_stable_win.ps1 +24 -0
  74. patchright/driver/package/bin/reinstall_msedge_beta_linux.sh +40 -0
  75. patchright/driver/package/bin/reinstall_msedge_beta_mac.sh +11 -0
  76. patchright/driver/package/bin/reinstall_msedge_beta_win.ps1 +23 -0
  77. patchright/driver/package/bin/reinstall_msedge_dev_linux.sh +40 -0
  78. patchright/driver/package/bin/reinstall_msedge_dev_mac.sh +11 -0
  79. patchright/driver/package/bin/reinstall_msedge_dev_win.ps1 +23 -0
  80. patchright/driver/package/bin/reinstall_msedge_stable_linux.sh +40 -0
  81. patchright/driver/package/bin/reinstall_msedge_stable_mac.sh +11 -0
  82. patchright/driver/package/bin/reinstall_msedge_stable_win.ps1 +24 -0
  83. patchright/driver/package/browsers.json +57 -0
  84. patchright/driver/package/cli.js +18 -0
  85. patchright/driver/package/index.d.ts +17 -0
  86. patchright/driver/package/index.js +33 -0
  87. patchright/driver/package/index.mjs +28 -0
  88. patchright/driver/package/lib/androidServerImpl.js +69 -0
  89. patchright/driver/package/lib/browserServerImpl.js +92 -0
  90. patchright/driver/package/lib/cli/driver.js +95 -0
  91. patchright/driver/package/lib/cli/program.js +587 -0
  92. patchright/driver/package/lib/cli/programWithTestStub.js +67 -0
  93. patchright/driver/package/lib/client/accessibility.js +50 -0
  94. patchright/driver/package/lib/client/android.js +473 -0
  95. patchright/driver/package/lib/client/api.js +285 -0
  96. patchright/driver/package/lib/client/artifact.js +79 -0
  97. patchright/driver/package/lib/client/browser.js +145 -0
  98. patchright/driver/package/lib/client/browserContext.js +559 -0
  99. patchright/driver/package/lib/client/browserType.js +241 -0
  100. patchright/driver/package/lib/client/cdpSession.js +53 -0
  101. patchright/driver/package/lib/client/channelOwner.js +235 -0
  102. patchright/driver/package/lib/client/clientHelper.js +57 -0
  103. patchright/driver/package/lib/client/clientInstrumentation.js +50 -0
  104. patchright/driver/package/lib/client/clock.js +68 -0
  105. patchright/driver/package/lib/client/connection.js +333 -0
  106. patchright/driver/package/lib/client/consoleMessage.js +55 -0
  107. patchright/driver/package/lib/client/coverage.js +41 -0
  108. patchright/driver/package/lib/client/dialog.js +57 -0
  109. patchright/driver/package/lib/client/download.js +62 -0
  110. patchright/driver/package/lib/client/electron.js +135 -0
  111. patchright/driver/package/lib/client/elementHandle.js +321 -0
  112. patchright/driver/package/lib/client/errors.js +77 -0
  113. patchright/driver/package/lib/client/eventEmitter.js +314 -0
  114. patchright/driver/package/lib/client/events.js +94 -0
  115. patchright/driver/package/lib/client/fetch.js +391 -0
  116. patchright/driver/package/lib/client/fileChooser.js +45 -0
  117. patchright/driver/package/lib/client/frame.js +504 -0
  118. patchright/driver/package/lib/client/harRouter.js +99 -0
  119. patchright/driver/package/lib/client/input.js +111 -0
  120. patchright/driver/package/lib/client/jsHandle.js +121 -0
  121. patchright/driver/package/lib/client/jsonPipe.js +35 -0
  122. patchright/driver/package/lib/client/localUtils.js +36 -0
  123. patchright/driver/package/lib/client/locator.js +441 -0
  124. patchright/driver/package/lib/client/network.js +762 -0
  125. patchright/driver/package/lib/client/page.js +746 -0
  126. patchright/driver/package/lib/client/playwright.js +80 -0
  127. patchright/driver/package/lib/client/selectors.js +67 -0
  128. patchright/driver/package/lib/client/stream.js +54 -0
  129. patchright/driver/package/lib/client/tracing.js +134 -0
  130. patchright/driver/package/lib/client/types.js +24 -0
  131. patchright/driver/package/lib/client/video.js +51 -0
  132. patchright/driver/package/lib/client/waiter.js +158 -0
  133. patchright/driver/package/lib/client/webError.js +37 -0
  134. patchright/driver/package/lib/client/worker.js +71 -0
  135. patchright/driver/package/lib/client/writableStream.js +54 -0
  136. patchright/driver/package/lib/common/socksProxy.js +569 -0
  137. patchright/driver/package/lib/common/timeoutSettings.js +73 -0
  138. patchright/driver/package/lib/common/types.js +5 -0
  139. patchright/driver/package/lib/generated/clockSource.js +7 -0
  140. patchright/driver/package/lib/generated/consoleApiSource.js +7 -0
  141. patchright/driver/package/lib/generated/injectedScriptSource.js +7 -0
  142. patchright/driver/package/lib/generated/pollingRecorderSource.js +7 -0
  143. patchright/driver/package/lib/generated/utilityScriptSource.js +7 -0
  144. patchright/driver/package/lib/generated/webSocketMockSource.js +7 -0
  145. patchright/driver/package/lib/image_tools/colorUtils.js +98 -0
  146. patchright/driver/package/lib/image_tools/compare.js +108 -0
  147. patchright/driver/package/lib/image_tools/imageChannel.js +70 -0
  148. patchright/driver/package/lib/image_tools/stats.js +102 -0
  149. patchright/driver/package/lib/inProcessFactory.js +54 -0
  150. patchright/driver/package/lib/inprocess.js +20 -0
  151. patchright/driver/package/lib/outofprocess.js +67 -0
  152. patchright/driver/package/lib/protocol/debug.js +27 -0
  153. patchright/driver/package/lib/protocol/serializers.js +173 -0
  154. patchright/driver/package/lib/protocol/transport.js +82 -0
  155. patchright/driver/package/lib/protocol/validator.js +2759 -0
  156. patchright/driver/package/lib/protocol/validatorPrimitives.js +139 -0
  157. patchright/driver/package/lib/remote/playwrightConnection.js +274 -0
  158. patchright/driver/package/lib/remote/playwrightServer.js +110 -0
  159. patchright/driver/package/lib/server/accessibility.js +62 -0
  160. patchright/driver/package/lib/server/android/android.js +441 -0
  161. patchright/driver/package/lib/server/android/backendAdb.js +172 -0
  162. patchright/driver/package/lib/server/artifact.js +104 -0
  163. patchright/driver/package/lib/server/bidi/bidiBrowser.js +311 -0
  164. patchright/driver/package/lib/server/bidi/bidiChromium.js +124 -0
  165. patchright/driver/package/lib/server/bidi/bidiConnection.js +206 -0
  166. patchright/driver/package/lib/server/bidi/bidiExecutionContext.js +159 -0
  167. patchright/driver/package/lib/server/bidi/bidiFirefox.js +104 -0
  168. patchright/driver/package/lib/server/bidi/bidiInput.js +158 -0
  169. patchright/driver/package/lib/server/bidi/bidiNetworkManager.js +338 -0
  170. patchright/driver/package/lib/server/bidi/bidiOverCdp.js +103 -0
  171. patchright/driver/package/lib/server/bidi/bidiPage.js +529 -0
  172. patchright/driver/package/lib/server/bidi/bidiPdf.js +140 -0
  173. patchright/driver/package/lib/server/bidi/third_party/bidiDeserializer.js +93 -0
  174. patchright/driver/package/lib/server/bidi/third_party/bidiKeyboard.js +238 -0
  175. patchright/driver/package/lib/server/bidi/third_party/bidiProtocol.js +139 -0
  176. patchright/driver/package/lib/server/bidi/third_party/bidiSerializer.js +144 -0
  177. patchright/driver/package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  178. patchright/driver/package/lib/server/browser.js +148 -0
  179. patchright/driver/package/lib/server/browserContext.js +666 -0
  180. patchright/driver/package/lib/server/browserType.js +335 -0
  181. patchright/driver/package/lib/server/chromium/appIcon.png +0 -0
  182. patchright/driver/package/lib/server/chromium/chromium.js +350 -0
  183. patchright/driver/package/lib/server/chromium/chromiumSwitches.js +36 -0
  184. patchright/driver/package/lib/server/chromium/crAccessibility.js +237 -0
  185. patchright/driver/package/lib/server/chromium/crBrowser.js +522 -0
  186. patchright/driver/package/lib/server/chromium/crConnection.js +228 -0
  187. patchright/driver/package/lib/server/chromium/crCoverage.js +246 -0
  188. patchright/driver/package/lib/server/chromium/crDevTools.js +104 -0
  189. patchright/driver/package/lib/server/chromium/crDragDrop.js +143 -0
  190. patchright/driver/package/lib/server/chromium/crExecutionContext.js +149 -0
  191. patchright/driver/package/lib/server/chromium/crInput.js +171 -0
  192. patchright/driver/package/lib/server/chromium/crNetworkManager.js +809 -0
  193. patchright/driver/package/lib/server/chromium/crPage.js +1235 -0
  194. patchright/driver/package/lib/server/chromium/crPdf.js +153 -0
  195. patchright/driver/package/lib/server/chromium/crProtocolHelper.js +133 -0
  196. patchright/driver/package/lib/server/chromium/crServiceWorker.js +111 -0
  197. patchright/driver/package/lib/server/chromium/defaultFontFamilies.js +145 -0
  198. patchright/driver/package/lib/server/chromium/videoRecorder.js +155 -0
  199. patchright/driver/package/lib/server/clock.js +133 -0
  200. patchright/driver/package/lib/server/codegen/csharp.js +299 -0
  201. patchright/driver/package/lib/server/codegen/java.js +235 -0
  202. patchright/driver/package/lib/server/codegen/javascript.js +223 -0
  203. patchright/driver/package/lib/server/codegen/jsonl.js +47 -0
  204. patchright/driver/package/lib/server/codegen/language.js +88 -0
  205. patchright/driver/package/lib/server/codegen/languages.js +30 -0
  206. patchright/driver/package/lib/server/codegen/python.js +265 -0
  207. patchright/driver/package/lib/server/codegen/types.js +5 -0
  208. patchright/driver/package/lib/server/console.js +57 -0
  209. patchright/driver/package/lib/server/cookieStore.js +185 -0
  210. patchright/driver/package/lib/server/debugController.js +234 -0
  211. patchright/driver/package/lib/server/debugger.js +132 -0
  212. patchright/driver/package/lib/server/deviceDescriptors.js +26 -0
  213. patchright/driver/package/lib/server/deviceDescriptorsSource.json +1669 -0
  214. patchright/driver/package/lib/server/dialog.js +71 -0
  215. patchright/driver/package/lib/server/dispatchers/androidDispatcher.js +193 -0
  216. patchright/driver/package/lib/server/dispatchers/artifactDispatcher.js +118 -0
  217. patchright/driver/package/lib/server/dispatchers/browserContextDispatcher.js +368 -0
  218. patchright/driver/package/lib/server/dispatchers/browserDispatcher.js +170 -0
  219. patchright/driver/package/lib/server/dispatchers/browserTypeDispatcher.js +55 -0
  220. patchright/driver/package/lib/server/dispatchers/cdpSessionDispatcher.js +48 -0
  221. patchright/driver/package/lib/server/dispatchers/debugControllerDispatcher.js +103 -0
  222. patchright/driver/package/lib/server/dispatchers/dialogDispatcher.js +44 -0
  223. patchright/driver/package/lib/server/dispatchers/dispatcher.js +395 -0
  224. patchright/driver/package/lib/server/dispatchers/electronDispatcher.js +93 -0
  225. patchright/driver/package/lib/server/dispatchers/elementHandlerDispatcher.js +228 -0
  226. patchright/driver/package/lib/server/dispatchers/frameDispatcher.js +286 -0
  227. patchright/driver/package/lib/server/dispatchers/jsHandleDispatcher.js +97 -0
  228. patchright/driver/package/lib/server/dispatchers/jsonPipeDispatcher.js +59 -0
  229. patchright/driver/package/lib/server/dispatchers/localUtilsDispatcher.js +413 -0
  230. patchright/driver/package/lib/server/dispatchers/networkDispatchers.js +221 -0
  231. patchright/driver/package/lib/server/dispatchers/pageDispatcher.js +367 -0
  232. patchright/driver/package/lib/server/dispatchers/playwrightDispatcher.js +107 -0
  233. patchright/driver/package/lib/server/dispatchers/selectorsDispatcher.js +36 -0
  234. patchright/driver/package/lib/server/dispatchers/streamDispatcher.js +62 -0
  235. patchright/driver/package/lib/server/dispatchers/tracingDispatcher.js +54 -0
  236. patchright/driver/package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  237. patchright/driver/package/lib/server/dispatchers/writableStreamDispatcher.js +58 -0
  238. patchright/driver/package/lib/server/dom.js +845 -0
  239. patchright/driver/package/lib/server/download.js +60 -0
  240. patchright/driver/package/lib/server/electron/electron.js +296 -0
  241. patchright/driver/package/lib/server/electron/loader.js +57 -0
  242. patchright/driver/package/lib/server/errors.js +68 -0
  243. patchright/driver/package/lib/server/fetch.js +656 -0
  244. patchright/driver/package/lib/server/fileChooser.js +42 -0
  245. patchright/driver/package/lib/server/fileUploadUtils.js +75 -0
  246. patchright/driver/package/lib/server/firefox/ffAccessibility.js +216 -0
  247. patchright/driver/package/lib/server/firefox/ffBrowser.js +460 -0
  248. patchright/driver/package/lib/server/firefox/ffConnection.js +168 -0
  249. patchright/driver/package/lib/server/firefox/ffExecutionContext.js +135 -0
  250. patchright/driver/package/lib/server/firefox/ffInput.js +150 -0
  251. patchright/driver/package/lib/server/firefox/ffNetworkManager.js +233 -0
  252. patchright/driver/package/lib/server/firefox/ffPage.js +559 -0
  253. patchright/driver/package/lib/server/firefox/firefox.js +99 -0
  254. patchright/driver/package/lib/server/formData.js +75 -0
  255. patchright/driver/package/lib/server/frameSelectors.js +171 -0
  256. patchright/driver/package/lib/server/frames.js +1808 -0
  257. patchright/driver/package/lib/server/har/harRecorder.js +139 -0
  258. patchright/driver/package/lib/server/har/harTracer.js +542 -0
  259. patchright/driver/package/lib/server/helper.js +103 -0
  260. patchright/driver/package/lib/server/index.js +114 -0
  261. patchright/driver/package/lib/server/input.js +310 -0
  262. patchright/driver/package/lib/server/instrumentation.js +70 -0
  263. patchright/driver/package/lib/server/isomorphic/utilityScriptSerializers.js +226 -0
  264. patchright/driver/package/lib/server/javascript.js +299 -0
  265. patchright/driver/package/lib/server/launchApp.js +91 -0
  266. patchright/driver/package/lib/server/macEditingCommands.js +139 -0
  267. patchright/driver/package/lib/server/network.js +617 -0
  268. patchright/driver/package/lib/server/page.js +819 -0
  269. patchright/driver/package/lib/server/pipeTransport.js +85 -0
  270. patchright/driver/package/lib/server/playwright.js +88 -0
  271. patchright/driver/package/lib/server/progress.js +102 -0
  272. patchright/driver/package/lib/server/protocolError.js +49 -0
  273. patchright/driver/package/lib/server/recorder/contextRecorder.js +299 -0
  274. patchright/driver/package/lib/server/recorder/recorderApp.js +196 -0
  275. patchright/driver/package/lib/server/recorder/recorderCollection.js +116 -0
  276. patchright/driver/package/lib/server/recorder/recorderFrontend.js +5 -0
  277. patchright/driver/package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  278. patchright/driver/package/lib/server/recorder/recorderRunner.js +155 -0
  279. patchright/driver/package/lib/server/recorder/recorderUtils.js +112 -0
  280. patchright/driver/package/lib/server/recorder/throttledFile.js +46 -0
  281. patchright/driver/package/lib/server/recorder.js +327 -0
  282. patchright/driver/package/lib/server/registry/browserFetcher.js +168 -0
  283. patchright/driver/package/lib/server/registry/dependencies.js +322 -0
  284. patchright/driver/package/lib/server/registry/index.js +1005 -0
  285. patchright/driver/package/lib/server/registry/nativeDeps.js +490 -0
  286. patchright/driver/package/lib/server/registry/oopDownloadBrowserMain.js +138 -0
  287. patchright/driver/package/lib/server/screenshotter.js +348 -0
  288. patchright/driver/package/lib/server/selectors.js +73 -0
  289. patchright/driver/package/lib/server/socksClientCertificatesInterceptor.js +340 -0
  290. patchright/driver/package/lib/server/socksInterceptor.js +100 -0
  291. patchright/driver/package/lib/server/trace/recorder/snapshotter.js +172 -0
  292. patchright/driver/package/lib/server/trace/recorder/snapshotterInjected.js +493 -0
  293. patchright/driver/package/lib/server/trace/recorder/tracing.js +542 -0
  294. patchright/driver/package/lib/server/trace/test/inMemorySnapshotter.js +93 -0
  295. patchright/driver/package/lib/server/trace/viewer/traceViewer.js +213 -0
  296. patchright/driver/package/lib/server/transport.js +191 -0
  297. patchright/driver/package/lib/server/types.js +24 -0
  298. patchright/driver/package/lib/server/usKeyboardLayout.js +555 -0
  299. patchright/driver/package/lib/server/webkit/webkit.js +87 -0
  300. patchright/driver/package/lib/server/webkit/wkAccessibility.js +194 -0
  301. patchright/driver/package/lib/server/webkit/wkBrowser.js +329 -0
  302. patchright/driver/package/lib/server/webkit/wkConnection.js +173 -0
  303. patchright/driver/package/lib/server/webkit/wkExecutionContext.js +143 -0
  304. patchright/driver/package/lib/server/webkit/wkInput.js +169 -0
  305. patchright/driver/package/lib/server/webkit/wkInterceptableRequest.js +162 -0
  306. patchright/driver/package/lib/server/webkit/wkPage.js +1219 -0
  307. patchright/driver/package/lib/server/webkit/wkProvisionalPage.js +94 -0
  308. patchright/driver/package/lib/server/webkit/wkWorkers.js +104 -0
  309. patchright/driver/package/lib/third_party/diff_match_patch.js +2222 -0
  310. patchright/driver/package/lib/third_party/pixelmatch.js +255 -0
  311. patchright/driver/package/lib/utils/ascii.js +31 -0
  312. patchright/driver/package/lib/utils/comparators.js +171 -0
  313. patchright/driver/package/lib/utils/crypto.js +174 -0
  314. patchright/driver/package/lib/utils/debug.js +46 -0
  315. patchright/driver/package/lib/utils/debugLogger.js +91 -0
  316. patchright/driver/package/lib/utils/env.js +49 -0
  317. patchright/driver/package/lib/utils/eventsHelper.js +38 -0
  318. patchright/driver/package/lib/utils/expectUtils.js +33 -0
  319. patchright/driver/package/lib/utils/fileUtils.js +205 -0
  320. patchright/driver/package/lib/utils/happy-eyeballs.js +194 -0
  321. patchright/driver/package/lib/utils/headers.js +52 -0
  322. patchright/driver/package/lib/utils/hostPlatform.js +133 -0
  323. patchright/driver/package/lib/utils/httpServer.js +237 -0
  324. patchright/driver/package/lib/utils/index.js +368 -0
  325. patchright/driver/package/lib/utils/isomorphic/cssParser.js +250 -0
  326. patchright/driver/package/lib/utils/isomorphic/cssTokenizer.js +979 -0
  327. patchright/driver/package/lib/utils/isomorphic/locatorGenerators.js +642 -0
  328. patchright/driver/package/lib/utils/isomorphic/locatorParser.js +179 -0
  329. patchright/driver/package/lib/utils/isomorphic/locatorUtils.js +62 -0
  330. patchright/driver/package/lib/utils/isomorphic/mimeType.js +29 -0
  331. patchright/driver/package/lib/utils/isomorphic/recorderUtils.js +195 -0
  332. patchright/driver/package/lib/utils/isomorphic/selectorParser.js +397 -0
  333. patchright/driver/package/lib/utils/isomorphic/stringUtils.js +139 -0
  334. patchright/driver/package/lib/utils/isomorphic/traceUtils.js +39 -0
  335. patchright/driver/package/lib/utils/isomorphic/urlMatch.js +120 -0
  336. patchright/driver/package/lib/utils/linuxUtils.js +78 -0
  337. patchright/driver/package/lib/utils/manualPromise.js +109 -0
  338. patchright/driver/package/lib/utils/multimap.js +75 -0
  339. patchright/driver/package/lib/utils/network.js +160 -0
  340. patchright/driver/package/lib/utils/processLauncher.js +248 -0
  341. patchright/driver/package/lib/utils/profiler.js +53 -0
  342. patchright/driver/package/lib/utils/rtti.js +44 -0
  343. patchright/driver/package/lib/utils/semaphore.js +51 -0
  344. patchright/driver/package/lib/utils/spawnAsync.js +45 -0
  345. patchright/driver/package/lib/utils/stackTrace.js +121 -0
  346. patchright/driver/package/lib/utils/task.js +58 -0
  347. patchright/driver/package/lib/utils/time.js +37 -0
  348. patchright/driver/package/lib/utils/timeoutRunner.js +66 -0
  349. patchright/driver/package/lib/utils/traceUtils.js +44 -0
  350. patchright/driver/package/lib/utils/userAgent.js +105 -0
  351. patchright/driver/package/lib/utils/wsServer.js +127 -0
  352. patchright/driver/package/lib/utils/zipFile.js +75 -0
  353. patchright/driver/package/lib/utils/zones.js +62 -0
  354. patchright/driver/package/lib/utilsBundle.js +82 -0
  355. patchright/driver/package/lib/utilsBundleImpl/index.js +53 -0
  356. patchright/driver/package/lib/utilsBundleImpl/xdg-open +1066 -0
  357. patchright/driver/package/lib/vite/htmlReport/index.html +66 -0
  358. patchright/driver/package/lib/vite/recorder/assets/codeMirrorModule-d0KhC1qL.js +24 -0
  359. patchright/driver/package/lib/vite/recorder/assets/codeMirrorModule-ez37Vkbh.css +1 -0
  360. patchright/driver/package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
  361. patchright/driver/package/lib/vite/recorder/assets/index-BW-aOBcL.css +1 -0
  362. patchright/driver/package/lib/vite/recorder/assets/index-Bxxcmxlu.js +42 -0
  363. patchright/driver/package/lib/vite/recorder/index.html +29 -0
  364. patchright/driver/package/lib/vite/recorder/playwright-logo.svg +9 -0
  365. patchright/driver/package/lib/vite/traceViewer/assets/codeMirrorModule-CZTtn9l8.js +24 -0
  366. patchright/driver/package/lib/vite/traceViewer/assets/inspectorTab-DTusvprx.js +64 -0
  367. patchright/driver/package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +1 -0
  368. patchright/driver/package/lib/vite/traceViewer/assets/workbench-DIEjrm3Z.js +9 -0
  369. patchright/driver/package/lib/vite/traceViewer/assets/xtermModule-BeNbaIVa.js +9 -0
  370. patchright/driver/package/lib/vite/traceViewer/codeMirrorModule.ez37Vkbh.css +1 -0
  371. patchright/driver/package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  372. patchright/driver/package/lib/vite/traceViewer/embedded.Do_J5Hgs.js +2 -0
  373. patchright/driver/package/lib/vite/traceViewer/embedded.html +18 -0
  374. patchright/driver/package/lib/vite/traceViewer/embedded.w7WN2u1R.css +1 -0
  375. patchright/driver/package/lib/vite/traceViewer/index.B21BXreT.js +2 -0
  376. patchright/driver/package/lib/vite/traceViewer/index.CrbWWHbf.css +1 -0
  377. patchright/driver/package/lib/vite/traceViewer/index.html +29 -0
  378. patchright/driver/package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  379. patchright/driver/package/lib/vite/traceViewer/playwright-logo.svg +9 -0
  380. patchright/driver/package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  381. patchright/driver/package/lib/vite/traceViewer/recorder.Bfh_9UGt.js +2 -0
  382. patchright/driver/package/lib/vite/traceViewer/recorder.html +17 -0
  383. patchright/driver/package/lib/vite/traceViewer/snapshot.html +21 -0
  384. patchright/driver/package/lib/vite/traceViewer/sw.bundle.js +3 -0
  385. patchright/driver/package/lib/vite/traceViewer/uiMode.CAYqod-m.css +1 -0
  386. patchright/driver/package/lib/vite/traceViewer/uiMode.DloKQa-h.js +5 -0
  387. patchright/driver/package/lib/vite/traceViewer/uiMode.html +20 -0
  388. patchright/driver/package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
  389. patchright/driver/package/lib/vite/traceViewer/xtermModule.DSXBckUd.css +32 -0
  390. patchright/driver/package/lib/zipBundle.js +25 -0
  391. patchright/driver/package/lib/zipBundleImpl.js +5 -0
  392. patchright/driver/package/package.json +44 -0
  393. patchright/driver/package/protocol.yml +3720 -0
  394. patchright/driver/package/types/protocol.d.ts +21571 -0
  395. patchright/driver/package/types/structs.d.ts +45 -0
  396. patchright/driver/package/types/types.d.ts +22519 -0
  397. patchright/py.typed +0 -0
  398. patchright/sync_api/__init__.py +177 -0
  399. patchright/sync_api/_context_manager.py +74 -0
  400. patchright/sync_api/_generated.py +20155 -0
  401. patchright-1.48.0.dist-info/LICENSE +202 -0
  402. patchright-1.48.0.dist-info/METADATA +83 -0
  403. patchright-1.48.0.dist-info/RECORD +406 -0
  404. patchright-1.48.0.dist-info/WHEEL +5 -0
  405. patchright-1.48.0.dist-info/entry_points.txt +5 -0
  406. patchright-1.48.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,934 @@
1
+ import asyncio
2
+ import base64
3
+ import inspect
4
+ import json
5
+ import json as json_utils
6
+ import mimetypes
7
+ import re
8
+ from collections import defaultdict
9
+ from pathlib import Path
10
+ from types import SimpleNamespace
11
+ from typing import (
12
+ TYPE_CHECKING,
13
+ Any,
14
+ Callable,
15
+ Coroutine,
16
+ Dict,
17
+ List,
18
+ Optional,
19
+ TypedDict,
20
+ Union,
21
+ cast,
22
+ )
23
+ from urllib import parse
24
+ from patchright._impl._api_structures import (
25
+ ClientCertificate,
26
+ Headers,
27
+ HeadersArray,
28
+ RemoteAddr,
29
+ RequestSizes,
30
+ ResourceTiming,
31
+ SecurityDetails,
32
+ )
33
+ from patchright._impl._connection import (
34
+ ChannelOwner,
35
+ from_channel,
36
+ from_nullable_channel,
37
+ )
38
+ from patchright._impl._errors import Error
39
+ from patchright._impl._event_context_manager import EventContextManagerImpl
40
+ from patchright._impl._helper import (
41
+ URLMatcher,
42
+ WebSocketRouteHandlerCallback,
43
+ async_readfile,
44
+ locals_to_params,
45
+ )
46
+ from patchright._impl._str_utils import escape_regex_flags
47
+ from patchright._impl._waiter import Waiter
48
+
49
+ if TYPE_CHECKING:
50
+ from patchright._impl._browser_context import BrowserContext
51
+ from patchright._impl._fetch import APIResponse
52
+ from patchright._impl._frame import Frame
53
+ from patchright._impl._page import Page
54
+
55
+
56
+ class FallbackOverrideParameters(TypedDict, total=False):
57
+ url: Optional[str]
58
+ method: Optional[str]
59
+ headers: Optional[Dict[str, str]]
60
+ postData: Optional[Union[str, bytes]]
61
+
62
+
63
+ class SerializedFallbackOverrides:
64
+
65
+ def __init__(self) -> None:
66
+ self.url: Optional[str] = None
67
+ self.method: Optional[str] = None
68
+ self.headers: Optional[Dict[str, str]] = None
69
+ self.post_data_buffer: Optional[bytes] = None
70
+
71
+
72
+ def serialize_headers(headers: Dict[str, str]) -> HeadersArray:
73
+ return [
74
+ {"name": name, "value": value}
75
+ for name, value in headers.items()
76
+ if value is not None
77
+ ]
78
+
79
+
80
+ async def to_client_certificates_protocol(
81
+ clientCertificates: Optional[List[ClientCertificate]],
82
+ ) -> Optional[List[Dict[str, str]]]:
83
+ if not clientCertificates:
84
+ return None
85
+ out = []
86
+ for clientCertificate in clientCertificates:
87
+ out_record = {"origin": clientCertificate["origin"]}
88
+ if passphrase := clientCertificate.get("passphrase"):
89
+ out_record["passphrase"] = passphrase
90
+ if pfx := clientCertificate.get("pfx"):
91
+ out_record["pfx"] = base64.b64encode(pfx).decode()
92
+ if pfx_path := clientCertificate.get("pfxPath"):
93
+ out_record["pfx"] = base64.b64encode(
94
+ await async_readfile(pfx_path)
95
+ ).decode()
96
+ if cert := clientCertificate.get("cert"):
97
+ out_record["cert"] = base64.b64encode(cert).decode()
98
+ if cert_path := clientCertificate.get("certPath"):
99
+ out_record["cert"] = base64.b64encode(
100
+ await async_readfile(cert_path)
101
+ ).decode()
102
+ if key := clientCertificate.get("key"):
103
+ out_record["key"] = base64.b64encode(key).decode()
104
+ if key_path := clientCertificate.get("keyPath"):
105
+ out_record["key"] = base64.b64encode(
106
+ await async_readfile(key_path)
107
+ ).decode()
108
+ out.append(out_record)
109
+ return out
110
+
111
+
112
+ class Request(ChannelOwner):
113
+
114
+ def __init__(
115
+ self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
116
+ ) -> None:
117
+ super().__init__(parent, type, guid, initializer)
118
+ self._redirected_from: Optional["Request"] = from_nullable_channel(
119
+ initializer.get("redirectedFrom")
120
+ )
121
+ self._redirected_to: Optional["Request"] = None
122
+ if self._redirected_from:
123
+ self._redirected_from._redirected_to = self
124
+ self._failure_text: Optional[str] = None
125
+ self._timing: ResourceTiming = {
126
+ "startTime": 0,
127
+ "domainLookupStart": -1,
128
+ "domainLookupEnd": -1,
129
+ "connectStart": -1,
130
+ "secureConnectionStart": -1,
131
+ "connectEnd": -1,
132
+ "requestStart": -1,
133
+ "responseStart": -1,
134
+ "responseEnd": -1,
135
+ }
136
+ self._provisional_headers = RawHeaders(self._initializer["headers"])
137
+ self._all_headers_future: Optional[asyncio.Future[RawHeaders]] = None
138
+ self._fallback_overrides: SerializedFallbackOverrides = (
139
+ SerializedFallbackOverrides()
140
+ )
141
+
142
+ def __repr__(self) -> str:
143
+ return f"<Request url={self.url!r} method={self.method!r}>"
144
+
145
+ def _apply_fallback_overrides(self, overrides: FallbackOverrideParameters) -> None:
146
+ self._fallback_overrides.url = overrides.get(
147
+ "url", self._fallback_overrides.url
148
+ )
149
+ self._fallback_overrides.method = overrides.get(
150
+ "method", self._fallback_overrides.method
151
+ )
152
+ self._fallback_overrides.headers = overrides.get(
153
+ "headers", self._fallback_overrides.headers
154
+ )
155
+ post_data = overrides.get("postData")
156
+ if isinstance(post_data, str):
157
+ self._fallback_overrides.post_data_buffer = post_data.encode()
158
+ elif isinstance(post_data, bytes):
159
+ self._fallback_overrides.post_data_buffer = post_data
160
+ elif post_data is not None:
161
+ self._fallback_overrides.post_data_buffer = json.dumps(post_data).encode()
162
+
163
+ @property
164
+ def url(self) -> str:
165
+ return cast(str, self._fallback_overrides.url or self._initializer["url"])
166
+
167
+ @property
168
+ def resource_type(self) -> str:
169
+ return self._initializer["resourceType"]
170
+
171
+ @property
172
+ def method(self) -> str:
173
+ return cast(str, self._fallback_overrides.method or self._initializer["method"])
174
+
175
+ async def sizes(self) -> RequestSizes:
176
+ response = await self.response()
177
+ if not response:
178
+ raise Error("Unable to fetch sizes for failed request")
179
+ return await response._channel.send("sizes")
180
+
181
+ @property
182
+ def post_data(self) -> Optional[str]:
183
+ data = self._fallback_overrides.post_data_buffer
184
+ if data:
185
+ return data.decode()
186
+ base64_post_data = self._initializer.get("postData")
187
+ if base64_post_data is not None:
188
+ return base64.b64decode(base64_post_data).decode()
189
+ return None
190
+
191
+ @property
192
+ def post_data_json(self) -> Optional[Any]:
193
+ post_data = self.post_data
194
+ if not post_data:
195
+ return None
196
+ content_type = self.headers["content-type"]
197
+ if "application/x-www-form-urlencoded" in content_type:
198
+ return dict(parse.parse_qsl(post_data))
199
+ try:
200
+ return json.loads(post_data)
201
+ except Exception:
202
+ raise Error(f"POST data is not a valid JSON object: {post_data}")
203
+
204
+ @property
205
+ def post_data_buffer(self) -> Optional[bytes]:
206
+ if self._fallback_overrides.post_data_buffer:
207
+ return self._fallback_overrides.post_data_buffer
208
+ if self._initializer.get("postData"):
209
+ return base64.b64decode(self._initializer["postData"])
210
+ return None
211
+
212
+ async def response(self) -> Optional["Response"]:
213
+ return from_nullable_channel(await self._channel.send("response"))
214
+
215
+ @property
216
+ def frame(self) -> "Frame":
217
+ if not self._initializer.get("frame"):
218
+ raise Error("Service Worker requests do not have an associated frame.")
219
+ frame = cast("Frame", from_channel(self._initializer["frame"]))
220
+ if not frame._page:
221
+ raise Error(
222
+ "\n".join(
223
+ [
224
+ "Frame for this navigation request is not available, because the request",
225
+ "was issued before the frame is created. You can check whether the request",
226
+ "is a navigation request by calling isNavigationRequest() method.",
227
+ ]
228
+ )
229
+ )
230
+ return frame
231
+
232
+ def is_navigation_request(self) -> bool:
233
+ return self._initializer["isNavigationRequest"]
234
+
235
+ @property
236
+ def redirected_from(self) -> Optional["Request"]:
237
+ return self._redirected_from
238
+
239
+ @property
240
+ def redirected_to(self) -> Optional["Request"]:
241
+ return self._redirected_to
242
+
243
+ @property
244
+ def failure(self) -> Optional[str]:
245
+ return self._failure_text
246
+
247
+ @property
248
+ def timing(self) -> ResourceTiming:
249
+ return self._timing
250
+
251
+ def _set_response_end_timing(self, response_end_timing: float) -> None:
252
+ self._timing["responseEnd"] = response_end_timing
253
+ if self._timing["responseStart"] == -1:
254
+ self._timing["responseStart"] = response_end_timing
255
+
256
+ @property
257
+ def headers(self) -> Headers:
258
+ override = self._fallback_overrides.headers
259
+ if override:
260
+ return RawHeaders._from_headers_dict_lossy(override).headers()
261
+ return self._provisional_headers.headers()
262
+
263
+ async def all_headers(self) -> Headers:
264
+ return (await self._actual_headers()).headers()
265
+
266
+ async def headers_array(self) -> HeadersArray:
267
+ return (await self._actual_headers()).headers_array()
268
+
269
+ async def header_value(self, name: str) -> Optional[str]:
270
+ return (await self._actual_headers()).get(name)
271
+
272
+ async def _actual_headers(self) -> "RawHeaders":
273
+ override = self._fallback_overrides.headers
274
+ if override:
275
+ return RawHeaders(serialize_headers(override))
276
+ if not self._all_headers_future:
277
+ self._all_headers_future = asyncio.Future()
278
+ headers = await self._channel.send("rawRequestHeaders")
279
+ self._all_headers_future.set_result(RawHeaders(headers))
280
+ return await self._all_headers_future
281
+
282
+ def _target_closed_future(self) -> asyncio.Future:
283
+ frame = cast(
284
+ Optional["Frame"], from_nullable_channel(self._initializer.get("frame"))
285
+ )
286
+ if not frame:
287
+ return asyncio.Future()
288
+ page = frame._page
289
+ if not page:
290
+ return asyncio.Future()
291
+ return page._closed_or_crashed_future
292
+
293
+ def _safe_page(self) -> "Optional[Page]":
294
+ frame = from_nullable_channel(self._initializer.get("frame"))
295
+ if not frame:
296
+ return None
297
+ return cast("Frame", frame)._page
298
+
299
+
300
+ class Route(ChannelOwner):
301
+
302
+ def __init__(
303
+ self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
304
+ ) -> None:
305
+ super().__init__(parent, type, guid, initializer)
306
+ self.mark_as_internal_type()
307
+ self._handling_future: Optional[asyncio.Future["bool"]] = None
308
+ self._context: "BrowserContext" = cast("BrowserContext", None)
309
+ self._did_throw = False
310
+
311
+ def _start_handling(self) -> "asyncio.Future[bool]":
312
+ self._handling_future = asyncio.Future()
313
+ return self._handling_future
314
+
315
+ def _report_handled(self, done: bool) -> None:
316
+ chain = self._handling_future
317
+ assert chain
318
+ self._handling_future = None
319
+ chain.set_result(done)
320
+
321
+ def _check_not_handled(self) -> None:
322
+ if not self._handling_future:
323
+ raise Error("Route is already handled!")
324
+
325
+ def __repr__(self) -> str:
326
+ return f"<Route request={self.request}>"
327
+
328
+ @property
329
+ def request(self) -> Request:
330
+ return from_channel(self._initializer["request"])
331
+
332
+ async def abort(self, errorCode: str = None) -> None:
333
+ await self._handle_route(
334
+ lambda: self._race_with_page_close(
335
+ self._channel.send("abort", {"errorCode": errorCode})
336
+ )
337
+ )
338
+
339
+ async def fulfill(
340
+ self,
341
+ status: int = None,
342
+ headers: Dict[str, str] = None,
343
+ body: Union[str, bytes] = None,
344
+ json: Any = None,
345
+ path: Union[str, Path] = None,
346
+ contentType: str = None,
347
+ response: "APIResponse" = None,
348
+ ) -> None:
349
+ await self._handle_route(
350
+ lambda: self._inner_fulfill(
351
+ status, headers, body, json, path, contentType, response
352
+ )
353
+ )
354
+
355
+ async def _inner_fulfill(
356
+ self,
357
+ status: int = None,
358
+ headers: Dict[str, str] = None,
359
+ body: Union[str, bytes] = None,
360
+ json: Any = None,
361
+ path: Union[str, Path] = None,
362
+ contentType: str = None,
363
+ response: "APIResponse" = None,
364
+ ) -> None:
365
+ params = locals_to_params(locals())
366
+ if json is not None:
367
+ if body is not None:
368
+ raise Error("Can specify either body or json parameters")
369
+ body = json_utils.dumps(json)
370
+ if response:
371
+ del params["response"]
372
+ params["status"] = (
373
+ params["status"] if params.get("status") else response.status
374
+ )
375
+ params["headers"] = (
376
+ params["headers"] if params.get("headers") else response.headers
377
+ )
378
+ from patchright._impl._fetch import APIResponse
379
+
380
+ if body is None and path is None and isinstance(response, APIResponse):
381
+ if response._request._connection is self._connection:
382
+ params["fetchResponseUid"] = response._fetch_uid
383
+ else:
384
+ body = await response.body()
385
+ length = 0
386
+ if isinstance(body, str):
387
+ params["body"] = body
388
+ params["isBase64"] = False
389
+ length = len(body.encode())
390
+ elif isinstance(body, bytes):
391
+ params["body"] = base64.b64encode(body).decode()
392
+ params["isBase64"] = True
393
+ length = len(body)
394
+ elif path:
395
+ del params["path"]
396
+ file_content = Path(path).read_bytes()
397
+ params["body"] = base64.b64encode(file_content).decode()
398
+ params["isBase64"] = True
399
+ length = len(file_content)
400
+ headers = {k.lower(): str(v) for k, v in params.get("headers", {}).items()}
401
+ if params.get("contentType"):
402
+ headers["content-type"] = params["contentType"]
403
+ elif json:
404
+ headers["content-type"] = "application/json"
405
+ elif path:
406
+ headers["content-type"] = (
407
+ mimetypes.guess_type(str(Path(path)))[0] or "application/octet-stream"
408
+ )
409
+ if length and "content-length" not in headers:
410
+ headers["content-length"] = str(length)
411
+ params["headers"] = serialize_headers(headers)
412
+ await self._race_with_page_close(self._channel.send("fulfill", params))
413
+
414
+ async def _handle_route(self, callback: Callable) -> None:
415
+ self._check_not_handled()
416
+ try:
417
+ await callback()
418
+ self._report_handled(True)
419
+ except Exception as e:
420
+ self._did_throw = True
421
+ raise e
422
+
423
+ async def fetch(
424
+ self,
425
+ url: str = None,
426
+ method: str = None,
427
+ headers: Dict[str, str] = None,
428
+ postData: Union[Any, str, bytes] = None,
429
+ maxRedirects: int = None,
430
+ maxRetries: int = None,
431
+ timeout: float = None,
432
+ ) -> "APIResponse":
433
+ return await self._connection.wrap_api_call(
434
+ lambda: self._context.request._inner_fetch(
435
+ self.request,
436
+ url,
437
+ method,
438
+ headers,
439
+ postData,
440
+ maxRedirects=maxRedirects,
441
+ maxRetries=maxRetries,
442
+ timeout=timeout,
443
+ )
444
+ )
445
+
446
+ async def fallback(
447
+ self,
448
+ url: str = None,
449
+ method: str = None,
450
+ headers: Dict[str, str] = None,
451
+ postData: Union[Any, str, bytes] = None,
452
+ ) -> None:
453
+ overrides = cast(FallbackOverrideParameters, locals_to_params(locals()))
454
+ self._check_not_handled()
455
+ self.request._apply_fallback_overrides(overrides)
456
+ self._report_handled(False)
457
+
458
+ async def continue_(
459
+ self,
460
+ url: str = None,
461
+ method: str = None,
462
+ headers: Dict[str, str] = None,
463
+ postData: Union[Any, str, bytes] = None,
464
+ ) -> None:
465
+ overrides = cast(FallbackOverrideParameters, locals_to_params(locals()))
466
+
467
+ async def _inner() -> None:
468
+ self.request._apply_fallback_overrides(overrides)
469
+ await self._inner_continue(False)
470
+
471
+ return await self._handle_route(_inner)
472
+
473
+ async def _inner_continue(self, is_fallback: bool = False) -> None:
474
+ options = self.request._fallback_overrides
475
+ await self._race_with_page_close(
476
+ self._channel.send(
477
+ "continue",
478
+ {
479
+ "url": options.url,
480
+ "method": options.method,
481
+ "headers": (
482
+ serialize_headers(options.headers) if options.headers else None
483
+ ),
484
+ "postData": (
485
+ base64.b64encode(options.post_data_buffer).decode()
486
+ if options.post_data_buffer is not None
487
+ else None
488
+ ),
489
+ "isFallback": is_fallback,
490
+ },
491
+ )
492
+ )
493
+
494
+ async def _redirected_navigation_request(self, url: str) -> None:
495
+ await self._handle_route(
496
+ lambda: self._race_with_page_close(
497
+ self._channel.send("redirectNavigationRequest", {"url": url})
498
+ )
499
+ )
500
+
501
+ async def _race_with_page_close(self, future: Coroutine) -> None:
502
+ fut = asyncio.create_task(future)
503
+ setattr(
504
+ fut,
505
+ "__pw_stack__",
506
+ getattr(asyncio.current_task(self._loop), "__pw_stack__", inspect.stack()),
507
+ )
508
+ target_closed_future = self.request._target_closed_future()
509
+ await asyncio.wait(
510
+ [fut, target_closed_future], return_when=asyncio.FIRST_COMPLETED
511
+ )
512
+ if fut.done() and fut.exception():
513
+ raise cast(BaseException, fut.exception())
514
+ if target_closed_future.done():
515
+ await asyncio.gather(fut, return_exceptions=True)
516
+
517
+
518
+ def _create_task_and_ignore_exception(coro: Coroutine) -> None:
519
+
520
+ async def _ignore_exception() -> None:
521
+ try:
522
+ await coro
523
+ except Exception:
524
+ pass
525
+
526
+ asyncio.create_task(_ignore_exception())
527
+
528
+
529
+ class ServerWebSocketRoute:
530
+
531
+ def __init__(self, ws: "WebSocketRoute"):
532
+ self._ws = ws
533
+
534
+ def on_message(self, handler: Callable[[Union[str, bytes]], Any]) -> None:
535
+ self._ws._on_server_message = handler
536
+
537
+ def on_close(self, handler: Callable[[Optional[int], Optional[str]], Any]) -> None:
538
+ self._ws._on_server_close = handler
539
+
540
+ def connect_to_server(self) -> None:
541
+ raise NotImplementedError(
542
+ "connectToServer must be called on the page-side WebSocketRoute"
543
+ )
544
+
545
+ @property
546
+ def url(self) -> str:
547
+ return self._ws._initializer["url"]
548
+
549
+ def close(self, code: int = None, reason: str = None) -> None:
550
+ _create_task_and_ignore_exception(
551
+ self._ws._channel.send(
552
+ "closeServer", {"code": code, "reason": reason, "wasClean": True}
553
+ )
554
+ )
555
+
556
+ def send(self, message: Union[str, bytes]) -> None:
557
+ if isinstance(message, str):
558
+ _create_task_and_ignore_exception(
559
+ self._ws._channel.send(
560
+ "sendToServer", {"message": message, "isBase64": False}
561
+ )
562
+ )
563
+ else:
564
+ _create_task_and_ignore_exception(
565
+ self._ws._channel.send(
566
+ "sendToServer",
567
+ {"message": base64.b64encode(message).decode(), "isBase64": True},
568
+ )
569
+ )
570
+
571
+
572
+ class WebSocketRoute(ChannelOwner):
573
+
574
+ def __init__(
575
+ self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
576
+ ) -> None:
577
+ super().__init__(parent, type, guid, initializer)
578
+ self.mark_as_internal_type()
579
+ self._on_page_message: Optional[Callable[[Union[str, bytes]], Any]] = None
580
+ self._on_page_close: Optional[Callable[[Optional[int], Optional[str]], Any]] = (
581
+ None
582
+ )
583
+ self._on_server_message: Optional[Callable[[Union[str, bytes]], Any]] = None
584
+ self._on_server_close: Optional[
585
+ Callable[[Optional[int], Optional[str]], Any]
586
+ ] = None
587
+ self._server = ServerWebSocketRoute(self)
588
+ self._connected = False
589
+ self._channel.on("messageFromPage", self._channel_message_from_page)
590
+ self._channel.on("messageFromServer", self._channel_message_from_server)
591
+ self._channel.on("closePage", self._channel_close_page)
592
+ self._channel.on("closeServer", self._channel_close_server)
593
+
594
+ def _channel_message_from_page(self, event: Dict) -> None:
595
+ if self._on_page_message:
596
+ self._on_page_message(
597
+ base64.b64decode(event["message"])
598
+ if event["isBase64"]
599
+ else event["message"]
600
+ )
601
+ elif self._connected:
602
+ _create_task_and_ignore_exception(self._channel.send("sendToServer", event))
603
+
604
+ def _channel_message_from_server(self, event: Dict) -> None:
605
+ if self._on_server_message:
606
+ self._on_server_message(
607
+ base64.b64decode(event["message"])
608
+ if event["isBase64"]
609
+ else event["message"]
610
+ )
611
+ else:
612
+ _create_task_and_ignore_exception(self._channel.send("sendToPage", event))
613
+
614
+ def _channel_close_page(self, event: Dict) -> None:
615
+ if self._on_page_close:
616
+ self._on_page_close(event["code"], event["reason"])
617
+ else:
618
+ _create_task_and_ignore_exception(self._channel.send("closeServer", event))
619
+
620
+ def _channel_close_server(self, event: Dict) -> None:
621
+ if self._on_server_close:
622
+ self._on_server_close(event["code"], event["reason"])
623
+ else:
624
+ _create_task_and_ignore_exception(self._channel.send("closePage", event))
625
+
626
+ @property
627
+ def url(self) -> str:
628
+ return self._initializer["url"]
629
+
630
+ async def close(self, code: int = None, reason: str = None) -> None:
631
+ try:
632
+ await self._channel.send(
633
+ "closePage", {"code": code, "reason": reason, "wasClean": True}
634
+ )
635
+ except Exception:
636
+ pass
637
+
638
+ def connect_to_server(self) -> "WebSocketRoute":
639
+ if self._connected:
640
+ raise Error("Already connected to the server")
641
+ self._connected = True
642
+ asyncio.create_task(self._channel.send("connect"))
643
+ return cast("WebSocketRoute", self._server)
644
+
645
+ def send(self, message: Union[str, bytes]) -> None:
646
+ if isinstance(message, str):
647
+ _create_task_and_ignore_exception(
648
+ self._channel.send(
649
+ "sendToPage", {"message": message, "isBase64": False}
650
+ )
651
+ )
652
+ else:
653
+ _create_task_and_ignore_exception(
654
+ self._channel.send(
655
+ "sendToPage",
656
+ {"message": base64.b64encode(message).decode(), "isBase64": True},
657
+ )
658
+ )
659
+
660
+ def on_message(self, handler: Callable[[Union[str, bytes]], Any]) -> None:
661
+ self._on_page_message = handler
662
+
663
+ def on_close(self, handler: Callable[[Optional[int], Optional[str]], Any]) -> None:
664
+ self._on_page_close = handler
665
+
666
+ async def _after_handle(self) -> None:
667
+ if self._connected:
668
+ return
669
+ await self._channel.send("ensureOpened")
670
+
671
+
672
+ class WebSocketRouteHandler:
673
+
674
+ def __init__(self, matcher: URLMatcher, handler: WebSocketRouteHandlerCallback):
675
+ self.matcher = matcher
676
+ self.handler = handler
677
+
678
+ @staticmethod
679
+ def prepare_interception_patterns(
680
+ handlers: List["WebSocketRouteHandler"],
681
+ ) -> List[dict]:
682
+ patterns = []
683
+ all_urls = False
684
+ for handler in handlers:
685
+ if isinstance(handler.matcher.match, str):
686
+ patterns.append({"glob": handler.matcher.match})
687
+ elif isinstance(handler.matcher._regex_obj, re.Pattern):
688
+ patterns.append(
689
+ {
690
+ "regexSource": handler.matcher._regex_obj.pattern,
691
+ "regexFlags": escape_regex_flags(handler.matcher._regex_obj),
692
+ }
693
+ )
694
+ else:
695
+ all_urls = True
696
+ if all_urls:
697
+ return [{"glob": "**/*"}]
698
+ return patterns
699
+
700
+ def matches(self, ws_url: str) -> bool:
701
+ return self.matcher.matches(ws_url)
702
+
703
+ async def handle(self, websocket_route: "WebSocketRoute") -> None:
704
+ coro_or_future = self.handler(websocket_route)
705
+ if asyncio.iscoroutine(coro_or_future):
706
+ await coro_or_future
707
+ await websocket_route._after_handle()
708
+
709
+
710
+ class Response(ChannelOwner):
711
+
712
+ def __init__(
713
+ self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
714
+ ) -> None:
715
+ super().__init__(parent, type, guid, initializer)
716
+ self._request: Request = from_channel(self._initializer["request"])
717
+ timing = self._initializer["timing"]
718
+ self._request._timing["startTime"] = timing["startTime"]
719
+ self._request._timing["domainLookupStart"] = timing["domainLookupStart"]
720
+ self._request._timing["domainLookupEnd"] = timing["domainLookupEnd"]
721
+ self._request._timing["connectStart"] = timing["connectStart"]
722
+ self._request._timing["secureConnectionStart"] = timing["secureConnectionStart"]
723
+ self._request._timing["connectEnd"] = timing["connectEnd"]
724
+ self._request._timing["requestStart"] = timing["requestStart"]
725
+ self._request._timing["responseStart"] = timing["responseStart"]
726
+ self._provisional_headers = RawHeaders(
727
+ cast(HeadersArray, self._initializer["headers"])
728
+ )
729
+ self._raw_headers_future: Optional[asyncio.Future[RawHeaders]] = None
730
+ self._finished_future: asyncio.Future[bool] = asyncio.Future()
731
+
732
+ def __repr__(self) -> str:
733
+ return f"<Response url={self.url!r} request={self.request}>"
734
+
735
+ @property
736
+ def url(self) -> str:
737
+ return self._initializer["url"]
738
+
739
+ @property
740
+ def ok(self) -> bool:
741
+ return self._initializer["status"] == 0 or (
742
+ self._initializer["status"] >= 200 and self._initializer["status"] <= 299
743
+ )
744
+
745
+ @property
746
+ def status(self) -> int:
747
+ return self._initializer["status"]
748
+
749
+ @property
750
+ def status_text(self) -> str:
751
+ return self._initializer["statusText"]
752
+
753
+ @property
754
+ def headers(self) -> Headers:
755
+ return self._provisional_headers.headers()
756
+
757
+ @property
758
+ def from_service_worker(self) -> bool:
759
+ return self._initializer["fromServiceWorker"]
760
+
761
+ async def all_headers(self) -> Headers:
762
+ return (await self._actual_headers()).headers()
763
+
764
+ async def headers_array(self) -> HeadersArray:
765
+ return (await self._actual_headers()).headers_array()
766
+
767
+ async def header_value(self, name: str) -> Optional[str]:
768
+ return (await self._actual_headers()).get(name)
769
+
770
+ async def header_values(self, name: str) -> List[str]:
771
+ return (await self._actual_headers()).get_all(name)
772
+
773
+ async def _actual_headers(self) -> "RawHeaders":
774
+ if not self._raw_headers_future:
775
+ self._raw_headers_future = asyncio.Future()
776
+ headers = cast(HeadersArray, await self._channel.send("rawResponseHeaders"))
777
+ self._raw_headers_future.set_result(RawHeaders(headers))
778
+ return await self._raw_headers_future
779
+
780
+ async def server_addr(self) -> Optional[RemoteAddr]:
781
+ return await self._channel.send("serverAddr")
782
+
783
+ async def security_details(self) -> Optional[SecurityDetails]:
784
+ return await self._channel.send("securityDetails")
785
+
786
+ async def finished(self) -> None:
787
+
788
+ async def on_finished() -> None:
789
+ await self._request._target_closed_future()
790
+ raise Error("Target closed")
791
+
792
+ on_finished_task = asyncio.create_task(on_finished())
793
+ await asyncio.wait(
794
+ cast(
795
+ List[Union[asyncio.Task, asyncio.Future]],
796
+ [self._finished_future, on_finished_task],
797
+ ),
798
+ return_when=asyncio.FIRST_COMPLETED,
799
+ )
800
+ if on_finished_task.done():
801
+ await on_finished_task
802
+
803
+ async def body(self) -> bytes:
804
+ binary = await self._channel.send("body")
805
+ return base64.b64decode(binary)
806
+
807
+ async def text(self) -> str:
808
+ content = await self.body()
809
+ return content.decode()
810
+
811
+ async def json(self) -> Any:
812
+ return json.loads(await self.text())
813
+
814
+ @property
815
+ def request(self) -> Request:
816
+ return self._request
817
+
818
+ @property
819
+ def frame(self) -> "Frame":
820
+ return self._request.frame
821
+
822
+
823
+ class WebSocket(ChannelOwner):
824
+ Events = SimpleNamespace(
825
+ Close="close",
826
+ FrameReceived="framereceived",
827
+ FrameSent="framesent",
828
+ Error="socketerror",
829
+ )
830
+
831
+ def __init__(
832
+ self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
833
+ ) -> None:
834
+ super().__init__(parent, type, guid, initializer)
835
+ self._is_closed = False
836
+ self._page = cast("Page", parent)
837
+ self._channel.on(
838
+ "frameSent",
839
+ lambda params: self._on_frame_sent(params["opcode"], params["data"]),
840
+ )
841
+ self._channel.on(
842
+ "frameReceived",
843
+ lambda params: self._on_frame_received(params["opcode"], params["data"]),
844
+ )
845
+ self._channel.on(
846
+ "socketError",
847
+ lambda params: self.emit(WebSocket.Events.Error, params["error"]),
848
+ )
849
+ self._channel.on("close", lambda params: self._on_close())
850
+
851
+ def __repr__(self) -> str:
852
+ return f"<WebSocket url={self.url!r}>"
853
+
854
+ @property
855
+ def url(self) -> str:
856
+ return self._initializer["url"]
857
+
858
+ def expect_event(
859
+ self, event: str, predicate: Callable = None, timeout: float = None
860
+ ) -> EventContextManagerImpl:
861
+ if timeout is None:
862
+ timeout = cast(Any, self._parent)._timeout_settings.timeout()
863
+ waiter = Waiter(self, f"web_socket.expect_event({event})")
864
+ waiter.reject_on_timeout(
865
+ cast(float, timeout),
866
+ f'Timeout {timeout}ms exceeded while waiting for event "{event}"',
867
+ )
868
+ if event != WebSocket.Events.Close:
869
+ waiter.reject_on_event(self, WebSocket.Events.Close, Error("Socket closed"))
870
+ if event != WebSocket.Events.Error:
871
+ waiter.reject_on_event(self, WebSocket.Events.Error, Error("Socket error"))
872
+ waiter.reject_on_event(
873
+ self._page, "close", lambda: self._page._close_error_with_reason()
874
+ )
875
+ waiter.wait_for_event(self, event, predicate)
876
+ return EventContextManagerImpl(waiter.result())
877
+
878
+ async def wait_for_event(
879
+ self, event: str, predicate: Callable = None, timeout: float = None
880
+ ) -> Any:
881
+ async with self.expect_event(event, predicate, timeout) as event_info:
882
+ pass
883
+ return await event_info
884
+
885
+ def _on_frame_sent(self, opcode: int, data: str) -> None:
886
+ if opcode == 2:
887
+ self.emit(WebSocket.Events.FrameSent, base64.b64decode(data))
888
+ elif opcode == 1:
889
+ self.emit(WebSocket.Events.FrameSent, data)
890
+
891
+ def _on_frame_received(self, opcode: int, data: str) -> None:
892
+ if opcode == 2:
893
+ self.emit(WebSocket.Events.FrameReceived, base64.b64decode(data))
894
+ elif opcode == 1:
895
+ self.emit(WebSocket.Events.FrameReceived, data)
896
+
897
+ def is_closed(self) -> bool:
898
+ return self._is_closed
899
+
900
+ def _on_close(self) -> None:
901
+ self._is_closed = True
902
+ self.emit(WebSocket.Events.Close, self)
903
+
904
+
905
+ class RawHeaders:
906
+
907
+ def __init__(self, headers: HeadersArray) -> None:
908
+ self._headers_array = headers
909
+ self._headers_map: Dict[str, Dict[str, bool]] = defaultdict(dict)
910
+ for header in headers:
911
+ self._headers_map[header["name"].lower()][header["value"]] = True
912
+
913
+ @staticmethod
914
+ def _from_headers_dict_lossy(headers: Dict[str, str]) -> "RawHeaders":
915
+ return RawHeaders(serialize_headers(headers))
916
+
917
+ def get(self, name: str) -> Optional[str]:
918
+ values = self.get_all(name)
919
+ if not values:
920
+ return None
921
+ separator = "\n" if name.lower() == "set-cookie" else ", "
922
+ return separator.join(values)
923
+
924
+ def get_all(self, name: str) -> List[str]:
925
+ return list(self._headers_map[name.lower()].keys())
926
+
927
+ def headers(self) -> Dict[str, str]:
928
+ result = {}
929
+ for name in self._headers_map.keys():
930
+ result[name] = cast(str, self.get(name))
931
+ return result
932
+
933
+ def headers_array(self) -> HeadersArray:
934
+ return self._headers_array