brave-real-playwright-core 1.55.1 → 1.56.1

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 (94) hide show
  1. package/README.md +5 -5
  2. package/advanced-stealth.js +1 -1
  3. package/lib/browserServerImpl.js +3 -6
  4. package/lib/client/browser.js +0 -10
  5. package/lib/client/browserContext.js +2 -8
  6. package/lib/client/channelOwner.js +0 -7
  7. package/lib/client/consoleMessage.js +2 -3
  8. package/lib/client/electron.js +1 -1
  9. package/lib/client/events.js +1 -0
  10. package/lib/client/network.js +3 -0
  11. package/lib/client/page.js +13 -1
  12. package/lib/generated/bindingsControllerSource.js +1 -1
  13. package/lib/generated/injectedScriptSource.js +1 -1
  14. package/lib/generated/pollingRecorderSource.js +1 -1
  15. package/lib/generated/utilityScriptSource.js +1 -1
  16. package/lib/protocol/validator.js +26 -15
  17. package/lib/remote/playwrightServer.js +12 -14
  18. package/lib/server/bidi/bidiBrowser.js +54 -10
  19. package/lib/server/bidi/bidiChromium.js +1 -1
  20. package/lib/server/bidi/bidiConnection.js +31 -6
  21. package/lib/server/bidi/bidiExecutionContext.js +4 -4
  22. package/lib/server/bidi/bidiFirefox.js +16 -1
  23. package/lib/server/bidi/bidiNetworkManager.js +82 -16
  24. package/lib/server/bidi/bidiPage.js +84 -18
  25. package/lib/server/browserType.js +3 -3
  26. package/lib/server/chromium/chromium.js +1 -1
  27. package/lib/server/chromium/chromiumSwitches.js +3 -1
  28. package/lib/server/chromium/crBrowser.js +4 -34
  29. package/lib/server/chromium/crPage.js +22 -31
  30. package/lib/server/codegen/csharp.js +19 -26
  31. package/lib/server/codegen/java.js +4 -0
  32. package/lib/server/codegen/javascript.js +3 -1
  33. package/lib/server/codegen/python.js +2 -0
  34. package/lib/server/debugController.js +8 -36
  35. package/lib/server/deviceDescriptorsSource.json +62 -62
  36. package/lib/server/dispatchers/androidDispatcher.js +17 -0
  37. package/lib/server/dispatchers/browserContextDispatcher.js +1 -15
  38. package/lib/server/dispatchers/networkDispatchers.js +6 -3
  39. package/lib/server/dispatchers/pageDispatcher.js +24 -0
  40. package/lib/server/dom.js +8 -3
  41. package/lib/server/firefox/ffPage.js +1 -2
  42. package/lib/server/firefox/firefox.js +1 -1
  43. package/lib/server/frames.js +12 -4
  44. package/lib/server/har/harTracer.js +7 -8
  45. package/lib/server/network.js +12 -0
  46. package/lib/server/page.js +39 -17
  47. package/lib/server/recorder/chat.js +2 -2
  48. package/lib/server/recorder/recorderRunner.js +4 -0
  49. package/lib/server/registry/browserFetcher.js +3 -3
  50. package/lib/server/registry/index.js +27 -0
  51. package/lib/server/trace/recorder/snapshotter.js +13 -2
  52. package/lib/server/trace/recorder/snapshotterInjected.js +3 -1
  53. package/lib/server/utils/comparators.js +2 -2
  54. package/lib/server/utils/env.js +7 -2
  55. package/lib/server/utils/wsServer.js +2 -7
  56. package/lib/server/webkit/webkit.js +24 -8
  57. package/lib/server/webkit/wkBrowser.js +7 -3
  58. package/lib/server/webkit/wkPage.js +7 -8
  59. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +74 -0
  60. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +113 -0
  61. package/lib/utils/isomorphic/ariaSnapshot.js +12 -10
  62. package/lib/utils/isomorphic/protocolMetainfo.js +3 -0
  63. package/lib/utils/isomorphic/urlMatch.js +3 -8
  64. package/lib/utilsBundle.js +3 -0
  65. package/lib/utilsBundleImpl/index.js +80 -80
  66. package/lib/vite/htmlReport/index.html +37 -28
  67. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +24 -0
  68. package/lib/vite/recorder/assets/index-Ri0uHF7I.css +1 -0
  69. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +193 -0
  70. package/lib/vite/recorder/index.html +2 -2
  71. package/lib/vite/traceViewer/assets/codeMirrorModule-eyVcHN77.js +24 -0
  72. package/lib/vite/traceViewer/assets/defaultSettingsView-w0zYjHsW.js +265 -0
  73. package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
  74. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +1 -0
  75. package/lib/vite/traceViewer/index.Bx16ehp1.js +2 -0
  76. package/lib/vite/traceViewer/index.I8N9v4jT.css +1 -0
  77. package/lib/vite/traceViewer/index.html +4 -4
  78. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  79. package/lib/vite/traceViewer/uiMode.Btcz36p_.css +1 -0
  80. package/lib/vite/traceViewer/uiMode.DRQ310U5.js +5 -0
  81. package/lib/vite/traceViewer/uiMode.html +4 -4
  82. package/lib/vite/traceViewer/{xtermModule.Beg8tuEN.css → xtermModule.DYP7pi_n.css} +1 -1
  83. package/package.json +9 -9
  84. package/lib/vite/recorder/assets/codeMirrorModule-DzQ0k89p.js +0 -24
  85. package/lib/vite/recorder/assets/index-CI4HQ-Zb.css +0 -1
  86. package/lib/vite/recorder/assets/index-D7C7daHH.js +0 -184
  87. package/lib/vite/traceViewer/assets/codeMirrorModule-CEFqZ5b3.js +0 -24
  88. package/lib/vite/traceViewer/assets/defaultSettingsView-BA25Usqk.js +0 -256
  89. package/lib/vite/traceViewer/assets/xtermModule-BoAIEibi.js +0 -9
  90. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +0 -1
  91. package/lib/vite/traceViewer/index.BFsek2M6.css +0 -1
  92. package/lib/vite/traceViewer/index.CheexZ4_.js +0 -2
  93. package/lib/vite/traceViewer/uiMode.BatfzHMG.css +0 -1
  94. package/lib/vite/traceViewer/uiMode.Dy4dnPNW.js +0 -5
