rebrowser-playwright-core 1.47.100 → 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 (121) hide show
  1. package/README.md +1 -1
  2. package/browsers.json +14 -10
  3. package/lib/cli/program.js +26 -14
  4. package/lib/client/api.js +6 -0
  5. package/lib/client/browserContext.js +20 -2
  6. package/lib/client/channelOwner.js +5 -1
  7. package/lib/client/connection.js +3 -0
  8. package/lib/client/fetch.js +16 -21
  9. package/lib/client/jsHandle.js +0 -8
  10. package/lib/client/localUtils.js +1 -0
  11. package/lib/client/network.js +175 -17
  12. package/lib/client/page.js +21 -0
  13. package/lib/client/playwright.js +6 -3
  14. package/lib/client/tracing.js +16 -20
  15. package/lib/generated/consoleApiSource.js +1 -1
  16. package/lib/generated/injectedScriptSource.js +1 -1
  17. package/lib/generated/pollingRecorderSource.js +7 -0
  18. package/lib/generated/webSocketMockSource.js +7 -0
  19. package/lib/protocol/validator.js +80 -14
  20. package/lib/server/bidi/bidiBrowser.js +23 -8
  21. package/lib/server/bidi/bidiChromium.js +124 -0
  22. package/lib/server/bidi/bidiConnection.js +1 -1
  23. package/lib/server/bidi/bidiExecutionContext.js +0 -3
  24. package/lib/server/bidi/bidiFirefox.js +15 -21
  25. package/lib/server/bidi/bidiInput.js +16 -32
  26. package/lib/server/bidi/bidiNetworkManager.js +39 -5
  27. package/lib/server/bidi/bidiOverCdp.js +103 -0
  28. package/lib/server/bidi/bidiPage.js +98 -25
  29. package/lib/server/bidi/bidiPdf.js +140 -0
  30. package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  31. package/lib/server/browser.js +13 -2
  32. package/lib/server/browserContext.js +6 -23
  33. package/lib/server/browserType.js +39 -11
  34. package/lib/server/chromium/chromium.js +3 -15
  35. package/lib/server/chromium/chromiumSwitches.js +3 -1
  36. package/lib/server/chromium/crBrowser.js +4 -3
  37. package/lib/server/chromium/crExecutionContext.js +0 -7
  38. package/lib/server/chromium/crPage.js +16 -6
  39. package/lib/server/chromium/videoRecorder.js +1 -1
  40. package/lib/server/codegen/csharp.js +1 -1
  41. package/lib/server/codegen/java.js +1 -1
  42. package/lib/server/codegen/javascript.js +1 -1
  43. package/lib/server/codegen/language.js +14 -2
  44. package/lib/server/codegen/python.js +1 -1
  45. package/lib/server/cookieStore.js +73 -0
  46. package/lib/server/debugController.js +2 -2
  47. package/lib/server/deviceDescriptorsSource.json +50 -50
  48. package/lib/server/dialog.js +1 -0
  49. package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
  50. package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
  51. package/lib/server/dispatchers/pageDispatcher.js +9 -0
  52. package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
  53. package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  54. package/lib/server/download.js +9 -2
  55. package/lib/server/fetch.js +90 -94
  56. package/lib/server/firefox/ffBrowser.js +6 -4
  57. package/lib/server/firefox/ffExecutionContext.js +0 -3
  58. package/lib/server/firefox/ffPage.js +6 -3
  59. package/lib/server/firefox/firefox.js +2 -13
  60. package/lib/server/frameSelectors.js +1 -1
  61. package/lib/server/frames.js +158 -27
  62. package/lib/server/har/harTracer.js +11 -0
  63. package/lib/server/input.js +0 -1
  64. package/lib/server/javascript.js +0 -7
  65. package/lib/server/page.js +5 -1
  66. package/lib/server/playwright.js +5 -2
  67. package/lib/server/recorder/contextRecorder.js +33 -50
  68. package/lib/server/recorder/recorderApp.js +16 -10
  69. package/lib/server/recorder/recorderCollection.js +68 -79
  70. package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  71. package/lib/server/recorder/recorderRunner.js +75 -97
  72. package/lib/server/recorder/recorderUtils.js +47 -6
  73. package/lib/server/recorder.js +30 -25
  74. package/lib/server/registry/index.js +85 -4
  75. package/lib/server/socksClientCertificatesInterceptor.js +15 -3
  76. package/lib/server/trace/recorder/snapshotter.js +1 -0
  77. package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
  78. package/lib/server/trace/recorder/tracing.js +58 -2
  79. package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
  80. package/lib/server/trace/viewer/traceViewer.js +2 -5
  81. package/lib/server/webkit/webkit.js +1 -1
  82. package/lib/server/webkit/wkBrowser.js +6 -5
  83. package/lib/server/webkit/wkExecutionContext.js +0 -3
  84. package/lib/server/webkit/wkPage.js +7 -4
  85. package/lib/utils/happy-eyeballs.js +13 -0
  86. package/lib/utils/hostPlatform.js +2 -2
  87. package/lib/utils/httpServer.js +1 -0
  88. package/lib/utils/isomorphic/locatorGenerators.js +9 -18
  89. package/lib/utils/isomorphic/locatorParser.js +2 -2
  90. package/lib/utils/isomorphic/recorderUtils.js +195 -0
  91. package/lib/vite/htmlReport/index.html +12 -12
  92. package/lib/vite/recorder/assets/{codeMirrorModule-aW6Vz3gf.js → codeMirrorModule-baozm8ur.js} +1 -1
  93. package/lib/vite/recorder/assets/{index-DCpXOVIh.js → index-2ElAIWFB.js} +10 -15
  94. package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
  95. package/lib/vite/recorder/index.html +2 -2
  96. package/lib/vite/traceViewer/assets/{codeMirrorModule-eFKCUIu2.js → codeMirrorModule-Bh1rfd2w.js} +1 -1
  97. package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
  98. package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
  99. package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
  100. package/lib/vite/traceViewer/embedded.html +5 -3
  101. package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
  102. package/lib/vite/traceViewer/index.html +5 -3
  103. package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  104. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  105. package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
  106. package/lib/vite/traceViewer/recorder.html +17 -0
  107. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  108. package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.CAYqod-m.css} +1 -1
  109. package/lib/vite/traceViewer/uiMode.html +6 -4
  110. package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
  111. package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
  112. package/package.json +1 -1
  113. package/types/protocol.d.ts +79 -8
  114. package/types/types.d.ts +2037 -949
  115. package/lib/generated/recorderSource.js +0 -7
  116. package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
  117. package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
  118. package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
  119. package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
  120. package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
  121. /package/lib/server/recorder/{recorderActions.js → recorderFrontend.js} +0 -0
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.source = void 0;
7
+ const source = exports.source = "\nvar __commonJS = obj => {\n let required = false;\n let result;\n return function __require() {\n if (!required) {\n required = true;\n let fn;\n for (const name in obj) { fn = obj[name]; break; }\n const module = { exports: {} };\n fn(module.exports, module);\n result = module.exports;\n }\n return result;\n }\n};\nvar __export = (target, all) => {for (var name in all) target[name] = all[name];};\nvar __toESM = mod => ({ ...mod, 'default': mod });\nvar __toCommonJS = mod => ({ ...mod, __esModule: true });\n\n\n// packages/playwright-core/src/server/injected/recorder/pollingRecorder.ts\nvar pollingRecorder_exports = {};\n__export(pollingRecorder_exports, {\n PollingRecorder: () => PollingRecorder,\n default: () => pollingRecorder_default\n});\nmodule.exports = __toCommonJS(pollingRecorder_exports);\n\n// packages/playwright-core/src/server/injected/recorder/clipPaths.ts\nvar svgJson = { \"tagName\": \"svg\", \"children\": [{ \"tagName\": \"defs\", \"children\": [{ \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-gripper\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"d\": \"M5 3h2v2H5zm0 4h2v2H5zm0 4h2v2H5zm4-8h2v2H9zm0 4h2v2H9zm0 4h2v2H9z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-circle-large-filled\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"d\": \"M8 1a6.8 6.8 0 0 1 1.86.253 6.899 6.899 0 0 1 3.083 1.805 6.903 6.903 0 0 1 1.804 3.083C14.916 6.738 15 7.357 15 8s-.084 1.262-.253 1.86a6.9 6.9 0 0 1-.704 1.674 7.157 7.157 0 0 1-2.516 2.509 6.966 6.966 0 0 1-1.668.71A6.984 6.984 0 0 1 8 15a6.984 6.984 0 0 1-1.86-.246 7.098 7.098 0 0 1-1.674-.711 7.3 7.3 0 0 1-1.415-1.094 7.295 7.295 0 0 1-1.094-1.415 7.098 7.098 0 0 1-.71-1.675A6.985 6.985 0 0 1 1 8c0-.643.082-1.262.246-1.86a6.968 6.968 0 0 1 .711-1.667 7.156 7.156 0 0 1 2.509-2.516 6.895 6.895 0 0 1 1.675-.704A6.808 6.808 0 0 1 8 1z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-inspect\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M1 3l1-1h12l1 1v6h-1V3H2v8h5v1H2l-1-1V3zm14.707 9.707L9 6v9.414l2.707-2.707h4zM10 13V8.414l3.293 3.293h-2L10 13z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-whole-word\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M0 11H1V13H15V11H16V14H15H1H0V11Z\" } }, { \"tagName\": \"path\", \"attrs\": { \"d\": \"M6.84048 11H5.95963V10.1406H5.93814C5.555 10.7995 4.99104 11.1289 4.24625 11.1289C3.69839 11.1289 3.26871 10.9839 2.95718 10.6938C2.64924 10.4038 2.49527 10.0189 2.49527 9.53906C2.49527 8.51139 3.10041 7.91341 4.3107 7.74512L5.95963 7.51416C5.95963 6.57959 5.58186 6.1123 4.82632 6.1123C4.16389 6.1123 3.56591 6.33789 3.03238 6.78906V5.88672C3.57307 5.54297 4.19612 5.37109 4.90152 5.37109C6.19416 5.37109 6.84048 6.05501 6.84048 7.42285V11ZM5.95963 8.21777L4.63297 8.40039C4.22476 8.45768 3.91682 8.55973 3.70914 8.70654C3.50145 8.84977 3.39761 9.10579 3.39761 9.47461C3.39761 9.74316 3.4925 9.96338 3.68228 10.1353C3.87564 10.3035 4.13166 10.3877 4.45035 10.3877C4.8872 10.3877 5.24706 10.2355 5.52994 9.93115C5.8164 9.62321 5.95963 9.2347 5.95963 8.76562V8.21777Z\" } }, { \"tagName\": \"path\", \"attrs\": { \"d\": \"M9.3475 10.2051H9.32601V11H8.44515V2.85742H9.32601V6.4668H9.3475C9.78076 5.73633 10.4146 5.37109 11.2489 5.37109C11.9543 5.37109 12.5057 5.61816 12.9032 6.1123C13.3042 6.60286 13.5047 7.26172 13.5047 8.08887C13.5047 9.00911 13.2809 9.74674 12.8333 10.3018C12.3857 10.8532 11.7734 11.1289 10.9964 11.1289C10.2695 11.1289 9.71989 10.821 9.3475 10.2051ZM9.32601 7.98682V8.75488C9.32601 9.20964 9.47282 9.59635 9.76644 9.91504C10.0636 10.2301 10.4396 10.3877 10.8944 10.3877C11.4279 10.3877 11.8451 10.1836 12.1458 9.77539C12.4502 9.36719 12.6024 8.79964 12.6024 8.07275C12.6024 7.46045 12.4609 6.98063 12.1781 6.6333C11.8952 6.28597 11.512 6.1123 11.0286 6.1123C10.5166 6.1123 10.1048 6.29134 9.7933 6.64941C9.48177 7.00391 9.32601 7.44971 9.32601 7.98682Z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-eye\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"d\": \"M7.99993 6.00316C9.47266 6.00316 10.6666 7.19708 10.6666 8.66981C10.6666 10.1426 9.47266 11.3365 7.99993 11.3365C6.52715 11.3365 5.33324 10.1426 5.33324 8.66981C5.33324 7.19708 6.52715 6.00316 7.99993 6.00316ZM7.99993 7.00315C7.07946 7.00315 6.33324 7.74935 6.33324 8.66981C6.33324 9.59028 7.07946 10.3365 7.99993 10.3365C8.9204 10.3365 9.6666 9.59028 9.6666 8.66981C9.6666 7.74935 8.9204 7.00315 7.99993 7.00315ZM7.99993 3.66675C11.0756 3.66675 13.7307 5.76675 14.4673 8.70968C14.5344 8.97755 14.3716 9.24908 14.1037 9.31615C13.8358 9.38315 13.5643 9.22041 13.4973 8.95248C12.8713 6.45205 10.6141 4.66675 7.99993 4.66675C5.38454 4.66675 3.12664 6.45359 2.50182 8.95555C2.43491 9.22341 2.16348 9.38635 1.89557 9.31948C1.62766 9.25255 1.46471 8.98115 1.53162 8.71321C2.26701 5.76856 4.9229 3.66675 7.99993 3.66675Z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-symbol-constant\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M4 6h8v1H4V6zm8 3H4v1h8V9z\" } }, { \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M1 4l1-1h12l1 1v8l-1 1H2l-1-1V4zm1 0v8h12V4H2z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-check\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M14.431 3.323l-8.47 10-.79-.036-3.35-4.77.818-.574 2.978 4.24 8.051-9.506.764.646z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-close\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M8 8.707l3.646 3.647.708-.707L8.707 8l3.647-3.646-.707-.708L8 7.293 4.354 3.646l-.707.708L7.293 8l-3.646 3.646.707.708L8 8.707z\" } }] }, { \"tagName\": \"clipPath\", \"attrs\": { \"width\": \"16\", \"height\": \"16\", \"viewBox\": \"0 0 16 16\", \"fill\": \"currentColor\", \"id\": \"icon-pass\" }, \"children\": [{ \"tagName\": \"path\", \"attrs\": { \"d\": \"M6.27 10.87h.71l4.56-4.56-.71-.71-4.2 4.21-1.92-1.92L4 8.6l2.27 2.27z\" } }, { \"tagName\": \"path\", \"attrs\": { \"fill-rule\": \"evenodd\", \"clip-rule\": \"evenodd\", \"d\": \"M8.6 1c1.6.1 3.1.9 4.2 2 1.3 1.4 2 3.1 2 5.1 0 1.6-.6 3.1-1.6 4.4-1 1.2-2.4 2.1-4 2.4-1.6.3-3.2.1-4.6-.7-1.4-.8-2.5-2-3.1-3.5C.9 9.2.8 7.5 1.3 6c.5-1.6 1.4-2.9 2.8-3.8C5.4 1.3 7 .9 8.6 1zm.5 12.9c1.3-.3 2.5-1 3.4-2.1.8-1.1 1.3-2.4 1.2-3.8 0-1.6-.6-3.2-1.7-4.3-1-1-2.2-1.6-3.6-1.7-1.3-.1-2.7.2-3.8 1-1.1.8-1.9 1.9-2.3 3.3-.4 1.3-.4 2.7.2 4 .6 1.3 1.5 2.3 2.7 3 1.2.7 2.6.9 3.9.6z\" } }] }] }] };\nvar clipPaths_default = svgJson;\n\n// packages/playwright-core/src/server/injected/recorder/recorder.ts\nvar NoneTool = class {\n cursor() {\n return \"default\";\n }\n};\nvar InspectTool = class {\n constructor(recorder, assertVisibility) {\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._hoveredSelectors = null;\n this._recorder = recorder;\n this._assertVisibility = assertVisibility;\n }\n cursor() {\n return \"pointer\";\n }\n cleanup() {\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._hoveredSelectors = null;\n }\n onClick(event) {\n var _a;\n consumeEvent(event);\n if (event.button !== 0)\n return;\n if ((_a = this._hoveredModel) == null ? void 0 : _a.selector)\n this._commit(this._hoveredModel.selector);\n }\n onContextMenu(event) {\n if (this._hoveredModel && !this._hoveredModel.tooltipListItemSelected && this._hoveredSelectors && this._hoveredSelectors.length > 1) {\n consumeEvent(event);\n const selectors = this._hoveredSelectors;\n this._hoveredModel.tooltipFooter = void 0;\n this._hoveredModel.tooltipList = selectors.map((selector) => this._recorder.injectedScript.utils.asLocator(this._recorder.state.language, selector));\n this._hoveredModel.tooltipListItemSelected = (index) => {\n if (index === void 0)\n this._reset(true);\n else\n this._commit(selectors[index]);\n };\n this._recorder.updateHighlight(this._hoveredModel, true);\n }\n }\n onPointerDown(event) {\n consumeEvent(event);\n }\n onPointerUp(event) {\n consumeEvent(event);\n }\n onMouseDown(event) {\n consumeEvent(event);\n }\n onMouseUp(event) {\n consumeEvent(event);\n }\n onMouseMove(event) {\n var _a;\n consumeEvent(event);\n let target = this._recorder.deepEventTarget(event);\n if (!target.isConnected)\n target = null;\n if (this._hoveredElement === target)\n return;\n this._hoveredElement = target;\n let model = null;\n let selectors = [];\n if (this._hoveredElement) {\n const generated = this._recorder.injectedScript.generateSelector(this._hoveredElement, { testIdAttributeName: this._recorder.state.testIdAttributeName, multiple: false });\n selectors = generated.selectors;\n model = {\n selector: generated.selector,\n elements: generated.elements,\n tooltipText: this._recorder.injectedScript.utils.asLocator(this._recorder.state.language, generated.selector),\n tooltipFooter: selectors.length > 1 ? `Click to select, right-click for more options` : void 0,\n color: this._assertVisibility ? \"#8acae480\" : void 0\n };\n }\n if (((_a = this._hoveredModel) == null ? void 0 : _a.selector) === (model == null ? void 0 : model.selector))\n return;\n this._hoveredModel = model;\n this._hoveredSelectors = selectors;\n this._recorder.updateHighlight(model, true);\n }\n onMouseEnter(event) {\n consumeEvent(event);\n }\n onMouseLeave(event) {\n consumeEvent(event);\n const window = this._recorder.injectedScript.window;\n if (window.top !== window && this._recorder.deepEventTarget(event).nodeType === Node.DOCUMENT_NODE)\n this._reset(true);\n }\n onKeyDown(event) {\n var _a;\n consumeEvent(event);\n if (event.key === \"Escape\") {\n if ((_a = this._hoveredModel) == null ? void 0 : _a.tooltipListItemSelected)\n this._reset(true);\n else if (this._assertVisibility)\n this._recorder.setMode(\"recording\");\n }\n }\n onKeyUp(event) {\n consumeEvent(event);\n }\n onScroll(event) {\n this._reset(false);\n }\n _commit(selector) {\n var _a;\n if (this._assertVisibility) {\n this._recorder.recordAction({\n name: \"assertVisible\",\n selector,\n signals: []\n });\n this._recorder.setMode(\"recording\");\n (_a = this._recorder.overlay) == null ? void 0 : _a.flashToolSucceeded(\"assertingVisibility\");\n } else {\n this._recorder.setSelector(selector);\n }\n }\n _reset(userGesture) {\n this._hoveredElement = null;\n this._hoveredModel = null;\n this._hoveredSelectors = null;\n this._recorder.updateHighlight(null, userGesture);\n }\n};\nvar RecordActionTool = class {\n constructor(recorder) {\n this._performingActions = /* @__PURE__ */ new Set();\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._activeModel = null;\n this._expectProgrammaticKeyUp = false;\n this._recorder = recorder;\n }\n cursor() {\n return \"pointer\";\n }\n cleanup() {\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._activeModel = null;\n this._expectProgrammaticKeyUp = false;\n }\n onClick(event) {\n if (isRangeInput(this._hoveredElement))\n return;\n if (event.button === 2 && event.type === \"auxclick\")\n return;\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (this._actionInProgress(event))\n return;\n if (this._consumedDueToNoModel(event, this._hoveredModel))\n return;\n const checkbox = asCheckbox(this._recorder.deepEventTarget(event));\n if (checkbox) {\n this._performAction({\n name: checkbox.checked ? \"check\" : \"uncheck\",\n selector: this._hoveredModel.selector,\n signals: []\n });\n return;\n }\n this._cancelPendingClickAction();\n if (event.detail === 1) {\n this._pendingClickAction = {\n action: {\n name: \"click\",\n selector: this._hoveredModel.selector,\n position: positionForEvent(event),\n signals: [],\n button: buttonForEvent(event),\n modifiers: modifiersForEvent(event),\n clickCount: event.detail\n },\n timeout: this._recorder.injectedScript.builtinSetTimeout(() => this._commitPendingClickAction(), 200)\n };\n }\n }\n onDblClick(event) {\n if (isRangeInput(this._hoveredElement))\n return;\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (this._actionInProgress(event))\n return;\n if (this._consumedDueToNoModel(event, this._hoveredModel))\n return;\n this._cancelPendingClickAction();\n this._performAction({\n name: \"click\",\n selector: this._hoveredModel.selector,\n position: positionForEvent(event),\n signals: [],\n button: buttonForEvent(event),\n modifiers: modifiersForEvent(event),\n clickCount: event.detail\n });\n }\n _commitPendingClickAction() {\n if (this._pendingClickAction)\n this._performAction(this._pendingClickAction.action);\n this._cancelPendingClickAction();\n }\n _cancelPendingClickAction() {\n if (this._pendingClickAction)\n clearTimeout(this._pendingClickAction.timeout);\n this._pendingClickAction = void 0;\n }\n onContextMenu(event) {\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (this._actionInProgress(event))\n return;\n if (this._consumedDueToNoModel(event, this._hoveredModel))\n return;\n this._performAction({\n name: \"click\",\n selector: this._hoveredModel.selector,\n position: positionForEvent(event),\n signals: [],\n button: \"right\",\n modifiers: 0,\n clickCount: 0\n });\n }\n onPointerDown(event) {\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (!this._performingActions.size)\n consumeEvent(event);\n }\n onPointerUp(event) {\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (!this._performingActions.size)\n consumeEvent(event);\n }\n onMouseDown(event) {\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (!this._performingActions.size)\n consumeEvent(event);\n this._activeModel = this._hoveredModel;\n }\n onMouseUp(event) {\n if (this._shouldIgnoreMouseEvent(event))\n return;\n if (!this._performingActions.size)\n consumeEvent(event);\n }\n onMouseMove(event) {\n const target = this._recorder.deepEventTarget(event);\n if (this._hoveredElement === target)\n return;\n this._hoveredElement = target;\n this._updateModelForHoveredElement();\n }\n onMouseLeave(event) {\n const window = this._recorder.injectedScript.window;\n if (window.top !== window && this._recorder.deepEventTarget(event).nodeType === Node.DOCUMENT_NODE) {\n this._hoveredElement = null;\n this._updateModelForHoveredElement();\n }\n }\n onFocus(event) {\n this._onFocus(true);\n }\n onInput(event) {\n const target = this._recorder.deepEventTarget(event);\n if (target.nodeName === \"INPUT\" && target.type.toLowerCase() === \"file\") {\n this._recorder.recordAction({\n name: \"setInputFiles\",\n selector: this._activeModel.selector,\n signals: [],\n files: [...target.files || []].map((file) => file.name)\n });\n return;\n }\n if (isRangeInput(target)) {\n this._recorder.recordAction({\n name: \"fill\",\n // must use hoveredModel instead of activeModel for it to work in webkit\n selector: this._hoveredModel.selector,\n signals: [],\n text: target.value\n });\n return;\n }\n if ([\"INPUT\", \"TEXTAREA\"].includes(target.nodeName) || target.isContentEditable) {\n if (target.nodeName === \"INPUT\" && [\"checkbox\", \"radio\"].includes(target.type.toLowerCase())) {\n return;\n }\n if (this._consumedDueWrongTarget(event))\n return;\n this._recorder.recordAction({\n name: \"fill\",\n selector: this._activeModel.selector,\n signals: [],\n text: target.isContentEditable ? target.innerText : target.value\n });\n }\n if (target.nodeName === \"SELECT\") {\n const selectElement = target;\n if (this._actionInProgress(event))\n return;\n this._performAction({\n name: \"select\",\n selector: this._activeModel.selector,\n options: [...selectElement.selectedOptions].map((option) => option.value),\n signals: []\n });\n }\n }\n onKeyDown(event) {\n if (!this._shouldGenerateKeyPressFor(event))\n return;\n if (this._actionInProgress(event)) {\n this._expectProgrammaticKeyUp = true;\n return;\n }\n if (this._consumedDueWrongTarget(event))\n return;\n if (event.key === \" \") {\n const checkbox = asCheckbox(this._recorder.deepEventTarget(event));\n if (checkbox) {\n this._performAction({\n name: checkbox.checked ? \"uncheck\" : \"check\",\n selector: this._activeModel.selector,\n signals: []\n });\n return;\n }\n }\n this._performAction({\n name: \"press\",\n selector: this._activeModel.selector,\n signals: [],\n key: event.key,\n modifiers: modifiersForEvent(event)\n });\n }\n onKeyUp(event) {\n if (!this._shouldGenerateKeyPressFor(event))\n return;\n if (!this._expectProgrammaticKeyUp) {\n consumeEvent(event);\n return;\n }\n this._expectProgrammaticKeyUp = false;\n }\n onScroll(event) {\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._recorder.updateHighlight(null, false);\n }\n _onFocus(userGesture) {\n const activeElement = deepActiveElement(this._recorder.document);\n if (userGesture && activeElement === this._recorder.document.body)\n return;\n const result = activeElement ? this._recorder.injectedScript.generateSelector(activeElement, { testIdAttributeName: this._recorder.state.testIdAttributeName }) : null;\n this._activeModel = result && result.selector ? result : null;\n if (userGesture)\n this._hoveredElement = activeElement;\n this._updateModelForHoveredElement();\n }\n _shouldIgnoreMouseEvent(event) {\n const target = this._recorder.deepEventTarget(event);\n const nodeName = target.nodeName;\n if (nodeName === \"SELECT\" || nodeName === \"OPTION\")\n return true;\n if (nodeName === \"INPUT\" && [\"date\", \"range\"].includes(target.type))\n return true;\n return false;\n }\n _actionInProgress(event) {\n const isKeyEvent = event instanceof KeyboardEvent;\n const isMouseOrPointerEvent = event instanceof MouseEvent || event instanceof PointerEvent;\n for (const action of this._performingActions) {\n if (isKeyEvent && action.name === \"press\" && event.key === action.key)\n return true;\n if (isMouseOrPointerEvent && (action.name === \"click\" || action.name === \"check\" || action.name === \"uncheck\"))\n return true;\n }\n consumeEvent(event);\n return false;\n }\n _consumedDueToNoModel(event, model) {\n if (model)\n return false;\n consumeEvent(event);\n return true;\n }\n _consumedDueWrongTarget(event) {\n if (this._activeModel && this._activeModel.elements[0] === this._recorder.deepEventTarget(event))\n return false;\n consumeEvent(event);\n return true;\n }\n _performAction(action) {\n this._hoveredElement = null;\n this._hoveredModel = null;\n this._activeModel = null;\n this._recorder.updateHighlight(null, false);\n this._performingActions.add(action);\n void this._recorder.performAction(action).then(() => {\n this._performingActions.delete(action);\n this._onFocus(false);\n if (this._recorder.injectedScript.isUnderTest) {\n console.error(\"Action performed for test: \" + JSON.stringify({\n // eslint-disable-line no-console\n hovered: this._hoveredModel ? this._hoveredModel.selector : null,\n active: this._activeModel ? this._activeModel.selector : null\n }));\n }\n });\n }\n _shouldGenerateKeyPressFor(event) {\n if (event.key === \"Enter\" && (this._recorder.deepEventTarget(event).nodeName === \"TEXTAREA\" || this._recorder.deepEventTarget(event).isContentEditable))\n return false;\n if ([\"Backspace\", \"Delete\", \"AltGraph\"].includes(event.key))\n return false;\n if (event.key === \"@\" && event.code === \"KeyL\")\n return false;\n if (navigator.platform.includes(\"Mac\")) {\n if (event.key === \"v\" && event.metaKey)\n return false;\n } else {\n if (event.key === \"v\" && event.ctrlKey)\n return false;\n if (event.key === \"Insert\" && event.shiftKey)\n return false;\n }\n if ([\"Shift\", \"Control\", \"Meta\", \"Alt\", \"Process\"].includes(event.key))\n return false;\n const hasModifier = event.ctrlKey || event.altKey || event.metaKey;\n if (event.key.length === 1 && !hasModifier)\n return !!asCheckbox(this._recorder.deepEventTarget(event));\n return true;\n }\n _updateModelForHoveredElement() {\n if (!this._hoveredElement || !this._hoveredElement.isConnected) {\n this._hoveredModel = null;\n this._hoveredElement = null;\n this._recorder.updateHighlight(null, true);\n return;\n }\n const { selector, elements } = this._recorder.injectedScript.generateSelector(this._hoveredElement, { testIdAttributeName: this._recorder.state.testIdAttributeName });\n if (this._hoveredModel && this._hoveredModel.selector === selector)\n return;\n this._hoveredModel = selector ? { selector, elements, color: \"#dc6f6f7f\" } : null;\n this._recorder.updateHighlight(this._hoveredModel, true);\n }\n};\nvar TextAssertionTool = class {\n constructor(recorder, kind) {\n this._hoverHighlight = null;\n this._action = null;\n this._textCache = /* @__PURE__ */ new Map();\n this._recorder = recorder;\n this._kind = kind;\n this._dialog = new Dialog(recorder);\n }\n cursor() {\n return \"pointer\";\n }\n cleanup() {\n this._dialog.close();\n this._hoverHighlight = null;\n }\n onClick(event) {\n consumeEvent(event);\n if (this._kind === \"value\") {\n this._commitAssertValue();\n } else {\n if (!this._dialog.isShowing())\n this._showDialog();\n }\n }\n onMouseDown(event) {\n const target = this._recorder.deepEventTarget(event);\n if (this._elementHasValue(target))\n event.preventDefault();\n }\n onPointerUp(event) {\n var _a;\n const target = (_a = this._hoverHighlight) == null ? void 0 : _a.elements[0];\n if (this._kind === \"value\" && target && (target.nodeName === \"INPUT\" || target.nodeName === \"SELECT\") && target.disabled) {\n this._commitAssertValue();\n }\n }\n onMouseMove(event) {\n var _a;\n if (this._dialog.isShowing())\n return;\n const target = this._recorder.deepEventTarget(event);\n if (((_a = this._hoverHighlight) == null ? void 0 : _a.elements[0]) === target)\n return;\n if (this._kind === \"text\")\n this._hoverHighlight = this._recorder.injectedScript.utils.elementText(this._textCache, target).full ? { elements: [target], selector: \"\" } : null;\n else\n this._hoverHighlight = this._elementHasValue(target) ? this._recorder.injectedScript.generateSelector(target, { testIdAttributeName: this._recorder.state.testIdAttributeName }) : null;\n if (this._hoverHighlight)\n this._hoverHighlight.color = \"#8acae480\";\n this._recorder.updateHighlight(this._hoverHighlight, true);\n }\n onKeyDown(event) {\n if (event.key === \"Escape\")\n this._recorder.setMode(\"recording\");\n consumeEvent(event);\n }\n onScroll(event) {\n this._recorder.updateHighlight(this._hoverHighlight, false);\n }\n _elementHasValue(element) {\n return element.nodeName === \"TEXTAREA\" || element.nodeName === \"SELECT\" || element.nodeName === \"INPUT\" && ![\"button\", \"image\", \"reset\", \"submit\"].includes(element.type);\n }\n _generateAction() {\n var _a;\n this._textCache.clear();\n const target = (_a = this._hoverHighlight) == null ? void 0 : _a.elements[0];\n if (!target)\n return null;\n if (this._kind === \"value\") {\n if (!this._elementHasValue(target))\n return null;\n const { selector } = this._recorder.injectedScript.generateSelector(target, { testIdAttributeName: this._recorder.state.testIdAttributeName });\n if (target.nodeName === \"INPUT\" && [\"checkbox\", \"radio\"].includes(target.type.toLowerCase())) {\n return {\n name: \"assertChecked\",\n selector,\n signals: [],\n // Interestingly, inputElement.checked is reversed inside this event handler.\n checked: !target.checked\n };\n } else {\n return {\n name: \"assertValue\",\n selector,\n signals: [],\n value: target.value\n };\n }\n } else {\n this._hoverHighlight = this._recorder.injectedScript.generateSelector(target, { testIdAttributeName: this._recorder.state.testIdAttributeName, forTextExpect: true });\n this._hoverHighlight.color = \"#8acae480\";\n this._recorder.updateHighlight(this._hoverHighlight, true);\n return {\n name: \"assertText\",\n selector: this._hoverHighlight.selector,\n signals: [],\n text: this._recorder.injectedScript.utils.elementText(this._textCache, target).normalized,\n substring: true\n };\n }\n }\n _renderValue(action) {\n if ((action == null ? void 0 : action.name) === \"assertText\")\n return this._recorder.injectedScript.utils.normalizeWhiteSpace(action.text);\n if ((action == null ? void 0 : action.name) === \"assertChecked\")\n return String(action.checked);\n if ((action == null ? void 0 : action.name) === \"assertValue\")\n return action.value;\n return \"\";\n }\n _commit() {\n if (!this._action || !this._dialog.isShowing())\n return;\n this._dialog.close();\n this._recorder.recordAction(this._action);\n this._recorder.setMode(\"recording\");\n }\n _showDialog() {\n var _a;\n if (!((_a = this._hoverHighlight) == null ? void 0 : _a.elements[0]))\n return;\n this._action = this._generateAction();\n if (!this._action || this._action.name !== \"assertText\")\n return;\n const action = this._action;\n const textElement = this._recorder.document.createElement(\"textarea\");\n textElement.setAttribute(\"spellcheck\", \"false\");\n textElement.value = this._renderValue(this._action);\n textElement.classList.add(\"text-editor\");\n const updateAndValidate = () => {\n var _a2;\n const newValue = this._recorder.injectedScript.utils.normalizeWhiteSpace(textElement.value);\n const target = (_a2 = this._hoverHighlight) == null ? void 0 : _a2.elements[0];\n if (!target)\n return;\n action.text = newValue;\n const targetText = this._recorder.injectedScript.utils.elementText(this._textCache, target).normalized;\n const matches = newValue && targetText.includes(newValue);\n textElement.classList.toggle(\"does-not-match\", !matches);\n };\n textElement.addEventListener(\"input\", updateAndValidate);\n const label = \"Assert that element contains text\";\n const dialogElement = this._dialog.show({\n label,\n body: textElement,\n onCommit: () => this._commit()\n });\n const position = this._recorder.highlight.tooltipPosition(this._recorder.highlight.firstBox(), dialogElement);\n this._dialog.moveTo(position.anchorTop, position.anchorLeft);\n textElement.focus();\n }\n _commitAssertValue() {\n var _a;\n if (this._kind !== \"value\")\n return;\n const action = this._generateAction();\n if (!action)\n return;\n this._recorder.recordAction(action);\n this._recorder.setMode(\"recording\");\n (_a = this._recorder.overlay) == null ? void 0 : _a.flashToolSucceeded(\"assertingValue\");\n }\n};\nvar Overlay = class {\n constructor(recorder) {\n this._listeners = [];\n this._offsetX = 0;\n this._measure = { width: 0, height: 0 };\n this._recorder = recorder;\n const document = this._recorder.document;\n this._overlayElement = document.createElement(\"x-pw-overlay\");\n this._overlayElement.appendChild(createSvgElement(this._recorder.document, clipPaths_default));\n const toolsListElement = document.createElement(\"x-pw-tools-list\");\n this._overlayElement.appendChild(toolsListElement);\n this._dragHandle = document.createElement(\"x-pw-tool-gripper\");\n this._dragHandle.appendChild(document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._dragHandle);\n this._recordToggle = this._recorder.document.createElement(\"x-pw-tool-item\");\n this._recordToggle.title = \"Record\";\n this._recordToggle.classList.add(\"record\");\n this._recordToggle.appendChild(this._recorder.document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._recordToggle);\n this._pickLocatorToggle = this._recorder.document.createElement(\"x-pw-tool-item\");\n this._pickLocatorToggle.title = \"Pick locator\";\n this._pickLocatorToggle.classList.add(\"pick-locator\");\n this._pickLocatorToggle.appendChild(this._recorder.document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._pickLocatorToggle);\n this._assertVisibilityToggle = this._recorder.document.createElement(\"x-pw-tool-item\");\n this._assertVisibilityToggle.title = \"Assert visibility\";\n this._assertVisibilityToggle.classList.add(\"visibility\");\n this._assertVisibilityToggle.appendChild(this._recorder.document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._assertVisibilityToggle);\n this._assertTextToggle = this._recorder.document.createElement(\"x-pw-tool-item\");\n this._assertTextToggle.title = \"Assert text\";\n this._assertTextToggle.classList.add(\"text\");\n this._assertTextToggle.appendChild(this._recorder.document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._assertTextToggle);\n this._assertValuesToggle = this._recorder.document.createElement(\"x-pw-tool-item\");\n this._assertValuesToggle.title = \"Assert value\";\n this._assertValuesToggle.classList.add(\"value\");\n this._assertValuesToggle.appendChild(this._recorder.document.createElement(\"x-div\"));\n toolsListElement.appendChild(this._assertValuesToggle);\n this._updateVisualPosition();\n this._refreshListeners();\n }\n _refreshListeners() {\n removeEventListeners(this._listeners);\n this._listeners = [\n addEventListener(this._dragHandle, \"mousedown\", (event) => {\n this._dragState = { offsetX: this._offsetX, dragStart: { x: event.clientX, y: 0 } };\n }),\n addEventListener(this._recordToggle, \"click\", () => {\n this._recorder.setMode(this._recorder.state.mode === \"none\" || this._recorder.state.mode === \"standby\" || this._recorder.state.mode === \"inspecting\" ? \"recording\" : \"standby\");\n }),\n addEventListener(this._pickLocatorToggle, \"click\", () => {\n const newMode = {\n \"inspecting\": \"standby\",\n \"none\": \"inspecting\",\n \"standby\": \"inspecting\",\n \"recording\": \"recording-inspecting\",\n \"recording-inspecting\": \"recording\",\n \"assertingText\": \"recording-inspecting\",\n \"assertingVisibility\": \"recording-inspecting\",\n \"assertingValue\": \"recording-inspecting\"\n };\n this._recorder.setMode(newMode[this._recorder.state.mode]);\n }),\n addEventListener(this._assertVisibilityToggle, \"click\", () => {\n if (!this._assertVisibilityToggle.classList.contains(\"disabled\"))\n this._recorder.setMode(this._recorder.state.mode === \"assertingVisibility\" ? \"recording\" : \"assertingVisibility\");\n }),\n addEventListener(this._assertTextToggle, \"click\", () => {\n if (!this._assertTextToggle.classList.contains(\"disabled\"))\n this._recorder.setMode(this._recorder.state.mode === \"assertingText\" ? \"recording\" : \"assertingText\");\n }),\n addEventListener(this._assertValuesToggle, \"click\", () => {\n if (!this._assertValuesToggle.classList.contains(\"disabled\"))\n this._recorder.setMode(this._recorder.state.mode === \"assertingValue\" ? \"recording\" : \"assertingValue\");\n })\n ];\n }\n install() {\n this._recorder.highlight.appendChild(this._overlayElement);\n this._refreshListeners();\n this._updateVisualPosition();\n }\n contains(element) {\n return this._recorder.injectedScript.utils.isInsideScope(this._overlayElement, element);\n }\n setUIState(state) {\n this._recordToggle.classList.toggle(\"active\", state.mode === \"recording\" || state.mode === \"assertingText\" || state.mode === \"assertingVisibility\" || state.mode === \"assertingValue\" || state.mode === \"recording-inspecting\");\n this._pickLocatorToggle.classList.toggle(\"active\", state.mode === \"inspecting\" || state.mode === \"recording-inspecting\");\n this._assertVisibilityToggle.classList.toggle(\"active\", state.mode === \"assertingVisibility\");\n this._assertVisibilityToggle.classList.toggle(\"disabled\", state.mode === \"none\" || state.mode === \"standby\" || state.mode === \"inspecting\");\n this._assertTextToggle.classList.toggle(\"active\", state.mode === \"assertingText\");\n this._assertTextToggle.classList.toggle(\"disabled\", state.mode === \"none\" || state.mode === \"standby\" || state.mode === \"inspecting\");\n this._assertValuesToggle.classList.toggle(\"active\", state.mode === \"assertingValue\");\n this._assertValuesToggle.classList.toggle(\"disabled\", state.mode === \"none\" || state.mode === \"standby\" || state.mode === \"inspecting\");\n if (this._offsetX !== state.overlay.offsetX) {\n this._offsetX = state.overlay.offsetX;\n this._updateVisualPosition();\n }\n if (state.mode === \"none\")\n this._hideOverlay();\n else\n this._showOverlay();\n }\n flashToolSucceeded(tool) {\n const element = tool === \"assertingVisibility\" ? this._assertVisibilityToggle : this._assertValuesToggle;\n element.classList.add(\"succeeded\");\n this._recorder.injectedScript.builtinSetTimeout(() => element.classList.remove(\"succeeded\"), 2e3);\n }\n _hideOverlay() {\n this._overlayElement.setAttribute(\"hidden\", \"true\");\n }\n _showOverlay() {\n if (!this._overlayElement.hasAttribute(\"hidden\"))\n return;\n this._overlayElement.removeAttribute(\"hidden\");\n this._updateVisualPosition();\n }\n _updateVisualPosition() {\n this._measure = this._overlayElement.getBoundingClientRect();\n this._overlayElement.style.left = (this._recorder.injectedScript.window.innerWidth - this._measure.width) / 2 + this._offsetX + \"px\";\n }\n onMouseMove(event) {\n if (!event.buttons) {\n this._dragState = void 0;\n return false;\n }\n if (this._dragState) {\n this._offsetX = this._dragState.offsetX + event.clientX - this._dragState.dragStart.x;\n const halfGapSize = (this._recorder.injectedScript.window.innerWidth - this._measure.width) / 2 - 10;\n this._offsetX = Math.max(-halfGapSize, Math.min(halfGapSize, this._offsetX));\n this._updateVisualPosition();\n this._recorder.setOverlayState({ offsetX: this._offsetX });\n consumeEvent(event);\n return true;\n }\n return false;\n }\n onMouseUp(event) {\n if (this._dragState) {\n consumeEvent(event);\n return true;\n }\n return false;\n }\n onClick(event) {\n if (this._dragState) {\n this._dragState = void 0;\n consumeEvent(event);\n return true;\n }\n return false;\n }\n onDblClick(event) {\n return false;\n }\n};\nvar Recorder = class {\n constructor(injectedScript) {\n this._listeners = [];\n this._actionSelectorModel = null;\n this.state = {\n mode: \"none\",\n testIdAttributeName: \"data-testid\",\n language: \"javascript\",\n overlay: { offsetX: 0 }\n };\n this._delegate = {};\n this.document = injectedScript.document;\n this.injectedScript = injectedScript;\n this.highlight = injectedScript.createHighlight();\n this._tools = {\n \"none\": new NoneTool(),\n \"standby\": new NoneTool(),\n \"inspecting\": new InspectTool(this, false),\n \"recording\": new RecordActionTool(this),\n \"recording-inspecting\": new InspectTool(this, false),\n \"assertingText\": new TextAssertionTool(this, \"text\"),\n \"assertingVisibility\": new InspectTool(this, true),\n \"assertingValue\": new TextAssertionTool(this, \"value\")\n };\n this._currentTool = this._tools.none;\n if (injectedScript.window.top === injectedScript.window) {\n this.overlay = new Overlay(this);\n this.overlay.setUIState(this.state);\n }\n this._stylesheet = new injectedScript.window.CSSStyleSheet();\n this._stylesheet.replaceSync(`\n body[data-pw-cursor=pointer] *, body[data-pw-cursor=pointer] *::after { cursor: pointer !important; }\n body[data-pw-cursor=text] *, body[data-pw-cursor=text] *::after { cursor: text !important; }\n `);\n this.installListeners();\n injectedScript.utils.cacheNormalizedWhitespaces();\n if (injectedScript.isUnderTest)\n console.error(\"Recorder script ready for test\");\n }\n installListeners() {\n var _a;\n removeEventListeners(this._listeners);\n this._listeners = [\n addEventListener(this.document, \"click\", (event) => this._onClick(event), true),\n addEventListener(this.document, \"auxclick\", (event) => this._onClick(event), true),\n addEventListener(this.document, \"dblclick\", (event) => this._onDblClick(event), true),\n addEventListener(this.document, \"contextmenu\", (event) => this._onContextMenu(event), true),\n addEventListener(this.document, \"dragstart\", (event) => this._onDragStart(event), true),\n addEventListener(this.document, \"input\", (event) => this._onInput(event), true),\n addEventListener(this.document, \"keydown\", (event) => this._onKeyDown(event), true),\n addEventListener(this.document, \"keyup\", (event) => this._onKeyUp(event), true),\n addEventListener(this.document, \"pointerdown\", (event) => this._onPointerDown(event), true),\n addEventListener(this.document, \"pointerup\", (event) => this._onPointerUp(event), true),\n addEventListener(this.document, \"mousedown\", (event) => this._onMouseDown(event), true),\n addEventListener(this.document, \"mouseup\", (event) => this._onMouseUp(event), true),\n addEventListener(this.document, \"mousemove\", (event) => this._onMouseMove(event), true),\n addEventListener(this.document, \"mouseleave\", (event) => this._onMouseLeave(event), true),\n addEventListener(this.document, \"mouseenter\", (event) => this._onMouseEnter(event), true),\n addEventListener(this.document, \"focus\", (event) => this._onFocus(event), true),\n addEventListener(this.document, \"scroll\", (event) => this._onScroll(event), true)\n ];\n this.highlight.install();\n let recreationInterval;\n const recreate = () => {\n this.highlight.install();\n recreationInterval = this.injectedScript.builtinSetTimeout(recreate, 500);\n };\n recreationInterval = this.injectedScript.builtinSetTimeout(recreate, 500);\n this._listeners.push(() => this.injectedScript.builtinClearTimeout(recreationInterval));\n (_a = this.overlay) == null ? void 0 : _a.install();\n this.document.adoptedStyleSheets.push(this._stylesheet);\n }\n _switchCurrentTool() {\n var _a, _b, _c;\n const newTool = this._tools[this.state.mode];\n if (newTool === this._currentTool)\n return;\n (_b = (_a = this._currentTool).cleanup) == null ? void 0 : _b.call(_a);\n this.clearHighlight();\n this._currentTool = newTool;\n (_c = this.injectedScript.document.body) == null ? void 0 : _c.setAttribute(\"data-pw-cursor\", newTool.cursor());\n }\n setUIState(state, delegate) {\n var _a, _b, _c, _d;\n this._delegate = delegate;\n if (state.actionPoint && this.state.actionPoint && state.actionPoint.x === this.state.actionPoint.x && state.actionPoint.y === this.state.actionPoint.y) {\n } else if (!state.actionPoint && !this.state.actionPoint) {\n } else {\n if (state.actionPoint)\n this.highlight.showActionPoint(state.actionPoint.x, state.actionPoint.y);\n else\n this.highlight.hideActionPoint();\n }\n this.state = state;\n this.highlight.setLanguage(state.language);\n this._switchCurrentTool();\n (_a = this.overlay) == null ? void 0 : _a.setUIState(state);\n if (((_b = this._actionSelectorModel) == null ? void 0 : _b.selector) && !((_c = this._actionSelectorModel) == null ? void 0 : _c.elements.length))\n this._actionSelectorModel = null;\n if (state.actionSelector !== ((_d = this._actionSelectorModel) == null ? void 0 : _d.selector))\n this._actionSelectorModel = state.actionSelector ? querySelector(this.injectedScript, state.actionSelector, this.document) : null;\n if (this.state.mode === \"none\" || this.state.mode === \"standby\")\n this.updateHighlight(this._actionSelectorModel, false);\n }\n clearHighlight() {\n var _a, _b;\n (_b = (_a = this._currentTool).cleanup) == null ? void 0 : _b.call(_a);\n this.updateHighlight(null, false);\n }\n _onClick(event) {\n var _a, _b, _c;\n if (!event.isTrusted)\n return;\n if ((_a = this.overlay) == null ? void 0 : _a.onClick(event))\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_c = (_b = this._currentTool).onClick) == null ? void 0 : _c.call(_b, event);\n }\n _onDblClick(event) {\n var _a, _b, _c;\n if (!event.isTrusted)\n return;\n if ((_a = this.overlay) == null ? void 0 : _a.onDblClick(event))\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_c = (_b = this._currentTool).onDblClick) == null ? void 0 : _c.call(_b, event);\n }\n _onContextMenu(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onContextMenu) == null ? void 0 : _b.call(_a, event);\n }\n _onDragStart(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onDragStart) == null ? void 0 : _b.call(_a, event);\n }\n _onPointerDown(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onPointerDown) == null ? void 0 : _b.call(_a, event);\n }\n _onPointerUp(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onPointerUp) == null ? void 0 : _b.call(_a, event);\n }\n _onMouseDown(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onMouseDown) == null ? void 0 : _b.call(_a, event);\n }\n _onMouseUp(event) {\n var _a, _b, _c;\n if (!event.isTrusted)\n return;\n if ((_a = this.overlay) == null ? void 0 : _a.onMouseUp(event))\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_c = (_b = this._currentTool).onMouseUp) == null ? void 0 : _c.call(_b, event);\n }\n _onMouseMove(event) {\n var _a, _b, _c;\n if (!event.isTrusted)\n return;\n if ((_a = this.overlay) == null ? void 0 : _a.onMouseMove(event))\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_c = (_b = this._currentTool).onMouseMove) == null ? void 0 : _c.call(_b, event);\n }\n _onMouseEnter(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onMouseEnter) == null ? void 0 : _b.call(_a, event);\n }\n _onMouseLeave(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onMouseLeave) == null ? void 0 : _b.call(_a, event);\n }\n _onFocus(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onFocus) == null ? void 0 : _b.call(_a, event);\n }\n _onScroll(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n this.highlight.hideActionPoint();\n (_b = (_a = this._currentTool).onScroll) == null ? void 0 : _b.call(_a, event);\n }\n _onInput(event) {\n var _a, _b;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onInput) == null ? void 0 : _b.call(_a, event);\n }\n _onKeyDown(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onKeyDown) == null ? void 0 : _b.call(_a, event);\n }\n _onKeyUp(event) {\n var _a, _b;\n if (!event.isTrusted)\n return;\n if (this._ignoreOverlayEvent(event))\n return;\n (_b = (_a = this._currentTool).onKeyUp) == null ? void 0 : _b.call(_a, event);\n }\n updateHighlight(model, userGesture) {\n var _a, _b;\n let tooltipText = model == null ? void 0 : model.tooltipText;\n if (tooltipText === void 0 && !(model == null ? void 0 : model.tooltipList) && (model == null ? void 0 : model.selector))\n tooltipText = this.injectedScript.utils.asLocator(this.state.language, model.selector);\n this.highlight.updateHighlight((model == null ? void 0 : model.elements) || [], { ...model, tooltipText });\n if (userGesture)\n (_b = (_a = this._delegate).highlightUpdated) == null ? void 0 : _b.call(_a);\n }\n _ignoreOverlayEvent(event) {\n return event.composedPath().some((e) => {\n const nodeName = e.nodeName || \"\";\n return nodeName.toLowerCase() === \"x-pw-glass\";\n });\n }\n deepEventTarget(event) {\n var _a;\n for (const element of event.composedPath()) {\n if (!((_a = this.overlay) == null ? void 0 : _a.contains(element)))\n return element;\n }\n return event.composedPath()[0];\n }\n setMode(mode) {\n var _a, _b;\n void ((_b = (_a = this._delegate).setMode) == null ? void 0 : _b.call(_a, mode));\n }\n async performAction(action) {\n var _a, _b;\n await ((_b = (_a = this._delegate).performAction) == null ? void 0 : _b.call(_a, action).catch(() => {\n }));\n }\n recordAction(action) {\n var _a, _b;\n void ((_b = (_a = this._delegate).recordAction) == null ? void 0 : _b.call(_a, action));\n }\n setOverlayState(state) {\n var _a, _b;\n void ((_b = (_a = this._delegate).setOverlayState) == null ? void 0 : _b.call(_a, state));\n }\n setSelector(selector) {\n var _a, _b;\n void ((_b = (_a = this._delegate).setSelector) == null ? void 0 : _b.call(_a, selector));\n }\n};\nvar Dialog = class {\n constructor(recorder) {\n this._dialogElement = null;\n this._recorder = recorder;\n }\n isShowing() {\n return !!this._dialogElement;\n }\n show(options) {\n const acceptButton = this._recorder.document.createElement(\"x-pw-tool-item\");\n acceptButton.title = \"Accept\";\n acceptButton.classList.add(\"accept\");\n acceptButton.appendChild(this._recorder.document.createElement(\"x-div\"));\n acceptButton.addEventListener(\"click\", () => options.onCommit());\n const cancelButton = this._recorder.document.createElement(\"x-pw-tool-item\");\n cancelButton.title = \"Close\";\n cancelButton.classList.add(\"cancel\");\n cancelButton.appendChild(this._recorder.document.createElement(\"x-div\"));\n cancelButton.addEventListener(\"click\", () => {\n var _a;\n this.close();\n (_a = options.onCancel) == null ? void 0 : _a.call(options);\n });\n this._dialogElement = this._recorder.document.createElement(\"x-pw-dialog\");\n this._keyboardListener = (event) => {\n var _a;\n if (event.key === \"Escape\") {\n this.close();\n (_a = options.onCancel) == null ? void 0 : _a.call(options);\n return;\n }\n if (event.key === \"Enter\" && (event.ctrlKey || event.metaKey)) {\n if (this._dialogElement)\n options.onCommit();\n return;\n }\n };\n this._recorder.document.addEventListener(\"keydown\", this._keyboardListener, true);\n const toolbarElement = this._recorder.document.createElement(\"x-pw-tools-list\");\n const labelElement = this._recorder.document.createElement(\"label\");\n labelElement.textContent = options.label;\n toolbarElement.appendChild(labelElement);\n toolbarElement.appendChild(this._recorder.document.createElement(\"x-spacer\"));\n toolbarElement.appendChild(acceptButton);\n toolbarElement.appendChild(cancelButton);\n this._dialogElement.appendChild(toolbarElement);\n const bodyElement = this._recorder.document.createElement(\"x-pw-dialog-body\");\n bodyElement.appendChild(options.body);\n this._dialogElement.appendChild(bodyElement);\n this._recorder.highlight.appendChild(this._dialogElement);\n return this._dialogElement;\n }\n moveTo(top, left) {\n if (!this._dialogElement)\n return;\n this._dialogElement.style.top = top + \"px\";\n this._dialogElement.style.left = left + \"px\";\n }\n close() {\n if (!this._dialogElement)\n return;\n this._dialogElement.remove();\n this._recorder.document.removeEventListener(\"keydown\", this._keyboardListener);\n this._dialogElement = null;\n }\n};\nfunction deepActiveElement(document) {\n let activeElement = document.activeElement;\n while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)\n activeElement = activeElement.shadowRoot.activeElement;\n return activeElement;\n}\nfunction modifiersForEvent(event) {\n return (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0);\n}\nfunction buttonForEvent(event) {\n switch (event.which) {\n case 1:\n return \"left\";\n case 2:\n return \"middle\";\n case 3:\n return \"right\";\n }\n return \"left\";\n}\nfunction positionForEvent(event) {\n const targetElement = event.target;\n if (targetElement.nodeName !== \"CANVAS\")\n return;\n return {\n x: event.offsetX,\n y: event.offsetY\n };\n}\nfunction consumeEvent(e) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n}\nfunction asCheckbox(node) {\n if (!node || node.nodeName !== \"INPUT\")\n return null;\n const inputElement = node;\n return [\"checkbox\", \"radio\"].includes(inputElement.type) ? inputElement : null;\n}\nfunction isRangeInput(node) {\n if (!node || node.nodeName !== \"INPUT\")\n return false;\n const inputElement = node;\n return inputElement.type.toLowerCase() === \"range\";\n}\nfunction addEventListener(target, eventName, listener, useCapture) {\n target.addEventListener(eventName, listener, useCapture);\n const remove = () => {\n target.removeEventListener(eventName, listener, useCapture);\n };\n return remove;\n}\nfunction removeEventListeners(listeners) {\n for (const listener of listeners)\n listener();\n listeners.splice(0, listeners.length);\n}\nfunction querySelector(injectedScript, selector, ownerDocument) {\n try {\n const parsedSelector = injectedScript.parseSelector(selector);\n return {\n selector,\n elements: injectedScript.querySelectorAll(parsedSelector, ownerDocument)\n };\n } catch (e) {\n return {\n selector,\n elements: []\n };\n }\n}\nfunction createSvgElement(doc, { tagName, attrs, children }) {\n const elem = doc.createElementNS(\"http://www.w3.org/2000/svg\", tagName);\n if (attrs) {\n for (const [k, v] of Object.entries(attrs))\n elem.setAttribute(k, v);\n }\n if (children) {\n for (const c of children)\n elem.appendChild(createSvgElement(doc, c));\n }\n return elem;\n}\n\n// packages/playwright-core/src/server/injected/recorder/pollingRecorder.ts\nvar PollingRecorder = class {\n constructor(injectedScript) {\n this._recorder = new Recorder(injectedScript);\n this._embedder = injectedScript.window;\n injectedScript.onGlobalListenersRemoved.add(() => this._recorder.installListeners());\n const refreshOverlay = () => {\n this._pollRecorderMode().catch((e) => console.log(e));\n };\n this._embedder.__pw_refreshOverlay = refreshOverlay;\n refreshOverlay();\n }\n async _pollRecorderMode() {\n const pollPeriod = 1e3;\n if (this._pollRecorderModeTimer)\n clearTimeout(this._pollRecorderModeTimer);\n const state = await this._embedder.__pw_recorderState().catch(() => {\n });\n if (!state) {\n this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);\n return;\n }\n const win = this._recorder.document.defaultView;\n if (win.top !== win) {\n state.actionPoint = void 0;\n }\n this._recorder.setUIState(state, this);\n this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);\n }\n async performAction(action) {\n await this._embedder.__pw_recorderPerformAction(action);\n }\n async recordAction(action) {\n await this._embedder.__pw_recorderRecordAction(action);\n }\n async setSelector(selector) {\n await this._embedder.__pw_recorderSetSelector(selector);\n }\n async setMode(mode) {\n await this._embedder.__pw_recorderSetMode(mode);\n }\n async setOverlayState(state) {\n await this._embedder.__pw_recorderSetOverlayState(state);\n }\n};\nvar pollingRecorder_default = PollingRecorder;\n";
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.source = void 0;
7
+ const source = exports.source = "\nvar __commonJS = obj => {\n let required = false;\n let result;\n return function __require() {\n if (!required) {\n required = true;\n let fn;\n for (const name in obj) { fn = obj[name]; break; }\n const module = { exports: {} };\n fn(module.exports, module);\n result = module.exports;\n }\n return result;\n }\n};\nvar __export = (target, all) => {for (var name in all) target[name] = all[name];};\nvar __toESM = mod => ({ ...mod, 'default': mod });\nvar __toCommonJS = mod => ({ ...mod, __esModule: true });\n\n\n// packages/playwright-core/src/server/injected/webSocketMock.ts\nvar webSocketMock_exports = {};\n__export(webSocketMock_exports, {\n inject: () => inject\n});\nmodule.exports = __toCommonJS(webSocketMock_exports);\nfunction inject(globalThis) {\n if (globalThis.__pwWebSocketDispatch)\n return;\n function generateId() {\n const bytes = new Uint8Array(32);\n globalThis.crypto.getRandomValues(bytes);\n const hex = \"0123456789abcdef\";\n return [...bytes].map((value) => {\n const high = Math.floor(value / 16);\n const low = value % 16;\n return hex[high] + hex[low];\n }).join(\"\");\n }\n function bufferToData(b) {\n let s = \"\";\n for (let i = 0; i < b.length; i++)\n s += String.fromCharCode(b[i]);\n return { data: globalThis.btoa(s), isBase64: true };\n }\n function stringToBuffer(s) {\n s = globalThis.atob(s);\n const b = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++)\n b[i] = s.charCodeAt(i);\n return b.buffer;\n }\n function messageToData(message, cb) {\n if (message instanceof globalThis.Blob)\n return message.arrayBuffer().then((buffer) => cb(bufferToData(new Uint8Array(buffer))));\n if (typeof message === \"string\")\n return cb({ data: message, isBase64: false });\n if (ArrayBuffer.isView(message))\n return cb(bufferToData(new Uint8Array(message.buffer, message.byteOffset, message.byteLength)));\n return cb(bufferToData(new Uint8Array(message)));\n }\n function dataToMessage(data, binaryType) {\n if (!data.isBase64)\n return data.data;\n const buffer = stringToBuffer(data.data);\n return binaryType === \"arraybuffer\" ? buffer : new Blob([buffer]);\n }\n const binding = globalThis.__pwWebSocketBinding;\n const NativeWebSocket = globalThis.WebSocket;\n const idToWebSocket = /* @__PURE__ */ new Map();\n globalThis.__pwWebSocketDispatch = (request) => {\n const ws = idToWebSocket.get(request.id);\n if (!ws)\n return;\n if (request.type === \"connect\")\n ws._apiConnect();\n if (request.type === \"passthrough\")\n ws._apiPassThrough();\n if (request.type === \"ensureOpened\")\n ws._apiEnsureOpened();\n if (request.type === \"sendToPage\")\n ws._apiSendToPage(dataToMessage(request.data, ws.binaryType));\n if (request.type === \"closePage\")\n ws._apiClosePage(request.code, request.reason, request.wasClean);\n if (request.type === \"sendToServer\")\n ws._apiSendToServer(dataToMessage(request.data, ws.binaryType));\n if (request.type === \"closeServer\")\n ws._apiCloseServer(request.code, request.reason, request.wasClean);\n };\n const _WebSocketMock = class _WebSocketMock extends EventTarget {\n constructor(url, protocols) {\n super();\n // WebSocket.CLOSED\n this.CONNECTING = 0;\n // WebSocket.CONNECTING\n this.OPEN = 1;\n // WebSocket.OPEN\n this.CLOSING = 2;\n // WebSocket.CLOSING\n this.CLOSED = 3;\n // WebSocket.CLOSED\n this._oncloseListener = null;\n this._onerrorListener = null;\n this._onmessageListener = null;\n this._onopenListener = null;\n this.bufferedAmount = 0;\n this.extensions = \"\";\n this.protocol = \"\";\n this.readyState = 0;\n this._origin = \"\";\n this._passthrough = false;\n this._wsBufferedMessages = [];\n this._binaryType = \"blob\";\n this.url = typeof url === \"string\" ? url : url.href;\n try {\n this.url = new URL(url).href;\n this._origin = new URL(url).origin;\n } catch {\n }\n this._protocols = protocols;\n this._id = generateId();\n idToWebSocket.set(this._id, this);\n binding({ type: \"onCreate\", id: this._id, url: this.url });\n }\n // --- native WebSocket implementation ---\n get binaryType() {\n return this._binaryType;\n }\n set binaryType(type) {\n this._binaryType = type;\n if (this._ws)\n this._ws.binaryType = type;\n }\n get onclose() {\n return this._oncloseListener;\n }\n set onclose(listener) {\n if (this._oncloseListener)\n this.removeEventListener(\"close\", this._oncloseListener);\n this._oncloseListener = listener;\n if (this._oncloseListener)\n this.addEventListener(\"close\", this._oncloseListener);\n }\n get onerror() {\n return this._onerrorListener;\n }\n set onerror(listener) {\n if (this._onerrorListener)\n this.removeEventListener(\"error\", this._onerrorListener);\n this._onerrorListener = listener;\n if (this._onerrorListener)\n this.addEventListener(\"error\", this._onerrorListener);\n }\n get onopen() {\n return this._onopenListener;\n }\n set onopen(listener) {\n if (this._onopenListener)\n this.removeEventListener(\"open\", this._onopenListener);\n this._onopenListener = listener;\n if (this._onopenListener)\n this.addEventListener(\"open\", this._onopenListener);\n }\n get onmessage() {\n return this._onmessageListener;\n }\n set onmessage(listener) {\n if (this._onmessageListener)\n this.removeEventListener(\"message\", this._onmessageListener);\n this._onmessageListener = listener;\n if (this._onmessageListener)\n this.addEventListener(\"message\", this._onmessageListener);\n }\n send(message) {\n if (this.readyState === _WebSocketMock.CONNECTING)\n throw new DOMException(`Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.`);\n if (this.readyState !== _WebSocketMock.OPEN)\n throw new DOMException(`WebSocket is already in CLOSING or CLOSED state.`);\n if (this._passthrough) {\n if (this._ws)\n this._apiSendToServer(message);\n } else {\n messageToData(message, (data) => binding({ type: \"onMessageFromPage\", id: this._id, data }));\n }\n }\n close(code, reason) {\n if (code !== void 0 && code !== 1e3 && (code < 3e3 || code > 4999))\n throw new DOMException(`Failed to execute 'close' on 'WebSocket': The close code must be either 1000, or between 3000 and 4999. ${code} is neither.`);\n if (this.readyState === _WebSocketMock.OPEN || this.readyState === _WebSocketMock.CONNECTING)\n this.readyState = _WebSocketMock.CLOSING;\n if (this._passthrough)\n this._apiCloseServer(code, reason, true);\n else\n binding({ type: \"onClosePage\", id: this._id, code, reason, wasClean: true });\n }\n // --- methods called from the routing API ---\n _apiEnsureOpened() {\n if (!this._ws)\n this._ensureOpened();\n }\n _apiSendToPage(message) {\n this._ensureOpened();\n if (this.readyState !== _WebSocketMock.OPEN)\n throw new DOMException(`WebSocket is already in CLOSING or CLOSED state.`);\n this.dispatchEvent(new MessageEvent(\"message\", { data: message, origin: this._origin, cancelable: true }));\n }\n _apiSendToServer(message) {\n if (!this._ws)\n throw new Error(\"Cannot send a message before connecting to the server\");\n if (this._ws.readyState === _WebSocketMock.CONNECTING)\n this._wsBufferedMessages.push(message);\n else\n this._ws.send(message);\n }\n _apiConnect() {\n if (this._ws)\n throw new Error(\"Can only connect to the server once\");\n this._ws = new NativeWebSocket(this.url, this._protocols);\n this._ws.binaryType = this._binaryType;\n this._ws.onopen = () => {\n for (const message of this._wsBufferedMessages)\n this._ws.send(message);\n this._wsBufferedMessages = [];\n this._ensureOpened();\n };\n this._ws.onclose = (event) => {\n this._onWSClose(event.code, event.reason, event.wasClean);\n };\n this._ws.onmessage = (event) => {\n if (this._passthrough)\n this._apiSendToPage(event.data);\n else\n messageToData(event.data, (data) => binding({ type: \"onMessageFromServer\", id: this._id, data }));\n };\n this._ws.onerror = () => {\n const event = new Event(\"error\", { cancelable: true });\n this.dispatchEvent(event);\n };\n }\n // This method connects to the server, and passes all messages through,\n // as if WebSocketMock was not engaged.\n _apiPassThrough() {\n this._passthrough = true;\n this._apiConnect();\n }\n _apiCloseServer(code, reason, wasClean) {\n if (!this._ws) {\n this._onWSClose(code, reason, wasClean);\n return;\n }\n if (this._ws.readyState === _WebSocketMock.CONNECTING || this._ws.readyState === _WebSocketMock.OPEN)\n this._ws.close(code, reason);\n }\n _apiClosePage(code, reason, wasClean) {\n if (this.readyState === _WebSocketMock.CLOSED)\n return;\n this.readyState = _WebSocketMock.CLOSED;\n this.dispatchEvent(new CloseEvent(\"close\", { code, reason, wasClean, cancelable: true }));\n this._maybeCleanup();\n if (this._passthrough)\n this._apiCloseServer(code, reason, wasClean);\n else\n binding({ type: \"onClosePage\", id: this._id, code, reason, wasClean });\n }\n // --- internals ---\n _ensureOpened() {\n if (this.readyState !== _WebSocketMock.CONNECTING)\n return;\n this.readyState = _WebSocketMock.OPEN;\n this.dispatchEvent(new Event(\"open\", { cancelable: true }));\n }\n _onWSClose(code, reason, wasClean) {\n if (this._passthrough)\n this._apiClosePage(code, reason, wasClean);\n else\n binding({ type: \"onCloseServer\", id: this._id, code, reason, wasClean });\n if (this._ws) {\n this._ws.onopen = null;\n this._ws.onclose = null;\n this._ws.onmessage = null;\n this._ws.onerror = null;\n this._ws = void 0;\n this._wsBufferedMessages = [];\n }\n this._maybeCleanup();\n }\n _maybeCleanup() {\n if (this.readyState === _WebSocketMock.CLOSED && !this._ws)\n idToWebSocket.delete(this._id);\n }\n };\n _WebSocketMock.CONNECTING = 0;\n // WebSocket.CONNECTING\n _WebSocketMock.OPEN = 1;\n // WebSocket.OPEN\n _WebSocketMock.CLOSING = 2;\n // WebSocket.CLOSING\n _WebSocketMock.CLOSED = 3;\n let WebSocketMock = _WebSocketMock;\n globalThis.WebSocket = class WebSocket extends WebSocketMock {\n };\n}\n";
@@ -202,6 +202,7 @@ _validatorPrimitives.scheme.APIRequestContextInitializer = (0, _validatorPrimiti
202
202
  });
