patchright-core 1.57.0 → 1.59.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 (307) hide show
  1. package/ThirdPartyNotices.txt +2688 -297
  2. package/browsers.json +23 -22
  3. package/lib/bootstrap.js +77 -0
  4. package/lib/cli/browserActions.js +308 -0
  5. package/lib/cli/driver.js +3 -2
  6. package/lib/cli/installActions.js +171 -0
  7. package/lib/cli/program.js +48 -413
  8. package/lib/client/android.js +4 -4
  9. package/lib/client/api.js +3 -0
  10. package/lib/client/browser.js +11 -5
  11. package/lib/client/browserContext.js +20 -23
  12. package/lib/client/browserType.js +23 -54
  13. package/lib/client/cdpSession.js +6 -2
  14. package/lib/client/channelOwner.js +1 -1
  15. package/lib/client/clientHelper.js +2 -1
  16. package/lib/client/clock.js +0 -1
  17. package/lib/client/{webSocket.js → connect.js} +57 -7
  18. package/lib/client/connection.js +8 -0
  19. package/lib/client/consoleMessage.js +3 -0
  20. package/lib/client/debugger.js +57 -0
  21. package/lib/client/dialog.js +8 -1
  22. package/lib/client/disposable.js +76 -0
  23. package/lib/client/electron.js +1 -0
  24. package/lib/client/elementHandle.js +1 -1
  25. package/lib/client/events.js +3 -0
  26. package/lib/client/fetch.js +2 -4
  27. package/lib/client/frame.js +9 -13
  28. package/lib/client/harRouter.js +13 -1
  29. package/lib/client/jsHandle.js +4 -8
  30. package/lib/client/locator.js +13 -36
  31. package/lib/client/network.js +14 -11
  32. package/lib/client/page.js +44 -50
  33. package/lib/client/screencast.js +88 -0
  34. package/lib/client/selectors.js +3 -1
  35. package/lib/client/tracing.js +11 -5
  36. package/lib/client/video.js +13 -20
  37. package/lib/client/worker.js +6 -6
  38. package/lib/generated/bindingsControllerSource.js +1 -1
  39. package/lib/generated/clockSource.js +1 -1
  40. package/lib/generated/injectedScriptSource.js +1 -1
  41. package/lib/generated/pollingRecorderSource.js +1 -1
  42. package/lib/generated/storageScriptSource.js +1 -1
  43. package/lib/generated/utilityScriptSource.js +1 -1
  44. package/lib/mcpBundle.js +78 -0
  45. package/lib/mcpBundleImpl.js +91 -0
  46. package/lib/protocol/serializers.js +5 -0
  47. package/lib/protocol/validator.js +228 -58
  48. package/lib/protocol/validatorPrimitives.js +1 -1
  49. package/lib/remote/playwrightConnection.js +10 -8
  50. package/lib/remote/playwrightPipeServer.js +100 -0
  51. package/lib/remote/playwrightServer.js +14 -10
  52. package/lib/remote/playwrightWebSocketServer.js +73 -0
  53. package/lib/remote/serverTransport.js +96 -0
  54. package/lib/server/android/android.js +2 -2
  55. package/lib/server/artifact.js +1 -1
  56. package/lib/server/bidi/bidiBrowser.js +80 -14
  57. package/lib/server/bidi/bidiChromium.js +23 -14
  58. package/lib/server/bidi/bidiConnection.js +1 -0
  59. package/lib/server/bidi/bidiDeserializer.js +116 -0
  60. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  61. package/lib/server/bidi/bidiFirefox.js +6 -8
  62. package/lib/server/bidi/bidiNetworkManager.js +40 -12
  63. package/lib/server/bidi/bidiPage.js +67 -40
  64. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  65. package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
  66. package/lib/server/browser.js +84 -21
  67. package/lib/server/browserContext.js +137 -77
  68. package/lib/server/browserType.js +26 -16
  69. package/lib/server/chromium/chromium.js +28 -31
  70. package/lib/server/chromium/chromiumSwitches.js +16 -4
  71. package/lib/server/chromium/crBrowser.js +40 -27
  72. package/lib/server/chromium/crConnection.js +0 -5
  73. package/lib/server/chromium/crDevTools.js +1 -2
  74. package/lib/server/chromium/crNetworkManager.js +54 -229
  75. package/lib/server/chromium/crPage.js +74 -260
  76. package/lib/server/chromium/crServiceWorker.js +7 -14
  77. package/lib/server/clock.js +33 -41
  78. package/lib/server/codegen/javascript.js +6 -29
  79. package/lib/server/console.js +5 -1
  80. package/lib/server/debugController.js +12 -6
  81. package/lib/server/debugger.js +40 -47
  82. package/lib/server/deviceDescriptorsSource.json +137 -137
  83. package/lib/server/dispatchers/browserContextDispatcher.js +30 -30
  84. package/lib/server/dispatchers/browserDispatcher.js +11 -5
  85. package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
  86. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
  87. package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
  88. package/lib/server/dispatchers/dispatcher.js +7 -14
  89. package/lib/server/dispatchers/disposableDispatcher.js +39 -0
  90. package/lib/server/dispatchers/electronDispatcher.js +2 -1
  91. package/lib/server/dispatchers/frameDispatcher.js +7 -7
  92. package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
  93. package/lib/server/dispatchers/networkDispatchers.js +6 -5
  94. package/lib/server/dispatchers/pageDispatcher.js +101 -34
  95. package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
  96. package/lib/server/disposable.js +41 -0
  97. package/lib/server/dom.js +56 -29
  98. package/lib/server/download.js +3 -2
  99. package/lib/server/electron/electron.js +17 -9
  100. package/lib/server/firefox/ffBrowser.js +9 -29
  101. package/lib/server/firefox/ffConnection.js +0 -5
  102. package/lib/server/firefox/ffInput.js +21 -5
  103. package/lib/server/firefox/ffNetworkManager.js +4 -4
  104. package/lib/server/firefox/ffPage.js +27 -33
  105. package/lib/server/firefox/firefox.js +6 -8
  106. package/lib/server/frameSelectors.js +14 -169
  107. package/lib/server/frames.js +263 -551
  108. package/lib/server/har/harRecorder.js +2 -2
  109. package/lib/server/har/harTracer.js +5 -4
  110. package/lib/server/input.js +49 -4
  111. package/lib/server/instrumentation.js +8 -0
  112. package/lib/server/javascript.js +6 -22
  113. package/lib/server/launchApp.js +0 -1
  114. package/lib/server/localUtils.js +6 -6
  115. package/lib/server/network.js +59 -20
  116. package/lib/server/overlay.js +138 -0
  117. package/lib/server/page.js +179 -157
  118. package/lib/server/progress.js +32 -6
  119. package/lib/server/recorder/recorderApp.js +84 -104
  120. package/lib/server/recorder.js +76 -40
  121. package/lib/server/registry/browserFetcher.js +6 -4
  122. package/lib/server/registry/index.js +222 -226
  123. package/lib/server/registry/nativeDeps.js +1 -0
  124. package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
  125. package/lib/server/screencast.js +137 -0
  126. package/lib/server/trace/recorder/snapshotter.js +2 -2
  127. package/lib/server/trace/recorder/snapshotterInjected.js +21 -1
  128. package/lib/server/trace/recorder/tracing.js +98 -47
  129. package/lib/server/trace/viewer/traceViewer.js +24 -21
  130. package/lib/server/usKeyboardLayout.js +7 -0
  131. package/lib/server/utils/comparators.js +1 -1
  132. package/lib/server/utils/disposable.js +32 -0
  133. package/lib/server/utils/eventsHelper.js +3 -1
  134. package/lib/server/utils/expectUtils.js +87 -2
  135. package/lib/server/utils/fileUtils.js +16 -2
  136. package/lib/server/utils/happyEyeballs.js +15 -12
  137. package/lib/server/utils/httpServer.js +10 -23
  138. package/lib/server/utils/network.js +39 -29
  139. package/lib/server/utils/processLauncher.js +8 -6
  140. package/lib/server/utils/zipFile.js +2 -2
  141. package/lib/server/videoRecorder.js +194 -0
  142. package/lib/server/webkit/webkit.js +4 -6
  143. package/lib/server/webkit/wkBrowser.js +1 -10
  144. package/lib/server/webkit/wkConnection.js +1 -6
  145. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  146. package/lib/server/webkit/wkPage.js +88 -57
  147. package/lib/server/webkit/wkWorkers.js +2 -1
  148. package/lib/serverRegistry.js +156 -0
  149. package/lib/tools/backend/browserBackend.js +79 -0
  150. package/lib/tools/backend/common.js +63 -0
  151. package/lib/tools/backend/config.js +41 -0
  152. package/lib/tools/backend/console.js +66 -0
  153. package/lib/tools/backend/context.js +296 -0
  154. package/lib/tools/backend/cookies.js +152 -0
  155. package/lib/tools/backend/devtools.js +69 -0
  156. package/lib/tools/backend/dialogs.js +59 -0
  157. package/lib/tools/backend/evaluate.js +64 -0
  158. package/lib/tools/backend/files.js +60 -0
  159. package/lib/tools/backend/form.js +64 -0
  160. package/lib/tools/backend/keyboard.js +155 -0
  161. package/lib/tools/backend/logFile.js +95 -0
  162. package/lib/tools/backend/mouse.js +168 -0
  163. package/lib/tools/backend/navigate.js +106 -0
  164. package/lib/tools/backend/network.js +135 -0
  165. package/lib/tools/backend/pdf.js +48 -0
  166. package/lib/tools/backend/response.js +305 -0
  167. package/lib/tools/backend/route.js +140 -0
  168. package/lib/tools/backend/runCode.js +77 -0
  169. package/lib/tools/backend/screenshot.js +88 -0
  170. package/lib/tools/backend/sessionLog.js +74 -0
  171. package/lib/tools/backend/snapshot.js +208 -0
  172. package/lib/tools/backend/storage.js +68 -0
  173. package/lib/tools/backend/tab.js +445 -0
  174. package/lib/tools/backend/tabs.js +67 -0
  175. package/lib/tools/backend/tool.js +47 -0
  176. package/lib/tools/backend/tools.js +102 -0
  177. package/lib/tools/backend/tracing.js +78 -0
  178. package/lib/tools/backend/utils.js +83 -0
  179. package/lib/tools/backend/verify.js +151 -0
  180. package/lib/tools/backend/video.js +98 -0
  181. package/lib/tools/backend/wait.js +63 -0
  182. package/lib/tools/backend/webstorage.js +223 -0
  183. package/lib/tools/cli-client/cli.js +6 -0
  184. package/lib/tools/cli-client/help.json +399 -0
  185. package/lib/tools/cli-client/minimist.js +128 -0
  186. package/lib/tools/cli-client/program.js +350 -0
  187. package/lib/tools/cli-client/registry.js +176 -0
  188. package/lib/tools/cli-client/session.js +289 -0
  189. package/lib/tools/cli-client/skill/SKILL.md +328 -0
  190. package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
  191. package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
  192. package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
  193. package/lib/tools/cli-client/skill/references/running-code.md +231 -0
  194. package/lib/tools/cli-client/skill/references/session-management.md +169 -0
  195. package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
  196. package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
  197. package/lib/tools/cli-client/skill/references/tracing.md +139 -0
  198. package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
  199. package/lib/tools/cli-daemon/command.js +73 -0
  200. package/lib/tools/cli-daemon/commands.js +956 -0
  201. package/lib/tools/cli-daemon/daemon.js +157 -0
  202. package/lib/tools/cli-daemon/helpGenerator.js +177 -0
  203. package/lib/tools/cli-daemon/program.js +129 -0
  204. package/lib/tools/dashboard/appIcon.png +0 -0
  205. package/lib/tools/dashboard/dashboardApp.js +284 -0
  206. package/lib/tools/dashboard/dashboardController.js +296 -0
  207. package/lib/tools/exports.js +60 -0
  208. package/lib/tools/mcp/browserFactory.js +233 -0
  209. package/lib/tools/mcp/cdpRelay.js +352 -0
  210. package/lib/tools/mcp/cli-stub.js +7 -0
  211. package/lib/tools/mcp/config.d.js +16 -0
  212. package/lib/tools/mcp/config.js +446 -0
  213. package/lib/tools/mcp/configIni.js +189 -0
  214. package/lib/tools/mcp/extensionContextFactory.js +55 -0
  215. package/lib/tools/mcp/index.js +62 -0
  216. package/lib/tools/mcp/log.js +35 -0
  217. package/lib/tools/mcp/program.js +107 -0
  218. package/lib/tools/mcp/protocol.js +28 -0
  219. package/lib/tools/mcp/watchdog.js +44 -0
  220. package/lib/tools/trace/SKILL.md +171 -0
  221. package/lib/tools/trace/installSkill.js +48 -0
  222. package/lib/tools/trace/traceActions.js +142 -0
  223. package/lib/tools/trace/traceAttachments.js +69 -0
  224. package/lib/tools/trace/traceCli.js +87 -0
  225. package/lib/tools/trace/traceConsole.js +97 -0
  226. package/lib/tools/trace/traceErrors.js +55 -0
  227. package/lib/tools/trace/traceOpen.js +69 -0
  228. package/lib/tools/trace/traceParser.js +96 -0
  229. package/lib/tools/trace/traceRequests.js +182 -0
  230. package/lib/tools/trace/traceScreenshot.js +68 -0
  231. package/lib/tools/trace/traceSnapshot.js +149 -0
  232. package/lib/tools/trace/traceUtils.js +153 -0
  233. package/lib/tools/utils/connect.js +32 -0
  234. package/lib/tools/utils/mcp/http.js +152 -0
  235. package/lib/tools/utils/mcp/server.js +230 -0
  236. package/lib/tools/utils/mcp/tool.js +47 -0
  237. package/lib/tools/utils/socketConnection.js +108 -0
  238. package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
  239. package/lib/utils/isomorphic/formatUtils.js +64 -0
  240. package/lib/utils/isomorphic/jsonSchema.js +89 -0
  241. package/lib/utils/isomorphic/lruCache.js +51 -0
  242. package/lib/utils/isomorphic/mimeType.js +7 -2
  243. package/lib/utils/isomorphic/protocolFormatter.js +2 -2
  244. package/lib/utils/isomorphic/protocolMetainfo.js +127 -98
  245. package/lib/utils/isomorphic/stringUtils.js +49 -0
  246. package/lib/utils/isomorphic/timeoutRunner.js +3 -3
  247. package/lib/utils/isomorphic/trace/entries.js +16 -0
  248. package/lib/utils/isomorphic/trace/snapshotRenderer.js +492 -0
  249. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  250. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  251. package/lib/utils/isomorphic/trace/traceLoader.js +132 -0
  252. package/lib/utils/isomorphic/trace/traceModel.js +366 -0
  253. package/lib/utils/isomorphic/trace/traceModernizer.js +401 -0
  254. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  255. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  256. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  257. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  258. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  259. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  260. package/lib/utils/isomorphic/urlMatch.js +54 -1
  261. package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
  262. package/lib/utils/isomorphic/yaml.js +84 -0
  263. package/lib/utils.js +8 -2
  264. package/lib/utilsBundle.js +5 -26
  265. package/lib/utilsBundleImpl/index.js +172 -173
  266. package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
  267. package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
  268. package/lib/vite/dashboard/index.html +28 -0
  269. package/lib/vite/htmlReport/index.html +2 -70
  270. package/lib/vite/htmlReport/report.css +1 -0
  271. package/lib/vite/htmlReport/report.js +72 -0
  272. package/lib/vite/recorder/assets/codeMirrorModule-C8KMvO9L.js +32 -0
  273. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  274. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  275. package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
  276. package/lib/vite/recorder/index.html +2 -2
  277. package/lib/vite/traceViewer/assets/codeMirrorModule-DS0FLvoc.js +32 -0
  278. package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
  279. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  280. package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
  281. package/lib/vite/traceViewer/index.CzXZzn5A.css +1 -0
  282. package/lib/vite/traceViewer/index.Dtstcb7U.js +2 -0
  283. package/lib/vite/traceViewer/index.html +4 -4
  284. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  285. package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
  286. package/lib/vite/traceViewer/uiMode.html +3 -3
  287. package/lib/zipBundleImpl.js +2 -2
  288. package/lib/zodBundle.js +39 -0
  289. package/lib/zodBundleImpl.js +40 -0
  290. package/package.json +7 -1
  291. package/types/protocol.d.ts +1696 -221
  292. package/types/types.d.ts +879 -112
  293. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  294. package/lib/server/chromium/videoRecorder.js +0 -115
  295. package/lib/server/pageBinding.js +0 -87
  296. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  297. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +0 -248
  298. package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
  299. package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
  300. package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
  301. package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
  302. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
  303. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
  304. package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
  305. package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
  306. /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
  307. /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var browserContext_exports = {};
