patchright-core 1.48.2

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 (333) hide show
  1. package/README.md +3 -0
  2. package/ThirdPartyNotices.txt +1548 -0
  3. package/bin/PrintDeps.exe +0 -0
  4. package/bin/README.md +2 -0
  5. package/bin/install_media_pack.ps1 +5 -0
  6. package/bin/reinstall_chrome_beta_linux.sh +40 -0
  7. package/bin/reinstall_chrome_beta_mac.sh +13 -0
  8. package/bin/reinstall_chrome_beta_win.ps1 +24 -0
  9. package/bin/reinstall_chrome_stable_linux.sh +40 -0
  10. package/bin/reinstall_chrome_stable_mac.sh +12 -0
  11. package/bin/reinstall_chrome_stable_win.ps1 +24 -0
  12. package/bin/reinstall_msedge_beta_linux.sh +40 -0
  13. package/bin/reinstall_msedge_beta_mac.sh +11 -0
  14. package/bin/reinstall_msedge_beta_win.ps1 +23 -0
  15. package/bin/reinstall_msedge_dev_linux.sh +40 -0
  16. package/bin/reinstall_msedge_dev_mac.sh +11 -0
  17. package/bin/reinstall_msedge_dev_win.ps1 +23 -0
  18. package/bin/reinstall_msedge_stable_linux.sh +40 -0
  19. package/bin/reinstall_msedge_stable_mac.sh +11 -0
  20. package/bin/reinstall_msedge_stable_win.ps1 +24 -0
  21. package/browsers.json +57 -0
  22. package/cli.js +18 -0
  23. package/index.d.ts +17 -0
  24. package/index.js +33 -0
  25. package/index.mjs +28 -0
  26. package/lib/androidServerImpl.js +69 -0
  27. package/lib/browserServerImpl.js +92 -0
  28. package/lib/cli/driver.js +95 -0
  29. package/lib/cli/program.js +589 -0
  30. package/lib/cli/programWithTestStub.js +67 -0
  31. package/lib/client/accessibility.js +50 -0
  32. package/lib/client/android.js +473 -0
  33. package/lib/client/api.js +285 -0
  34. package/lib/client/artifact.js +79 -0
  35. package/lib/client/browser.js +145 -0
  36. package/lib/client/browserContext.js +583 -0
  37. package/lib/client/browserType.js +241 -0
  38. package/lib/client/cdpSession.js +53 -0
  39. package/lib/client/channelOwner.js +235 -0
  40. package/lib/client/clientHelper.js +57 -0
  41. package/lib/client/clientInstrumentation.js +50 -0
  42. package/lib/client/clock.js +69 -0
  43. package/lib/client/connection.js +333 -0
  44. package/lib/client/consoleMessage.js +55 -0
  45. package/lib/client/coverage.js +41 -0
  46. package/lib/client/dialog.js +57 -0
  47. package/lib/client/download.js +62 -0
  48. package/lib/client/electron.js +135 -0
  49. package/lib/client/elementHandle.js +321 -0
  50. package/lib/client/errors.js +77 -0
  51. package/lib/client/eventEmitter.js +314 -0
  52. package/lib/client/events.js +94 -0
  53. package/lib/client/fetch.js +391 -0
  54. package/lib/client/fileChooser.js +45 -0
  55. package/lib/client/frame.js +504 -0
  56. package/lib/client/harRouter.js +99 -0
  57. package/lib/client/input.js +111 -0
  58. package/lib/client/jsHandle.js +121 -0
  59. package/lib/client/jsonPipe.js +35 -0
  60. package/lib/client/localUtils.js +36 -0
  61. package/lib/client/locator.js +441 -0
  62. package/lib/client/network.js +762 -0
  63. package/lib/client/page.js +770 -0
  64. package/lib/client/playwright.js +80 -0
  65. package/lib/client/selectors.js +67 -0
  66. package/lib/client/stream.js +54 -0
  67. package/lib/client/tracing.js +134 -0
  68. package/lib/client/types.js +24 -0
  69. package/lib/client/video.js +51 -0
  70. package/lib/client/waiter.js +158 -0
  71. package/lib/client/webError.js +37 -0
  72. package/lib/client/worker.js +71 -0
  73. package/lib/client/writableStream.js +54 -0
  74. package/lib/common/socksProxy.js +569 -0
  75. package/lib/common/timeoutSettings.js +73 -0
  76. package/lib/common/types.js +5 -0
  77. package/lib/generated/clockSource.js +7 -0
  78. package/lib/generated/consoleApiSource.js +7 -0
  79. package/lib/generated/injectedScriptSource.js +7 -0
  80. package/lib/generated/pollingRecorderSource.js +7 -0
  81. package/lib/generated/utilityScriptSource.js +7 -0
  82. package/lib/generated/webSocketMockSource.js +7 -0
  83. package/lib/image_tools/colorUtils.js +98 -0
  84. package/lib/image_tools/compare.js +108 -0
  85. package/lib/image_tools/imageChannel.js +70 -0
  86. package/lib/image_tools/stats.js +102 -0
  87. package/lib/inProcessFactory.js +54 -0
  88. package/lib/inprocess.js +20 -0
  89. package/lib/outofprocess.js +67 -0
  90. package/lib/protocol/debug.js +27 -0
  91. package/lib/protocol/serializers.js +173 -0
  92. package/lib/protocol/transport.js +82 -0
  93. package/lib/protocol/validator.js +2760 -0
  94. package/lib/protocol/validatorPrimitives.js +139 -0
  95. package/lib/remote/playwrightConnection.js +274 -0
  96. package/lib/remote/playwrightServer.js +110 -0
  97. package/lib/server/accessibility.js +62 -0
  98. package/lib/server/android/android.js +441 -0
  99. package/lib/server/android/backendAdb.js +172 -0
  100. package/lib/server/artifact.js +104 -0
  101. package/lib/server/bidi/bidiBrowser.js +311 -0
  102. package/lib/server/bidi/bidiChromium.js +124 -0
  103. package/lib/server/bidi/bidiConnection.js +206 -0
  104. package/lib/server/bidi/bidiExecutionContext.js +159 -0
  105. package/lib/server/bidi/bidiFirefox.js +104 -0
  106. package/lib/server/bidi/bidiInput.js +158 -0
  107. package/lib/server/bidi/bidiNetworkManager.js +338 -0
  108. package/lib/server/bidi/bidiOverCdp.js +103 -0
  109. package/lib/server/bidi/bidiPage.js +529 -0
  110. package/lib/server/bidi/bidiPdf.js +140 -0
  111. package/lib/server/bidi/third_party/bidiDeserializer.js +93 -0
  112. package/lib/server/bidi/third_party/bidiKeyboard.js +238 -0
  113. package/lib/server/bidi/third_party/bidiProtocol.js +139 -0
  114. package/lib/server/bidi/third_party/bidiSerializer.js +144 -0
  115. package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  116. package/lib/server/browser.js +148 -0
  117. package/lib/server/browserContext.js +666 -0
  118. package/lib/server/browserType.js +335 -0
  119. package/lib/server/chromium/appIcon.png +0 -0
  120. package/lib/server/chromium/chromium.js +350 -0
  121. package/lib/server/chromium/chromiumSwitches.js +36 -0
  122. package/lib/server/chromium/crAccessibility.js +237 -0
  123. package/lib/server/chromium/crBrowser.js +522 -0
  124. package/lib/server/chromium/crConnection.js +228 -0
  125. package/lib/server/chromium/crCoverage.js +246 -0
  126. package/lib/server/chromium/crDevTools.js +104 -0
  127. package/lib/server/chromium/crDragDrop.js +143 -0
  128. package/lib/server/chromium/crExecutionContext.js +149 -0
  129. package/lib/server/chromium/crInput.js +171 -0
  130. package/lib/server/chromium/crNetworkManager.js +809 -0
  131. package/lib/server/chromium/crPage.js +1235 -0
  132. package/lib/server/chromium/crPdf.js +153 -0
  133. package/lib/server/chromium/crProtocolHelper.js +133 -0
  134. package/lib/server/chromium/crServiceWorker.js +111 -0
  135. package/lib/server/chromium/defaultFontFamilies.js +145 -0
  136. package/lib/server/chromium/videoRecorder.js +155 -0
  137. package/lib/server/clock.js +133 -0
  138. package/lib/server/codegen/csharp.js +299 -0
  139. package/lib/server/codegen/java.js +235 -0
  140. package/lib/server/codegen/javascript.js +223 -0
  141. package/lib/server/codegen/jsonl.js +47 -0
  142. package/lib/server/codegen/language.js +88 -0
  143. package/lib/server/codegen/languages.js +30 -0
  144. package/lib/server/codegen/python.js +265 -0
  145. package/lib/server/codegen/types.js +5 -0
  146. package/lib/server/console.js +57 -0
  147. package/lib/server/cookieStore.js +185 -0
  148. package/lib/server/debugController.js +234 -0
  149. package/lib/server/debugger.js +132 -0
  150. package/lib/server/deviceDescriptors.js +26 -0
  151. package/lib/server/deviceDescriptorsSource.json +1669 -0
  152. package/lib/server/dialog.js +71 -0
  153. package/lib/server/dispatchers/androidDispatcher.js +193 -0
  154. package/lib/server/dispatchers/artifactDispatcher.js +118 -0
  155. package/lib/server/dispatchers/browserContextDispatcher.js +368 -0
  156. package/lib/server/dispatchers/browserDispatcher.js +170 -0
  157. package/lib/server/dispatchers/browserTypeDispatcher.js +55 -0
  158. package/lib/server/dispatchers/cdpSessionDispatcher.js +48 -0
  159. package/lib/server/dispatchers/debugControllerDispatcher.js +103 -0
  160. package/lib/server/dispatchers/dialogDispatcher.js +44 -0
  161. package/lib/server/dispatchers/dispatcher.js +395 -0
  162. package/lib/server/dispatchers/electronDispatcher.js +93 -0
  163. package/lib/server/dispatchers/elementHandlerDispatcher.js +228 -0
  164. package/lib/server/dispatchers/frameDispatcher.js +286 -0
  165. package/lib/server/dispatchers/jsHandleDispatcher.js +97 -0
  166. package/lib/server/dispatchers/jsonPipeDispatcher.js +59 -0
  167. package/lib/server/dispatchers/localUtilsDispatcher.js +413 -0
  168. package/lib/server/dispatchers/networkDispatchers.js +221 -0
  169. package/lib/server/dispatchers/pageDispatcher.js +367 -0
  170. package/lib/server/dispatchers/playwrightDispatcher.js +107 -0
  171. package/lib/server/dispatchers/selectorsDispatcher.js +36 -0
  172. package/lib/server/dispatchers/streamDispatcher.js +62 -0
  173. package/lib/server/dispatchers/tracingDispatcher.js +54 -0
  174. package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  175. package/lib/server/dispatchers/writableStreamDispatcher.js +58 -0
  176. package/lib/server/dom.js +845 -0
  177. package/lib/server/download.js +60 -0
  178. package/lib/server/electron/electron.js +296 -0
  179. package/lib/server/electron/loader.js +57 -0
  180. package/lib/server/errors.js +68 -0
  181. package/lib/server/fetch.js +656 -0
  182. package/lib/server/fileChooser.js +42 -0
  183. package/lib/server/fileUploadUtils.js +75 -0
  184. package/lib/server/firefox/ffAccessibility.js +216 -0
  185. package/lib/server/firefox/ffBrowser.js +460 -0
  186. package/lib/server/firefox/ffConnection.js +168 -0
  187. package/lib/server/firefox/ffExecutionContext.js +135 -0
  188. package/lib/server/firefox/ffInput.js +150 -0
  189. package/lib/server/firefox/ffNetworkManager.js +233 -0
  190. package/lib/server/firefox/ffPage.js +559 -0
  191. package/lib/server/firefox/firefox.js +99 -0
  192. package/lib/server/formData.js +75 -0
  193. package/lib/server/frameSelectors.js +171 -0
  194. package/lib/server/frames.js +1808 -0
  195. package/lib/server/har/harRecorder.js +139 -0
  196. package/lib/server/har/harTracer.js +542 -0
  197. package/lib/server/helper.js +103 -0
  198. package/lib/server/index.js +114 -0
  199. package/lib/server/input.js +310 -0
  200. package/lib/server/instrumentation.js +70 -0
  201. package/lib/server/isomorphic/utilityScriptSerializers.js +226 -0
  202. package/lib/server/javascript.js +299 -0
  203. package/lib/server/launchApp.js +91 -0
  204. package/lib/server/macEditingCommands.js +139 -0
  205. package/lib/server/network.js +617 -0
  206. package/lib/server/page.js +819 -0
  207. package/lib/server/pipeTransport.js +85 -0
  208. package/lib/server/playwright.js +88 -0
  209. package/lib/server/progress.js +102 -0
  210. package/lib/server/protocolError.js +49 -0
  211. package/lib/server/recorder/contextRecorder.js +299 -0
  212. package/lib/server/recorder/recorderApp.js +196 -0
  213. package/lib/server/recorder/recorderCollection.js +116 -0
  214. package/lib/server/recorder/recorderFrontend.js +5 -0
  215. package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  216. package/lib/server/recorder/recorderRunner.js +155 -0
  217. package/lib/server/recorder/recorderUtils.js +112 -0
  218. package/lib/server/recorder/throttledFile.js +46 -0
  219. package/lib/server/recorder.js +329 -0
  220. package/lib/server/registry/browserFetcher.js +168 -0
  221. package/lib/server/registry/dependencies.js +322 -0
  222. package/lib/server/registry/index.js +1005 -0
  223. package/lib/server/registry/nativeDeps.js +490 -0
  224. package/lib/server/registry/oopDownloadBrowserMain.js +138 -0
  225. package/lib/server/screenshotter.js +348 -0
  226. package/lib/server/selectors.js +73 -0
  227. package/lib/server/socksClientCertificatesInterceptor.js +340 -0
  228. package/lib/server/socksInterceptor.js +100 -0
  229. package/lib/server/trace/recorder/snapshotter.js +172 -0
  230. package/lib/server/trace/recorder/snapshotterInjected.js +493 -0
  231. package/lib/server/trace/recorder/tracing.js +542 -0
  232. package/lib/server/trace/test/inMemorySnapshotter.js +93 -0
  233. package/lib/server/trace/viewer/traceViewer.js +213 -0
  234. package/lib/server/transport.js +191 -0
  235. package/lib/server/types.js +24 -0
  236. package/lib/server/usKeyboardLayout.js +555 -0
  237. package/lib/server/webkit/webkit.js +87 -0
  238. package/lib/server/webkit/wkAccessibility.js +194 -0
  239. package/lib/server/webkit/wkBrowser.js +329 -0
  240. package/lib/server/webkit/wkConnection.js +173 -0
  241. package/lib/server/webkit/wkExecutionContext.js +143 -0
  242. package/lib/server/webkit/wkInput.js +169 -0
  243. package/lib/server/webkit/wkInterceptableRequest.js +162 -0
  244. package/lib/server/webkit/wkPage.js +1219 -0
  245. package/lib/server/webkit/wkProvisionalPage.js +94 -0
  246. package/lib/server/webkit/wkWorkers.js +104 -0
  247. package/lib/third_party/diff_match_patch.js +2222 -0
  248. package/lib/third_party/pixelmatch.js +255 -0
  249. package/lib/utils/ascii.js +31 -0
  250. package/lib/utils/comparators.js +171 -0
  251. package/lib/utils/crypto.js +174 -0
  252. package/lib/utils/debug.js +46 -0
  253. package/lib/utils/debugLogger.js +91 -0
  254. package/lib/utils/env.js +49 -0
  255. package/lib/utils/eventsHelper.js +38 -0
  256. package/lib/utils/expectUtils.js +33 -0
  257. package/lib/utils/fileUtils.js +205 -0
  258. package/lib/utils/happy-eyeballs.js +194 -0
  259. package/lib/utils/headers.js +52 -0
  260. package/lib/utils/hostPlatform.js +133 -0
  261. package/lib/utils/httpServer.js +237 -0
  262. package/lib/utils/index.js +368 -0
  263. package/lib/utils/isomorphic/cssParser.js +250 -0
  264. package/lib/utils/isomorphic/cssTokenizer.js +979 -0
  265. package/lib/utils/isomorphic/locatorGenerators.js +642 -0
  266. package/lib/utils/isomorphic/locatorParser.js +179 -0
  267. package/lib/utils/isomorphic/locatorUtils.js +62 -0
  268. package/lib/utils/isomorphic/mimeType.js +29 -0
  269. package/lib/utils/isomorphic/recorderUtils.js +195 -0
  270. package/lib/utils/isomorphic/selectorParser.js +397 -0
  271. package/lib/utils/isomorphic/stringUtils.js +139 -0
  272. package/lib/utils/isomorphic/traceUtils.js +39 -0
  273. package/lib/utils/isomorphic/urlMatch.js +120 -0
  274. package/lib/utils/linuxUtils.js +78 -0
  275. package/lib/utils/manualPromise.js +109 -0
  276. package/lib/utils/multimap.js +75 -0
  277. package/lib/utils/network.js +160 -0
  278. package/lib/utils/processLauncher.js +248 -0
  279. package/lib/utils/profiler.js +53 -0
  280. package/lib/utils/rtti.js +44 -0
  281. package/lib/utils/semaphore.js +51 -0
  282. package/lib/utils/spawnAsync.js +45 -0
  283. package/lib/utils/stackTrace.js +121 -0
  284. package/lib/utils/task.js +58 -0
  285. package/lib/utils/time.js +37 -0
  286. package/lib/utils/timeoutRunner.js +66 -0
  287. package/lib/utils/traceUtils.js +44 -0
  288. package/lib/utils/userAgent.js +105 -0
  289. package/lib/utils/wsServer.js +127 -0
  290. package/lib/utils/zipFile.js +75 -0
  291. package/lib/utils/zones.js +62 -0
  292. package/lib/utilsBundle.js +82 -0
  293. package/lib/utilsBundleImpl/index.js +53 -0
  294. package/lib/utilsBundleImpl/xdg-open +1066 -0
  295. package/lib/vite/htmlReport/index.html +66 -0
  296. package/lib/vite/recorder/assets/codeMirrorModule-baozm8ur.js +24 -0
  297. package/lib/vite/recorder/assets/codeMirrorModule-ez37Vkbh.css +1 -0
  298. package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
  299. package/lib/vite/recorder/assets/index-2ElAIWFB.js +42 -0
  300. package/lib/vite/recorder/assets/index-BW-aOBcL.css +1 -0
  301. package/lib/vite/recorder/index.html +29 -0
  302. package/lib/vite/recorder/playwright-logo.svg +9 -0
  303. package/lib/vite/traceViewer/assets/codeMirrorModule-Bh1rfd2w.js +24 -0
  304. package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
  305. package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +1 -0
  306. package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
  307. package/lib/vite/traceViewer/assets/xtermModule-BeNbaIVa.js +9 -0
  308. package/lib/vite/traceViewer/codeMirrorModule.ez37Vkbh.css +1 -0
  309. package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  310. package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
  311. package/lib/vite/traceViewer/embedded.html +18 -0
  312. package/lib/vite/traceViewer/embedded.w7WN2u1R.css +1 -0
  313. package/lib/vite/traceViewer/index.CrbWWHbf.css +1 -0
  314. package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
  315. package/lib/vite/traceViewer/index.html +29 -0
  316. package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  317. package/lib/vite/traceViewer/playwright-logo.svg +9 -0
  318. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  319. package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
  320. package/lib/vite/traceViewer/recorder.html +17 -0
  321. package/lib/vite/traceViewer/snapshot.html +21 -0
  322. package/lib/vite/traceViewer/sw.bundle.js +3 -0
  323. package/lib/vite/traceViewer/uiMode.CAYqod-m.css +1 -0
  324. package/lib/vite/traceViewer/uiMode.html +20 -0
  325. package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
  326. package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
  327. package/lib/vite/traceViewer/xtermModule.DSXBckUd.css +32 -0
  328. package/lib/zipBundle.js +25 -0
  329. package/lib/zipBundleImpl.js +5 -0
  330. package/package.json +44 -0
  331. package/types/protocol.d.ts +21571 -0
  332. package/types/structs.d.ts +45 -0
  333. package/types/types.d.ts +22519 -0
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.kBrowserCloseMessageId = exports.BidiSession = exports.BidiConnection = void 0;
7
+ var _events = require("events");
8
+ var _utils = require("../../utils");
9
+ var _debugLogger = require("../../utils/debugLogger");
10
+ var _helper = require("../helper");
11
+ var _protocolError = require("../protocolError");
12
+ /**
13
+ * Copyright (c) Microsoft Corporation.
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the 'License');
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an 'AS IS' BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ */
27
+
28
+ // BidiPlaywright uses this special id to issue Browser.close command which we
29
+ // should ignore.
30
+ const kBrowserCloseMessageId = exports.kBrowserCloseMessageId = 0;
31
+ class BidiConnection {
32
+ constructor(transport, onDisconnect, protocolLogger, browserLogsCollector) {
33
+ this._transport = void 0;
34
+ this._onDisconnect = void 0;
35
+ this._protocolLogger = void 0;
36
+ this._browserLogsCollector = void 0;
37
+ this._browserDisconnectedLogs = void 0;
38
+ this._lastId = 0;
39
+ this._closed = false;
40
+ this.browserSession = void 0;
41
+ this._browsingContextToSession = new Map();
42
+ this._transport = transport;
43
+ this._onDisconnect = onDisconnect;
44
+ this._protocolLogger = protocolLogger;
45
+ this._browserLogsCollector = browserLogsCollector;
46
+ this.browserSession = new BidiSession(this, '', message => {
47
+ this.rawSend(message);
48
+ });
49
+ this._transport.onmessage = this._dispatchMessage.bind(this);
50
+ // onclose should be set last, since it can be immediately called.
51
+ this._transport.onclose = this._onClose.bind(this);
52
+ }
53
+ nextMessageId() {
54
+ return ++this._lastId;
55
+ }
56
+ rawSend(message) {
57
+ this._protocolLogger('send', message);
58
+ this._transport.send(message);
59
+ }
60
+ _dispatchMessage(message) {
61
+ this._protocolLogger('receive', message);
62
+ const object = message;
63
+ // Bidi messages do not have a common session identifier, so we
64
+ // route them based on BrowsingContext.
65
+ if (object.type === 'event') {
66
+ var _object$params$source;
67
+ // Route page events to the right session.
68
+ let context;
69
+ if ('context' in object.params) context = object.params.context;else if (object.method === 'log.entryAdded' || object.method === 'script.message') context = (_object$params$source = object.params.source) === null || _object$params$source === void 0 ? void 0 : _object$params$source.context;
70
+ if (context) {
71
+ const session = this._browsingContextToSession.get(context);
72
+ if (session) {
73
+ session.dispatchMessage(message);
74
+ return;
75
+ }
76
+ }
77
+ } else if (message.id) {
78
+ // Find caller session.
79
+ for (const session of this._browsingContextToSession.values()) {
80
+ if (session.hasCallback(message.id)) {
81
+ session.dispatchMessage(message);
82
+ return;
83
+ }
84
+ }
85
+ }
86
+ this.browserSession.dispatchMessage(message);
87
+ }
88
+ _onClose(reason) {
89
+ this._closed = true;
90
+ this._transport.onmessage = undefined;
91
+ this._transport.onclose = undefined;
92
+ this._browserDisconnectedLogs = _helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs(), reason);
93
+ this.browserSession.dispose();
94
+ this._onDisconnect();
95
+ }
96
+ isClosed() {
97
+ return this._closed;
98
+ }
99
+ close() {
100
+ if (!this._closed) this._transport.close();
101
+ }
102
+ createMainFrameBrowsingContextSession(bowsingContextId) {
103
+ const result = new BidiSession(this, bowsingContextId, message => this.rawSend(message));
104
+ this._browsingContextToSession.set(bowsingContextId, result);
105
+ return result;
106
+ }
107
+ }
108
+ exports.BidiConnection = BidiConnection;
109
+ class BidiSession extends _events.EventEmitter {
110
+ constructor(connection, sessionId, rawSend) {
111
+ super();
112
+ this.connection = void 0;
113
+ this.sessionId = void 0;
114
+ this._disposed = false;
115
+ this._rawSend = void 0;
116
+ this._callbacks = new Map();
117
+ this._crashed = false;
118
+ this._browsingContexts = new Set();
119
+ this.on = void 0;
120
+ this.addListener = void 0;
121
+ this.off = void 0;
122
+ this.removeListener = void 0;
123
+ this.once = void 0;
124
+ this.setMaxListeners(0);
125
+ this.connection = connection;
126
+ this.sessionId = sessionId;
127
+ this._rawSend = rawSend;
128
+ this.on = super.on;
129
+ this.off = super.removeListener;
130
+ this.addListener = super.addListener;
131
+ this.removeListener = super.removeListener;
132
+ this.once = super.once;
133
+ }
134
+ addFrameBrowsingContext(context) {
135
+ this._browsingContexts.add(context);
136
+ this.connection._browsingContextToSession.set(context, this);
137
+ }
138
+ removeFrameBrowsingContext(context) {
139
+ this._browsingContexts.delete(context);
140
+ this.connection._browsingContextToSession.delete(context);
141
+ }
142
+ async send(method, params) {
143
+ if (this._crashed || this._disposed || this.connection._browserDisconnectedLogs) throw new _protocolError.ProtocolError(this._crashed ? 'crashed' : 'closed', undefined, this.connection._browserDisconnectedLogs);
144
+ const id = this.connection.nextMessageId();
145
+ const messageObj = {
146
+ id,
147
+ method,
148
+ params
149
+ };
150
+ this._rawSend(messageObj);
151
+ return new Promise((resolve, reject) => {
152
+ this._callbacks.set(id, {
153
+ resolve,
154
+ reject,
155
+ error: new _protocolError.ProtocolError('error', method)
156
+ });
157
+ });
158
+ }
159
+ sendMayFail(method, params) {
160
+ return this.send(method, params).catch(error => _debugLogger.debugLogger.log('error', error));
161
+ }
162
+ markAsCrashed() {
163
+ this._crashed = true;
164
+ }
165
+ isDisposed() {
166
+ return this._disposed;
167
+ }
168
+ dispose() {
169
+ this._disposed = true;
170
+ this.connection._browsingContextToSession.delete(this.sessionId);
171
+ for (const context of this._browsingContexts) this.connection._browsingContextToSession.delete(context);
172
+ this._browsingContexts.clear();
173
+ for (const callback of this._callbacks.values()) {
174
+ callback.error.type = this._crashed ? 'crashed' : 'closed';
175
+ callback.error.logs = this.connection._browserDisconnectedLogs;
176
+ callback.reject(callback.error);
177
+ }
178
+ this._callbacks.clear();
179
+ }
180
+ hasCallback(id) {
181
+ return this._callbacks.has(id);
182
+ }
183
+ dispatchMessage(message) {
184
+ const object = message;
185
+ if (object.id === kBrowserCloseMessageId) return;
186
+ if (object.id && this._callbacks.has(object.id)) {
187
+ const callback = this._callbacks.get(object.id);
188
+ this._callbacks.delete(object.id);
189
+ if (object.type === 'error') {
190
+ callback.error.setMessage(object.error + '\nMessage: ' + object.message);
191
+ callback.reject(callback.error);
192
+ } else if (object.type === 'success') {
193
+ callback.resolve(object.result);
194
+ } else {
195
+ callback.error.setMessage('Internal error, unexpected response type: ' + JSON.stringify(object));
196
+ callback.reject(callback.error);
197
+ }
198
+ } else if (object.id) {
199
+ // Response might come after session has been disposed and rejected all callbacks.
200
+ (0, _utils.assert)(this.isDisposed());
201
+ } else {
202
+ Promise.resolve().then(() => this.emit(object.method, object.params));
203
+ }
204
+ }
205
+ }
206
+ exports.BidiSession = BidiSession;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BidiExecutionContext = void 0;
7
+ var _utilityScriptSerializers = require("../isomorphic/utilityScriptSerializers");
8
+ var js = _interopRequireWildcard(require("../javascript"));
9
+ var _bidiDeserializer = require("./third_party/bidiDeserializer");
10
+ var bidi = _interopRequireWildcard(require("./third_party/bidiProtocol"));
11
+ var _bidiSerializer = require("./third_party/bidiSerializer");
12
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
+ /**
15
+ * Copyright (c) Microsoft Corporation.
16
+ *
17
+ * Licensed under the Apache License, Version 2.0 (the 'License');
18
+ * you may not use this file except in compliance with the License.
19
+ * You may obtain a copy of the License at
20
+ *
21
+ * http://www.apache.org/licenses/LICENSE-2.0
22
+ *
23
+ * Unless required by applicable law or agreed to in writing, software
24
+ * distributed under the License is distributed on an 'AS IS' BASIS,
25
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26
+ * See the License for the specific language governing permissions and
27
+ * limitations under the License.
28
+ */
29
+
30
+ class BidiExecutionContext {
31
+ constructor(session, realmInfo) {
32
+ this._session = void 0;
33
+ this._target = void 0;
34
+ this._session = session;
35
+ if (realmInfo.type === 'window') {
36
+ // Simple realm does not seem to work for Window contexts.
37
+ this._target = {
38
+ context: realmInfo.context,
39
+ sandbox: realmInfo.sandbox
40
+ };
41
+ } else {
42
+ this._target = {
43
+ realm: realmInfo.realm
44
+ };
45
+ }
46
+ }
47
+ async rawEvaluateJSON(expression) {
48
+ const response = await this._session.send('script.evaluate', {
49
+ expression,
50
+ target: this._target,
51
+ serializationOptions: {
52
+ maxObjectDepth: 10,
53
+ maxDomDepth: 10
54
+ },
55
+ awaitPromise: true,
56
+ userActivation: true
57
+ });
58
+ if (response.type === 'success') return _bidiDeserializer.BidiDeserializer.deserialize(response.result);
59
+ if (response.type === 'exception') throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + '\nFull val: ' + JSON.stringify(response.exceptionDetails));
60
+ throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
61
+ }
62
+ async rawEvaluateHandle(expression) {
63
+ const response = await this._session.send('script.evaluate', {
64
+ expression,
65
+ target: this._target,
66
+ resultOwnership: bidi.Script.ResultOwnership.Root,
67
+ // Necessary for the handle to be returned.
68
+ serializationOptions: {
69
+ maxObjectDepth: 0,
70
+ maxDomDepth: 0
71
+ },
72
+ awaitPromise: true,
73
+ userActivation: true
74
+ });
75
+ if (response.type === 'success') {
76
+ if ('handle' in response.result) return response.result.handle;
77
+ throw new js.JavaScriptErrorInEvaluate('Cannot get handle: ' + JSON.stringify(response.result));
78
+ }
79
+ if (response.type === 'exception') throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + '\nFull val: ' + JSON.stringify(response.exceptionDetails));
80
+ throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
81
+ }
82
+ rawCallFunctionNoReply(func, ...args) {
83
+ throw new Error('Method not implemented.');
84
+ }
85
+ async evaluateWithArguments(functionDeclaration, returnByValue, utilityScript, values, objectIds) {
86
+ const response = await this._session.send('script.callFunction', {
87
+ functionDeclaration,
88
+ target: this._target,
89
+ arguments: [{
90
+ handle: utilityScript._objectId
91
+ }, ...values.map(_bidiSerializer.BidiSerializer.serialize), ...objectIds.map(handle => ({
92
+ handle
93
+ }))],
94
+ resultOwnership: returnByValue ? undefined : bidi.Script.ResultOwnership.Root,
95
+ // Necessary for the handle to be returned.
96
+ serializationOptions: returnByValue ? {} : {
97
+ maxObjectDepth: 0,
98
+ maxDomDepth: 0
99
+ },
100
+ awaitPromise: true,
101
+ userActivation: true
102
+ });
103
+ if (response.type === 'exception') throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + '\nFull val: ' + JSON.stringify(response.exceptionDetails));
104
+ if (response.type === 'success') {
105
+ if (returnByValue) return (0, _utilityScriptSerializers.parseEvaluationResultValue)(_bidiDeserializer.BidiDeserializer.deserialize(response.result));
106
+ const objectId = 'handle' in response.result ? response.result.handle : undefined;
107
+ return utilityScript._context.createHandle({
108
+ objectId,
109
+ ...response.result
110
+ });
111
+ }
112
+ throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
113
+ }
114
+ async getProperties(context, objectId) {
115
+ throw new Error('Method not implemented.');
116
+ }
117
+ createHandle(context, jsRemoteObject) {
118
+ const remoteObject = jsRemoteObject;
119
+ return new js.JSHandle(context, remoteObject.type, renderPreview(remoteObject), jsRemoteObject.objectId, remoteObjectValue(remoteObject));
120
+ }
121
+ async releaseHandle(objectId) {
122
+ await this._session.send('script.disown', {
123
+ target: this._target,
124
+ handles: [objectId]
125
+ });
126
+ }
127
+ async rawCallFunction(functionDeclaration, arg) {
128
+ const response = await this._session.send('script.callFunction', {
129
+ functionDeclaration,
130
+ target: this._target,
131
+ arguments: [arg],
132
+ resultOwnership: bidi.Script.ResultOwnership.Root,
133
+ // Necessary for the handle to be returned.
134
+ serializationOptions: {
135
+ maxObjectDepth: 0,
136
+ maxDomDepth: 0
137
+ },
138
+ awaitPromise: true,
139
+ userActivation: true
140
+ });
141
+ if (response.type === 'exception') throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + '\nFull val: ' + JSON.stringify(response.exceptionDetails));
142
+ if (response.type === 'success') return response.result;
143
+ throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
144
+ }
145
+ }
146
+ exports.BidiExecutionContext = BidiExecutionContext;
147
+ function renderPreview(remoteObject) {
148
+ if (remoteObject.type === 'undefined') return 'undefined';
149
+ if (remoteObject.type === 'null') return 'null';
150
+ if ('value' in remoteObject) return String(remoteObject.value);
151
+ return `<${remoteObject.type}>`;
152
+ }
153
+ function remoteObjectValue(remoteObject) {
154
+ if (remoteObject.type === 'undefined') return undefined;
155
+ if (remoteObject.type === 'null') return null;
156
+ if (remoteObject.type === 'number' && typeof remoteObject.value === 'string') return js.parseUnserializableValue(remoteObject.value);
157
+ if ('value' in remoteObject) return remoteObject.value;
158
+ return undefined;
159
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BidiFirefox = void 0;
7
+ var _os = _interopRequireDefault(require("os"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _utils = require("../../utils");
10
+ var _browserType = require("../browserType");
11
+ var _bidiBrowser = require("./bidiBrowser");
12
+ var _bidiConnection = require("./bidiConnection");
13
+ var _firefoxPrefs = require("./third_party/firefoxPrefs");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ /**
16
+ * Copyright (c) Microsoft Corporation.
17
+ *
18
+ * Licensed under the Apache License, Version 2.0 (the 'License');
19
+ * you may not use this file except in compliance with the License.
20
+ * You may obtain a copy of the License at
21
+ *
22
+ * http://www.apache.org/licenses/LICENSE-2.0
23
+ *
24
+ * Unless required by applicable law or agreed to in writing, software
25
+ * distributed under the License is distributed on an 'AS IS' BASIS,
26
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27
+ * See the License for the specific language governing permissions and
28
+ * limitations under the License.
29
+ */
30
+
31
+ class BidiFirefox extends _browserType.BrowserType {
32
+ constructor(parent) {
33
+ super(parent, 'bidi');
34
+ this._useBidi = true;
35
+ }
36
+ async connectToTransport(transport, options) {
37
+ return _bidiBrowser.BidiBrowser.connect(this.attribution.playwright, transport, options);
38
+ }
39
+ doRewriteStartupLog(error) {
40
+ if (!error.logs) return error;
41
+ // https://github.com/microsoft/playwright/issues/6500
42
+ if (error.logs.includes(`as root in a regular user's session is not supported.`)) error.logs = '\n' + (0, _utils.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.\nWorkaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? ' in your GitHub Actions workflow file' : ''} when running Playwright.`, 1);
43
+ if (error.logs.includes('no DISPLAY environment variable specified')) error.logs = '\n' + (0, _utils.wrapInASCIIBox)(_browserType.kNoXServerRunningError, 1);
44
+ return error;
45
+ }
46
+ amendEnvironment(env, userDataDir, executable, browserArguments) {
47
+ if (!_path.default.isAbsolute(_os.default.homedir())) throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${_os.default.platform() === 'win32' ? 'USERPROFILE' : 'HOME'} to a relative path?`);
48
+ env = {
49
+ ...env,
50
+ 'MOZ_CRASHREPORTER': '1',
51
+ 'MOZ_CRASHREPORTER_NO_REPORT': '1',
52
+ 'MOZ_CRASHREPORTER_SHUTDOWN': '1'
53
+ };
54
+ if (_os.default.platform() === 'linux') {
55
+ // Always remove SNAP_NAME and SNAP_INSTANCE_NAME env variables since they
56
+ // confuse Firefox: in our case, builds never come from SNAP.
57
+ // See https://github.com/microsoft/playwright/issues/20555
58
+ return {
59
+ ...env,
60
+ SNAP_NAME: undefined,
61
+ SNAP_INSTANCE_NAME: undefined
62
+ };
63
+ }
64
+ return env;
65
+ }
66
+ attemptToGracefullyCloseBrowser(transport) {
67
+ transport.send({
68
+ method: 'browser.close',
69
+ params: {},
70
+ id: _bidiConnection.kBrowserCloseMessageId
71
+ });
72
+ }
73
+ async prepareUserDataDir(options, userDataDir) {
74
+ await (0, _firefoxPrefs.createProfile)({
75
+ path: userDataDir,
76
+ preferences: options.firefoxUserPrefs || {}
77
+ });
78
+ }
79
+ defaultArgs(options, isPersistent, userDataDir) {
80
+ const {
81
+ args = [],
82
+ headless
83
+ } = options;
84
+ const userDataDirArg = args.find(arg => arg.startsWith('-profile') || arg.startsWith('--profile'));
85
+ if (userDataDirArg) throw this._createUserDataDirArgMisuseError('--profile');
86
+ const firefoxArguments = ['--remote-debugging-port=0'];
87
+ if (headless) firefoxArguments.push('--headless');else firefoxArguments.push('--foreground');
88
+ firefoxArguments.push(`--profile`, userDataDir);
89
+ firefoxArguments.push(...args);
90
+ return firefoxArguments;
91
+ }
92
+ readyState(options) {
93
+ (0, _utils.assert)(options.useWebSocket);
94
+ return new FirefoxReadyState();
95
+ }
96
+ }
97
+ exports.BidiFirefox = BidiFirefox;
98
+ class FirefoxReadyState extends _browserType.BrowserReadyState {
99
+ onBrowserOutput(message) {
100
+ // Bidi WebSocket in Firefox.
101
+ const match = message.match(/WebDriver BiDi listening on (ws:\/\/.*)$/);
102
+ if (match) this._wsEndpoint.resolve(match[1] + '/session');
103
+ }
104
+ }
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RawTouchscreenImpl = exports.RawMouseImpl = exports.RawKeyboardImpl = void 0;
7
+ var bidi = _interopRequireWildcard(require("./third_party/bidiProtocol"));
8
+ var _bidiKeyboard = require("./third_party/bidiKeyboard");
9
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
10
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
11
+ /**
12
+ * Copyright (c) Microsoft Corporation.
13
+ *
14
+ * Licensed under the Apache License, Version 2.0 (the 'License');
15
+ * you may not use this file except in compliance with the License.
16
+ * You may obtain a copy of the License at
17
+ *
18
+ * http://www.apache.org/licenses/LICENSE-2.0
19
+ *
20
+ * Unless required by applicable law or agreed to in writing, software
21
+ * distributed under the License is distributed on an 'AS IS' BASIS,
22
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ * See the License for the specific language governing permissions and
24
+ * limitations under the License.
25
+ */
26
+
27
+ class RawKeyboardImpl {
28
+ constructor(session) {
29
+ this._session = void 0;
30
+ this._session = session;
31
+ }
32
+ setSession(session) {
33
+ this._session = session;
34
+ }
35
+ async keydown(modifiers, code, keyCode, keyCodeWithoutLocation, key, location, autoRepeat, text) {
36
+ const actions = [];
37
+ actions.push({
38
+ type: 'keyDown',
39
+ value: (0, _bidiKeyboard.getBidiKeyValue)(key)
40
+ });
41
+ // TODO: add modifiers?
42
+ await this._performActions(actions);
43
+ }
44
+ async keyup(modifiers, code, keyCode, keyCodeWithoutLocation, key, location) {
45
+ const actions = [];
46
+ actions.push({
47
+ type: 'keyUp',
48
+ value: (0, _bidiKeyboard.getBidiKeyValue)(key)
49
+ });
50
+ await this._performActions(actions);
51
+ }
52
+ async sendText(text) {
53
+ const actions = [];
54
+ for (const char of text) {
55
+ const value = (0, _bidiKeyboard.getBidiKeyValue)(char);
56
+ actions.push({
57
+ type: 'keyDown',
58
+ value
59
+ });
60
+ actions.push({
61
+ type: 'keyUp',
62
+ value
63
+ });
64
+ }
65
+ await this._performActions(actions);
66
+ }
67
+ async _performActions(actions) {
68
+ await this._session.send('input.performActions', {
69
+ context: this._session.sessionId,
70
+ actions: [{
71
+ type: 'key',
72
+ id: 'pw_keyboard',
73
+ actions
74
+ }]
75
+ });
76
+ }
77
+ }
78
+ exports.RawKeyboardImpl = RawKeyboardImpl;
79
+ class RawMouseImpl {
80
+ constructor(session) {
81
+ this._session = void 0;
82
+ this._session = session;
83
+ }
84
+ async move(x, y, button, buttons, modifiers, forClick) {
85
+ // Bidi throws when x/y are not integers.
86
+ x = Math.round(x);
87
+ y = Math.round(y);
88
+ await this._performActions([{
89
+ type: 'pointerMove',
90
+ x,
91
+ y
92
+ }]);
93
+ }
94
+ async down(x, y, button, buttons, modifiers, clickCount) {
95
+ await this._performActions([{
96
+ type: 'pointerDown',
97
+ button: toBidiButton(button)
98
+ }]);
99
+ }
100
+ async up(x, y, button, buttons, modifiers, clickCount) {
101
+ await this._performActions([{
102
+ type: 'pointerUp',
103
+ button: toBidiButton(button)
104
+ }]);
105
+ }
106
+ async wheel(x, y, buttons, modifiers, deltaX, deltaY) {
107
+ // Bidi throws when x/y are not integers.
108
+ x = Math.round(x);
109
+ y = Math.round(y);
110
+ await this._session.send('input.performActions', {
111
+ context: this._session.sessionId,
112
+ actions: [{
113
+ type: 'wheel',
114
+ id: 'pw_mouse_wheel',
115
+ actions: [{
116
+ type: 'scroll',
117
+ x,
118
+ y,
119
+ deltaX,
120
+ deltaY
121
+ }]
122
+ }]
123
+ });
124
+ }
125
+ async _performActions(actions) {
126
+ await this._session.send('input.performActions', {
127
+ context: this._session.sessionId,
128
+ actions: [{
129
+ type: 'pointer',
130
+ id: 'pw_mouse',
131
+ parameters: {
132
+ pointerType: bidi.Input.PointerType.Mouse
133
+ },
134
+ actions
135
+ }]
136
+ });
137
+ }
138
+ }
139
+ exports.RawMouseImpl = RawMouseImpl;
140
+ class RawTouchscreenImpl {
141
+ constructor(session) {
142
+ this._session = void 0;
143
+ this._session = session;
144
+ }
145
+ async tap(x, y, modifiers) {}
146
+ }
147
+ exports.RawTouchscreenImpl = RawTouchscreenImpl;
148
+ function toBidiButton(button) {
149
+ switch (button) {
150
+ case 'left':
151
+ return 0;
152
+ case 'right':
153
+ return 2;
154
+ case 'middle':
155
+ return 1;
156
+ }
157
+ throw new Error('Unknown button: ' + button);
158
+ }