@@ -30,7 +30,8 @@ var bidiBrowser_exports = {};
30
30
  __export(bidiBrowser_exports, {
31
31
  BidiBrowser: () => BidiBrowser,
32
32
  BidiBrowserContext: () => BidiBrowserContext,
33
- Network: () => Network
33
+ Network: () => Network,
34
+ getScreenOrientation: () => getScreenOrientation
34
35
  });
35
36
  module.exports = __toCommonJS(bidiBrowser_exports);
36
37
  var import_eventsHelper = require("../utils/eventsHelper");
@@ -78,6 +79,11 @@ class BidiBrowser extends import_browser.Browser {
78
79
  "script"
79
80
  ]
80
81
  });
82
+ await browser._browserSession.send("network.addDataCollector", {
83
+ dataTypes: [bidi.Network.DataType.Response],
84
+ maxEncodedDataSize: 2e7
85
+ // same default as in CDP: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/inspector/inspector_network_agent.cc;l=134;drc=4128411589187a396829a827f59a655bed876aa7
86
+ });
81
87
  if (options.persistent) {
82
88
  const context = new BidiBrowserContext(browser, void 0, options.persistent);
83
89
  browser._defaultContext = context;
@@ -189,6 +195,18 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
189
195
  userContexts: [this._userContextId()]
190
196
  }));
191
197
  }
198
+ if (this._options.timezoneId) {
199
+ promises.push(this._browser._browserSession.send("emulation.setTimezoneOverride", {
200
+ timezone: this._options.timezoneId,
201
+ userContexts: [this._userContextId()]
202
+ }));
203
+ }
204
+ if (this._options.userAgent) {
205
+ promises.push(this._browser._browserSession.send("emulation.setUserAgentOverride", {
206
+ userAgent: this._options.userAgent,
207
+ userContexts: [this._userContextId()]
208
+ }));
209
+ }
192
210
  await Promise.all(promises);
193
211
  }