30
30
  __export(browserContext_exports, {
31
31
  BrowserContext: () => BrowserContext,
32
+ calculateUserAgentEmulation: () => calculateUserAgentEmulation,
32
33
  normalizeProxySettings: () => normalizeProxySettings,
33
34
  validateBrowserContextOptions: () => validateBrowserContextOptions,
34
35
  verifyClientCertificates: () => verifyClientCertificates,
@@ -36,14 +37,12 @@ __export(browserContext_exports, {
36
37
  });
37
38
  module.exports = __toCommonJS(browserContext_exports);
38
39
  var import_fs = __toESM(require("fs"));
39
- var import_path = __toESM(require("path"));
40
40
  var import_crypto = require("./utils/crypto");
41
41
  var import_debug = require("./utils/debug");
42
42
  var import_clock = require("./clock");
43
43
  var import_debugger = require("./debugger");
44
44
  var import_dialog = require("./dialog");
45
45
  var import_fetch = require("./fetch");
46
- var import_fileUtils = require("./utils/fileUtils");
47
46
  var import_stackTrace = require("../utils/isomorphic/stackTrace");
48
47
  var import_harRecorder = require("./har/harRecorder");
49
48
  var import_helper = require("./helper");
@@ -55,6 +54,25 @@ var import_recorderApp = require("./recorder/recorderApp");
55
54
  var import_selectors = require("./selectors");
56
55
  var import_tracing = require("./trace/recorder/tracing");
57
56
  var rawStorageSource = __toESM(require("../generated/storageScriptSource"));
57
+ const BrowserContextEvent = {
58
+ Console: "console",
59
+ Close: "close",
60
+ Page: "page",
61
+ // Can't use just 'error' due to node.js special treatment of error events.
62
+ // @see https://nodejs.org/api/events.html#events_error_events
63
+ PageError: "pageerror",
64
+ Request: "request",
65
+ Response: "response",
66
+ RequestFailed: "requestfailed",
67
+ RequestFinished: "requestfinished",
68
+ RequestAborted: "requestaborted",
69
+ RequestFulfilled: "requestfulfilled",
70
+ RequestContinued: "requestcontinued",
71
+ BeforeClose: "beforeclose",
72
+ RecorderEvent: "recorderevent",
73
+ PageClosed: "pageclosed",
74
+ InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument"
75
+ };
58
76
  class BrowserContext extends import_instrumentation.SdkObject {
59
77
  constructor(browser, options, browserContextId) {
60
78
  super(browser, "browser-context");
@@ -69,6 +87,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
69
87
  this._creatingStorageStatePage = false;
70
88
  this.initScripts = [];
71
89
  this._routesInFlight = /* @__PURE__ */ new Set();
90
+ this._consoleApiExposed = false;
72
91
  this.attribution.context = this;
73
92
  this._browser = browser;
74
93
  this._options = options;
@@ -82,24 +101,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
82
101
  this.dialogManager = new import_dialog.DialogManager(this.instrumentation);
83
102
  }
84
103
  static {
85
- this.Events = {
86
- Console: "console",
87
- Close: "close",
88
- Page: "page",
89
- // Can't use just 'error' due to node.js special treatment of error events.
90
- // @see https://nodejs.org/api/events.html#events_error_events
91
- PageError: "pageerror",
92
- Request: "request",
93
- Response: "response",
94
- RequestFailed: "requestfailed",
95
- RequestFinished: "requestfinished",
96
- RequestAborted: "requestaborted",
97
- RequestFulfilled: "requestfulfilled",
98
- RequestContinued: "requestcontinued",
99
- BeforeClose: "beforeclose",
100
- VideoStarted: "videostarted",
101
- RecorderEvent: "recorderevent"
102
- };
104
+ this.Events = BrowserContextEvent;
103
105
  }
104
106
  isPersistentContext() {
105
107
  return this._isPersistentContext;
@@ -111,31 +113,38 @@ class BrowserContext extends import_instrumentation.SdkObject {
111
113
  if (this.attribution.playwright.options.isInternalPlaywright)
112
114
  return;
113
115
  this._debugger = new import_debugger.Debugger(this);
114
- if ((0, import_debug.debugMode)() === "inspector")
116
+ const shouldEnableDebugger = !this.attribution.playwright.options.isServer && ((0, import_debug.isUnderTest)() || !!this._browser.options.headful);
117
+ if (shouldEnableDebugger) {
118
+ this._debugger.setPauseAt();
119
+ this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
120
+ if (this._debugger.isPaused())
121
+ import_recorderApp.RecorderApp.showInspectorNoReply(this);
122
+ });
123
+ }
124
+ if ((0, import_debug.debugMode)() === "inspector") {
125
+ this._debugger.setPauseAt({ next: true });
115
126
  await import_recorderApp.RecorderApp.show(this, { pauseOnNextStatement: true });
116
- if (this._debugger.isPaused())
117
- import_recorderApp.RecorderApp.showInspectorNoReply(this);
118
- this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
119
- if (this._debugger.isPaused())
120
- import_recorderApp.RecorderApp.showInspectorNoReply(this);
121
- });
122
- if ((0, import_debug.debugMode)() === "console") {
123
- await this.extendInjectedScript(`
124
- function installConsoleApi(injectedScript) { injectedScript.consoleApi.install(); }
125
- module.exports = { default: () => installConsoleApi };
126
- `);
127
127
  }
128
+ if ((0, import_debug.debugMode)() === "console")
129
+ await this.exposeConsoleApi();
128
130
  if (this._options.serviceWorkers === "block")
129
- await this.addInitScript(void 0, `navigator.serviceWorker.register = async () => { };`);
131
+ await this.addInitScript(`
132
+ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { console.warn('Service Worker registration blocked by Playwright'); };
133
+ `);
130
134
  if (this._options.permissions)
131
135
  await this.grantPermissions(this._options.permissions);
132
136
  }
133
137
  debugger() {
134
138
  return this._debugger;
135
139
  }
136
- async _ensureVideosPath() {
137
- if (this._options.recordVideo)
138
- await (0, import_fileUtils.mkdirIfNeeded)(import_path.default.join(this._options.recordVideo.dir, "dummy"));
140
+ async exposeConsoleApi() {
141
+ if (this._consoleApiExposed)
142
+ return;
143
+ this._consoleApiExposed = true;
144
+ await this.extendInjectedScript(`
145
+ function installConsoleApi(injectedScript) { injectedScript.consoleApi.install(); }
146
+ module.exports = { default: () => installConsoleApi };
147
+ `);
139
148
  }
140
149
  canResetForReuse() {
141
150
  if (this._closedStatus !== "open")
@@ -230,7 +239,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
230
239
  async exposePlaywrightBindingIfNeeded() {
231
240
  this._playwrightBindingExposed ??= (async () => {
232
241
  await this.doExposePlaywrightBinding();
233
- this.bindingsInitScript = import_page2.PageBinding.createInitScript();
242
+ this.bindingsInitScript = import_page2.PageBinding.createInitScript(this);
234
243
  this.initScripts.push(this.bindingsInitScript);
235
244
  await this.doAddInitScript(this.bindingsInitScript);
236
245
  await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
@@ -247,16 +256,26 @@ class BrowserContext extends import_instrumentation.SdkObject {
247
256
  if (page.getBinding(name))
248
257
  throw new Error(`Function "${name}" has been already registered in one of the pages`);
249
258
  }
250
- const binding = new import_page2.PageBinding(name, playwrightBinding, needsHandle);
259
+ await progress.race(this.exposePlaywrightBindingIfNeeded());
260
+ const binding = new import_page2.PageBinding(this, name, playwrightBinding, needsHandle);
251
261
  binding.forClient = forClient;
252
262
  this._pageBindings.set(name, binding);
253
- await this.doExposeBinding(binding);
254
- }
255
- async removeExposedBindings(bindings) {
256
- for (const key of this._pageBindings.keys()) {
257
- if (!key.startsWith("__pw")) this._pageBindings.delete(key);
263
+ try {
264
+ await progress.race(this.doAddInitScript(binding.initScript));
265
+ await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
266
+ return binding;
267
+ } catch (error) {
268
+ this._pageBindings.delete(name);
269
+ throw error;
258
270
  }
259
- await this.doRemoveExposedBindings();
271
+ }
272
+ async removeExposedBinding(binding) {
273
+ if (this._pageBindings.get(binding.name) !== binding)
274
+ return;
275
+ this._pageBindings.delete(binding.name);
276
+ await this.doRemoveInitScripts([binding.initScript]);
277
+ const cleanup = `{ ${binding.cleanupScript} };`;
278
+ await this.safeNonStallingEvaluateInAllFrames(cleanup, "main");
260
279
  }
261
280
  async grantPermissions(permissions, origin) {
262
281
  let resolvedOrigin = "*";
@@ -309,7 +328,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
309
328
  const pageOrError = await progress.race(page.waitForInitializedOrError());
310
329
  if (pageOrError instanceof Error)
311
330
  throw pageOrError;
312
- await page.mainFrame()._waitForLoadState(progress, "load");
331
+ await page.mainFrame().waitForLoadState(progress, "load");
313
332
  return page;
314
333
  }
315
334
  async _loadDefaultContext(progress) {
@@ -342,25 +361,21 @@ class BrowserContext extends import_instrumentation.SdkObject {
342
361
  if (username)
343
362
  this._options.httpCredentials = { username, password: password || "" };
344
363
  }
345
- async addInitScript(progress, source) {
346
- const initScript = new import_page.InitScript(source);
364
+ async addInitScript(source) {
365
+ const initScript = new import_page.InitScript(this, source);
347
366
  this.initScripts.push(initScript);
348
367
  try {
349
- const promise = this.doAddInitScript(initScript);
350
- if (progress)
351
- await progress.race(promise);
352
- else
353
- await promise;
368
+ await this.doAddInitScript(initScript);
354
369
  return initScript;
355
370
  } catch (error) {
356
- this.removeInitScripts([initScript]).catch(() => {
371
+ initScript.dispose().catch(() => {
357
372
  });
358
373
  throw error;
359
374
  }
360
375
  }
361
- async removeInitScripts(initScripts) {
362
- this.initScripts.splice(0, this.initScripts.length);
363
- await this.doRemoveInitScripts();
376
+ async removeInitScript(initScript) {
377
+ this.initScripts = this.initScripts.filter((script) => initScript !== script);
378
+ await this.doRemoveInitScripts([initScript]);
364
379
  }
365
380
  async addRequestInterceptor(progress, handler) {
366
381
  this.requestInterceptors.push(handler);
@@ -396,16 +411,13 @@ class BrowserContext extends import_instrumentation.SdkObject {
396
411
  for (const harRecorder of this._harRecorders.values())
397
412
  await harRecorder.flush();
398
413
  await this.tracing.flush();
399
- const promises = [];
400
- for (const { context, artifact } of this._browser._idToVideo.values()) {
401
- if (context === this)
402
- promises.push(artifact.finishedPromise());
403
- }
414
+ await Promise.all(this.pages().map((page) => page.screencast.handlePageOrContextClose()));
404
415
  if (this._customCloseHandler) {
405
416
  await this._customCloseHandler();
406
417
  } else {
407
418
  await this.doClose(options.reason);
408
419
  }
420
+ const promises = [];
409
421
  promises.push(this._deleteAllDownloads());
410
422
  promises.push(this._deleteAllTempDirs());
411
423
  await Promise.all(promises);
@@ -581,22 +593,6 @@ function validateBrowserContextOptions(options, browserOptions) {
581
593
  options.acceptDownloads = "internal-browser-default";
582
594
  if (!options.viewport && !options.noDefaultViewport)
583
595
  options.viewport = { width: 1280, height: 720 };
584
- if (options.recordVideo) {
585
- if (!options.recordVideo.size) {
586
- if (options.noDefaultViewport) {
587
- options.recordVideo.size = { width: 800, height: 600 };
588
- } else {
589
- const size = options.viewport;
590
- const scale = Math.min(1, 800 / Math.max(size.width, size.height));
591
- options.recordVideo.size = {
592
- width: Math.floor(size.width * scale),
593
- height: Math.floor(size.height * scale)
594
- };
595
- }
596
- }
597
- options.recordVideo.size.width &= ~1;
598
- options.recordVideo.size.height &= ~1;
599
- }
600
596
  if (options.proxy)
601
597
  options.proxy = normalizeProxySettings(options.proxy);
602
598
  verifyGeolocation(options.geolocation);
@@ -648,6 +644,69 @@ function normalizeProxySettings(proxy) {
648
644
  bypass = bypass.split(",").map((t) => t.trim()).join(",");
649
645
  return { ...proxy, server, bypass };
650
646
  }
647
+ function calculateUserAgentEmulation(options) {
648
+ const ua = options.userAgent;
649
+ if (!ua)
650
+ return { navigatorPlatform: void 0, userAgentMetadata: void 0 };
651
+ const userAgentMetadata = {
652
+ mobile: !!options.isMobile,
653
+ model: "",
654
+ architecture: "x86",
655
+ platform: "Windows",
656
+ platformVersion: ""
657
+ };
658
+ const androidMatch = ua.match(/Android (\d+(\.\d+)?(\.\d+)?)/);
659
+ const iPhoneMatch = ua.match(/iPhone OS (\d+(_\d+)?)/);
660
+ const iPadMatch = ua.match(/iPad; CPU OS (\d+(_\d+)?)/);
661
+ const macOSMatch = ua.match(/Mac OS X (\d+(_\d+)?(_\d+)?)/);
662
+ const windowsMatch = ua.match(/Windows\D+(\d+(\.\d+)?(\.\d+)?)/);
663
+ if (androidMatch) {
664
+ userAgentMetadata.platform = "Android";
665
+ userAgentMetadata.platformVersion = androidMatch[1];
666
+ userAgentMetadata.architecture = "arm";
667
+ } else if (iPhoneMatch) {
668
+ userAgentMetadata.platform = "iOS";
669
+ userAgentMetadata.platformVersion = iPhoneMatch[1].replace(/_/g, ".");
670
+ userAgentMetadata.architecture = "arm";
671
+ } else if (iPadMatch) {
672
+ userAgentMetadata.platform = "iOS";
673
+ userAgentMetadata.platformVersion = iPadMatch[1].replace(/_/g, ".");
674
+ userAgentMetadata.architecture = "arm";
675
+ } else if (macOSMatch) {
676
+ userAgentMetadata.platform = "macOS";
677
+ userAgentMetadata.platformVersion = macOSMatch[1].replace(/_/g, ".");
678
+ if (!ua.includes("Intel"))
679
+ userAgentMetadata.architecture = "arm";
680
+ } else if (windowsMatch) {
681
+ userAgentMetadata.platform = "Windows";
682
+ userAgentMetadata.platformVersion = windowsMatch[1];
683
+ } else if (ua.toLowerCase().includes("linux")) {
684
+ userAgentMetadata.platform = "Linux";
685
+ }
686
+ if (ua.includes("ARM") || ua.includes("aarch64"))
687
+ userAgentMetadata.architecture = "arm";
688
+ let navigatorPlatform;
689
+ if (!process.env.PLAYWRIGHT_NO_UA_PLATFORM) {
690
+ switch (userAgentMetadata.platform) {
691
+ case "Android":
692
+ navigatorPlatform = userAgentMetadata.architecture === "arm" ? "Linux armv8l" : "Linux x86_64";
693
+ break;
694
+ case "iOS":
695
+ navigatorPlatform = ua.includes("iPad") ? "iPad" : "iPhone";
696
+ break;
697
+ case "macOS":
698
+ navigatorPlatform = "MacIntel";
699
+ break;
700
+ case "Linux":
701
+ navigatorPlatform = userAgentMetadata.architecture === "arm" ? "Linux aarch64" : "Linux x86_64";
702
+ break;
703
+ case "Windows":
704
+ navigatorPlatform = "Win32";
705
+ break;
706
+ }
707
+ }
708
+ return { navigatorPlatform, userAgentMetadata };
709
+ }
651
710
  const paramsThatAllowContextReuse = [
652
711
  "colorScheme",
653
712
  "forcedColors",
@@ -674,6 +733,7 @@ const defaultNewContextParamValues = {
674
733
  // Annotate the CommonJS export names for ESM import in node:
675
734
  0 && (module.exports = {
676
735
  BrowserContext,
736
+ calculateUserAgentEmulation,
677
737
  normalizeProxySettings,
678
738
  validateBrowserContextOptions,
679
739
  verifyClientCertificates,
@@ -59,7 +59,7 @@ class BrowserType extends import_instrumentation.SdkObject {
59
59
  this.logName = "browser";
60
60
  }
61
61
  executablePath() {
62
- return import_registry.registry.findExecutable(this._name).executablePath(this.attribution.playwright.options.sdkLanguage) || "";
62
+ return import_registry.registry.findExecutable(this._name).executablePath() || "";
63
63
  }
64
64
  name() {
65
65
  return this._name;
@@ -115,7 +115,7 @@ class BrowserType extends import_instrumentation.SdkObject {
115
115
  await progress.race(options.__testHookBeforeCreateBrowser());
116
116
  const browserOptions = {
117
117
  name: this._name,
118
- isChromium: this._name === "chromium",
118
+ browserType: this._name,
119
119
  channel: options.channel,
120
120
  slowMo: options.slowMo,
121
121
  persistent,
@@ -129,7 +129,8 @@ class BrowserType extends import_instrumentation.SdkObject {
129
129
  protocolLogger,
130
130
  browserLogsCollector,
131
131
  wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
132
- originalLaunchOptions: options
132
+ originalLaunchOptions: options,
133
+ userDataDir: persistent ? userDataDir : void 0
133
134
  };
134
135
  if (persistent)
135
136
  (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
@@ -152,10 +153,14 @@ class BrowserType extends import_instrumentation.SdkObject {
152
153
  args = [],
153
154
  executablePath = null
154
155
  } = options;
155
- await this._createArtifactDirs(options);
156
156
  const tempDirectories = [];
157
- const artifactsDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-"));
158
- tempDirectories.push(artifactsDir);
157
+ let artifactsDir;
158
+ if (options.artifactsDir) {
159
+ artifactsDir = options.artifactsDir;
160
+ } else {
161
+ artifactsDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-"));
162
+ tempDirectories.push(artifactsDir);
163
+ }
159
164
  if (userDataDir) {
160
165
  (0, import_assert.assert)(import_path.default.isAbsolute(userDataDir), "userDataDir must be an absolute path");
161
166
  if (!await (0, import_fileUtils.existsAsync)(userDataDir))
@@ -250,6 +255,13 @@ class BrowserType extends import_instrumentation.SdkObject {
250
255
  this.waitForReadyState(options, browserLogsCollector),
251
256
  exitPromise.then(() => ({ wsEndpoint: void 0 }))
252
257
  ]);
258
+ if (exitPromise.isDone()) {
259
+ const log = import_helper.helper.formatBrowserLogs(browserLogsCollector.recentLogs());
260
+ const updatedLog = this.doRewriteStartupLog(log);
261
+ throw new Error(`Failed to launch the browser process.
262
+ Browser logs:
263
+ ${updatedLog}`);
264
+ }
253
265
  if (options.cdpPort !== void 0 || !this.supportsPipeTransport()) {
254
266
  transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
255
267
  } else {
@@ -263,28 +275,24 @@ class BrowserType extends import_instrumentation.SdkObject {
263
275
  throw error;
264
276
  }
265
277
  }
266
- async _createArtifactDirs(options) {
267
- if (options.downloadsPath)
268
- await import_fs.default.promises.mkdir(options.downloadsPath, { recursive: true });
269
- if (options.tracesDir)
270
- await import_fs.default.promises.mkdir(options.tracesDir, { recursive: true });
271
- }
272
278
  async connectOverCDP(progress, endpointURL, options) {
273
279
  throw new Error("CDP connections are only supported by Chromium");
274
280
  }
281
+ async connectOverCDPTransport(progress, transport) {
282
+ throw new Error("CDP connections are only supported by Chromium");
283
+ }
275
284
  async _launchWithSeleniumHub(progress, hubUrl, options) {
276
285
  throw new Error("Connecting to SELENIUM_REMOTE_URL is only supported by Chromium");
277
286
  }
278
287
  _validateLaunchOptions(options) {
279
- const { devtools = false } = options;
280
- let { headless = !devtools, downloadsPath, proxy } = options;
288
+ let { headless = true, downloadsPath, proxy } = options;
281
289
  if ((0, import_debug.debugMode)() === "inspector")
282
290
  headless = false;
283
291
  if (downloadsPath && !import_path.default.isAbsolute(downloadsPath))
284
292
  downloadsPath = import_path.default.join(process.cwd(), downloadsPath);
285
293
  if (options.socksProxyPort)
286
294
  proxy = { server: `socks5://127.0.0.1:${options.socksProxyPort}` };
287
- return { ...options, devtools, headless, downloadsPath, proxy };
295
+ return { ...options, headless, downloadsPath, proxy };
288
296
  }
289
297
  _createUserDataDirArgMisuseError(userDataDirArg) {
290
298
  switch (this.attribution.playwright.options.sdkLanguage) {
@@ -301,7 +309,9 @@ class BrowserType extends import_instrumentation.SdkObject {
301
309
  _rewriteStartupLog(error) {
302
310
  if (!(0, import_protocolError.isProtocolError)(error))
303
311
  return error;
304
- return this.doRewriteStartupLog(error);
312
+ if (error.logs)
313
+ error.logs = this.doRewriteStartupLog(error.logs);
314
+ return error;
305
315
  }
306
316
  async waitForReadyState(options, browserLogsCollector) {
307
317
  return {};
@@ -82,6 +82,12 @@ class Chromium extends import_browserType.BrowserType {
82
82
  headersMap = { "User-Agent": (0, import_userAgent.getUserAgent)() };
83
83
  else if (headersMap && !Object.keys(headersMap).some((key) => key.toLowerCase() === "user-agent"))
84
84
  headersMap["User-Agent"] = (0, import_userAgent.getUserAgent)();
85
+ const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
86
+ const chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap, followRedirects: true, debugLogHeader: "x-playwright-debug-log" });
87
+ const closeAndWait = async () => await chromeTransport.closeAndWait();
88
+ return this._connectOverCDPImpl(progress, chromeTransport, closeAndWait, options, onClose);
89
+ }
90
+ async _connectOverCDPImpl(progress, transport, closeAndWait, options, onClose) {
85
91
  const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
86
92
  const doCleanup = async () => {
87
93
  await (0, import_fileUtils.removeFolders)([artifactsDir]);
@@ -89,20 +95,17 @@ class Chromium extends import_browserType.BrowserType {
89
95
  onClose = void 0;
90
96
  await cb?.();
91
97
  };
92
- let chromeTransport;
93
98
  const doClose = async () => {
94
- await chromeTransport?.closeAndWait();
99
+ await closeAndWait();
95
100
  await doCleanup();
96
101
  };
97
102
  try {
98
- const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
99
- chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
100
103
  const browserProcess = { close: doClose, kill: doClose };
101
104
  const persistent = { noDefaultViewport: true };
102
105
  const browserOptions = {
103
106
  slowMo: options.slowMo,
104
107
  name: "chromium",
105
- isChromium: true,
108
+ browserType: "chromium",
106
109
  persistent,
107
110
  browserProcess,
108
111
  protocolLogger: import_helper.helper.debugProtocolLogger(),
@@ -113,8 +116,9 @@ class Chromium extends import_browserType.BrowserType {
113
116
  originalLaunchOptions: {}
114
117
  };
115
118
  (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
116
- const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
117
- browser._isCollocatedWithServer = false;
119
+ const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, browserOptions));
120
+ if (!options.isLocal)
121
+ browser._isCollocatedWithServer = false;
118
122
  browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
119
123
  return browser;
120
124
  } catch (error) {
@@ -123,18 +127,17 @@ class Chromium extends import_browserType.BrowserType {
123
127
  throw error;
124
128
  }
125
129
  }
130
+ async connectOverCDPTransport(progress, transport) {
131
+ const closeAndWait = async () => transport.close();
132
+ return this._connectOverCDPImpl(progress, transport, closeAndWait, { isLocal: true });
133
+ }
126
134
  _createDevTools() {
127
135
  const directory = import_registry.registry.findExecutable("chromium").directory;
128
136
  return directory ? new import_crDevTools.CRDevTools(import_path.default.join(directory, "devtools-preferences.json")) : void 0;
129
137
  }
130
138
  async connectToTransport(transport, options, browserLogsCollector) {
131
- let devtools = this._devtools;
132
- if (options.__testHookForDevTools) {
133
- devtools = this._createDevTools();
134
- await options.__testHookForDevTools(devtools);
135
- }
136
139
  try {
137
- return await import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, options, devtools);
140
+ return await import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, options, this._devtools);
138
141
  } catch (e) {
139
142
  if (browserLogsCollector.recentLogs().some((log) => log.includes("Failed to create a ProcessSingleton for your profile directory."))) {
140
143
  throw new Error(
@@ -144,14 +147,12 @@ class Chromium extends import_browserType.BrowserType {
144
147
  throw e;
145
148
  }
146
149
  }
147
- doRewriteStartupLog(error) {
148
- if (!error.logs)
149
- return error;
150
- if (error.logs.includes("Missing X server"))
151
- error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
152
- if (!error.logs.includes("crbug.com/357670") && !error.logs.includes("No usable sandbox!") && !error.logs.includes("crbug.com/638180"))
153
- return error;
154
- error.logs = [
150
+ doRewriteStartupLog(logs) {
151
+ if (logs.includes("Missing X server"))
152
+ logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
153
+ if (!logs.includes("crbug.com/357670") && !logs.includes("No usable sandbox!") && !logs.includes("crbug.com/638180"))
154
+ return logs;
155
+ return [
155
156
  `Chromium sandboxing failed!`,
156
157
  `================================`,
157
158
  `To avoid the sandboxing issue, do either of the following:`,
@@ -160,7 +161,6 @@ class Chromium extends import_browserType.BrowserType {
160
161
  `================================`,
161
162
  ``
162
163
  ].join("\n");
163
- return error;
164
164
  }
165
165
  amendEnvironment(env) {
166
166
  return env;
@@ -170,7 +170,6 @@ class Chromium extends import_browserType.BrowserType {
170
170
  transport.send(message);
171
171
  }
172
172
  async _launchWithSeleniumHub(progress, hubUrl, options) {
173
- await progress.race(this._createArtifactDirs(options));
174
173
  if (!hubUrl.endsWith("/"))
175
174
  hubUrl = hubUrl + "/";
176
175
  const args = this._innerDefaultArgs(options);
@@ -284,11 +283,7 @@ class Chromium extends import_browserType.BrowserType {
284
283
  if (args.find((arg) => !arg.startsWith("-")))
285
284
  throw new Error("Arguments can not specify page to be opened");
286
285
  const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode, options.channel)];
287
- if (import_os.default.platform() === "darwin") {
288
- chromeArguments.push("--enable-unsafe-swiftshader");
289
- }
290
- if (options.devtools)
291
- chromeArguments.push("--auto-open-devtools-for-tabs");
286
+ chromeArguments.push("--enable-unsafe-swiftshader");
292
287
  if (options.headless) {
293
288
  chromeArguments.push("--headless");
294
289
  chromeArguments.push(
@@ -308,11 +303,9 @@ class Chromium extends import_browserType.BrowserType {
308
303
  }
309
304
  chromeArguments.push(`--proxy-server=${proxy.server}`);
310
305
  const proxyBypassRules = [];
311
- if (options.socksProxyPort)
312
- proxyBypassRules.push("<-loopback>");
313
306
  if (proxy.bypass)
314
307
  proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
315
- if (!process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK && !proxyBypassRules.includes("<-loopback>"))
308
+ if (options.socksProxyPort || (0, import_crBrowser.shouldProxyLoopback)(proxy.bypass))
316
309
  proxyBypassRules.push("<-loopback>");
317
310
  if (proxyBypassRules.length > 0)
318
311
  chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(";")}`);
@@ -324,6 +317,10 @@ class Chromium extends import_browserType.BrowserType {
324
317
  return waitForReadyState(options, browserLogsCollector);
325
318
  }
326
319
  getExecutableName(options) {
320
+ if (options.channel && import_registry.registry.isChromiumAlias(options.channel))
321
+ return "chromium";
322
+ if (options.channel === "chromium-tip-of-tree")
323
+ return options.headless ? "chromium-tip-of-tree-headless-shell" : "chromium-tip-of-tree";
327
324
  if (options.channel)
328
325
  return options.channel;
329
326
  return options.headless ? "chromium-headless-shell" : "chromium";
@@ -22,10 +22,10 @@ __export(chromiumSwitches_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(chromiumSwitches_exports);
24
24
  const disabledFeatures = (assistantMode) => [
25
- // See https://github.com/microsoft/playwright/pull/10380
26
- "AcceptCHFrame",
27
25
  // See https://github.com/microsoft/playwright/issues/14047
28
26
  "AvoidUnnecessaryBeforeUnloadCheckSync",
27
+ // See https://github.com/microsoft/playwright/issues/38568
28
+ "BoundaryEventDispatchTracksNodeRemoval",
29
29
  "DestroyProfileOnBrowserClose",
30
30
  // See https://github.com/microsoft/playwright/pull/13854
31
31
  "DialMediaRouteProvider",
@@ -56,17 +56,27 @@ const chromiumSwitches = (assistantMode, channel, android) => [
56
56
  "--disable-background-networking",
57
57
  "--disable-background-timer-throttling",
58
58
  "--disable-backgrounding-occluded-windows",
59
+ "--disable-back-forward-cache",
59
60
  // Avoids surprises like main request not being intercepted during page.goBack().
60
61
  "--disable-breakpad",
62
+ "--disable-client-side-phishing-detection",
63
+ "--disable-component-extensions-with-background-pages",
64
+ "--disable-component-update",
61
65
  // Avoids unneeded network activity after startup.
62
66
  "--no-default-browser-check",
67
+ "--disable-default-apps",
63
68
  "--disable-dev-shm-usage",
69
+ "--disable-extensions",
64
70
  "--disable-features=" + disabledFeatures(assistantMode).join(","),
65
71
  process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? "" : "--enable-features=CDPScreenshotNewSurface",
72
+ "--allow-pre-commit-input",
66
73
  "--disable-hang-monitor",
74
+ "--disable-ipc-flooding-protection",
75
+ "--disable-popup-blocking",
67
76
  "--disable-prompt-on-repost",
68
77
  "--disable-renderer-backgrounding",
69
78
  "--force-color-profile=srgb",
79
+ "--metrics-recording-only",
70
80
  "--no-first-run",
71
81
  "--password-store=basic",
72
82
  "--use-mock-keychain",
@@ -75,16 +85,18 @@ const chromiumSwitches = (assistantMode, channel, android) => [
75
85
  "--export-tagged-pdf",
76
86
  // https://chromium-review.googlesource.com/c/chromium/src/+/4853540
77
87
  "--disable-search-engine-choice-screen",
88
+ // https://issues.chromium.org/41491762
89
+ "--unsafely-disable-devtools-self-xss-warnings",
78
90
  // Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
79
91
  "--edge-skip-compat-layer-relaunch",
92
+ assistantMode ? "" : "--enable-automation",
80
93
  // This disables Chrome for Testing infobar that is visible in the persistent context.
81
94
  // The switch is ignored everywhere else, including Chromium/Chrome/Edge.
82
95
  "--disable-infobars",
83
96
  // Less annoying popups.
84
97
  "--disable-search-engine-choice-screen",
85
98
  // Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
86
- android ? "" : "--disable-sync",
87
- "--disable-blink-features=AutomationControlled"
99
+ android ? "" : "--disable-sync"
88
100
  ].filter(Boolean);
89
101
  // Annotate the CommonJS export names for ESM import in node:
90
102
  0 && (module.exports = {