203
203
  _validatorPrimitives.scheme.APIRequestContextFetchParams = (0, _validatorPrimitives.tObject)({
204
204
  url: _validatorPrimitives.tString,
205
+ encodedParams: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
205
206
  params: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tType)('NameValue'))),
206
207
  method: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
207
208
  headers: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tType)('NameValue'))),
@@ -347,9 +348,10 @@ _validatorPrimitives.scheme.RootInitializeResult = (0, _validatorPrimitives.tObj
347
348
  });
348
349
  _validatorPrimitives.scheme.PlaywrightInitializer = (0, _validatorPrimitives.tObject)({
349
350
  chromium: (0, _validatorPrimitives.tChannel)(['BrowserType']),
350
- bidi: (0, _validatorPrimitives.tChannel)(['BrowserType']),
351
351
  firefox: (0, _validatorPrimitives.tChannel)(['BrowserType']),
352
352
  webkit: (0, _validatorPrimitives.tChannel)(['BrowserType']),
353
+ bidiChromium: (0, _validatorPrimitives.tChannel)(['BrowserType']),
354
+ bidiFirefox: (0, _validatorPrimitives.tChannel)(['BrowserType']),
353
355
  android: (0, _validatorPrimitives.tChannel)(['Android']),
354
356
  electron: (0, _validatorPrimitives.tChannel)(['Electron']),
355
357
  utils: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tChannel)(['LocalUtils'])),
