patchright-core 1.52.5 → 1.55.0

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 (218) hide show
  1. package/ThirdPartyNotices.txt +65 -123
  2. package/bin/reinstall_chrome_beta_mac.sh +1 -1
  3. package/bin/reinstall_chrome_stable_mac.sh +1 -1
  4. package/bin/reinstall_msedge_beta_mac.sh +1 -1
  5. package/bin/reinstall_msedge_dev_mac.sh +1 -1
  6. package/bin/reinstall_msedge_stable_mac.sh +1 -1
  7. package/browsers.json +14 -14
  8. package/index.js +1 -1
  9. package/lib/androidServerImpl.js +4 -2
  10. package/lib/browserServerImpl.js +47 -12
  11. package/lib/cli/program.js +116 -50
  12. package/lib/cli/programWithTestStub.js +1 -1
  13. package/lib/client/android.js +30 -34
  14. package/lib/client/browser.js +54 -17
  15. package/lib/client/browserContext.js +67 -71
  16. package/lib/client/browserType.js +25 -34
  17. package/lib/client/channelOwner.js +20 -24
  18. package/lib/client/connection.js +6 -10
  19. package/lib/client/electron.js +8 -3
  20. package/lib/client/elementHandle.js +18 -21
  21. package/lib/client/fetch.js +5 -3
  22. package/lib/client/frame.js +54 -32
  23. package/lib/client/input.js +3 -1
  24. package/lib/client/jsHandle.js +4 -0
  25. package/lib/client/localUtils.js +0 -1
  26. package/lib/client/locator.js +30 -26
  27. package/lib/client/network.js +5 -12
  28. package/lib/client/page.js +32 -32
  29. package/lib/client/playwright.js +6 -16
  30. package/lib/client/selectors.js +18 -38
  31. package/lib/client/timeoutSettings.js +12 -8
  32. package/lib/client/tracing.js +24 -20
  33. package/lib/client/waiter.js +2 -2
  34. package/lib/client/webSocket.js +4 -22
  35. package/lib/generated/bindingsControllerSource.js +28 -0
  36. package/lib/generated/clockSource.js +1 -1
  37. package/lib/generated/injectedScriptSource.js +1 -1
  38. package/lib/generated/pollingRecorderSource.js +1 -1
  39. package/lib/generated/storageScriptSource.js +28 -0
  40. package/lib/generated/utilityScriptSource.js +1 -1
  41. package/lib/generated/webSocketMockSource.js +12 -50
  42. package/lib/inProcessFactory.js +9 -6
  43. package/lib/outofprocess.js +0 -2
  44. package/lib/protocol/validator.js +421 -345
  45. package/lib/protocol/validatorPrimitives.js +18 -4
  46. package/lib/remote/playwrightConnection.js +29 -166
  47. package/lib/remote/playwrightServer.js +233 -35
  48. package/lib/server/android/android.js +97 -83
  49. package/lib/server/android/backendAdb.js +0 -2
  50. package/lib/server/bidi/bidiBrowser.js +139 -73
  51. package/lib/server/bidi/bidiChromium.js +23 -22
  52. package/lib/server/bidi/bidiExecutionContext.js +2 -1
  53. package/lib/server/bidi/bidiFirefox.js +17 -14
  54. package/lib/server/bidi/bidiInput.js +22 -22
  55. package/lib/server/bidi/bidiNetworkManager.js +8 -11
  56. package/lib/server/bidi/bidiPage.js +42 -86
  57. package/lib/server/bidi/third_party/bidiProtocol.js +5 -133
  58. package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
  59. package/lib/server/{dispatchers/selectorsDispatcher.js → bidi/third_party/bidiProtocolPermissions.js} +20 -18
  60. package/lib/server/browser.js +30 -21
  61. package/lib/server/browserContext.js +203 -165
  62. package/lib/server/browserType.js +109 -107
  63. package/lib/server/chromium/chromium.js +84 -69
  64. package/lib/server/chromium/chromiumSwitches.js +13 -20
  65. package/lib/server/chromium/crBrowser.js +74 -40
  66. package/lib/server/chromium/crConnection.js +8 -9
  67. package/lib/server/chromium/crCoverage.js +11 -8
  68. package/lib/server/chromium/crDragDrop.js +25 -20
  69. package/lib/server/chromium/crExecutionContext.js +2 -1
  70. package/lib/server/chromium/crInput.js +32 -29
  71. package/lib/server/chromium/crNetworkManager.js +43 -31
  72. package/lib/server/chromium/crPage.js +98 -72
  73. package/lib/server/chromium/crServiceWorker.js +13 -18
  74. package/lib/server/chromium/videoRecorder.js +10 -18
  75. package/lib/server/clock.js +51 -39
  76. package/lib/server/codegen/csharp.js +10 -5
  77. package/lib/server/codegen/java.js +1 -1
  78. package/lib/server/codegen/javascript.js +1 -1
  79. package/lib/server/codegen/jsonl.js +2 -1
  80. package/lib/server/codegen/language.js +22 -1
  81. package/lib/server/codegen/languages.js +4 -4
  82. package/lib/server/codegen/python.js +1 -1
  83. package/lib/server/cookieStore.js +3 -1
  84. package/lib/server/debugController.js +105 -71
  85. package/lib/server/debugger.js +6 -23
  86. package/lib/server/deviceDescriptorsSource.json +237 -127
  87. package/lib/server/dialog.js +50 -6
  88. package/lib/server/dispatchers/androidDispatcher.js +77 -62
  89. package/lib/server/dispatchers/artifactDispatcher.js +18 -18
  90. package/lib/server/dispatchers/browserContextDispatcher.js +141 -91
  91. package/lib/server/dispatchers/browserDispatcher.js +55 -88
  92. package/lib/server/dispatchers/browserTypeDispatcher.js +18 -9
  93. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -4
  94. package/lib/server/dispatchers/debugControllerDispatcher.js +12 -21
  95. package/lib/server/dispatchers/dialogDispatcher.js +4 -4
  96. package/lib/server/dispatchers/dispatcher.js +78 -53
  97. package/lib/server/dispatchers/electronDispatcher.js +19 -20
  98. package/lib/server/dispatchers/elementHandlerDispatcher.js +83 -93
  99. package/lib/server/dispatchers/frameDispatcher.js +98 -101
  100. package/lib/server/dispatchers/jsHandleDispatcher.js +21 -16
  101. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -4
  102. package/lib/server/dispatchers/localUtilsDispatcher.js +53 -59
  103. package/lib/server/dispatchers/networkDispatchers.js +41 -35
  104. package/lib/server/dispatchers/pageDispatcher.js +156 -107
  105. package/lib/server/dispatchers/playwrightDispatcher.js +37 -25
  106. package/lib/server/dispatchers/streamDispatcher.js +15 -8
  107. package/lib/server/dispatchers/tracingDispatcher.js +22 -13
  108. package/lib/server/dispatchers/webSocketRouteDispatcher.js +46 -35
  109. package/lib/server/dispatchers/writableStreamDispatcher.js +16 -10
  110. package/lib/server/dom.js +198 -266
  111. package/lib/server/download.js +3 -3
  112. package/lib/server/electron/electron.js +96 -103
  113. package/lib/server/electron/loader.js +1 -1
  114. package/lib/server/fetch.js +22 -41
  115. package/lib/server/fileUploadUtils.js +1 -1
  116. package/lib/server/firefox/ffBrowser.js +79 -55
  117. package/lib/server/firefox/ffExecutionContext.js +2 -1
  118. package/lib/server/firefox/ffInput.js +23 -23
  119. package/lib/server/firefox/ffNetworkManager.js +8 -6
  120. package/lib/server/firefox/ffPage.js +39 -36
  121. package/lib/server/firefox/firefox.js +9 -10
  122. package/lib/server/frameSelectors.js +63 -20
  123. package/lib/server/frames.js +495 -555
  124. package/lib/server/har/harRecorder.js +1 -1
  125. package/lib/server/har/harTracer.js +4 -2
  126. package/lib/server/helper.js +3 -7
  127. package/lib/server/index.js +0 -3
  128. package/lib/server/input.js +47 -54
  129. package/lib/server/instrumentation.js +8 -14
  130. package/lib/server/javascript.js +8 -16
  131. package/lib/server/launchApp.js +48 -30
  132. package/lib/server/localUtils.js +45 -38
  133. package/lib/server/network.js +44 -10
  134. package/lib/server/page.js +232 -177
  135. package/lib/server/pageBinding.js +6 -7
  136. package/lib/server/playwright.js +4 -14
  137. package/lib/server/progress.js +57 -49
  138. package/lib/server/recorder/recorderApp.js +298 -95
  139. package/lib/server/recorder/recorderRunner.js +23 -24
  140. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  141. package/lib/server/recorder/recorderUtils.js +67 -10
  142. package/lib/server/recorder.js +284 -146
  143. package/lib/server/registry/index.js +83 -48
  144. package/lib/server/registry/nativeDeps.js +175 -0
  145. package/lib/server/registry/oopDownloadBrowserMain.js +1 -1
  146. package/lib/server/screenshotter.js +84 -83
  147. package/lib/server/selectors.js +12 -12
  148. package/lib/server/socksClientCertificatesInterceptor.js +198 -136
  149. package/lib/server/trace/recorder/snapshotter.js +12 -19
  150. package/lib/server/trace/recorder/tracing.js +36 -27
  151. package/lib/server/trace/viewer/traceViewer.js +11 -20
  152. package/lib/server/transport.js +20 -22
  153. package/lib/server/utils/comparators.js +2 -2
  154. package/lib/server/utils/debug.js +3 -8
  155. package/lib/server/utils/debugLogger.js +8 -0
  156. package/lib/server/utils/hostPlatform.js +3 -1
  157. package/lib/server/utils/network.js +35 -25
  158. package/lib/server/utils/nodePlatform.js +1 -1
  159. package/lib/server/utils/processLauncher.js +4 -1
  160. package/lib/server/utils/wsServer.js +11 -17
  161. package/lib/server/webkit/webkit.js +5 -2
  162. package/lib/server/webkit/wkBrowser.js +51 -28
  163. package/lib/server/webkit/wkExecutionContext.js +2 -1
  164. package/lib/server/webkit/wkInput.js +25 -25
  165. package/lib/server/webkit/wkInterceptableRequest.js +1 -1
  166. package/lib/server/webkit/wkPage.js +80 -59
  167. package/lib/server/webkit/wkProvisionalPage.js +1 -1
  168. package/lib/server/webkit/wkWorkers.js +7 -7
  169. package/lib/utils/isomorphic/ariaSnapshot.js +13 -7
  170. package/lib/utils/isomorphic/cssParser.js +1 -2
  171. package/lib/utils/isomorphic/locatorGenerators.js +18 -0
  172. package/lib/utils/isomorphic/manualPromise.js +1 -2
  173. package/lib/utils/isomorphic/mimeType.js +1 -2
  174. package/lib/utils/isomorphic/multimap.js +1 -2
  175. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
  176. package/lib/utils/isomorphic/protocolFormatter.js +78 -0
  177. package/lib/utils/isomorphic/protocolMetainfo.js +318 -0
  178. package/lib/utils/isomorphic/selectorParser.js +3 -4
  179. package/lib/utils/isomorphic/stringUtils.js +3 -24
  180. package/lib/utils/isomorphic/time.js +9 -4
  181. package/lib/utils/isomorphic/timeoutRunner.js +3 -4
  182. package/lib/utils/isomorphic/traceUtils.js +2 -3
  183. package/lib/utils/isomorphic/urlMatch.js +21 -7
  184. package/lib/utils/isomorphic/utilityScriptSerializers.js +208 -205
  185. package/lib/utils.js +8 -2
  186. package/lib/utilsBundleImpl/index.js +160 -150
  187. package/lib/vite/htmlReport/index.html +17 -17
  188. package/lib/vite/recorder/assets/{codeMirrorModule-CXVeovup.js → codeMirrorModule-DzQ0k89p.js} +1 -1
  189. package/lib/vite/recorder/assets/{index-eHBmevrY.css → index-CI4HQ-Zb.css} +1 -1
  190. package/lib/vite/recorder/assets/index-D7C7daHH.js +184 -0
  191. package/lib/vite/recorder/index.html +3 -3
  192. package/lib/vite/traceViewer/assets/{codeMirrorModule-_GLjJL-7.js → codeMirrorModule-Di48jgWx.js} +1 -1
  193. package/lib/vite/traceViewer/assets/defaultSettingsView-szBn8781.js +256 -0
  194. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +1 -0
  195. package/lib/vite/traceViewer/index.BFsek2M6.css +1 -0
  196. package/lib/vite/traceViewer/index.DQvXoPLL.js +2 -0
  197. package/lib/vite/traceViewer/index.html +6 -6
  198. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  199. package/lib/vite/traceViewer/uiMode.dBV3oN9h.js +5 -0
  200. package/lib/vite/traceViewer/uiMode.html +4 -4
  201. package/lib/zipBundleImpl.js +4 -4
  202. package/package.json +1 -1
  203. package/types/protocol.d.ts +712 -107
  204. package/types/types.d.ts +128 -17
  205. package/lib/generated/consoleApiSource.js +0 -28
  206. package/lib/protocol/debug.js +0 -211
  207. package/lib/server/recorder/contextRecorder.js +0 -286
  208. package/lib/server/recorder/recorderCollection.js +0 -116
  209. package/lib/server/recorder/recorderFrontend.js +0 -16
  210. package/lib/server/storageScript.js +0 -154
  211. package/lib/server/timeoutSettings.js +0 -89
  212. package/lib/utils/isomorphic/builtins.js +0 -86
  213. package/lib/vite/recorder/assets/index-BsWQsSGl.js +0 -184
  214. package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +0 -265
  215. package/lib/vite/traceViewer/defaultSettingsView.QdHITyLI.css +0 -1
  216. package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
  217. package/lib/vite/traceViewer/index.cFZzK9RN.js +0 -2
  218. package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +0 -5
