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
@@ -31,6 +31,8 @@ __export(registry_exports, {
31
31
  Registry: () => Registry,
32
32
  browserDirectoryToMarkerFilePath: () => browserDirectoryToMarkerFilePath,
33
33
  buildPlaywrightCLICommand: () => buildPlaywrightCLICommand,
34
+ defaultCacheDirectory: () => defaultCacheDirectory,
35
+ defaultRegistryDirectory: () => defaultRegistryDirectory,
34
36
  findChromiumChannelBestEffort: () => findChromiumChannelBestEffort,
35
37
  installBrowsersForNpmInstall: () => installBrowsersForNpmInstall,
36
38
  registry: () => registry,
@@ -145,130 +147,140 @@ const EXECUTABLE_PATHS = {
145
147
  "win-x64": ["PrintDeps.exe"]
146
148
  }
147
149
  };
150
+ function cftUrl(suffix) {
151
+ return ({ browserVersion }) => {
152
+ return {
153
+ path: `builds/cft/${browserVersion}/${suffix}`,
154
+ mirrors: [
155
+ "https://cdn.playwright.dev"
156
+ ]
157
+ };
158
+ };
159
+ }
148
160
  const DOWNLOAD_PATHS = {
149
161
  "chromium": {
150
162
  "<unknown>": void 0,
151
163
  "ubuntu18.04-x64": void 0,
152
- "ubuntu20.04-x64": "builds/chromium/%s/chromium-linux.zip",
153
- "ubuntu22.04-x64": "builds/chromium/%s/chromium-linux.zip",
154
- "ubuntu24.04-x64": "builds/chromium/%s/chromium-linux.zip",
164
+ "ubuntu20.04-x64": cftUrl("linux64/chrome-linux64.zip"),
165
+ "ubuntu22.04-x64": cftUrl("linux64/chrome-linux64.zip"),
166
+ "ubuntu24.04-x64": cftUrl("linux64/chrome-linux64.zip"),
155
167
  "ubuntu18.04-arm64": void 0,
156
168
  "ubuntu20.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
157
169
  "ubuntu22.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
158
170
  "ubuntu24.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
159
- "debian11-x64": "builds/chromium/%s/chromium-linux.zip",
171
+ "debian11-x64": cftUrl("linux64/chrome-linux64.zip"),
160
172
  "debian11-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
161
- "debian12-x64": "builds/chromium/%s/chromium-linux.zip",
173
+ "debian12-x64": cftUrl("linux64/chrome-linux64.zip"),
162
174
  "debian12-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
163
- "debian13-x64": "builds/chromium/%s/chromium-linux.zip",
175
+ "debian13-x64": cftUrl("linux64/chrome-linux64.zip"),
164
176
  "debian13-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
165
- "mac10.13": "builds/chromium/%s/chromium-mac.zip",
166
- "mac10.14": "builds/chromium/%s/chromium-mac.zip",
167
- "mac10.15": "builds/chromium/%s/chromium-mac.zip",
168
- "mac11": "builds/chromium/%s/chromium-mac.zip",
169
- "mac11-arm64": "builds/chromium/%s/chromium-mac-arm64.zip",
170
- "mac12": "builds/chromium/%s/chromium-mac.zip",
171
- "mac12-arm64": "builds/chromium/%s/chromium-mac-arm64.zip",
172
- "mac13": "builds/chromium/%s/chromium-mac.zip",
173
- "mac13-arm64": "builds/chromium/%s/chromium-mac-arm64.zip",
174
- "mac14": "builds/chromium/%s/chromium-mac.zip",
175
- "mac14-arm64": "builds/chromium/%s/chromium-mac-arm64.zip",
176
- "mac15": "builds/chromium/%s/chromium-mac.zip",
177
- "mac15-arm64": "builds/chromium/%s/chromium-mac-arm64.zip",
178
- "win64": "builds/chromium/%s/chromium-win64.zip"
177
+ "mac10.13": cftUrl("mac-x64/chrome-mac-x64.zip"),
178
+ "mac10.14": cftUrl("mac-x64/chrome-mac-x64.zip"),
179
+ "mac10.15": cftUrl("mac-x64/chrome-mac-x64.zip"),
180
+ "mac11": cftUrl("mac-x64/chrome-mac-x64.zip"),
181
+ "mac11-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
182
+ "mac12": cftUrl("mac-x64/chrome-mac-x64.zip"),
183
+ "mac12-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
184
+ "mac13": cftUrl("mac-x64/chrome-mac-x64.zip"),
185
+ "mac13-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
186
+ "mac14": cftUrl("mac-x64/chrome-mac-x64.zip"),
187
+ "mac14-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
188
+ "mac15": cftUrl("mac-x64/chrome-mac-x64.zip"),
189
+ "mac15-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
190
+ "win64": cftUrl("win64/chrome-win64.zip")
179
191
  },
180
192
  "chromium-headless-shell": {
181
193
  "<unknown>": void 0,
182
194
  "ubuntu18.04-x64": void 0,
183
- "ubuntu20.04-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
184
- "ubuntu22.04-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
185
- "ubuntu24.04-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
195
+ "ubuntu20.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
196
+ "ubuntu22.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
197
+ "ubuntu24.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
186
198
  "ubuntu18.04-arm64": void 0,
187
199
  "ubuntu20.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
188
200
  "ubuntu22.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
189
201
  "ubuntu24.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
190
- "debian11-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
202
+ "debian11-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
191
203
  "debian11-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
192
- "debian12-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
204
+ "debian12-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
193
205
  "debian12-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
194
- "debian13-x64": "builds/chromium/%s/chromium-headless-shell-linux.zip",
206
+ "debian13-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
195
207
  "debian13-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
196
208
  "mac10.13": void 0,
197
209
  "mac10.14": void 0,
198
210
  "mac10.15": void 0,
199
- "mac11": "builds/chromium/%s/chromium-headless-shell-mac.zip",
200
- "mac11-arm64": "builds/chromium/%s/chromium-headless-shell-mac-arm64.zip",
201
- "mac12": "builds/chromium/%s/chromium-headless-shell-mac.zip",
202
- "mac12-arm64": "builds/chromium/%s/chromium-headless-shell-mac-arm64.zip",
203
- "mac13": "builds/chromium/%s/chromium-headless-shell-mac.zip",
204
- "mac13-arm64": "builds/chromium/%s/chromium-headless-shell-mac-arm64.zip",
205
- "mac14": "builds/chromium/%s/chromium-headless-shell-mac.zip",
206
- "mac14-arm64": "builds/chromium/%s/chromium-headless-shell-mac-arm64.zip",
207
- "mac15": "builds/chromium/%s/chromium-headless-shell-mac.zip",
208
- "mac15-arm64": "builds/chromium/%s/chromium-headless-shell-mac-arm64.zip",
209
- "win64": "builds/chromium/%s/chromium-headless-shell-win64.zip"
211
+ "mac11": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
212
+ "mac11-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
213
+ "mac12": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
214
+ "mac12-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
215
+ "mac13": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
216
+ "mac13-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
217
+ "mac14": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
218
+ "mac14-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
219
+ "mac15": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
220
+ "mac15-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
221
+ "win64": cftUrl("win64/chrome-headless-shell-win64.zip")
210
222
  },
211
223
  "chromium-tip-of-tree": {
212
224
  "<unknown>": void 0,
213
225
  "ubuntu18.04-x64": void 0,
214
- "ubuntu20.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
215
- "ubuntu22.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
216
- "ubuntu24.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
226
+ "ubuntu20.04-x64": cftUrl("linux64/chrome-linux64.zip"),
227
+ "ubuntu22.04-x64": cftUrl("linux64/chrome-linux64.zip"),
228
+ "ubuntu24.04-x64": cftUrl("linux64/chrome-linux64.zip"),
217
229
  "ubuntu18.04-arm64": void 0,
218
230
  "ubuntu20.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
219
231
  "ubuntu22.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
220
232
  "ubuntu24.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
221
- "debian11-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
233
+ "debian11-x64": cftUrl("linux64/chrome-linux64.zip"),
222
234
  "debian11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
223
- "debian12-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
235
+ "debian12-x64": cftUrl("linux64/chrome-linux64.zip"),
224
236
  "debian12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
225
- "debian13-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip",
237
+ "debian13-x64": cftUrl("linux64/chrome-linux64.zip"),
226
238
  "debian13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
227
- "mac10.13": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
228
- "mac10.14": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
229
- "mac10.15": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
230
- "mac11": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
231
- "mac11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip",
232
- "mac12": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
233
- "mac12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip",
234
- "mac13": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
235
- "mac13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip",
236
- "mac14": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
237
- "mac14-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip",
238
- "mac15": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip",
239
- "mac15-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip",
240
- "win64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-win64.zip"
239
+ "mac10.13": cftUrl("mac-x64/chrome-mac-x64.zip"),
240
+ "mac10.14": cftUrl("mac-x64/chrome-mac-x64.zip"),
241
+ "mac10.15": cftUrl("mac-x64/chrome-mac-x64.zip"),
242
+ "mac11": cftUrl("mac-x64/chrome-mac-x64.zip"),
243
+ "mac11-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
244
+ "mac12": cftUrl("mac-x64/chrome-mac-x64.zip"),
245
+ "mac12-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
246
+ "mac13": cftUrl("mac-x64/chrome-mac-x64.zip"),
247
+ "mac13-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
248
+ "mac14": cftUrl("mac-x64/chrome-mac-x64.zip"),
249
+ "mac14-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
250
+ "mac15": cftUrl("mac-x64/chrome-mac-x64.zip"),
251
+ "mac15-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
252
+ "win64": cftUrl("win64/chrome-win64.zip")
241
253
  },
242
254
  "chromium-tip-of-tree-headless-shell": {
243
255
  "<unknown>": void 0,
244
256
  "ubuntu18.04-x64": void 0,
245
- "ubuntu20.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
246
- "ubuntu22.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
247
- "ubuntu24.04-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
257
+ "ubuntu20.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
258
+ "ubuntu22.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
259
+ "ubuntu24.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
248
260
  "ubuntu18.04-arm64": void 0,
249
261
  "ubuntu20.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
250
262
  "ubuntu22.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
251
263
  "ubuntu24.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
252
- "debian11-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
264
+ "debian11-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
253
265
  "debian11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
254
- "debian12-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
266
+ "debian12-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
255
267
  "debian12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
256
- "debian13-x64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux.zip",
268
+ "debian13-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
257
269
  "debian13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
258
270
  "mac10.13": void 0,
259
271
  "mac10.14": void 0,
260
272
  "mac10.15": void 0,
261
- "mac11": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac.zip",
262
- "mac11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac-arm64.zip",
263
- "mac12": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac.zip",
264
- "mac12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac-arm64.zip",
265
- "mac13": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac.zip",
266
- "mac13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac-arm64.zip",
267
- "mac14": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac.zip",
268
- "mac14-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac-arm64.zip",
269
- "mac15": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac.zip",
270
- "mac15-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-mac-arm64.zip",
271
- "win64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-win64.zip"
273
+ "mac11": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
274
+ "mac11-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
275
+ "mac12": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
276
+ "mac12-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
277
+ "mac13": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
278
+ "mac13-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
279
+ "mac14": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
280
+ "mac14-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
281
+ "mac15": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
282
+ "mac15-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
283
+ "win64": cftUrl("win64/chrome-headless-shell-win64.zip")
272
284
  },
273
285
  "firefox": {
274
286
  "<unknown>": void 0,
@@ -349,14 +361,14 @@ const DOWNLOAD_PATHS = {
349
361
  "debian13-x64": "builds/webkit/%s/webkit-debian-13.zip",
350
362
  "debian13-arm64": "builds/webkit/%s/webkit-debian-13-arm64.zip",
351
363
  "mac10.13": void 0,
352
- "mac10.14": "builds/deprecated-webkit-mac-10.14/%s/deprecated-webkit-mac-10.14.zip",
353
- "mac10.15": "builds/deprecated-webkit-mac-10.15/%s/deprecated-webkit-mac-10.15.zip",
354
- "mac11": "builds/webkit/%s/webkit-mac-11.zip",
355
- "mac11-arm64": "builds/webkit/%s/webkit-mac-11-arm64.zip",
356
- "mac12": "builds/webkit/%s/webkit-mac-12.zip",
357
- "mac12-arm64": "builds/webkit/%s/webkit-mac-12-arm64.zip",
358
- "mac13": "builds/webkit/%s/webkit-mac-13.zip",
359
- "mac13-arm64": "builds/webkit/%s/webkit-mac-13-arm64.zip",
364
+ "mac10.14": void 0,
365
+ "mac10.15": void 0,
366
+ "mac11": void 0,
367
+ "mac11-arm64": void 0,
368
+ "mac12": void 0,
369
+ "mac12-arm64": void 0,
370
+ "mac13": void 0,
371
+ "mac13-arm64": void 0,
360
372
  "mac14": "builds/webkit/%s/webkit-mac-14.zip",
361
373
  "mac14-arm64": "builds/webkit/%s/webkit-mac-14-arm64.zip",
362
374
  "mac15": "builds/webkit/%s/webkit-mac-15.zip",
@@ -457,25 +469,25 @@ const DOWNLOAD_PATHS = {
457
469
  "win64": "builds/android/%s/android.zip"
458
470
  }
459
471
  };
472
+ const defaultCacheDirectory = (() => {
473
+ if (process.platform === "linux")
474
+ return process.env.XDG_CACHE_HOME || import_path.default.join(import_os.default.homedir(), ".cache");
475
+ if (process.platform === "darwin")
476
+ return import_path.default.join(import_os.default.homedir(), "Library", "Caches");
477
+ if (process.platform === "win32")
478
+ return process.env.LOCALAPPDATA || import_path.default.join(import_os.default.homedir(), "AppData", "Local");
479
+ throw new Error("Unsupported platform: " + process.platform);
480
+ })();
481
+ const defaultRegistryDirectory = import_path.default.join(defaultCacheDirectory, "ms-playwright");
460
482
  const registryDirectory = (() => {
461
483
  let result;
462
484
  const envDefined = (0, import_utils.getFromENV)("PLAYWRIGHT_BROWSERS_PATH");
463
- if (envDefined === "0") {
485
+ if (envDefined === "0")
464
486
  result = import_path.default.join(__dirname, "..", "..", "..", ".local-browsers");
465
- } else if (envDefined) {
487
+ else if (envDefined)
466
488
  result = envDefined;
467
- } else {
468
- let cacheDirectory;
469
- if (process.platform === "linux")
470
- cacheDirectory = process.env.XDG_CACHE_HOME || import_path.default.join(import_os.default.homedir(), ".cache");
471
- else if (process.platform === "darwin")
472
- cacheDirectory = import_path.default.join(import_os.default.homedir(), "Library", "Caches");
473
- else if (process.platform === "win32")
474
- cacheDirectory = process.env.LOCALAPPDATA || import_path.default.join(import_os.default.homedir(), "AppData", "Local");
475
- else
476
- throw new Error("Unsupported platform: " + process.platform);
477
- result = import_path.default.join(cacheDirectory, "ms-playwright");
478
- }
489
+ else
490
+ result = defaultRegistryDirectory;
479
491
  if (!import_path.default.isAbsolute(result)) {
480
492
  result = import_path.default.resolve((0, import_utils.getFromENV)("INIT_CWD") || process.cwd(), result);
481
493
  }
@@ -483,7 +495,7 @@ const registryDirectory = (() => {
483
495
  })();
484
496
  function isBrowserDirectory(browserDirectory) {
485
497
  const baseName = import_path.default.basename(browserDirectory);
486
- for (const browserName of allDownloadable) {
498
+ for (const browserName of allDownloadableDirectoriesThatEverExisted) {
487
499
  if (baseName.startsWith(browserName.replace(/-/g, "_") + "-"))
488
500
  return true;
489
501
  }
@@ -501,6 +513,7 @@ function readDescriptors(browsersJSON) {
501
513
  hasRevisionOverride: !!revisionOverride,
502
514
  // We only put browser version for the supported operating systems.
503
515
  browserVersion: revisionOverride ? void 0 : obj.browserVersion,
516
+ title: obj["title"],
504
517
  installByDefault: !!obj.installByDefault,
505
518
  // Method `isBrowserDirectory` determines directory to be browser iff
506
519
  // it starts with some browser name followed by '-'. Some browser names
@@ -512,7 +525,8 @@ function readDescriptors(browsersJSON) {
512
525
  return descriptor;
513
526
  });
514
527
  }
515
- const allDownloadable = ["android", "chromium", "firefox", "webkit", "ffmpeg", "firefox-beta", "chromium-tip-of-tree", "chromium-headless-shell", "chromium-tip-of-tree-headless-shell"];
528
+ const allDownloadableDirectoriesThatEverExisted = ["android", "chromium", "firefox", "webkit", "ffmpeg", "firefox-beta", "chromium-tip-of-tree", "chromium-headless-shell", "chromium-tip-of-tree-headless-shell", "winldd"];
529
+ const chromiumAliases = ["chrome-for-testing"];
516
530
  class Registry {
517
531
  constructor(browsersJSON) {
518
532
  const descriptors = readDescriptors(browsersJSON);
@@ -528,21 +542,37 @@ class Registry {
528
542
  const currentDockerVersion = (0, import_dependencies.readDockerVersionSync)();
529
543
  const preferredDockerVersion = currentDockerVersion ? (0, import_dependencies.dockerVersion)(currentDockerVersion.dockerImageNameTemplate) : null;
530
544
  const isOutdatedDockerImage = currentDockerVersion && preferredDockerVersion && currentDockerVersion.dockerImageName !== preferredDockerVersion.dockerImageName;
531
- const prettyMessage = isOutdatedDockerImage ? [
532
- `Looks like ${sdkLanguage === "javascript" ? "Playwright Test or " : ""}Playwright was just updated to ${preferredDockerVersion.driverVersion}.`,
533
- `Please update docker image as well.`,
534
- `- current: ${currentDockerVersion.dockerImageName}`,
535
- `- required: ${preferredDockerVersion.dockerImageName}`,
536
- ``,
537
- `<3 Playwright Team`
538
- ].join("\n") : [
539
- `Looks like ${sdkLanguage === "javascript" ? "Playwright Test or " : ""}Playwright was just installed or updated.`,
540
- `Please run the following command to download new browser${installByDefault ? "s" : ""}:`,
541
- ``,
542
- ` ${installCommand}`,
543
- ``,
544
- `<3 Playwright Team`
545
- ].join("\n");
545
+ const isFfmpeg = name === "ffmpeg";
546
+ let prettyMessage;
547
+ if (isOutdatedDockerImage) {
548
+ prettyMessage = [
549
+ `Looks like Playwright was just updated to ${preferredDockerVersion.driverVersion}.`,
550
+ `Please update docker image as well.`,
551
+ `- current: ${currentDockerVersion.dockerImageName}`,
552
+ `- required: ${preferredDockerVersion.dockerImageName}`,
553
+ ``,
554
+ `<3 Playwright Team`
555
+ ].join("\n");
556
+ } else if (isFfmpeg) {
557
+ prettyMessage = [
558
+ `Video rendering requires ffmpeg binary.`,
559
+ `Downloading it will not affect any of the system-wide settings.`,
560
+ `Please run the following command:`,
561
+ ``,
562
+ ` ${buildPlaywrightCLICommand(sdkLanguage, "install ffmpeg")}`,
563
+ ``,
564
+ `<3 Playwright Team`
565
+ ].join("\n");
566
+ } else {
567
+ prettyMessage = [
568
+ `Looks like Playwright was just installed or updated.`,
569
+ `Please run the following command to download new browser${installByDefault ? "s" : ""}:`,
570
+ ``,
571
+ ` ${installCommand}`,
572
+ ``,
573
+ `<3 Playwright Team`
574
+ ].join("\n");
575
+ }
546
576
  throw new Error(`Executable doesn't exist at ${e}
547
577
  ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
548
578
  }
@@ -552,7 +582,6 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
552
582
  const chromium = descriptors.find((d) => d.name === "chromium");
553
583
  const chromiumExecutable = findExecutablePath(chromium.dir, "chromium");
554
584
  this._executables.push({
555
- type: "browser",
556
585
  name: "chromium",
557
586
  browserName: "chromium",
558
587
  directory: chromium.dir,
@@ -561,15 +590,16 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
561
590
  installType: chromium.installByDefault ? "download-by-default" : "download-on-demand",
562
591
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromium.dir, ["chrome-linux"], [], ["chrome-win"]),
563
592
  downloadURLs: this._downloadURLs(chromium),
593
+ title: chromium.title,
594
+ revision: chromium.revision,
564
595
  browserVersion: chromium.browserVersion,
565
- _install: () => this._downloadExecutable(chromium, chromiumExecutable),
596
+ _install: (force) => this._downloadExecutable(chromium, force, chromiumExecutable),
566
597
  _dependencyGroup: "chromium",
567
598
  _isHermeticInstallation: true
568
599
  });
569
600
  const chromiumHeadlessShell = descriptors.find((d) => d.name === "chromium-headless-shell");
570
601
  const chromiumHeadlessShellExecutable = findExecutablePath(chromiumHeadlessShell.dir, "chromium-headless-shell");
571
602
  this._executables.push({
572
- type: "channel",
573
603
  name: "chromium-headless-shell",
574
604
  browserName: "chromium",
575
605
  directory: chromiumHeadlessShell.dir,
@@ -578,15 +608,16 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
578
608
  installType: chromiumHeadlessShell.installByDefault ? "download-by-default" : "download-on-demand",
579
609
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ["chrome-linux"], [], ["chrome-win"]),
580
610
  downloadURLs: this._downloadURLs(chromiumHeadlessShell),
581
- browserVersion: chromium.browserVersion,
582
- _install: () => this._downloadExecutable(chromiumHeadlessShell, chromiumHeadlessShellExecutable),
611
+ title: chromiumHeadlessShell.title,
612
+ revision: chromiumHeadlessShell.revision,
613
+ browserVersion: chromiumHeadlessShell.browserVersion,
614
+ _install: (force) => this._downloadExecutable(chromiumHeadlessShell, force, chromiumHeadlessShellExecutable),
583
615
  _dependencyGroup: "chromium",
584
616
  _isHermeticInstallation: true
585
617
  });
586
618
  const chromiumTipOfTreeHeadlessShell = descriptors.find((d) => d.name === "chromium-tip-of-tree-headless-shell");
587
619
  const chromiumTipOfTreeHeadlessShellExecutable = findExecutablePath(chromiumTipOfTreeHeadlessShell.dir, "chromium-tip-of-tree-headless-shell");
588
620
  this._executables.push({
589
- type: "channel",
590
621
  name: "chromium-tip-of-tree-headless-shell",
591
622
  browserName: "chromium",
592
623
  directory: chromiumTipOfTreeHeadlessShell.dir,
@@ -595,15 +626,16 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
595
626
  installType: chromiumTipOfTreeHeadlessShell.installByDefault ? "download-by-default" : "download-on-demand",
596
627
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTreeHeadlessShell.dir, ["chrome-linux"], [], ["chrome-win"]),
597
628
  downloadURLs: this._downloadURLs(chromiumTipOfTreeHeadlessShell),
598
- browserVersion: chromium.browserVersion,
599
- _install: () => this._downloadExecutable(chromiumTipOfTreeHeadlessShell, chromiumTipOfTreeHeadlessShellExecutable),
629
+ title: chromiumTipOfTreeHeadlessShell.title,
630
+ revision: chromiumTipOfTreeHeadlessShell.revision,
631
+ browserVersion: chromiumTipOfTreeHeadlessShell.browserVersion,
632
+ _install: (force) => this._downloadExecutable(chromiumTipOfTreeHeadlessShell, force, chromiumTipOfTreeHeadlessShellExecutable),
600
633
  _dependencyGroup: "chromium",
601
634
  _isHermeticInstallation: true
602
635
  });
603
636
  const chromiumTipOfTree = descriptors.find((d) => d.name === "chromium-tip-of-tree");
604
637
  const chromiumTipOfTreeExecutable = findExecutablePath(chromiumTipOfTree.dir, "chromium-tip-of-tree");
605
638
  this._executables.push({
606
- type: "tool",
607
639
  name: "chromium-tip-of-tree",
608
640
  browserName: "chromium",
609
641
  directory: chromiumTipOfTree.dir,
@@ -612,8 +644,10 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
612
644
  installType: chromiumTipOfTree.installByDefault ? "download-by-default" : "download-on-demand",
613
645
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ["chrome-linux"], [], ["chrome-win"]),
614
646
  downloadURLs: this._downloadURLs(chromiumTipOfTree),
647
+ title: chromiumTipOfTree.title,
648
+ revision: chromiumTipOfTree.revision,
615
649
  browserVersion: chromiumTipOfTree.browserVersion,
616
- _install: () => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable),
650
+ _install: (force) => this._downloadExecutable(chromiumTipOfTree, force, chromiumTipOfTreeExecutable),
617
651
  _dependencyGroup: "chromium",
618
652
  _isHermeticInstallation: true
619
653
  });
@@ -692,35 +726,9 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
692
726
  "darwin": "/Applications/Firefox Nightly.app/Contents/MacOS/firefox",
693
727
  "win32": "\\Mozilla Firefox\\firefox.exe"
694
728
  }));
695
- this._executables.push(this._createBidiChromiumChannel("bidi-chrome-stable", {
696
- "linux": "/opt/google/chrome/chrome",
697
- "darwin": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
698
- "win32": `\\Google\\Chrome\\Application\\chrome.exe`
699
- }));
700
- this._executables.push(this._createBidiChromiumChannel("bidi-chrome-canary", {
701
- "linux": "/opt/google/chrome-canary/chrome",
702
- "darwin": "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
703
- "win32": `\\Google\\Chrome SxS\\Application\\chrome.exe`
704
- }));
705
- this._executables.push({
706
- type: "channel",
707
- name: "bidi-chromium",
708
- browserName: "chromium",
709
- directory: chromium.dir,
710
- executablePath: () => chromiumExecutable,
711
- executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium", chromiumExecutable, chromium.installByDefault, sdkLanguage),
712
- installType: "download-on-demand",
713
- _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromium.dir, ["chrome-linux"], [], ["chrome-win"]),
714
- downloadURLs: this._downloadURLs(chromium),
715
- browserVersion: chromium.browserVersion,
716
- _install: () => this._downloadExecutable(chromium, chromiumExecutable),
717
- _dependencyGroup: "chromium",
718
- _isHermeticInstallation: true
719
- });
720
729
  const firefox = descriptors.find((d) => d.name === "firefox");
721
730
  const firefoxExecutable = findExecutablePath(firefox.dir, "firefox");
722
731
  this._executables.push({
723
- type: "browser",
724
732
  name: "firefox",
725
733
  browserName: "firefox",
726
734
  directory: firefox.dir,
@@ -729,15 +737,16 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
729
737
  installType: firefox.installByDefault ? "download-by-default" : "download-on-demand",
730
738
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, firefox.dir, ["firefox"], [], ["firefox"]),
731
739
  downloadURLs: this._downloadURLs(firefox),
740
+ title: firefox.title,
741
+ revision: firefox.revision,
732
742
  browserVersion: firefox.browserVersion,
733
- _install: () => this._downloadExecutable(firefox, firefoxExecutable),
743
+ _install: (force) => this._downloadExecutable(firefox, force, firefoxExecutable),
734
744
  _dependencyGroup: "firefox",
735
745
  _isHermeticInstallation: true
736
746
  });
737
747
  const firefoxBeta = descriptors.find((d) => d.name === "firefox-beta");
738
748
  const firefoxBetaExecutable = findExecutablePath(firefoxBeta.dir, "firefox");
739
749
  this._executables.push({
740
- type: "tool",
741
750
  name: "firefox-beta",
742
751
  browserName: "firefox",
743
752
  directory: firefoxBeta.dir,
@@ -746,8 +755,10 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
746
755
  installType: firefoxBeta.installByDefault ? "download-by-default" : "download-on-demand",
747
756
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ["firefox"], [], ["firefox"]),
748
757
  downloadURLs: this._downloadURLs(firefoxBeta),
758
+ title: firefoxBeta.title,
759
+ revision: firefoxBeta.revision,
749
760
  browserVersion: firefoxBeta.browserVersion,
750
- _install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable),
761
+ _install: (force) => this._downloadExecutable(firefoxBeta, force, firefoxBetaExecutable),
751
762
  _dependencyGroup: "firefox",
752
763
  _isHermeticInstallation: true
753
764
  });
@@ -764,7 +775,6 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
764
775
  import_path.default.join("minibrowser-wpe", "sys", "lib")
765
776
  ];
766
777
  this._executables.push({
767
- type: "browser",
768
778
  name: "webkit",
769
779
  browserName: "webkit",
770
780
  directory: webkit.dir,
@@ -773,19 +783,21 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
773
783
  installType: webkit.installByDefault ? "download-by-default" : "download-on-demand",
774
784
  _validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ["libGLESv2.so.2", "libx264.so"], [""]),
775
785
  downloadURLs: this._downloadURLs(webkit),
786
+ title: webkit.title,
787
+ revision: webkit.revision,
776
788
  browserVersion: webkit.browserVersion,
777
- _install: () => this._downloadExecutable(webkit, webkitExecutable),
789
+ _install: (force) => this._downloadExecutable(webkit, force, webkitExecutable),
778
790
  _dependencyGroup: "webkit",
779
791
  _isHermeticInstallation: true
780
792
  });
781
793
  this._executables.push({
782
- type: "channel",
783
794
  name: "webkit-wsl",
784
795
  browserName: "webkit",
785
796
  directory: webkit.dir,
786
797
  executablePath: () => webkitExecutable,
787
798
  executablePathOrDie: (sdkLanguage) => executablePathOrDie("webkit", webkitExecutable, webkit.installByDefault, sdkLanguage),
788
799
  installType: "download-on-demand",
800
+ title: "Webkit in WSL",
789
801
  _validateHostRequirements: (sdkLanguage) => Promise.resolve(),
790
802
  _isHermeticInstallation: true,
791
803
  _install: async () => {
@@ -807,7 +819,6 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
807
819
  const ffmpeg = descriptors.find((d) => d.name === "ffmpeg");
808
820
  const ffmpegExecutable = findExecutablePath(ffmpeg.dir, "ffmpeg");
809
821
  this._executables.push({
810
- type: "tool",
811
822
  name: "ffmpeg",
812
823
  browserName: void 0,
813
824
  directory: ffmpeg.dir,
@@ -816,14 +827,15 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
816
827
  installType: ffmpeg.installByDefault ? "download-by-default" : "download-on-demand",
817
828
  _validateHostRequirements: () => Promise.resolve(),
818
829
  downloadURLs: this._downloadURLs(ffmpeg),
819
- _install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable),
830
+ title: ffmpeg.title,
831
+ revision: ffmpeg.revision,
832
+ _install: (force) => this._downloadExecutable(ffmpeg, force, ffmpegExecutable),
820
833
  _dependencyGroup: "tools",
821
834
  _isHermeticInstallation: true
822
835
  });
823
836
  const winldd = descriptors.find((d) => d.name === "winldd");
824
837
  const winlddExecutable = findExecutablePath(winldd.dir, "winldd");
825
838
  this._executables.push({
826
- type: "tool",
827
839
  name: "winldd",
828
840
  browserName: void 0,
829
841
  directory: winldd.dir,
@@ -832,13 +844,14 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
832
844
  installType: process.platform === "win32" ? "download-by-default" : "none",
833
845
  _validateHostRequirements: () => Promise.resolve(),
834
846
  downloadURLs: this._downloadURLs(winldd),
835
- _install: () => this._downloadExecutable(winldd, winlddExecutable),
847
+ title: winldd.title,
848
+ revision: winldd.revision,
849
+ _install: (force) => this._downloadExecutable(winldd, force, winlddExecutable),
836
850
  _dependencyGroup: "tools",
837
851
  _isHermeticInstallation: true
838
852
  });
839
853
  const android = descriptors.find((d) => d.name === "android");
840
854
  this._executables.push({
841
- type: "tool",
842
855
  name: "android",
843
856
  browserName: void 0,
844
857
  directory: android.dir,
@@ -847,7 +860,9 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
847
860
  installType: "download-on-demand",
848
861
  _validateHostRequirements: () => Promise.resolve(),
849
862
  downloadURLs: this._downloadURLs(android),
850
- _install: () => this._downloadExecutable(android),
863
+ title: android.title,
864
+ revision: android.revision,
865
+ _install: (force) => this._downloadExecutable(android, force),
851
866
  _dependencyGroup: "tools",
852
867
  _isHermeticInstallation: true
853
868
  });
@@ -881,11 +896,10 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
881
896
  throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`);
882
897
  };
883
898
  return {
884
- type: "channel",
885
899
  name,
886
900
  browserName: "chromium",
887
901
  directory: void 0,
888
- executablePath: (sdkLanguage) => executablePath(sdkLanguage, false),
902
+ executablePath: () => executablePath("", false),
889
903
  executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
890
904
  installType: install ? "install-script" : "none",
891
905
  _validateHostRequirements: () => Promise.resolve(),
@@ -920,11 +934,10 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
920
934
  return void 0;
921
935
  };
922
936
  return {
923
- type: "channel",
924
937
  name,
925
938
  browserName: "firefox",
926
939
  directory: void 0,
927
- executablePath: (sdkLanguage) => executablePath(sdkLanguage, false),
940
+ executablePath: () => executablePath("", false),
928
941
  executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
929
942
  installType: "none",
930
943
  _validateHostRequirements: () => Promise.resolve(),
@@ -932,47 +945,6 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
932
945
  _install: install
933
946
  };
934
947
  }
935
- _createBidiChromiumChannel(name, lookAt, install) {
936
- const executablePath = (sdkLanguage, shouldThrow) => {
937
- const suffix = lookAt[process.platform];
938
- if (!suffix) {
939
- if (shouldThrow)
940
- throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`);
941
- return void 0;
942
- }
943
- const prefixes = process.platform === "win32" ? [
944
- process.env.LOCALAPPDATA,
945
- process.env.PROGRAMFILES,
946
- process.env["PROGRAMFILES(X86)"],
947
- // In some cases there is no PROGRAMFILES/(86) env var set but HOMEDRIVE is set.
948
- process.env.HOMEDRIVE + "\\Program Files",
949
- process.env.HOMEDRIVE + "\\Program Files (x86)"
950
- ].filter(Boolean) : [""];
951
- for (const prefix of prefixes) {
952
- const executablePath2 = import_path.default.join(prefix, suffix);
953
- if ((0, import_fileUtils.canAccessFile)(executablePath2))
954
- return executablePath2;
955
- }
956
- if (!shouldThrow)
957
- return void 0;
958
- const location = prefixes.length ? ` at ${import_path.default.join(prefixes[0], suffix)}` : ``;
959
- const installation = install ? `
960
- Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
961
- throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`);
962
- };
963
- return {
964
- type: "channel",
965
- name,
966
- browserName: "chromium",
967
- directory: void 0,
968
- executablePath: (sdkLanguage) => executablePath(sdkLanguage, false),
969
- executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
970
- installType: install ? "install-script" : "none",
971
- _validateHostRequirements: () => Promise.resolve(),
972
- _isHermeticInstallation: false,
973
- _install: install
974
- };
975
- }
976
948
  executables() {
977
949
  return this._executables;
978
950
  }
@@ -1031,8 +1003,8 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
1031
1003
  for (const executable of executables) {
1032
1004
  if (!executable._install)
1033
1005
  throw new Error(`ERROR: Playwright does not support installing ${executable.name}`);
1034
- const { embedderName } = (0, import_userAgent.getEmbedderName)();
1035
- if (!(0, import_utils.getAsBooleanFromENV)("CI") && !executable._isHermeticInstallation && !options?.force && executable.executablePath(embedderName)) {
1006
+ if (!(0, import_utils.getAsBooleanFromENV)("CI") && !executable._isHermeticInstallation && !options?.force && executable.executablePath()) {
1007
+ const { embedderName } = (0, import_userAgent.getEmbedderName)();
1036
1008
  const command = buildPlaywrightCLICommand(embedderName, "install --force " + executable.name);
1037
1009
  process.stderr.write("\n" + (0, import_ascii.wrapInASCIIBox)([
1038
1010
  `ATTENTION: "${executable.name}" is already installed on the system!`,
@@ -1051,7 +1023,7 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
1051
1023
  ].join("\n"), 1) + "\n\n");
1052
1024
  return;
1053
1025
  }
1054
- await executable._install();
1026
+ await executable._install(!!options?.force);
1055
1027
  }
1056
1028
  } catch (e) {
1057
1029
  if (e.code === "ELOCKED") {
@@ -1123,8 +1095,16 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
1123
1095
  const downloadPathTemplate = paths[import_hostPlatform.hostPlatform] || paths["<unknown>"];
1124
1096
  if (!downloadPathTemplate)
1125
1097
  return [];
1126
- const downloadPath = util.format(downloadPathTemplate, descriptor.revision);
1127
- let downloadURLs = PLAYWRIGHT_CDN_MIRRORS.map((mirror) => `${mirror}/${downloadPath}`);
1098
+ let downloadPath;
1099
+ let mirrors;
1100
+ if (typeof downloadPathTemplate === "function") {
1101
+ const result = downloadPathTemplate(descriptor);
1102
+ downloadPath = result.path;
1103
+ mirrors = result.mirrors;
1104
+ } else {
1105
+ downloadPath = util.format(downloadPathTemplate, descriptor.revision);
1106
+ mirrors = PLAYWRIGHT_CDN_MIRRORS;
1107
+ }
1128
1108
  let downloadHostEnv;
1129
1109
  if (descriptor.name.startsWith("chromium"))
1130
1110
  downloadHostEnv = "PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST";
@@ -1134,10 +1114,10 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
1134
1114
  downloadHostEnv = "PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST";
1135
1115
  const customHostOverride = downloadHostEnv && (0, import_utils.getFromENV)(downloadHostEnv) || (0, import_utils.getFromENV)("PLAYWRIGHT_DOWNLOAD_HOST");
1136
1116
  if (customHostOverride)
1137
- downloadURLs = [`${customHostOverride}/${downloadPath}`];
1138
- return downloadURLs;
1117
+ mirrors = [customHostOverride];
1118
+ return mirrors.map((mirror) => `${mirror}/${downloadPath}`);
1139
1119
  }
1140
- async _downloadExecutable(descriptor, executablePath) {
1120
+ async _downloadExecutable(descriptor, force, executablePath) {
1141
1121
  const downloadURLs = this._downloadURLs(descriptor);
1142
1122
  if (!downloadURLs.length)
1143
1123
  throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${import_hostPlatform.hostPlatform}`);
@@ -1150,18 +1130,22 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
1150
1130
  else
1151
1131
  (0, import_browserFetcher.logPolitely)(message);
1152
1132
  }
1153
- const displayName = descriptor.name.split("-").map((word) => {
1154
- return word === "ffmpeg" ? "FFMPEG" : word.charAt(0).toUpperCase() + word.slice(1);
1155
- }).join(" ");
1156
- const title = descriptor.browserVersion ? `${displayName} ${descriptor.browserVersion} (playwright build v${descriptor.revision})` : `${displayName} playwright build v${descriptor.revision}`;
1133
+ const title = this.calculateDownloadTitle(descriptor);
1157
1134
  const downloadFileName = `playwright-download-${descriptor.name}-${import_hostPlatform.hostPlatform}-${descriptor.revision}.zip`;
1158
1135
  const downloadSocketTimeoutEnv = (0, import_utils.getFromENV)("PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT");
1159
1136
  const downloadSocketTimeout = +(downloadSocketTimeoutEnv || "0") || import_network.NET_DEFAULT_TIMEOUT;
1160
- await (0, import_browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadSocketTimeout).catch((e) => {
1137
+ await (0, import_browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadSocketTimeout, force).catch((e) => {
1161
1138
  throw new Error(`Failed to download ${title}, caused by
1162
1139
  ${e.stack}`);
1163
1140
  });
1164
1141
  }
1142
+ calculateDownloadTitle(descriptor) {
1143
+ const title = descriptor.title ?? descriptor.name.split("-").map((word) => {
1144
+ return word === "ffmpeg" ? "FFmpeg" : word.charAt(0).toUpperCase() + word.slice(1);
1145
+ }).join(" ");
1146
+ const version = descriptor.browserVersion ? " " + descriptor.browserVersion : "";
1147
+ return `${title}${version} (playwright ${descriptor.name} v${descriptor.revision})`;
1148
+ }
1165
1149
  async _installMSEdgeChannel(channel, scripts) {
1166
1150
  const scriptArgs = [];
1167
1151
  if (process.platform !== "linux") {
@@ -1234,7 +1218,7 @@ ${e.stack}`);
1234
1218
  linkTarget = (await import_fs.default.promises.readFile(linkPath)).toString();
1235
1219
  const browsersJSON = require(import_path.default.join(linkTarget, "browsers.json"));
1236
1220
  const descriptors = readDescriptors(browsersJSON);
1237
- for (const browserName of allDownloadable) {
1221
+ for (const browserName of allDownloadableDirectoriesThatEverExisted) {
1238
1222
  const descriptor = descriptors.find((d) => d.name === browserName);
1239
1223
  if (!descriptor)
1240
1224
  continue;
@@ -1279,13 +1263,18 @@ ${e.stack}`);
1279
1263
  _defaultBrowsersToInstall(options) {
1280
1264
  let executables = this.defaultExecutables();
1281
1265
  if (options.shell === "no")
1282
- executables = executables.filter((e) => e.name !== "chromium-headless-shell");
1266
+ executables = executables.filter((e) => e.name !== "chromium-headless-shell" && e.name !== "chromium-tip-of-tree-headless-shell");
1283
1267
  if (options.shell === "only")
1284
- executables = executables.filter((e) => e.name !== "chromium");
1268
+ executables = executables.filter((e) => e.name !== "chromium" && e.name !== "chromium-tip-of-tree");
1285
1269
  return executables;
1286
1270
  }
1287
1271
  suggestedBrowsersToInstall() {
1288
- return this.executables().filter((e) => e.installType !== "none" && e.type !== "tool").map((e) => e.name).join(", ");
1272
+ const names = this.executables().filter((e) => e.installType !== "none").map((e) => e.name);
1273
+ names.push(...chromiumAliases);
1274
+ return names.sort().join(", ");
1275
+ }
1276
+ isChromiumAlias(name) {
1277
+ return chromiumAliases.includes(name);
1289
1278
  }
1290
1279
  resolveBrowsers(aliases, options) {
1291
1280
  if (aliases.length === 0)
@@ -1298,15 +1287,20 @@ ${e.stack}`);
1298
1287
  faultyArguments.push(arg);
1299
1288
  else
1300
1289
  executables.push(executable);
1301
- if (executable?.browserName === "chromium")
1290
+ if (executable?.browserName)
1302
1291
  executables.push(this.findExecutable("ffmpeg"));
1303
1292
  };
1304
1293
  for (const alias of aliases) {
1305
- if (alias === "chromium") {
1294
+ if (alias === "chromium" || chromiumAliases.includes(alias)) {
1306
1295
  if (options.shell !== "only")
1307
1296
  handleArgument("chromium");
1308
1297
  if (options.shell !== "no")
1309
1298
  handleArgument("chromium-headless-shell");
1299
+ } else if (alias === "chromium-tip-of-tree") {
1300
+ if (options.shell !== "only")
1301
+ handleArgument("chromium-tip-of-tree");
1302
+ if (options.shell !== "no")
1303
+ handleArgument("chromium-tip-of-tree-headless-shell");
1310
1304
  } else {
1311
1305
  handleArgument(alias);
1312
1306
  }
@@ -1331,7 +1325,7 @@ function buildPlaywrightCLICommand(sdkLanguage, parameters) {
1331
1325
  return `pwsh bin/Debug/netX/playwright.ps1 ${parameters}`;
1332
1326
  default: {
1333
1327
  const packageManagerCommand = (0, import_utils.getPackageManagerExecCommand)();
1334
- return `${packageManagerCommand} patchright ${parameters}`;
1328
+ return `${packageManagerCommand} playwright ${parameters}`;
1335
1329
  }
1336
1330
  }
1337
1331
  }
@@ -1391,6 +1385,8 @@ const registry = new Registry(require("../../../browsers.json"));
1391
1385
  Registry,
1392
1386
  browserDirectoryToMarkerFilePath,
1393
1387
  buildPlaywrightCLICommand,
1388
+ defaultCacheDirectory,
1389
+ defaultRegistryDirectory,
1394
1390
  findChromiumChannelBestEffort,
1395
1391
  installBrowsersForNpmInstall,
1396
1392
  registry,