@@ -856,6 +858,9 @@ _validatorPrimitives.scheme.BrowserContextPageErrorEvent = (0, _validatorPrimiti
856
858
  _validatorPrimitives.scheme.BrowserContextRouteEvent = (0, _validatorPrimitives.tObject)({
857
859
  route: (0, _validatorPrimitives.tChannel)(['Route'])
858
860
  });
861
+ _validatorPrimitives.scheme.BrowserContextWebSocketRouteEvent = (0, _validatorPrimitives.tObject)({
862
+ webSocketRoute: (0, _validatorPrimitives.tChannel)(['WebSocketRoute'])
863
+ });
859
864
  _validatorPrimitives.scheme.BrowserContextVideoEvent = (0, _validatorPrimitives.tObject)({
860
865
  artifact: (0, _validatorPrimitives.tChannel)(['Artifact'])
861
866
  });
@@ -967,6 +972,14 @@ _validatorPrimitives.scheme.BrowserContextSetNetworkInterceptionPatternsParams =
967
972
  }))
968
973
  });
969
974
  _validatorPrimitives.scheme.BrowserContextSetNetworkInterceptionPatternsResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
975
+ _validatorPrimitives.scheme.BrowserContextSetWebSocketInterceptionPatternsParams = (0, _validatorPrimitives.tObject)({
976
+ patterns: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
977
+ glob: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
978
+ regexSource: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
979
+ regexFlags: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
980
+ }))
981
+ });
982
+ _validatorPrimitives.scheme.BrowserContextSetWebSocketInterceptionPatternsResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
970
983
  _validatorPrimitives.scheme.BrowserContextSetOfflineParams = (0, _validatorPrimitives.tObject)({
971
984
  offline: _validatorPrimitives.tBoolean
972
985
  });