@@ -32,21 +32,29 @@ __export(bidiChromium_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(bidiChromium_exports);
34
34
  var import_os = __toESM(require("os"));
35
- var import_utils = require("../../utils");
36
35
  var import_ascii = require("../utils/ascii");
37
36
  var import_browserType = require("../browserType");
38
37
  var import_bidiBrowser = require("./bidiBrowser");
39
38
  var import_bidiConnection = require("./bidiConnection");
40
39
  var import_chromiumSwitches = require("../chromium/chromiumSwitches");
40
+ var import_chromium = require("../chromium/chromium");
41
41
  class BidiChromium extends import_browserType.BrowserType {
42
42
  constructor(parent) {
43
- super(parent, "bidi");
44
- this._useBidi = true;
43
+ super(parent, "_bidiChromium");
45
44
  }
46
- async connectToTransport(transport, options) {
45
+ async connectToTransport(transport, options, browserLogsCollector) {
47
46
  const bidiTransport = await require("./bidiOverCdp").connectBidiOverCdp(transport);
48
47
  transport[kBidiOverCdpWrapper] = bidiTransport;
49
- return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, bidiTransport, options);
48
+ try {
49
+ return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, bidiTransport, options);
50
+ } catch (e) {
51
+ if (browserLogsCollector.recentLogs().some((log) => log.includes("Failed to create a ProcessSingleton for your profile directory."))) {
52
+ throw new Error(
53
+ "Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."
54
+ );
55
+ }
56
+ throw e;
57
+ }
50
58
  }
51
59
  doRewriteStartupLog(error) {
52
60
  if (!error.logs)
@@ -66,7 +74,7 @@ class BidiChromium extends import_browserType.BrowserType {
66
74
  ].join("\n");
67
75
  return error;
68
76
  }
69
- amendEnvironment(env, userDataDir, executable, browserArguments) {
77
+ amendEnvironment(env) {
70
78
  return env;
71
79
  }
72
80
  attemptToGracefullyCloseBrowser(transport) {
@@ -75,6 +83,9 @@ class BidiChromium extends import_browserType.BrowserType {
75
83
  transport = bidiTransport;
76
84
  transport.send({ method: "browser.close", params: {}, id: import_bidiConnection.kBrowserCloseMessageId });
77
85
  }
86
+ supportsPipeTransport() {
87
+ return false;
88
+ }
78
89
  defaultArgs(options, isPersistent, userDataDir) {
79
90
  const chromeArguments = this._innerDefaultArgs(options);
80
91
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
@@ -85,9 +96,8 @@ class BidiChromium extends import_browserType.BrowserType {
85
96
  chromeArguments.push("--no-startup-window");
86
97
  return chromeArguments;
87
98
  }
88
- readyState(options) {
89
- (0, import_utils.assert)(options.useWebSocket);
90
- return new ChromiumReadyState();
99
+ async waitForReadyState(options, browserLogsCollector) {
100
+ return (0, import_chromium.waitForReadyState)({ ...options, cdpPort: 0 }, browserLogsCollector);
91
101
  }
92
102
  _innerDefaultArgs(options) {
93
103
  const { args = [] } = options;
@@ -98,11 +108,9 @@ class BidiChromium extends import_browserType.BrowserType {
98
108
  throw new Error("Playwright manages remote debugging connection itself.");
99
109
  if (args.find((arg) => !arg.startsWith("-")))
100
110
  throw new Error("Arguments can not specify page to be opened");
101
- const chromeArguments = [...import_chromiumSwitches.chromiumSwitches];
111
+ const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode)];
102
112
  if (import_os.default.platform() === "darwin") {
103
- chromeArguments.push("--enable-use-zoom-for-dsf=false");
104
- if (options.headless)
105
- chromeArguments.push("--use-angle");
113
+ chromeArguments.push("--enable-unsafe-swiftshader");
106
114
  }
107
115
  if (options.devtools)
108
116
  chromeArguments.push("--auto-open-devtools-for-tabs");
@@ -120,12 +128,12 @@ class BidiChromium extends import_browserType.BrowserType {
120
128
  if (proxy) {
121
129
  const proxyURL = new URL(proxy.server);
122
130
  const isSocks = proxyURL.protocol === "socks5:";
123
- if (isSocks && !this.attribution.playwright.options.socksProxyPort) {
131
+ if (isSocks && !options.socksProxyPort) {
124
132
  chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
125
133
  }
126
134
  chromeArguments.push(`--proxy-server=${proxy.server}`);
127
135
  const proxyBypassRules = [];
128
- if (this.attribution.playwright.options.socksProxyPort)
136
+ if (options.socksProxyPort)
129
137
  proxyBypassRules.push("<-loopback>");
130
138
  if (proxy.bypass)
131
139
  proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
@@ -138,13 +146,6 @@ class BidiChromium extends import_browserType.BrowserType {
138
146
  return chromeArguments;
139
147
  }
140
148
  }
141
- class ChromiumReadyState extends import_browserType.BrowserReadyState {
142
- onBrowserOutput(message) {
143
- const match = message.match(/DevTools listening on (.*)/);
144
- if (match)
145
- this._wsEndpoint.resolve(match[1]);
146
- }
147
- }
148
149
  const kBidiOverCdpWrapper = Symbol("kBidiConnectionWrapper");
149
150
  // Annotate the CommonJS export names for ESM import in node:
150
151
  0 && (module.exports = {
@@ -33,6 +33,7 @@ __export(bidiExecutionContext_exports, {
33
33
  });
34
34
  module.exports = __toCommonJS(bidiExecutionContext_exports);
35
35
  var import_utils = require("../../utils");
36
+ var import_utilityScriptSerializers = require("../../utils/isomorphic/utilityScriptSerializers");
36
37
  var js = __toESM(require("../javascript"));
37
38
  var dom = __toESM(require("../dom"));
38
39
  var import_bidiDeserializer = require("./third_party/bidiDeserializer");
@@ -107,7 +108,7 @@ class BidiExecutionContext {
107
108
  throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + "\nFull val: " + JSON.stringify(response.exceptionDetails));
108
109
  if (response.type === "success") {
109
110
  if (returnByValue)
110
- return js.parseEvaluationResultValue(import_bidiDeserializer.BidiDeserializer.deserialize(response.result));
111
+ return (0, import_utilityScriptSerializers.parseEvaluationResultValue)(import_bidiDeserializer.BidiDeserializer.deserialize(response.result));
111
112
  return createHandle(utilityScript._context, response.result);
112
113
  }
113
114
  throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
@@ -33,16 +33,18 @@ __export(bidiFirefox_exports, {
33
33
  module.exports = __toCommonJS(bidiFirefox_exports);
34
34
  var import_os = __toESM(require("os"));
35
35
  var import_path = __toESM(require("path"));
36
- var import_utils = require("../../utils");
37
36
  var import_ascii = require("../utils/ascii");
38
37
  var import_browserType = require("../browserType");
39
38
  var import_bidiBrowser = require("./bidiBrowser");
40
39
  var import_bidiConnection = require("./bidiConnection");
41
40
  var import_firefoxPrefs = require("./third_party/firefoxPrefs");
41
+ var import_manualPromise = require("../../utils/isomorphic/manualPromise");
42
42
  class BidiFirefox extends import_browserType.BrowserType {
43
43
  constructor(parent) {
44
- super(parent, "bidi");
45
- this._useBidi = true;
44
+ super(parent, "_bidiFirefox");
45
+ }
46
+ executablePath() {
47
+ return "";
46
48
  }
47
49
  async connectToTransport(transport, options) {
48
50
  return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, transport, options);
@@ -57,7 +59,7 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
57
59
  error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
58
60
  return error;
59
61
  }
60
- amendEnvironment(env, userDataDir, executable, browserArguments) {
62
+ amendEnvironment(env) {
61
63
  if (!import_path.default.isAbsolute(import_os.default.homedir()))
62
64
  throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${import_os.default.platform() === "win32" ? "USERPROFILE" : "HOME"} to a relative path?`);
63
65
  env = {
@@ -74,6 +76,9 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
74
76
  attemptToGracefullyCloseBrowser(transport) {
75
77
  transport.send({ method: "browser.close", params: {}, id: import_bidiConnection.kBrowserCloseMessageId });
76
78
  }
79
+ supportsPipeTransport() {
80
+ return false;
81
+ }
77
82
  async prepareUserDataDir(options, userDataDir) {
78
83
  await (0, import_firefoxPrefs.createProfile)({
79
84
  path: userDataDir,
@@ -94,16 +99,14 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
94
99
  firefoxArguments.push(...args);
95
100
  return firefoxArguments;
96
101
  }
97
- readyState(options) {
98
- (0, import_utils.assert)(options.useWebSocket);
99
- return new FirefoxReadyState();
100
- }
101
- }
102
- class FirefoxReadyState extends import_browserType.BrowserReadyState {
103
- onBrowserOutput(message) {
104
- const match = message.match(/WebDriver BiDi listening on (ws:\/\/.*)$/);
105
- if (match)
106
- this._wsEndpoint.resolve(match[1] + "/session");
102
+ async waitForReadyState(options, browserLogsCollector) {
103
+ const result = new import_manualPromise.ManualPromise();
104
+ browserLogsCollector.onMessage((message) => {
105
+ const match = message.match(/WebDriver BiDi listening on (ws:\/\/.*)$/);
106
+ if (match)
107
+ result.resolve({ wsEndpoint: match[1] + "/session" });
108
+ });
109
+ return result;
107
110
  }
108
111
  }
109
112
  // Annotate the CommonJS export names for ESM import in node:
@@ -43,29 +43,29 @@ class RawKeyboardImpl {
43
43
  setSession(session) {
44
44
  this._session = session;
45
45
  }
46
- async keydown(modifiers, keyName, description, autoRepeat) {
46
+ async keydown(progress, modifiers, keyName, description, autoRepeat) {
47
47
  keyName = (0, import_input.resolveSmartModifierString)(keyName);
48
48
  const actions = [];
49
49
  actions.push({ type: "keyDown", value: (0, import_bidiKeyboard.getBidiKeyValue)(keyName) });
50
- await this._performActions(actions);
50
+ await this._performActions(progress, actions);
51
51
  }
52
- async keyup(modifiers, keyName, description) {
52
+ async keyup(progress, modifiers, keyName, description) {
53
53
  keyName = (0, import_input.resolveSmartModifierString)(keyName);
54
54
  const actions = [];
55
55
  actions.push({ type: "keyUp", value: (0, import_bidiKeyboard.getBidiKeyValue)(keyName) });
56
- await this._performActions(actions);
56
+ await this._performActions(progress, actions);
57
57
  }
58
- async sendText(text) {
58
+ async sendText(progress, text) {
59
59
  const actions = [];
60
60
  for (const char of text) {
61
61
  const value = (0, import_bidiKeyboard.getBidiKeyValue)(char);
62
62
  actions.push({ type: "keyDown", value });
63
63
  actions.push({ type: "keyUp", value });
64
64
  }
65
- await this._performActions(actions);
65
+ await this._performActions(progress, actions);
66
66
  }
67
- async _performActions(actions) {
68
- await this._session.send("input.performActions", {
67
+ async _performActions(progress, actions) {
68
+ await progress.race(this._session.send("input.performActions", {
69
69
  context: this._session.sessionId,
70
70
  actions: [
71
71
  {
@@ -74,26 +74,26 @@ class RawKeyboardImpl {
74
74
  actions
75
75
  }
76
76
  ]
77
- });
77
+ }));
78
78
  }
79
79
  }
80
80
  class RawMouseImpl {
81
81
  constructor(session) {
82
82
  this._session = session;
83
83
  }
84
- async move(x, y, button, buttons, modifiers, forClick) {
85
- await this._performActions([{ type: "pointerMove", x, y }]);
84
+ async move(progress, x, y, button, buttons, modifiers, forClick) {
85
+ await this._performActions(progress, [{ type: "pointerMove", x, y }]);
86
86
  }
87
- async down(x, y, button, buttons, modifiers, clickCount) {
88
- await this._performActions([{ type: "pointerDown", button: toBidiButton(button) }]);
87
+ async down(progress, x, y, button, buttons, modifiers, clickCount) {
88
+ await this._performActions(progress, [{ type: "pointerDown", button: toBidiButton(button) }]);
89
89
  }
90
- async up(x, y, button, buttons, modifiers, clickCount) {
91
- await this._performActions([{ type: "pointerUp", button: toBidiButton(button) }]);
90
+ async up(progress, x, y, button, buttons, modifiers, clickCount) {
91
+ await this._performActions(progress, [{ type: "pointerUp", button: toBidiButton(button) }]);
92
92
  }
93
- async wheel(x, y, buttons, modifiers, deltaX, deltaY) {
93
+ async wheel(progress, x, y, buttons, modifiers, deltaX, deltaY) {
94
94
  x = Math.floor(x);
95
95
  y = Math.floor(y);
96
- await this._session.send("input.performActions", {
96
+ await progress.race(this._session.send("input.performActions", {
97
97
  context: this._session.sessionId,
98
98
  actions: [
99
99
  {
@@ -102,10 +102,10 @@ class RawMouseImpl {
102
102
  actions: [{ type: "scroll", x, y, deltaX, deltaY }]
103
103
  }
104
104
  ]
105
- });
105
+ }));
106
106
  }
107
- async _performActions(actions) {
108
- await this._session.send("input.performActions", {
107
+ async _performActions(progress, actions) {
108
+ await progress.race(this._session.send("input.performActions", {
109
109
  context: this._session.sessionId,
110
110
  actions: [
111
111
  {
@@ -117,14 +117,14 @@ class RawMouseImpl {
117
117
  actions
118
118
  }
119
119
  ]
120
- });
120
+ }));
121
121
  }
122
122
  }
123
123
  class RawTouchscreenImpl {
124
124
  constructor(session) {
125
125
  this._session = session;
126
126
  }
127
- async tap(x, y, modifiers) {
127
+ async tap(progress, x, y, modifiers) {
128
128
  }
129
129
  }
130
130
  function toBidiButton(button) {
@@ -37,13 +37,12 @@ var import_cookieStore = require("../cookieStore");
37
37
  var network = __toESM(require("../network"));
38
38
  var bidi = __toESM(require("./third_party/bidiProtocol"));
39
39
  class BidiNetworkManager {
40
- constructor(bidiSession, page, onNavigationResponseStarted) {
40
+ constructor(bidiSession, page) {
41
41
  this._userRequestInterceptionEnabled = false;
42
42
  this._protocolRequestInterceptionEnabled = false;
43
43
  this._session = bidiSession;
44
44
  this._requests = /* @__PURE__ */ new Map();
45
45
  this._page = page;
46
- this._onNavigationResponseStarted = onNavigationResponseStarted;
47
46
  this._eventListeners = [
48
47
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.beforeRequestSent", this._onBeforeRequestSent.bind(this)),
49
48
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.responseStarted", this._onResponseStarted.bind(this)),
@@ -59,7 +58,7 @@ class BidiNetworkManager {
59
58
  if (param.request.url.startsWith("data:"))
60
59
  return;
61
60
  const redirectedFrom = param.redirectCount ? this._requests.get(param.request.request) || null : null;
62
- const frame = redirectedFrom ? redirectedFrom.request.frame() : param.context ? this._page._frameManager.frame(param.context) : null;
61
+ const frame = redirectedFrom ? redirectedFrom.request.frame() : param.context ? this._page.frameManager.frame(param.context) : null;
63
62
  if (!frame)
64
63
  return;
65
64
  if (redirectedFrom)
@@ -80,7 +79,7 @@ class BidiNetworkManager {
80
79
  }
81
80
  const request = new BidiRequest(frame, redirectedFrom, param, route);
82
81
  this._requests.set(request._id, request);
83
- this._page._frameManager.requestStarted(request.request, route);
82
+ this._page.frameManager.requestStarted(request.request, route);
84
83
  }
85
84
  _onResponseStarted(params) {
86
85
  const request = this._requests.get(params.request.request);
@@ -111,9 +110,7 @@ class BidiNetworkManager {
111
110
  response._securityDetailsFinished();
112
111
  response.setRawResponseHeaders(null);
113
112
  response.setResponseHeadersSize(params.response.headersSize);
114
- this._page._frameManager.requestReceivedResponse(response);
115
- if (params.navigation)
116
- this._onNavigationResponseStarted(params);
113
+ this._page.frameManager.requestReceivedResponse(response);
117
114
  }
118
115
  _onResponseCompleted(params) {
119
116
  const request = this._requests.get(params.request.request);
@@ -131,7 +128,7 @@ class BidiNetworkManager {
131
128
  response._requestFinished(responseEndTime);
132
129
  }
133
130
  response._setHttpVersion(params.response.protocol);
134
- this._page._frameManager.reportRequestFinished(request.request, response);
131
+ this._page.frameManager.reportRequestFinished(request.request, response);
135
132
  }
136
133
  _onFetchError(params) {
137
134
  const request = this._requests.get(params.request.request);
@@ -145,11 +142,11 @@ class BidiNetworkManager {
145
142
  response._requestFinished(-1);
146
143
  }
147
144
  request.request._setFailureText(params.errorText);
148
- this._page._frameManager.requestFailed(request.request, params.errorText === "NS_BINDING_ABORTED");
145
+ this._page.frameManager.requestFailed(request.request, params.errorText === "NS_BINDING_ABORTED");
149
146
  }
150
147
  _onAuthRequired(params) {
151
148
  const isBasic = params.response.authChallenges?.some((challenge) => challenge.scheme.startsWith("Basic"));
152
- const credentials = this._page._browserContext._options.httpCredentials;
149
+ const credentials = this._page.browserContext._options.httpCredentials;
153
150
  if (isBasic && credentials) {
154
151
  this._session.sendMayFail("network.continueWithAuth", {
155
152
  request: params.request.request,
@@ -206,7 +203,7 @@ class BidiRequest {
206
203
  redirectedFrom._redirectedTo = this;
207
204
  const postDataBuffer = null;
208
205
  this.request = new network.Request(
209
- frame._page._browserContext,
206
+ frame._page.browserContext,
210
207
  frame,
211
208
  null,
212
209
  redirectedFrom ? redirectedFrom.request : null,
@@ -29,13 +29,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var bidiPage_exports = {};
30
30
  __export(bidiPage_exports, {
31
31
  BidiPage: () => BidiPage,
32
- addMainBinding: () => addMainBinding,
33
32
  kPlaywrightBindingChannel: () => kPlaywrightBindingChannel
34
33
  });
35
34
  module.exports = __toCommonJS(bidiPage_exports);
36
- var import_utils = require("../../utils");
37
35
  var import_eventsHelper = require("../utils/eventsHelper");
38
- var import_browserContext = require("../browserContext");
39
36
  var dialog = __toESM(require("../dialog"));
40
37
  var dom = __toESM(require("../dom"));
41
38
  var import_page = require("../page");
@@ -49,7 +46,7 @@ const kPlaywrightBindingChannel = "playwrightChannel";
49
46
  class BidiPage {
50
47
  constructor(browserContext, bidiSession, opener) {
51
48
  this._sessionListeners = [];
52
- this._initScriptIds = [];
49
+ this._initScriptIds = /* @__PURE__ */ new Map();
53
50
  this._session = bidiSession;
54
51
  this._opener = opener;
55
52
  this.rawKeyboard = new import_bidiInput.RawKeyboardImpl(bidiSession);
@@ -58,7 +55,7 @@ class BidiPage {
58
55
  this._realmToContext = /* @__PURE__ */ new Map();
59
56
  this._page = new import_page.Page(this, browserContext);
60
57
  this._browserContext = browserContext;
61
- this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page, this._onNavigationResponseStarted.bind(this));
58
+ this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page);
62
59
  this._pdf = new import_bidiPdf.BidiPDF(this._session);
63
60
  this._page.on(import_page.Page.Events.FrameDetached, (frame) => this._removeContextsForFrame(frame, false));
64
61
  this._sessionListeners = [
@@ -66,9 +63,11 @@ class BidiPage {
66
63
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.message", this._onScriptMessage.bind(this)),
67
64
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.contextDestroyed", this._onBrowsingContextDestroyed.bind(this)),
68
65
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationStarted", this._onNavigationStarted.bind(this)),
66
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationCommitted", this._onNavigationCommitted.bind(this)),
69
67
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationAborted", this._onNavigationAborted.bind(this)),
70
68
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationFailed", this._onNavigationFailed.bind(this)),
71
69
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.fragmentNavigated", this._onFragmentNavigated.bind(this)),
70
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.historyUpdated", this._onHistoryUpdated.bind(this)),
72
71
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.domContentLoaded", this._onDomContentLoaded.bind(this)),
73
72
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.load", this._onLoad.bind(this)),
74
73
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)),
@@ -83,21 +82,18 @@ class BidiPage {
83
82
  this._onFrameAttached(this._session.sessionId, null);
84
83
  await Promise.all([
85
84
  this.updateHttpCredentials(),
86
- this.updateRequestInterception(),
87
- this._installMainBinding(),
88
- this._addAllInitScripts()
85
+ this.updateRequestInterception()
86
+ // If the page is created by the Playwright client's call, some initialization
87
+ // may be pending. Wait for it to complete before reporting the page as new.
89
88
  ]);
90
89
  }
91
- async _addAllInitScripts() {
92
- return Promise.all(this._page.allInitScripts().map((initScript) => this.addInitScript(initScript)));
93
- }
94
90
  didClose() {
95
91
  this._session.dispose();
96
92
  import_eventsHelper.eventsHelper.removeEventListeners(this._sessionListeners);
97
93
  this._page._didClose();
98
94
  }
99
95
  _onFrameAttached(frameId, parentFrameId) {
100
- return this._page._frameManager.frameAttached(frameId, parentFrameId);
96
+ return this._page.frameManager.frameAttached(frameId, parentFrameId);
101
97
  }
102
98
  _removeContextsForFrame(frame, notifyFrame) {
103
99
  for (const [contextId, context] of this._realmToContext) {
@@ -113,7 +109,7 @@ class BidiPage {
113
109
  return;
114
110
  if (realmInfo.type !== "window")
115
111
  return;
116
- const frame = this._page._frameManager.frame(realmInfo.context);
112
+ const frame = this._page.frameManager.frame(realmInfo.context);
117
113
  if (!frame)
118
114
  return;
119
115
  let worldName;
@@ -159,29 +155,13 @@ class BidiPage {
159
155
  }
160
156
  _onNavigationStarted(params) {
161
157
  const frameId = params.context;
162
- this._page._frameManager.frameRequestedNavigation(frameId, params.navigation);
163
- const url = params.url.toLowerCase();
164
- if (url.startsWith("file:") || url.startsWith("data:") || url === "about:blank") {
165
- const frame = this._page._frameManager.frame(frameId);
166
- if (frame)
167
- this._page._frameManager.frameCommittedNewDocumentNavigation(
168
- frameId,
169
- params.url,
170
- "",
171
- params.navigation,
172
- /* initial */
173
- false
174
- );
175
- }
158
+ this._page.frameManager.frameRequestedNavigation(frameId, params.navigation);
176
159
  }
177
- // TODO: there is no separate event for committed navigation, so we approximate it with responseStarted.
178
- _onNavigationResponseStarted(params) {
160
+ _onNavigationCommitted(params) {
179
161
  const frameId = params.context;
180
- const frame = this._page._frameManager.frame(frameId);
181
- (0, import_utils.assert)(frame);
182
- this._page._frameManager.frameCommittedNewDocumentNavigation(
162
+ this._page.frameManager.frameCommittedNewDocumentNavigation(
183
163
  frameId,
184
- params.response.url,
164
+ params.url,
185
165
  "",
186
166
  params.navigation,
187
167
  /* initial */
@@ -190,22 +170,25 @@ class BidiPage {
190
170
  }
191
171
  _onDomContentLoaded(params) {
192
172
  const frameId = params.context;
193
- this._page._frameManager.frameLifecycleEvent(frameId, "domcontentloaded");
173
+ this._page.frameManager.frameLifecycleEvent(frameId, "domcontentloaded");
194
174
  }
195
175
  _onLoad(params) {
196
- this._page._frameManager.frameLifecycleEvent(params.context, "load");
176
+ this._page.frameManager.frameLifecycleEvent(params.context, "load");
197
177
  }
198
178
  _onNavigationAborted(params) {
199
- this._page._frameManager.frameAbortedNavigation(params.context, "Navigation aborted", params.navigation || void 0);
179
+ this._page.frameManager.frameAbortedNavigation(params.context, "Navigation aborted", params.navigation || void 0);
200
180
  }
201
181
  _onNavigationFailed(params) {
202
- this._page._frameManager.frameAbortedNavigation(params.context, "Navigation failed", params.navigation || void 0);
182
+ this._page.frameManager.frameAbortedNavigation(params.context, "Navigation failed", params.navigation || void 0);
203
183
  }
204
184
  _onFragmentNavigated(params) {
205
- this._page._frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
185
+ this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
186
+ }
187
+ _onHistoryUpdated(params) {
188
+ this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
206
189
  }
207
190
  _onUserPromptOpened(event) {
208
- this._page.emitOnContext(import_browserContext.BrowserContext.Events.Dialog, new dialog.Dialog(
191
+ this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
209
192
  this._page,
210
193
  event.type,
211
194
  event.message,
@@ -224,7 +207,7 @@ class BidiPage {
224
207
  return;
225
208
  const callFrame = params.stackTrace?.callFrames[0];
226
209
  const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
227
- this._page._addConsoleMessage(entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
210
+ this._page.addConsoleMessage(entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
228
211
  }
229
212
  async navigateFrame(frame, url, referrer) {
230
213
  const { navigation } = await this._session.send("browsingContext.navigate", {
@@ -246,10 +229,10 @@ class BidiPage {
246
229
  }
247
230
  async updateEmulatedViewportSize() {
248
231
  const options = this._browserContext._options;
249
- const deviceSize = this._page.emulatedSize();
250
- if (deviceSize === null)
232
+ const emulatedSize = this._page.emulatedSize();
233
+ if (!emulatedSize)
251
234
  return;
252
- const viewportSize = deviceSize.viewport;
235
+ const viewportSize = emulatedSize.viewport;
253
236
  await this._session.send("browsingContext.setViewport", {
254
237
  context: this._session.sessionId,
255
238
  viewport: {
@@ -291,33 +274,6 @@ class BidiPage {
291
274
  async requestGC() {
292
275
  throw new Error("Method not implemented.");
293
276
  }
294
- // TODO: consider calling this only when bindings are added.
295
- // TODO: delete this method once we can add preload script for persistent context.
296
- async _installMainBinding() {
297
- if (this._browserContext._browserContextId)
298
- return;
299
- const functionDeclaration = addMainBinding.toString();
300
- const args = [{
301
- type: "channel",
302
- value: {
303
- channel: kPlaywrightBindingChannel,
304
- ownership: bidi.Script.ResultOwnership.Root
305
- }
306
- }];
307
- const promises = [];
308
- promises.push(this._session.send("script.addPreloadScript", {
309
- functionDeclaration,
310
- arguments: args
311
- }));
312
- promises.push(this._session.send("script.callFunction", {
313
- functionDeclaration,
314
- arguments: args,
315
- target: toBidiExecutionContext(await this._page.mainFrame()._mainContext())._target,
316
- awaitPromise: false,
317
- userActivation: false
318
- }));
319
- await Promise.all(promises);
320
- }
321
277
  async _onScriptMessage(event) {
322
278
  if (event.channel !== kPlaywrightBindingChannel)
323
279
  return;
@@ -329,7 +285,7 @@ class BidiPage {
329
285
  return;
330
286
  if (event.data.type !== "string")
331
287
  return;
332
- await this._page._onBindingCalled(event.data.value, context);
288
+ await this._page.onBindingCalled(event.data.value, context);
333
289
  }
334
290
  async addInitScript(initScript) {
335
291
  const { script } = await this._session.send("script.addPreloadScript", {
@@ -338,13 +294,17 @@ class BidiPage {
338
294
  // TODO: push to iframes?
339
295
  contexts: [this._session.sessionId]
340
296
  });
341
- if (!initScript.internal)
342
- this._initScriptIds.push(script);
343
- }
344
- async removeInitScripts() {
345
- const promises = this._initScriptIds.map((script) => this._session.send("script.removePreloadScript", { script }));
346
- this._initScriptIds = [];
347
- await Promise.all(promises);
297
+ this._initScriptIds.set(initScript, script);
298
+ }
299
+ async removeInitScripts(initScripts) {
300
+ const ids = [];
301
+ for (const script of initScripts) {
302
+ const id = this._initScriptIds.get(script);
303
+ if (id)
304
+ ids.push(id);
305
+ this._initScriptIds.delete(script);
306
+ }
307
+ await Promise.all(ids.map((script) => this._session.send("script.removePreloadScript", { script })));
348
308
  }
349
309
  async closePage(runBeforeUnload) {
350
310
  await this._session.send("browsingContext.close", {
@@ -356,7 +316,7 @@ class BidiPage {
356
316
  }
357
317
  async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) {
358
318
  const rect = documentRect || viewportRect;
359
- const { data } = await this._session.send("browsingContext.captureScreenshot", {
319
+ const { data } = await progress.race(this._session.send("browsingContext.captureScreenshot", {
360
320
  context: this._session.sessionId,
361
321
  format: {
362
322
  type: `image/${format === "png" ? "png" : "jpeg"}`,
@@ -367,7 +327,7 @@ class BidiPage {
367
327
  type: "box",
368
328
  ...rect
369
329
  }
370
- });
330
+ }));
371
331
  return Buffer.from(data, "base64");
372
332
  }
373
333
  async getContentFrame(handle) {
@@ -375,7 +335,7 @@ class BidiPage {
375
335
  const frameId = await executionContext.contentFrameIdForFrame(handle);
376
336
  if (!frameId)
377
337
  return null;
378
- return this._page._frameManager.frame(frameId);
338
+ return this._page.frameManager.frame(frameId);
379
339
  }
380
340
  async getOwnerFrame(handle) {
381
341
  const windowHandle = await handle.evaluateHandle((node) => {
@@ -482,7 +442,7 @@ class BidiPage {
482
442
  }
483
443
  async inputActionEpilogue() {
484
444
  }
485
- async resetForReuse() {
445
+ async resetForReuse(progress) {
486
446
  }
487
447
  async pdf(options) {
488
448
  return this._pdf.generate(options);
@@ -516,15 +476,11 @@ class BidiPage {
516
476
  return true;
517
477
  }
518
478
  }
519
- function addMainBinding(callback) {
520
- globalThis["__playwright__binding__"] = callback;
521
- }
522
479
  function toBidiExecutionContext(executionContext) {
523
480
  return executionContext.delegate;
524
481
  }
525
482
  // Annotate the CommonJS export names for ESM import in node:
526
483
  0 && (module.exports = {
527
484
  BidiPage,
528
- addMainBinding,
529
485
  kPlaywrightBindingChannel
530
486
  });