194
212
  possiblyUninitializedPages() {
@@ -284,6 +302,11 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
284
302
  async doUpdateExtraHTTPHeaders() {
285
303
  }
286
304
  async setUserAgent(userAgent) {
305
+ this._options.userAgent = userAgent;
306
+ await this._browser._browserSession.send("emulation.setUserAgentOverride", {
307
+ userAgent: userAgent ?? null,
308
+ userContexts: [this._userContextId()]
309
+ });
287
310
  }
288
311
  async doUpdateOffline() {
289
312
  }
@@ -315,14 +338,20 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
315
338
  async doUpdateDefaultViewport() {
316
339
  if (!this._options.viewport)
317
340
  return;
318
- await this._browser._browserSession.send("browsingContext.setViewport", {
319
- viewport: {
320
- width: this._options.viewport.width,
321
- height: this._options.viewport.height
322
- },
323
- devicePixelRatio: this._options.deviceScaleFactor || 1,
324
- userContexts: [this._userContextId()]
325
- });
341
+ await Promise.all([
342
+ this._browser._browserSession.send("browsingContext.setViewport", {
343
+ viewport: {
344
+ width: this._options.viewport.width,
345
+ height: this._options.viewport.height
346
+ },
347
+ devicePixelRatio: this._options.deviceScaleFactor || 1,
348
+ userContexts: [this._userContextId()]
349
+ }),
350
+ this._browser._browserSession.send("emulation.setScreenOrientationOverride", {
351
+ screenOrientation: getScreenOrientation(!!this._options.isMobile, this._options.viewport),
352
+ userContexts: [this._userContextId()]
353
+ })
354
+ ]);
326
355
  }
327
356
  async doUpdateDefaultEmulatedMedia() {
328
357
  }
@@ -385,6 +414,8 @@ function fromBidiSameSite(sameSite) {
385
414
  return "Lax";
386
415
  case "none":
387
416
  return "None";
417
+ case "default":
418
+ return "Lax";
388
419
  }
389
420
  return "None";
390
421
  }
@@ -429,6 +460,18 @@ function getProxyConfiguration(proxySettings) {
429
460
  proxy.noProxy = bypass.split(",");
430
461
  return proxy;
431
462
  }
463
+ function getScreenOrientation(isMobile, viewportSize) {
464
+ const screenOrientation = {
465
+ type: "landscape-primary",
466
+ natural: bidi.Emulation.ScreenOrientationNatural.Landscape
467
+ };
468
+ if (isMobile) {
469
+ screenOrientation.natural = bidi.Emulation.ScreenOrientationNatural.Portrait;
470
+ if (viewportSize.width <= viewportSize.height)
471
+ screenOrientation.type = "portrait-primary";
472
+ }
473
+ return screenOrientation;
474
+ }
432
475
  var Network;