@@ -978,9 +991,10 @@ _validatorPrimitives.scheme.BrowserContextStorageStateResult = (0, _validatorPri
978
991
  });
979
992
  _validatorPrimitives.scheme.BrowserContextPauseParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
980
993
  _validatorPrimitives.scheme.BrowserContextPauseResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
981
- _validatorPrimitives.scheme.BrowserContextRecorderSupplementEnableParams = (0, _validatorPrimitives.tObject)({
994
+ _validatorPrimitives.scheme.BrowserContextEnableRecorderParams = (0, _validatorPrimitives.tObject)({
982
995
  language: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
983
996
  mode: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['inspecting', 'recording'])),
997
+ codegenMode: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['actions', 'trace-events'])),
984
998
  pauseOnNextStatement: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
985
999
  testIdAttributeName: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
986
1000
  launchOptions: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tAny),
@@ -988,9 +1002,10 @@ _validatorPrimitives.scheme.BrowserContextRecorderSupplementEnableParams = (0, _
988
1002
  device: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
989
1003
  saveStorage: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
990
1004
  outputFile: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1005
+ handleSIGINT: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
991
1006
  omitCallTracking: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean)
992
1007
  });
993
- _validatorPrimitives.scheme.BrowserContextRecorderSupplementEnableResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1008
+ _validatorPrimitives.scheme.BrowserContextEnableRecorderResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
994
1009
  _validatorPrimitives.scheme.BrowserContextNewCDPSessionParams = (0, _validatorPrimitives.tObject)({
995
1010
  page: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tChannel)(['Page'])),
996
1011
  frame: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tChannel)(['Frame']))
@@ -1094,6 +1109,9 @@ _validatorPrimitives.scheme.PageLocatorHandlerTriggeredEvent = (0, _validatorPri
1094
1109
  _validatorPrimitives.scheme.PageRouteEvent = (0, _validatorPrimitives.tObject)({
1095
1110
  route: (0, _validatorPrimitives.tChannel)(['Route'])
1096
1111
  });
1112
+ _validatorPrimitives.scheme.PageWebSocketRouteEvent = (0, _validatorPrimitives.tObject)({
1113
+ webSocketRoute: (0, _validatorPrimitives.tChannel)(['WebSocketRoute'])
1114
+ });
1097
1115
  _validatorPrimitives.scheme.PageVideoEvent = (0, _validatorPrimitives.tObject)({
1098
1116
  artifact: (0, _validatorPrimitives.tChannel)(['Artifact'])
1099
1117
  });
@@ -1146,6 +1164,8 @@ _validatorPrimitives.scheme.PageGoForwardParams = (0, _validatorPrimitives.tObje
1146
1164
  _validatorPrimitives.scheme.PageGoForwardResult = (0, _validatorPrimitives.tObject)({
1147
1165
  response: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tChannel)(['Response']))
1148
1166
  });