433
476
  ((Network2) => {
434
477
  let SameSite;
@@ -442,5 +485,6 @@ var Network;
442
485
  0 && (module.exports = {
443
486
  BidiBrowser,
444
487
  BidiBrowserContext,
445
- Network
488
+ Network,
489
+ getScreenOrientation
446
490
  });
@@ -86,7 +86,7 @@ class BidiChromium extends import_browserType.BrowserType {
86
86
  supportsPipeTransport() {
87
87
  return false;
88
88
  }
89
- defaultArgs(options, isPersistent, userDataDir) {
89
+ async defaultArgs(options, isPersistent, userDataDir) {
90
90
  const chromeArguments = this._innerDefaultArgs(options);
91
91
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
92
92
  chromeArguments.push("--remote-debugging-port=0");
@@ -20,19 +20,24 @@ var bidiConnection_exports = {};
20
20
  __export(bidiConnection_exports, {
21
21
  BidiConnection: () => BidiConnection,
22
22
  BidiSession: () => BidiSession,
23
- kBrowserCloseMessageId: () => kBrowserCloseMessageId
23
+ kBrowserCloseMessageId: () => kBrowserCloseMessageId,
24
+ kShutdownSessionNewMessageId: () => kShutdownSessionNewMessageId
24
25
  });
25
26
  module.exports = __toCommonJS(bidiConnection_exports);
26
27
  var import_events = require("events");
27
28
  var import_debugLogger = require("../utils/debugLogger");
28
29
  var import_helper = require("../helper");
29
30
  var import_protocolError = require("../protocolError");
30
- const kBrowserCloseMessageId = 0;
31
+ const kBrowserCloseMessageId = Number.MAX_SAFE_INTEGER - 1;
32
+ const kShutdownSessionNewMessageId = kBrowserCloseMessageId - 1;
31
33
  class BidiConnection {
32
34
  constructor(transport, onDisconnect, protocolLogger, browserLogsCollector) {
33
35
  this._lastId = 0;
34
36
  this._closed = false;
35
37
  this._browsingContextToSession = /* @__PURE__ */ new Map();
38
+ this._realmToBrowsingContext = /* @__PURE__ */ new Map();
39
+ // TODO: shared/service workers might have multiple owner realms.
40
+ this._realmToOwnerRealm = /* @__PURE__ */ new Map();
36
41
  this._transport = transport;
37
42
  this._onDisconnect = onDisconnect;
38
43
  this._protocolLogger = protocolLogger;
@@ -54,11 +59,30 @@ class BidiConnection {
54
59
  this._protocolLogger("receive", message);
55
60
  const object = message;
56
61
  if (object.type === "event") {
62
+ if (object.method === "script.realmCreated") {
63
+ if ("context" in object.params)
64
+ this._realmToBrowsingContext.set(object.params.realm, object.params.context);
65
+ if (object.params.type === "dedicated-worker")
66
+ this._realmToOwnerRealm.set(object.params.realm, object.params.owners[0]);
67
+ } else if (object.method === "script.realmDestroyed") {
68
+ this._realmToBrowsingContext.delete(object.params.realm);
69
+ this._realmToOwnerRealm.delete(object.params.realm);
70
+ }
57
71
  let context;
58
- if ("context" in object.params)
72
+ let realm;
73
+ if ("context" in object.params) {
59
74
  context = object.params.context;
60
- else if (object.method === "log.entryAdded" || object.method === "script.message")
75
+ } else if (object.method === "log.entryAdded" || object.method === "script.message") {
61
76
  context = object.params.source?.context;
77
+ realm = object.params.source?.realm;
78
+ } else if (object.method === "script.realmCreated" && object.params.type === "dedicated-worker") {
79
+ realm = object.params.owners[0];
80
+ }
81
+ if (!context && realm) {
82
+ while (this._realmToOwnerRealm.get(realm))
83
+ realm = this._realmToOwnerRealm.get(realm);
84
+ context = this._realmToBrowsingContext.get(realm);
85
+ }
62
86
  if (context) {
63
87
  const session = this._browsingContextToSession.get(context);
64
88
  if (session) {
@@ -159,7 +183,7 @@ class BidiSession extends import_events.EventEmitter {
159
183
  }
160
184
  dispatchMessage(message) {
161
185
  const object = message;
162
- if (object.id === kBrowserCloseMessageId)
186
+ if (object.id === kBrowserCloseMessageId || object.id === kShutdownSessionNewMessageId)
163
187
  return;
164
188
  if (object.id && this._callbacks.has(object.id)) {
165
189
  const callback = this._callbacks.get(object.id);
@@ -183,5 +207,6 @@ class BidiSession extends import_events.EventEmitter {
183
207
  0 && (module.exports = {
184
208
  BidiConnection,
185
209
  BidiSession,
186
- kBrowserCloseMessageId
210
+ kBrowserCloseMessageId,
211
+ kShutdownSessionNewMessageId
187
212
  });
@@ -67,7 +67,7 @@ class BidiExecutionContext {
67
67
  if (response.type === "success")
68
68
  return import_bidiDeserializer.BidiDeserializer.deserialize(response.result);
69
69
  if (response.type === "exception")
70
- throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + "\nFull val: " + JSON.stringify(response.exceptionDetails));
70
+ throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
71
71
  throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
72
72
  }
73
73
  async rawEvaluateHandle(context, expression) {
@@ -86,7 +86,7 @@ class BidiExecutionContext {
86
86
  throw new js.JavaScriptErrorInEvaluate("Cannot get handle: " + JSON.stringify(response.result));
87
87
  }
88
88
  if (response.type === "exception")
89
- throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + "\nFull val: " + JSON.stringify(response.exceptionDetails));
89
+ throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
90
90
  throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
91
91
  }
92
92
  async evaluateWithArguments(functionDeclaration, returnByValue, utilityScript, values, handles) {
@@ -105,7 +105,7 @@ class BidiExecutionContext {
105
105
  userActivation: true
106
106
  });
107
107
  if (response.type === "exception")
108
- throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + "\nFull val: " + JSON.stringify(response.exceptionDetails));
108
+ throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
109
109
  if (response.type === "success") {
110
110
  if (returnByValue)
111
111
  return (0, import_utilityScriptSerializers.parseEvaluationResultValue)(import_bidiDeserializer.BidiDeserializer.deserialize(response.result));
@@ -180,7 +180,7 @@ class BidiExecutionContext {
180
180
  userActivation: true
181
181
  });
182
182
  if (response.type === "exception")
183
- throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text + "\nFull val: " + JSON.stringify(response.exceptionDetails));
183
+ throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
184
184
  if (response.type === "success")
185
185
  return response.result;
186
186
  throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
@@ -74,6 +74,19 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
74
74
  return env;
75
75
  }
76
76
  attemptToGracefullyCloseBrowser(transport) {
77
+ this._attemptToGracefullyCloseBrowser(transport).catch(() => {
78
+ });
79
+ }
80
+ async _attemptToGracefullyCloseBrowser(transport) {
81
+ if (!transport.onmessage) {
82
+ transport.send({ method: "session.new", params: { capabilities: {} }, id: import_bidiConnection.kShutdownSessionNewMessageId });
83
+ await new Promise((resolve) => {
84
+ transport.onmessage = (message) => {
85
+ if (message.id === import_bidiConnection.kShutdownSessionNewMessageId)
86
+ resolve(true);
87
+ };
88
+ });
89
+ }
77
90
  transport.send({ method: "browser.close", params: {}, id: import_bidiConnection.kBrowserCloseMessageId });
78
91
  }
79
92
  supportsPipeTransport() {
@@ -85,11 +98,13 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
85
98
  preferences: options.firefoxUserPrefs || {}
86
99
  });
87
100
  }
88
- defaultArgs(options, isPersistent, userDataDir) {
101
+ async defaultArgs(options, isPersistent, userDataDir) {
89
102
  const { args = [], headless } = options;
90
103
  const userDataDirArg = args.find((arg) => arg.startsWith("-profile") || arg.startsWith("--profile"));
91
104
  if (userDataDirArg)
92
105
  throw this._createUserDataDirArgMisuseError("--profile");
106
+ if (args.find((arg) => !arg.startsWith("-")))
107
+ throw new Error("Arguments can not specify page to be opened");
93
108
  const firefoxArguments = ["--remote-debugging-port=0"];
94
109
  if (headless)
95
110
  firefoxArguments.push("--headless");
@@ -40,6 +40,7 @@ class BidiNetworkManager {
40
40
  constructor(bidiSession, page) {
41
41
  this._userRequestInterceptionEnabled = false;
42
42
  this._protocolRequestInterceptionEnabled = false;
43
+ this._attemptedAuthentications = /* @__PURE__ */ new Set();
43
44
  this._session = bidiSession;
44
45
  this._requests = /* @__PURE__ */ new Map();
45
46
  this._page = page;
@@ -62,7 +63,7 @@ class BidiNetworkManager {
62
63
  if (!frame)
63
64
  return;
64
65
  if (redirectedFrom)
65
- this._requests.delete(redirectedFrom._id);
66
+ this._deleteRequest(redirectedFrom._id);
66
67
  let route;
67
68
  if (param.intercepts) {
68
69
  if (redirectedFrom) {
@@ -86,7 +87,9 @@ class BidiNetworkManager {
86
87
  if (!request)
87
88
  return;
88
89
  const getResponseBody = async () => {
89
- throw new Error(`Response body is not available for requests in Bidi`);
90
+ const { bytes } = await this._session.send("network.getData", { request: params.request.request, dataType: bidi.Network.DataType.Response });
91
+ const encoding = bytes.type === "base64" ? "base64" : "utf8";
92
+ return Buffer.from(bytes.value, encoding);
90
93
  };
91
94
  const timings = params.request.timings;
92
95
  const startTime = timings.requestTime;
@@ -124,7 +127,7 @@ class BidiNetworkManager {
124
127
  if (isRedirected) {
125
128
  response._requestFinished(responseEndTime);
126
129
  } else {
127
- this._requests.delete(request._id);
130
+ this._deleteRequest(request._id);
128
131
  response._requestFinished(responseEndTime);
129
132
  }
130
133
  response._setHttpVersion(params.response.protocol);
@@ -134,7 +137,7 @@ class BidiNetworkManager {
134
137
  const request = this._requests.get(params.request.request);
135
138
  if (!request)
136
139
  return;
137
- this._requests.delete(request._id);
140
+ this._deleteRequest(request._id);
138
141
  const response = request.request._existingResponse();
139
142
  if (response) {
140
143
  response.setTransferSize(null);
@@ -147,23 +150,35 @@ class BidiNetworkManager {
147
150
  _onAuthRequired(params) {
148
151
  const isBasic = params.response.authChallenges?.some((challenge) => challenge.scheme.startsWith("Basic"));
149
152
  const credentials = this._page.browserContext._options.httpCredentials;
150
- if (isBasic && credentials) {
151
- this._session.sendMayFail("network.continueWithAuth", {
152
- request: params.request.request,
153
- action: "provideCredentials",
154
- credentials: {
155
- type: "password",
156
- username: credentials.username,
157
- password: credentials.password
158
- }
159
- });
153
+ if (isBasic && credentials && (!credentials.origin || new URL(params.request.url).origin.toLowerCase() === credentials.origin.toLowerCase())) {
154
+ if (this._attemptedAuthentications.has(params.request.request)) {
155
+ this._session.sendMayFail("network.continueWithAuth", {
156
+ request: params.request.request,
157
+ action: "cancel"
158
+ });
159
+ } else {
160
+ this._attemptedAuthentications.add(params.request.request);
161
+ this._session.sendMayFail("network.continueWithAuth", {
162
+ request: params.request.request,
163
+ action: "provideCredentials",
164
+ credentials: {
165
+ type: "password",
166
+ username: credentials.username,
167
+ password: credentials.password
168
+ }
169
+ });
170
+ }
160
171
  } else {
161
172
  this._session.sendMayFail("network.continueWithAuth", {
162
173
  request: params.request.request,
163
- action: "default"
174
+ action: "cancel"
164
175
  });
165
176
  }
166
177
  }
178
+ _deleteRequest(requestId) {
179
+ this._requests.delete(requestId);
180
+ this._attemptedAuthentications.delete(requestId);
181
+ }
167
182
  async setRequestInterception(value) {
168
183
  this._userRequestInterceptionEnabled = value;
169
184
  await this._updateProtocolRequestInterception();
@@ -209,7 +224,7 @@ class BidiRequest {
209
224
  redirectedFrom ? redirectedFrom.request : null,
210
225
  payload.navigation ?? void 0,
211
226
  payload.request.url,
212
- "other",
227
+ resourceTypeFromBidi(payload.request.destination, payload.request.initiatorType, payload.initiator?.type),
213
228
  payload.request.method,
214
229
  postDataBuffer,
215
230
  fromBidiHeaders(payload.request.headers)
@@ -310,6 +325,57 @@ function toBidiSameSite(sameSite) {
310
325
  return bidi.Network.SameSite.Lax;
311
326
  return bidi.Network.SameSite.None;
312
327
  }
328
+ function resourceTypeFromBidi(requestDestination, requestInitiatorType, eventInitiatorType) {
329
+ switch (requestDestination) {
330
+ case "audio":
331
+ return "media";
332
+ case "audioworklet":
333
+ return "script";
334
+ case "document":
335
+ return "document";
336
+ case "font":
337
+ return "font";
338
+ case "frame":
339
+ return "document";
340
+ case "iframe":
341
+ return "document";
342
+ case "image":
343
+ return "image";
344
+ case "object":
345
+ return "object";
346
+ case "paintworklet":
347
+ return "script";
348
+ case "script":
349
+ return "script";
350
+ case "serviceworker":
351
+ return "script";
352
+ case "sharedworker":
353
+ return "script";
354
+ case "style":
355
+ return "stylesheet";
356
+ case "track":
357
+ return "texttrack";
358
+ case "video":
359
+ return "media";
360
+ case "worker":
361
+ return "script";
362
+ case "":
363
+ switch (requestInitiatorType) {
364
+ case "fetch":
365
+ return "fetch";
366
+ case "font":
367
+ return "font";
368
+ case "xmlhttprequest":
369
+ return "xhr";
370
+ case null:
371
+ return eventInitiatorType === "script" ? "xhr" : "document";
372
+ default:
373
+ return "other";
374
+ }
375
+ default:
376
+ return "other";
377
+ }
378
+ }
313
379
  // Annotate the CommonJS export names for ESM import in node:
314
380
  0 && (module.exports = {
315
381
  BidiNetworkManager,
@@ -35,6 +35,7 @@ module.exports = __toCommonJS(bidiPage_exports);
35
35
  var import_eventsHelper = require("../utils/eventsHelper");
36
36
  var dialog = __toESM(require("../dialog"));
37
37
  var dom = __toESM(require("../dom"));
38
+ var import_bidiBrowser = require("./bidiBrowser");
38
39
  var import_page = require("../page");
39
40
  var import_bidiExecutionContext = require("./bidiExecutionContext");
40
41
  var import_bidiInput = require("./bidiInput");
@@ -45,6 +46,7 @@ const UTILITY_WORLD_NAME = "__playwright_utility_world__";
45
46
  const kPlaywrightBindingChannel = "playwrightChannel";
46
47
  class BidiPage {
47
48
  constructor(browserContext, bidiSession, opener) {
49
+ this._realmToWorkerContext = /* @__PURE__ */ new Map();
48
50
  this._sessionListeners = [];
49
51
  this._initScriptIds = /* @__PURE__ */ new Map();
50
52
  this._session = bidiSession;
@@ -70,6 +72,8 @@ class BidiPage {
70
72
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.historyUpdated", this._onHistoryUpdated.bind(this)),
71
73
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.domContentLoaded", this._onDomContentLoaded.bind(this)),
72
74
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.load", this._onLoad.bind(this)),
75
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadWillBegin", this._onDownloadWillBegin.bind(this)),
76
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadEnd", this._onDownloadEnded.bind(this)),
73
77
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)),
74
78
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this))
75
79
  ];
@@ -105,6 +109,13 @@ class BidiPage {
105
109
  }
106
110
  }
107
111
  _onRealmCreated(realmInfo) {
112
+ if (realmInfo.type === "dedicated-worker") {
113
+ const delegate2 = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
114
+ const worker = new import_page.Worker(this._page, realmInfo.origin);
115
+ this._realmToWorkerContext.set(realmInfo.realm, worker.createExecutionContext(delegate2));
116
+ this._page.addWorker(realmInfo.realm, worker);
117
+ return;
118
+ }
108
119
  if (this._realmToContext.has(realmInfo.realm))
109
120
  return;
110
121
  if (realmInfo.type !== "window")
@@ -143,11 +154,17 @@ class BidiPage {
143
154
  }
144
155
  _onRealmDestroyed(params) {
145
156
  const context = this._realmToContext.get(params.realm);
146
- if (!context)
147
- return false;
148
- this._realmToContext.delete(params.realm);
149
- context.frame._contextDestroyed(context);
150
- return true;
157
+ if (context) {
158
+ this._realmToContext.delete(params.realm);
159
+ context.frame._contextDestroyed(context);
160
+ return true;
161
+ }
162
+ const existed = this._realmToWorkerContext.delete(params.realm);
163
+ if (existed) {
164
+ this._page.removeWorker(params.realm);
165
+ return true;
166
+ }
167
+ return false;
151
168
  }
152
169
  // TODO: route the message directly to the browser
153
170
  _onBrowsingContextDestroyed(params) {
@@ -198,11 +215,47 @@ class BidiPage {
198
215
  event.defaultValue
199
216
  ));
200
217
  }
218
+ _onDownloadWillBegin(event) {
219
+ if (!event.navigation)
220
+ return;
221
+ this._page.frameManager.frameAbortedNavigation(event.context, "Download is starting");
222
+ let originPage = this._page.initializedOrUndefined();
223
+ if (!originPage && this._opener)
224
+ originPage = this._opener._page.initializedOrUndefined();
225
+ if (!originPage)
226
+ return;
227
+ this._browserContext._browser._downloadCreated(originPage, event.navigation, event.url, event.suggestedFilename);
228
+ }
229
+ _onDownloadEnded(event) {
230
+ if (!event.navigation)
231
+ return;
232
+ this._browserContext._browser._downloadFinished(event.navigation, event.status === "canceled" ? "canceled" : void 0);
233
+ }
201
234
  _onLogEntryAdded(params) {
235
+ if (params.type === "javascript" && params.level === "error") {
236
+ let errorName = "";
237
+ let errorMessage;
238
+ if (params.text?.includes(": ")) {
239
+ const index = params.text.indexOf(": ");
240
+ errorName = params.text.substring(0, index);
241
+ errorMessage = params.text.substring(index + 2);
242
+ } else {
243
+ errorMessage = params.text ?? void 0;
244
+ }
245
+ const error = new Error(errorMessage);
246
+ error.name = errorName;
247
+ error.stack = `${params.text}
248
+ ${params.stackTrace?.callFrames.map((f) => {
249
+ const location2 = `${f.url}:${f.lineNumber + 1}:${f.columnNumber + 1}`;
250
+ return f.functionName ? ` at ${f.functionName} (${location2})` : ` at ${location2}`;
251
+ }).join("\n")}`;
252
+ this._page.addPageError(error);
253
+ return;
254
+ }
202
255
  if (params.type !== "console")
203
256
  return;
204
257
  const entry = params;
205
- const context = this._realmToContext.get(params.source.realm);
258
+ const context = this._realmToContext.get(params.source.realm) ?? this._realmToWorkerContext.get(params.source.realm);
206
259
  if (!context)
207
260
  return;
208
261
  const callFrame = params.stackTrace?.callFrames[0];
@@ -233,14 +286,20 @@ class BidiPage {
233
286
  if (!emulatedSize)
234
287
  return;
235
288
  const viewportSize = emulatedSize.viewport;
236
- await this._session.send("browsingContext.setViewport", {
237
- context: this._session.sessionId,
238
- viewport: {
239
- width: viewportSize.width,
240
- height: viewportSize.height
241
- },
242
- devicePixelRatio: options.deviceScaleFactor || 1
243
- });
289
+ await Promise.all([
290
+ this._session.send("browsingContext.setViewport", {
291
+ context: this._session.sessionId,
292
+ viewport: {
293
+ width: viewportSize.width,
294
+ height: viewportSize.height
295
+ },
296
+ devicePixelRatio: options.deviceScaleFactor || 1
297
+ }),
298
+ this._session.send("emulation.setScreenOrientationOverride", {
299
+ contexts: [this._session.sessionId],
300
+ screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile, viewportSize)
301
+ })
302
+ ]);
244
303
  }
245
304
  async updateRequestInterception() {
246
305
  await this._networkManager.setRequestInterception(this._page.needsRequestInterception());
@@ -307,10 +366,17 @@ class BidiPage {
307
366
  await Promise.all(ids.map((script) => this._session.send("script.removePreloadScript", { script })));
308
367
  }
309
368
  async closePage(runBeforeUnload) {
310
- await this._session.send("browsingContext.close", {
311
- context: this._session.sessionId,
312
- promptUnload: runBeforeUnload
313
- });
369
+ if (runBeforeUnload) {
370
+ this._session.sendMayFail("browsingContext.close", {
371
+ context: this._session.sessionId,
372
+ promptUnload: runBeforeUnload
373
+ });
374
+ } else {
375
+ await this._session.send("browsingContext.close", {
376
+ context: this._session.sessionId,
377
+ promptUnload: runBeforeUnload
378
+ });
379
+ }
314
380
  }
315
381
  async setBackgroundColor(color) {
316
382
  }
@@ -169,9 +169,9 @@ class BrowserType extends import_instrumentation.SdkObject {
169
169
  if (ignoreAllDefaultArgs)
170
170
  browserArguments.push(...args);
171
171
  else if (ignoreDefaultArgs)
172
- browserArguments.push(...this.defaultArgs(options, isPersistent, userDataDir).filter((arg) => ignoreDefaultArgs.indexOf(arg) === -1));
172
+ browserArguments.push(...(await this.defaultArgs(options, isPersistent, userDataDir)).filter((arg) => ignoreDefaultArgs.indexOf(arg) === -1));
173
173
  else
174
- browserArguments.push(...this.defaultArgs(options, isPersistent, userDataDir));
174
+ browserArguments.push(...await this.defaultArgs(options, isPersistent, userDataDir));
175
175
  let executable;
176
176
  if (executablePath) {
177
177
  if (!await (0, import_fileUtils.existsAsync)(executablePath))
@@ -200,7 +200,7 @@ class BrowserType extends import_instrumentation.SdkObject {
200
200
  const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
201
201
  command: prepared.executable,
202
202
  args: prepared.browserArguments,
203
- env: this.amendEnvironment(env, prepared.userDataDir, isPersistent),
203
+ env: this.amendEnvironment(env, prepared.userDataDir, isPersistent, options),
204
204
  handleSIGINT,
205
205
  handleSIGTERM,
206
206
  handleSIGHUP,
@@ -250,7 +250,7 @@ class Chromium extends import_browserType.BrowserType {
250
250
  throw e;
251
251
  }
252
252
  }
253
- defaultArgs(options, isPersistent, userDataDir) {
253
+ async defaultArgs(options, isPersistent, userDataDir) {
254
254
  const chromeArguments = this._innerDefaultArgs(options);
255
255
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
256
256
  if (options.cdpPort !== void 0)
@@ -44,6 +44,8 @@ const disabledFeatures = (assistantMode) => [
44
44
  "Translate",
45
45
  // See https://issues.chromium.org/u/1/issues/435410220
46
46
  "AutoDeElevate",
47
+ // See https://github.com/microsoft/playwright/issues/37714
48
+ "RenderDocument",
47
49
  assistantMode ? "AutomationControlled" : ""
48
50
  ].filter(Boolean);
49
51
  const chromiumSwitches = (assistantMode, channel) => [
@@ -64,7 +66,7 @@ const chromiumSwitches = (assistantMode, channel) => [
64
66
  "--disable-dev-shm-usage",
65
67
  "--disable-extensions",
66
68
  "--disable-features=" + disabledFeatures(assistantMode).join(","),
67
- channel === "chromium-tip-of-tree" ? "--enable-features=CDPScreenshotNewSurface" : "",
69
+ process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? "" : "--enable-features=CDPScreenshotNewSurface",
68
70
  "--allow-pre-commit-input",
69
71
  "--disable-hang-monitor",
70
72
  "--disable-ipc-flooding-protection",