1167
+ _validatorPrimitives.scheme.PageRequestGCParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1168
+ _validatorPrimitives.scheme.PageRequestGCResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1149
1169
  _validatorPrimitives.scheme.PageRegisterLocatorHandlerParams = (0, _validatorPrimitives.tObject)({
1150
1170
  selector: _validatorPrimitives.tString,
1151
1171
  noWaitAfter: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean)
@@ -1233,6 +1253,14 @@ _validatorPrimitives.scheme.PageSetNetworkInterceptionPatternsParams = (0, _vali
1233
1253
  }))
1234
1254
  });
1235
1255
  _validatorPrimitives.scheme.PageSetNetworkInterceptionPatternsResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1256
+ _validatorPrimitives.scheme.PageSetWebSocketInterceptionPatternsParams = (0, _validatorPrimitives.tObject)({
1257
+ patterns: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
1258
+ glob: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1259
+ regexSource: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1260
+ regexFlags: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
1261
+ }))
1262
+ });
1263
+ _validatorPrimitives.scheme.PageSetWebSocketInterceptionPatternsResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1236
1264
  _validatorPrimitives.scheme.PageSetViewportSizeParams = (0, _validatorPrimitives.tObject)({
1237
1265
  viewportSize: (0, _validatorPrimitives.tObject)({
1238
1266
  width: _validatorPrimitives.tNumber,
@@ -1842,12 +1870,6 @@ _validatorPrimitives.scheme.JSHandleJsonValueResult = (0, _validatorPrimitives.t
1842
1870
  value: (0, _validatorPrimitives.tType)('SerializedValue')
1843
1871
  });
1844
1872
  _validatorPrimitives.scheme.ElementHandleJsonValueResult = (0, _validatorPrimitives.tType)('JSHandleJsonValueResult');
1845
- _validatorPrimitives.scheme.JSHandleObjectCountParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1846
- _validatorPrimitives.scheme.ElementHandleObjectCountParams = (0, _validatorPrimitives.tType)('JSHandleObjectCountParams');
1847
- _validatorPrimitives.scheme.JSHandleObjectCountResult = (0, _validatorPrimitives.tObject)({
1848
- count: _validatorPrimitives.tNumber
1849
- });
1850
- _validatorPrimitives.scheme.ElementHandleObjectCountResult = (0, _validatorPrimitives.tType)('JSHandleObjectCountResult');
1851
1873
  _validatorPrimitives.scheme.ElementHandleInitializer = (0, _validatorPrimitives.tObject)({
1852
1874
  preview: _validatorPrimitives.tString
1853
1875
  });
@@ -2114,8 +2136,7 @@ _validatorPrimitives.scheme.RouteRedirectNavigationRequestParams = (0, _validato
2114
2136
  });
2115
2137
  _validatorPrimitives.scheme.RouteRedirectNavigationRequestResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2116
2138
  _validatorPrimitives.scheme.RouteAbortParams = (0, _validatorPrimitives.tObject)({
2117
- errorCode: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2118
- requestUrl: _validatorPrimitives.tString
2139
+ errorCode: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
2119
2140
  });
2120
2141
  _validatorPrimitives.scheme.RouteAbortResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2121
2142
  _validatorPrimitives.scheme.RouteContinueParams = (0, _validatorPrimitives.tObject)({
@@ -2123,7 +2144,6 @@ _validatorPrimitives.scheme.RouteContinueParams = (0, _validatorPrimitives.tObje
2123
2144
  method: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2124
2145
  headers: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tType)('NameValue'))),
2125
2146
  postData: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBinary),
2126
- requestUrl: _validatorPrimitives.tString,
2127
2147
  isFallback: _validatorPrimitives.tBoolean
2128
2148
  });
2129
2149
  _validatorPrimitives.scheme.RouteContinueResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
@@ -2132,10 +2152,56 @@ _validatorPrimitives.scheme.RouteFulfillParams = (0, _validatorPrimitives.tObjec
2132
2152
  headers: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tType)('NameValue'))),
2133
2153
  body: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2134
2154
  isBase64: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
2135
- fetchResponseUid: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2136
- requestUrl: _validatorPrimitives.tString
2155
+ fetchResponseUid: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
2137
2156
  });
2138
2157
  _validatorPrimitives.scheme.RouteFulfillResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2158
+ _validatorPrimitives.scheme.WebSocketRouteInitializer = (0, _validatorPrimitives.tObject)({
2159
+ url: _validatorPrimitives.tString
2160
+ });
2161
+ _validatorPrimitives.scheme.WebSocketRouteMessageFromPageEvent = (0, _validatorPrimitives.tObject)({
2162
+ message: _validatorPrimitives.tString,
2163
+ isBase64: _validatorPrimitives.tBoolean
2164
+ });
2165
+ _validatorPrimitives.scheme.WebSocketRouteMessageFromServerEvent = (0, _validatorPrimitives.tObject)({
2166
+ message: _validatorPrimitives.tString,
2167
+ isBase64: _validatorPrimitives.tBoolean
2168
+ });
2169
+ _validatorPrimitives.scheme.WebSocketRouteClosePageEvent = (0, _validatorPrimitives.tObject)({
2170
+ code: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
2171
+ reason: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2172
+ wasClean: _validatorPrimitives.tBoolean
2173
+ });
2174
+ _validatorPrimitives.scheme.WebSocketRouteCloseServerEvent = (0, _validatorPrimitives.tObject)({
2175
+ code: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
2176
+ reason: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2177
+ wasClean: _validatorPrimitives.tBoolean
2178
+ });
2179
+ _validatorPrimitives.scheme.WebSocketRouteConnectParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2180
+ _validatorPrimitives.scheme.WebSocketRouteConnectResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2181
+ _validatorPrimitives.scheme.WebSocketRouteEnsureOpenedParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2182
+ _validatorPrimitives.scheme.WebSocketRouteEnsureOpenedResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2183
+ _validatorPrimitives.scheme.WebSocketRouteSendToPageParams = (0, _validatorPrimitives.tObject)({
2184
+ message: _validatorPrimitives.tString,
2185
+ isBase64: _validatorPrimitives.tBoolean
2186
+ });
2187
+ _validatorPrimitives.scheme.WebSocketRouteSendToPageResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2188
+ _validatorPrimitives.scheme.WebSocketRouteSendToServerParams = (0, _validatorPrimitives.tObject)({
2189
+ message: _validatorPrimitives.tString,
2190
+ isBase64: _validatorPrimitives.tBoolean
2191
+ });
2192
+ _validatorPrimitives.scheme.WebSocketRouteSendToServerResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2193
+ _validatorPrimitives.scheme.WebSocketRouteClosePageParams = (0, _validatorPrimitives.tObject)({
2194
+ code: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
2195
+ reason: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2196
+ wasClean: _validatorPrimitives.tBoolean
2197
+ });
2198
+ _validatorPrimitives.scheme.WebSocketRouteClosePageResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2199
+ _validatorPrimitives.scheme.WebSocketRouteCloseServerParams = (0, _validatorPrimitives.tObject)({
2200
+ code: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
2201
+ reason: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
2202
+ wasClean: _validatorPrimitives.tBoolean
2203
+ });
2204
+ _validatorPrimitives.scheme.WebSocketRouteCloseServerResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2139
2205
  _validatorPrimitives.scheme.ResourceTiming = (0, _validatorPrimitives.tObject)({
2140
2206
  startTime: _validatorPrimitives.tNumber,
2141
2207
  domainLookupStart: _validatorPrimitives.tNumber,
@@ -34,8 +34,6 @@ class BidiBrowser extends _browser.Browser {
34
34
  static async connect(parent, transport, options) {
35
35
  const browser = new BidiBrowser(parent, transport, options);
36
36
  if (options.__testHookOnConnectToBrowser) await options.__testHookOnConnectToBrowser();
37
- const sessionStatus = await browser._browserSession.send('session.status', {});
38
- if (!sessionStatus.ready) throw new Error('Bidi session is not ready. ' + sessionStatus.message);
39
37
  let proxy;
40
38
  if (options.proxy) {
41
39
  proxy = {
@@ -78,6 +76,13 @@ class BidiBrowser extends _browser.Browser {
78
76
  await browser._browserSession.send('session.subscribe', {
79
77
  events: ['browsingContext', 'network', 'log', 'script']
80
78
  });
79
+ if (options.persistent) {
80
+ browser._defaultContext = new BidiBrowserContext(browser, undefined, options.persistent);
81
+ await browser._defaultContext._initialize();
82
+ // Create default page as we cannot get access to the existing one.
83
+ const pageDelegate = await browser._defaultContext.newPageDelegate();
84
+ await pageDelegate.pageOrError();
85
+ }
81
86
  return browser;
82
87
  }
83
88
  constructor(parent, transport, options) {
@@ -165,8 +170,11 @@ class BidiBrowserContext extends _browserContext.BrowserContext {
165
170
  super(browser, options, browserContextId);
166
171
  this._authenticateProxyViaHeader();
167
172
  }
173
+ _bidiPages() {
174
+ return [...this._browser._bidiPages.values()].filter(bidiPage => bidiPage._browserContext === this);
175
+ }
168
176
  pages() {
169
- return [];
177
+ return this._bidiPages().map(bidiPage => bidiPage._initializedPage).filter(Boolean);
170
178
  }
171
179
  async newPageDelegate() {
172
180
  (0, _browserContext.assertBrowserContextIsNotOwned)(this);
@@ -242,18 +250,25 @@ class BidiBrowserContext extends _browserContext.BrowserContext {
242
250
  async setExtraHTTPHeaders(headers) {}
243
251
  async setUserAgent(userAgent) {}
244
252
  async setOffline(offline) {}
245
- async doSetHTTPCredentials(httpCredentials) {}
253
+ async doSetHTTPCredentials(httpCredentials) {
254
+ this._options.httpCredentials = httpCredentials;
255
+ for (const page of this.pages()) await page._delegate.updateHttpCredentials();
256
+ }
246
257
  async doAddInitScript(initScript) {
247
- // for (const page of this.pages())
248
- // await (page._delegate as WKPage)._updateBootstrapScript();
258
+ await Promise.all(this.pages().map(page => page._delegate.addInitScript(initScript)));
249
259
  }
250
260
  async doRemoveNonInternalInitScripts() {}
251
261
  async doUpdateRequestInterception() {}
252
262
  onClosePersistent() {}
253
263
  async clearCache() {}
254
264
  async doClose(reason) {
255
- // TODO: implement for persistent context
256
- if (!this._browserContextId) return;
265
+ if (!this._browserContextId) {
266
+ // Closing persistent context should close the browser.
267
+ await this._browser.close({
268
+ reason
269
+ });
270
+ return;
271
+ }
257
272
  await this._browser._browserSession.send('browser.removeUserContext', {
258
273
  userContext: this._browserContextId
259
274
  });
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BidiChromium = void 0;
7
+ var _os = _interopRequireDefault(require("os"));
8
+ var _utils = require("../../utils");
9
+ var _browserType = require("../browserType");
10
+ var _chromiumSwitches = require("../chromium/chromiumSwitches");
11
+ var _bidiBrowser = require("./bidiBrowser");
12
+ var _bidiConnection = require("./bidiConnection");
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 BidiChromium extends _browserType.BrowserType {
31
+ constructor(parent) {
32
+ super(parent, 'bidi');
33
+ this._useBidi = true;
34
+ }
35
+ async connectToTransport(transport, options) {
36
+ // Chrome doesn't support Bidi, we create Bidi over CDP which is used by Chrome driver.
37
+ // bidiOverCdp depends on chromium-bidi which we only have in devDependencies, so
38
+ // we load bidiOverCdp dynamically.
39
+ const bidiTransport = await require('./bidiOverCdp').connectBidiOverCdp(transport);
40
+ transport[kBidiOverCdpWrapper] = bidiTransport;
41
+ return _bidiBrowser.BidiBrowser.connect(this.attribution.playwright, bidiTransport, options);
42
+ }
43
+ doRewriteStartupLog(error) {
44
+ if (!error.logs) return error;
45
+ if (error.logs.includes('Missing X server')) error.logs = '\n' + (0, _utils.wrapInASCIIBox)(_browserType.kNoXServerRunningError, 1);
46
+ // These error messages are taken from Chromium source code as of July, 2020:
47
+ // https://github.com/chromium/chromium/blob/70565f67e79f79e17663ad1337dc6e63ee207ce9/content/browser/zygote_host/zygote_host_impl_linux.cc
48
+ if (!error.logs.includes('crbug.com/357670') && !error.logs.includes('No usable sandbox!') && !error.logs.includes('crbug.com/638180')) return error;
49
+ error.logs = [`Chromium sandboxing failed!`, `================================`, `To avoid the sandboxing issue, do either of the following:`, ` - (preferred): Configure your environment to support sandboxing`, ` - (alternative): Launch Chromium without sandbox using 'chromiumSandbox: false' option`, `================================`, ``].join('\n');
50
+ return error;
51
+ }
52
+ amendEnvironment(env, userDataDir, executable, browserArguments) {
53
+ return env;
54
+ }
55
+ attemptToGracefullyCloseBrowser(transport) {
56
+ const bidiTransport = transport[kBidiOverCdpWrapper];
57
+ if (bidiTransport) transport = bidiTransport;
58
+ transport.send({
59
+ method: 'browser.close',
60
+ params: {},
61
+ id: _bidiConnection.kBrowserCloseMessageId
62
+ });
63
+ }
64
+ defaultArgs(options, isPersistent, userDataDir) {
65
+ const chromeArguments = this._innerDefaultArgs(options);
66
+ chromeArguments.push(`--user-data-dir=${userDataDir}`);
67
+ chromeArguments.push('--remote-debugging-port=0');
68
+ if (isPersistent) chromeArguments.push('about:blank');else chromeArguments.push('--no-startup-window');
69
+ return chromeArguments;
70
+ }
71
+ readyState(options) {
72
+ (0, _utils.assert)(options.useWebSocket);
73
+ return new ChromiumReadyState();
74
+ }
75
+ _innerDefaultArgs(options) {
76
+ const {
77
+ args = []
78
+ } = options;
79
+ const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir'));
80
+ if (userDataDirArg) throw this._createUserDataDirArgMisuseError('--user-data-dir');
81
+ if (args.find(arg => arg.startsWith('--remote-debugging-pipe'))) throw new Error('Playwright manages remote debugging connection itself.');
82
+ if (args.find(arg => !arg.startsWith('-'))) throw new Error('Arguments can not specify page to be opened');
83
+ const chromeArguments = [..._chromiumSwitches.chromiumSwitches];
84
+ if (_os.default.platform() === 'darwin') {
85
+ // See https://github.com/microsoft/playwright/issues/7362
86
+ chromeArguments.push('--enable-use-zoom-for-dsf=false');
87
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=1407025.
88
+ if (options.headless) chromeArguments.push('--use-angle');
89
+ }
90
+ if (options.devtools) chromeArguments.push('--auto-open-devtools-for-tabs');
91
+ if (options.headless) {
92
+ if (process.env.PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW) chromeArguments.push('--headless=new');else chromeArguments.push('--headless=old');
93
+ chromeArguments.push('--hide-scrollbars', '--mute-audio', '--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4');
94
+ }
95
+ if (options.chromiumSandbox !== true) chromeArguments.push('--no-sandbox');
96
+ const proxy = options.proxyOverride || options.proxy;
97
+ if (proxy) {
98
+ const proxyURL = new URL(proxy.server);
99
+ const isSocks = proxyURL.protocol === 'socks5:';
100
+ // https://www.chromium.org/developers/design-documents/network-settings
101
+ if (isSocks && !this.attribution.playwright.options.socksProxyPort) {
102
+ // https://www.chromium.org/developers/design-documents/network-stack/socks-proxy
103
+ chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
104
+ }
105
+ chromeArguments.push(`--proxy-server=${proxy.server}`);
106
+ const proxyBypassRules = [];
107
+ // https://source.chromium.org/chromium/chromium/src/+/master:net/docs/proxy.md;l=548;drc=71698e610121078e0d1a811054dcf9fd89b49578
108
+ if (this.attribution.playwright.options.socksProxyPort) proxyBypassRules.push('<-loopback>');
109
+ if (proxy.bypass) proxyBypassRules.push(...proxy.bypass.split(',').map(t => t.trim()).map(t => t.startsWith('.') ? '*' + t : t));
110
+ if (!process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK && !proxyBypassRules.includes('<-loopback>')) proxyBypassRules.push('<-loopback>');
111
+ if (proxyBypassRules.length > 0) chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(';')}`);
112
+ }
113
+ chromeArguments.push(...args);
114
+ return chromeArguments;
115
+ }
116
+ }
117
+ exports.BidiChromium = BidiChromium;
118
+ class ChromiumReadyState extends _browserType.BrowserReadyState {
119
+ onBrowserOutput(message) {
120
+ const match = message.match(/DevTools listening on (.*)/);
121
+ if (match) this._wsEndpoint.resolve(match[1]);
122
+ }
123
+ }
124
+ const kBidiOverCdpWrapper = Symbol('kBidiConnectionWrapper');
@@ -66,7 +66,7 @@ class BidiConnection {
66
66
  var _object$params$source;
67
67
  // Route page events to the right session.
68
68
  let context;
69
- if ('context' in object.params) context = object.params.context;else if (object.method === 'log.entryAdded') context = (_object$params$source = object.params.source) === null || _object$params$source === void 0 ? void 0 : _object$params$source.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
70
  if (context) {
71
71
  const session = this._browsingContextToSession.get(context);
72
72
  if (session) {
@@ -124,9 +124,6 @@ class BidiExecutionContext {
124
124
  handles: [objectId]
125
125
  });
126
126
  }
127
- objectCount(objectId) {
128
- throw new Error('Method not implemented.');
129
- }
130
127
  async rawCallFunction(functionDeclaration, arg) {
131
128
  const response = await this._session.send('script.callFunction', {
132
129
  functionDeclaration,