patchright-core 1.52.5 → 1.55.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/ThirdPartyNotices.txt +65 -123
  2. package/bin/reinstall_chrome_beta_mac.sh +1 -1
  3. package/bin/reinstall_chrome_stable_mac.sh +1 -1
  4. package/bin/reinstall_msedge_beta_mac.sh +1 -1
  5. package/bin/reinstall_msedge_dev_mac.sh +1 -1
  6. package/bin/reinstall_msedge_stable_mac.sh +1 -1
  7. package/browsers.json +14 -14
  8. package/index.js +1 -1
  9. package/lib/androidServerImpl.js +4 -2
  10. package/lib/browserServerImpl.js +47 -12
  11. package/lib/cli/program.js +116 -50
  12. package/lib/cli/programWithTestStub.js +1 -1
  13. package/lib/client/android.js +30 -34
  14. package/lib/client/browser.js +54 -17
  15. package/lib/client/browserContext.js +67 -71
  16. package/lib/client/browserType.js +25 -34
  17. package/lib/client/channelOwner.js +20 -24
  18. package/lib/client/connection.js +6 -10
  19. package/lib/client/electron.js +8 -3
  20. package/lib/client/elementHandle.js +18 -21
  21. package/lib/client/fetch.js +5 -3
  22. package/lib/client/frame.js +54 -32
  23. package/lib/client/input.js +3 -1
  24. package/lib/client/jsHandle.js +4 -0
  25. package/lib/client/localUtils.js +0 -1
  26. package/lib/client/locator.js +30 -26
  27. package/lib/client/network.js +5 -12
  28. package/lib/client/page.js +32 -32
  29. package/lib/client/playwright.js +6 -16
  30. package/lib/client/selectors.js +18 -38
  31. package/lib/client/timeoutSettings.js +12 -8
  32. package/lib/client/tracing.js +24 -20
  33. package/lib/client/waiter.js +2 -2
  34. package/lib/client/webSocket.js +4 -22
  35. package/lib/generated/bindingsControllerSource.js +28 -0
  36. package/lib/generated/clockSource.js +1 -1
  37. package/lib/generated/injectedScriptSource.js +1 -1
  38. package/lib/generated/pollingRecorderSource.js +1 -1
  39. package/lib/generated/storageScriptSource.js +28 -0
  40. package/lib/generated/utilityScriptSource.js +1 -1
  41. package/lib/generated/webSocketMockSource.js +12 -50
  42. package/lib/inProcessFactory.js +9 -6
  43. package/lib/outofprocess.js +0 -2
  44. package/lib/protocol/validator.js +421 -345
  45. package/lib/protocol/validatorPrimitives.js +18 -4
  46. package/lib/remote/playwrightConnection.js +29 -166
  47. package/lib/remote/playwrightServer.js +233 -35
  48. package/lib/server/android/android.js +97 -83
  49. package/lib/server/android/backendAdb.js +0 -2
  50. package/lib/server/bidi/bidiBrowser.js +139 -73
  51. package/lib/server/bidi/bidiChromium.js +23 -22
  52. package/lib/server/bidi/bidiExecutionContext.js +2 -1
  53. package/lib/server/bidi/bidiFirefox.js +17 -14
  54. package/lib/server/bidi/bidiInput.js +22 -22
  55. package/lib/server/bidi/bidiNetworkManager.js +8 -11
  56. package/lib/server/bidi/bidiPage.js +42 -86
  57. package/lib/server/bidi/third_party/bidiProtocol.js +5 -133
  58. package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
  59. package/lib/server/{dispatchers/selectorsDispatcher.js → bidi/third_party/bidiProtocolPermissions.js} +20 -18
  60. package/lib/server/browser.js +30 -21
  61. package/lib/server/browserContext.js +203 -165
  62. package/lib/server/browserType.js +109 -107
  63. package/lib/server/chromium/chromium.js +84 -69
  64. package/lib/server/chromium/chromiumSwitches.js +13 -20
  65. package/lib/server/chromium/crBrowser.js +74 -40
  66. package/lib/server/chromium/crConnection.js +8 -9
  67. package/lib/server/chromium/crCoverage.js +11 -8
  68. package/lib/server/chromium/crDragDrop.js +25 -20
  69. package/lib/server/chromium/crExecutionContext.js +2 -1
  70. package/lib/server/chromium/crInput.js +32 -29
  71. package/lib/server/chromium/crNetworkManager.js +43 -31
  72. package/lib/server/chromium/crPage.js +98 -72
  73. package/lib/server/chromium/crServiceWorker.js +13 -18
  74. package/lib/server/chromium/videoRecorder.js +10 -18
  75. package/lib/server/clock.js +51 -39
  76. package/lib/server/codegen/csharp.js +10 -5
  77. package/lib/server/codegen/java.js +1 -1
  78. package/lib/server/codegen/javascript.js +1 -1
  79. package/lib/server/codegen/jsonl.js +2 -1
  80. package/lib/server/codegen/language.js +22 -1
  81. package/lib/server/codegen/languages.js +4 -4
  82. package/lib/server/codegen/python.js +1 -1
  83. package/lib/server/cookieStore.js +3 -1
  84. package/lib/server/debugController.js +105 -71
  85. package/lib/server/debugger.js +6 -23
  86. package/lib/server/deviceDescriptorsSource.json +237 -127
  87. package/lib/server/dialog.js +50 -6
  88. package/lib/server/dispatchers/androidDispatcher.js +77 -62
  89. package/lib/server/dispatchers/artifactDispatcher.js +18 -18
  90. package/lib/server/dispatchers/browserContextDispatcher.js +141 -91
  91. package/lib/server/dispatchers/browserDispatcher.js +55 -88
  92. package/lib/server/dispatchers/browserTypeDispatcher.js +18 -9
  93. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -4
  94. package/lib/server/dispatchers/debugControllerDispatcher.js +12 -21
  95. package/lib/server/dispatchers/dialogDispatcher.js +4 -4
  96. package/lib/server/dispatchers/dispatcher.js +78 -53
  97. package/lib/server/dispatchers/electronDispatcher.js +19 -20
  98. package/lib/server/dispatchers/elementHandlerDispatcher.js +83 -93
  99. package/lib/server/dispatchers/frameDispatcher.js +98 -101
  100. package/lib/server/dispatchers/jsHandleDispatcher.js +21 -16
  101. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -4
  102. package/lib/server/dispatchers/localUtilsDispatcher.js +53 -59
  103. package/lib/server/dispatchers/networkDispatchers.js +41 -35
  104. package/lib/server/dispatchers/pageDispatcher.js +156 -107
  105. package/lib/server/dispatchers/playwrightDispatcher.js +37 -25
  106. package/lib/server/dispatchers/streamDispatcher.js +15 -8
  107. package/lib/server/dispatchers/tracingDispatcher.js +22 -13
  108. package/lib/server/dispatchers/webSocketRouteDispatcher.js +46 -35
  109. package/lib/server/dispatchers/writableStreamDispatcher.js +16 -10
  110. package/lib/server/dom.js +198 -266
  111. package/lib/server/download.js +3 -3
  112. package/lib/server/electron/electron.js +96 -103
  113. package/lib/server/electron/loader.js +1 -1
  114. package/lib/server/fetch.js +22 -41
  115. package/lib/server/fileUploadUtils.js +1 -1
  116. package/lib/server/firefox/ffBrowser.js +79 -55
  117. package/lib/server/firefox/ffExecutionContext.js +2 -1
  118. package/lib/server/firefox/ffInput.js +23 -23
  119. package/lib/server/firefox/ffNetworkManager.js +8 -6
  120. package/lib/server/firefox/ffPage.js +39 -36
  121. package/lib/server/firefox/firefox.js +9 -10
  122. package/lib/server/frameSelectors.js +63 -20
  123. package/lib/server/frames.js +495 -555
  124. package/lib/server/har/harRecorder.js +1 -1
  125. package/lib/server/har/harTracer.js +4 -2
  126. package/lib/server/helper.js +3 -7
  127. package/lib/server/index.js +0 -3
  128. package/lib/server/input.js +47 -54
  129. package/lib/server/instrumentation.js +8 -14
  130. package/lib/server/javascript.js +8 -16
  131. package/lib/server/launchApp.js +48 -30
  132. package/lib/server/localUtils.js +45 -38
  133. package/lib/server/network.js +44 -10
  134. package/lib/server/page.js +232 -177
  135. package/lib/server/pageBinding.js +6 -7
  136. package/lib/server/playwright.js +4 -14
  137. package/lib/server/progress.js +57 -49
  138. package/lib/server/recorder/recorderApp.js +298 -95
  139. package/lib/server/recorder/recorderRunner.js +23 -24
  140. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  141. package/lib/server/recorder/recorderUtils.js +67 -10
  142. package/lib/server/recorder.js +284 -146
  143. package/lib/server/registry/index.js +83 -48
  144. package/lib/server/registry/nativeDeps.js +175 -0
  145. package/lib/server/registry/oopDownloadBrowserMain.js +1 -1
  146. package/lib/server/screenshotter.js +84 -83
  147. package/lib/server/selectors.js +12 -12
  148. package/lib/server/socksClientCertificatesInterceptor.js +198 -136
  149. package/lib/server/trace/recorder/snapshotter.js +12 -19
  150. package/lib/server/trace/recorder/tracing.js +36 -27
  151. package/lib/server/trace/viewer/traceViewer.js +11 -20
  152. package/lib/server/transport.js +20 -22
  153. package/lib/server/utils/comparators.js +2 -2
  154. package/lib/server/utils/debug.js +3 -8
  155. package/lib/server/utils/debugLogger.js +8 -0
  156. package/lib/server/utils/hostPlatform.js +3 -1
  157. package/lib/server/utils/network.js +35 -25
  158. package/lib/server/utils/nodePlatform.js +1 -1
  159. package/lib/server/utils/processLauncher.js +4 -1
  160. package/lib/server/utils/wsServer.js +11 -17
  161. package/lib/server/webkit/webkit.js +5 -2
  162. package/lib/server/webkit/wkBrowser.js +51 -28
  163. package/lib/server/webkit/wkExecutionContext.js +2 -1
  164. package/lib/server/webkit/wkInput.js +25 -25
  165. package/lib/server/webkit/wkInterceptableRequest.js +1 -1
  166. package/lib/server/webkit/wkPage.js +80 -59
  167. package/lib/server/webkit/wkProvisionalPage.js +1 -1
  168. package/lib/server/webkit/wkWorkers.js +7 -7
  169. package/lib/utils/isomorphic/ariaSnapshot.js +13 -7
  170. package/lib/utils/isomorphic/cssParser.js +1 -2
  171. package/lib/utils/isomorphic/locatorGenerators.js +18 -0
  172. package/lib/utils/isomorphic/manualPromise.js +1 -2
  173. package/lib/utils/isomorphic/mimeType.js +1 -2
  174. package/lib/utils/isomorphic/multimap.js +1 -2
  175. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
  176. package/lib/utils/isomorphic/protocolFormatter.js +78 -0
  177. package/lib/utils/isomorphic/protocolMetainfo.js +318 -0
  178. package/lib/utils/isomorphic/selectorParser.js +3 -4
  179. package/lib/utils/isomorphic/stringUtils.js +3 -24
  180. package/lib/utils/isomorphic/time.js +9 -4
  181. package/lib/utils/isomorphic/timeoutRunner.js +3 -4
  182. package/lib/utils/isomorphic/traceUtils.js +2 -3
  183. package/lib/utils/isomorphic/urlMatch.js +21 -7
  184. package/lib/utils/isomorphic/utilityScriptSerializers.js +208 -205
  185. package/lib/utils.js +8 -2
  186. package/lib/utilsBundleImpl/index.js +160 -150
  187. package/lib/vite/htmlReport/index.html +17 -17
  188. package/lib/vite/recorder/assets/{codeMirrorModule-CXVeovup.js → codeMirrorModule-DzQ0k89p.js} +1 -1
  189. package/lib/vite/recorder/assets/{index-eHBmevrY.css → index-CI4HQ-Zb.css} +1 -1
  190. package/lib/vite/recorder/assets/index-D7C7daHH.js +184 -0
  191. package/lib/vite/recorder/index.html +3 -3
  192. package/lib/vite/traceViewer/assets/{codeMirrorModule-_GLjJL-7.js → codeMirrorModule-Di48jgWx.js} +1 -1
  193. package/lib/vite/traceViewer/assets/defaultSettingsView-szBn8781.js +256 -0
  194. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +1 -0
  195. package/lib/vite/traceViewer/index.BFsek2M6.css +1 -0
  196. package/lib/vite/traceViewer/index.DQvXoPLL.js +2 -0
  197. package/lib/vite/traceViewer/index.html +6 -6
  198. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  199. package/lib/vite/traceViewer/uiMode.dBV3oN9h.js +5 -0
  200. package/lib/vite/traceViewer/uiMode.html +4 -4
  201. package/lib/zipBundleImpl.js +4 -4
  202. package/package.json +1 -1
  203. package/types/protocol.d.ts +712 -107
  204. package/types/types.d.ts +128 -17
  205. package/lib/generated/consoleApiSource.js +0 -28
  206. package/lib/protocol/debug.js +0 -211
  207. package/lib/server/recorder/contextRecorder.js +0 -286
  208. package/lib/server/recorder/recorderCollection.js +0 -116
  209. package/lib/server/recorder/recorderFrontend.js +0 -16
  210. package/lib/server/storageScript.js +0 -154
  211. package/lib/server/timeoutSettings.js +0 -89
  212. package/lib/utils/isomorphic/builtins.js +0 -86
  213. package/lib/vite/recorder/assets/index-BsWQsSGl.js +0 -184
  214. package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +0 -265
  215. package/lib/vite/traceViewer/defaultSettingsView.QdHITyLI.css +0 -1
  216. package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
  217. package/lib/vite/traceViewer/index.cFZzK9RN.js +0 -2
  218. package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +0 -5
@@ -28,7 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var browserType_exports = {};
30
30
  __export(browserType_exports, {
31
- BrowserReadyState: () => BrowserReadyState,
32
31
  BrowserType: () => BrowserType,
33
32
  kNoXServerRunningError: () => kNoXServerRunningError
34
33
  });
@@ -37,40 +36,27 @@ var import_fs = __toESM(require("fs"));
37
36
  var import_os = __toESM(require("os"));
38
37
  var import_path = __toESM(require("path"));
39
38
  var import_browserContext = require("./browserContext");
40
- var import_timeoutSettings = require("./timeoutSettings");
41
39
  var import_debug = require("./utils/debug");
42
40
  var import_assert = require("../utils/isomorphic/assert");
43
41
  var import_manualPromise = require("../utils/isomorphic/manualPromise");
42
+ var import_time = require("../utils/isomorphic/time");
44
43
  var import_fileUtils = require("./utils/fileUtils");
45
44
  var import_helper = require("./helper");
46
45
  var import_instrumentation = require("./instrumentation");
47
46
  var import_pipeTransport = require("./pipeTransport");
48
47
  var import_processLauncher = require("./utils/processLauncher");
49
- var import_progress = require("./progress");
50
48
  var import_protocolError = require("./protocolError");
51
49
  var import_registry = require("./registry");
52
50
  var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
53
51
  var import_transport = require("./transport");
54
52
  var import_debugLogger = require("./utils/debugLogger");
55
53
  const kNoXServerRunningError = "Looks like you launched a headed browser without having a XServer running.\nSet either 'headless: true' or use 'xvfb-run <your-playwright-app>' before running Playwright.\n\n<3 Playwright Team";
56
- class BrowserReadyState {
57
- constructor() {
58
- this._wsEndpoint = new import_manualPromise.ManualPromise();
59
- }
60
- onBrowserExit() {
61
- this._wsEndpoint.resolve(void 0);
62
- }
63
- async waitUntilReady() {
64
- const wsEndpoint = await this._wsEndpoint;
65
- return { wsEndpoint };
66
- }
67
- }
68
54
  class BrowserType extends import_instrumentation.SdkObject {
69
55
  constructor(parent, browserName) {
70
56
  super(parent, "browser-type");
71
- this._useBidi = false;
72
57
  this.attribution.browserType = this;
73
58
  this._name = browserName;
59
+ this.logName = "browser";
74
60
  }
75
61
  executablePath() {
76
62
  return import_registry.registry.findExecutable(this._name).executablePath(this.attribution.playwright.options.sdkLanguage) || "";
@@ -78,44 +64,35 @@ class BrowserType extends import_instrumentation.SdkObject {
78
64
  name() {
79
65
  return this._name;
80
66
  }
81
- async launch(metadata, options, protocolLogger) {
67
+ async launch(progress, options, protocolLogger) {
82
68
  options = this._validateLaunchOptions(options);
83
- if (this._useBidi)
84
- options.useWebSocket = true;
85
- const controller = new import_progress.ProgressController(metadata, this);
86
- controller.setLogName("browser");
87
- const browser = await controller.run((progress) => {
88
- const seleniumHubUrl = options.__testHookSeleniumRemoteURL || process.env.SELENIUM_REMOTE_URL;
89
- if (seleniumHubUrl)
90
- return this._launchWithSeleniumHub(progress, seleniumHubUrl, options);
91
- return this._innerLaunchWithRetries(progress, options, void 0, import_helper.helper.debugProtocolLogger(protocolLogger)).catch((e) => {
92
- throw this._rewriteStartupLog(e);
93
- });
94
- }, import_timeoutSettings.TimeoutSettings.launchTimeout(options));
95
- return browser;
69
+ const seleniumHubUrl = options.__testHookSeleniumRemoteURL || process.env.SELENIUM_REMOTE_URL;
70
+ if (seleniumHubUrl)
71
+ return this._launchWithSeleniumHub(progress, seleniumHubUrl, options);
72
+ return this._innerLaunchWithRetries(progress, options, void 0, import_helper.helper.debugProtocolLogger(protocolLogger)).catch((e) => {
73
+ throw this._rewriteStartupLog(e);
74
+ });
96
75
  }
97
- async launchPersistentContext(metadata, userDataDir, options) {
76
+ async launchPersistentContext(progress, userDataDir, options) {
98
77
  const launchOptions = this._validateLaunchOptions(options);
99
- if (this._useBidi)
100
- launchOptions.useWebSocket = true;
101
- const controller = new import_progress.ProgressController(metadata, this);
102
- controller.setLogName("browser");
103
- const browser = await controller.run(async (progress) => {
104
- let clientCertificatesProxy;
105
- if (options.clientCertificates?.length) {
106
- clientCertificatesProxy = new import_socksClientCertificatesInterceptor.ClientCertificatesProxy(options);
107
- launchOptions.proxyOverride = await clientCertificatesProxy?.listen();
108
- options = { ...options };
109
- options.internalIgnoreHTTPSErrors = true;
110
- }
111
- progress.cleanupWhenAborted(() => clientCertificatesProxy?.close());
112
- const browser2 = await this._innerLaunchWithRetries(progress, launchOptions, options, import_helper.helper.debugProtocolLogger(), userDataDir).catch((e) => {
78
+ let clientCertificatesProxy;
79
+ if (options.clientCertificates?.length) {
80
+ clientCertificatesProxy = await import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(progress, options);
81
+ launchOptions.proxyOverride = clientCertificatesProxy.proxySettings();
82
+ options = { ...options };
83
+ options.internalIgnoreHTTPSErrors = true;
84
+ }
85
+ try {
86
+ const browser = await this._innerLaunchWithRetries(progress, launchOptions, options, import_helper.helper.debugProtocolLogger(), userDataDir).catch((e) => {
113
87
  throw this._rewriteStartupLog(e);
114
88
  });
115
- browser2._defaultContext._clientCertificatesProxy = clientCertificatesProxy;
116
- return browser2;
117
- }, import_timeoutSettings.TimeoutSettings.launchTimeout(launchOptions));
118
- return browser._defaultContext;
89
+ browser._defaultContext._clientCertificatesProxy = clientCertificatesProxy;
90
+ return browser._defaultContext;
91
+ } catch (error) {
92
+ await clientCertificatesProxy?.close().catch(() => {
93
+ });
94
+ throw error;
95
+ }
119
96
  }
120
97
  async _innerLaunchWithRetries(progress, options, persistent, protocolLogger, userDataDir) {
121
98
  try {
@@ -133,46 +110,48 @@ class BrowserType extends import_instrumentation.SdkObject {
133
110
  options.proxy = options.proxy ? (0, import_browserContext.normalizeProxySettings)(options.proxy) : void 0;
134
111
  const browserLogsCollector = new import_debugLogger.RecentLogsCollector();
135
112
  const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
136
- if (options.__testHookBeforeCreateBrowser)
137
- await options.__testHookBeforeCreateBrowser();
138
- const browserOptions = {
139
- name: this._name,
140
- isChromium: this._name === "chromium",
141
- channel: options.channel,
142
- slowMo: options.slowMo,
143
- persistent,
144
- headful: !options.headless,
145
- artifactsDir,
146
- downloadsPath: options.downloadsPath || artifactsDir,
147
- tracesDir: options.tracesDir || artifactsDir,
148
- browserProcess,
149
- customExecutablePath: options.executablePath,
150
- proxy: options.proxy,
151
- protocolLogger,
152
- browserLogsCollector,
153
- wsEndpoint: options.useWebSocket ? transport.wsEndpoint : void 0,
154
- originalLaunchOptions: options
155
- };
156
- if (persistent)
157
- (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
158
- copyTestHooks(options, browserOptions);
159
- const browser = await this.connectToTransport(transport, browserOptions);
160
- browser._userDataDirForTest = userDataDir;
161
- if (persistent && !options.ignoreAllDefaultArgs)
162
- await browser._defaultContext._loadDefaultContext(progress);
163
- return browser;
113
+ try {
114
+ if (options.__testHookBeforeCreateBrowser)
115
+ await progress.race(options.__testHookBeforeCreateBrowser());
116
+ const browserOptions = {
117
+ name: this._name,
118
+ isChromium: this._name === "chromium",
119
+ channel: options.channel,
120
+ slowMo: options.slowMo,
121
+ persistent,
122
+ headful: !options.headless,
123
+ artifactsDir,
124
+ downloadsPath: options.downloadsPath || artifactsDir,
125
+ tracesDir: options.tracesDir || artifactsDir,
126
+ browserProcess,
127
+ customExecutablePath: options.executablePath,
128
+ proxy: options.proxy,
129
+ protocolLogger,
130
+ browserLogsCollector,
131
+ wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
132
+ originalLaunchOptions: options
133
+ };
134
+ if (persistent)
135
+ (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
136
+ copyTestHooks(options, browserOptions);
137
+ const browser = await progress.race(this.connectToTransport(transport, browserOptions, browserLogsCollector));
138
+ browser._userDataDirForTest = userDataDir;
139
+ if (persistent && !options.ignoreAllDefaultArgs)
140
+ await browser._defaultContext._loadDefaultContext(progress);
141
+ return browser;
142
+ } catch (error) {
143
+ await browserProcess.close().catch(() => {
144
+ });
145
+ throw error;
146
+ }
164
147
  }
165
- async _launchProcess(progress, options, isPersistent, browserLogsCollector, userDataDir) {
148
+ async _prepareToLaunch(options, isPersistent, userDataDir) {
166
149
  const {
167
150
  ignoreDefaultArgs,
168
151
  ignoreAllDefaultArgs,
169
152
  args = [],
170
- executablePath = null,
171
- handleSIGINT = true,
172
- handleSIGTERM = true,
173
- handleSIGHUP = true
153
+ executablePath = null
174
154
  } = options;
175
- const env = options.env ? (0, import_processLauncher.envArrayToObject)(options.env) : process.env;
176
155
  await this._createArtifactDirs(options);
177
156
  const tempDirectories = [];
178
157
  const artifactsDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-"));
@@ -205,30 +184,43 @@ class BrowserType extends import_instrumentation.SdkObject {
205
184
  executable = registryExecutable.executablePathOrDie(this.attribution.playwright.options.sdkLanguage);
206
185
  await import_registry.registry.validateHostRequirementsForExecutablesIfNeeded([registryExecutable], this.attribution.playwright.options.sdkLanguage);
207
186
  }
208
- const readyState = this.readyState(options);
187
+ return { executable, browserArguments, userDataDir, artifactsDir, tempDirectories };
188
+ }
189
+ async _launchProcess(progress, options, isPersistent, browserLogsCollector, userDataDir) {
190
+ const {
191
+ handleSIGINT = true,
192
+ handleSIGTERM = true,
193
+ handleSIGHUP = true
194
+ } = options;
195
+ const env = options.env ? (0, import_processLauncher.envArrayToObject)(options.env) : process.env;
196
+ const prepared = await progress.race(this._prepareToLaunch(options, isPersistent, userDataDir));
209
197
  let transport = void 0;
210
198
  let browserProcess = void 0;
199
+ const exitPromise = new import_manualPromise.ManualPromise();
211
200
  const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
212
- command: executable,
213
- args: browserArguments,
214
- env: this.amendEnvironment(env, userDataDir, executable, browserArguments),
201
+ command: prepared.executable,
202
+ args: prepared.browserArguments,
203
+ env: this.amendEnvironment(env, prepared.userDataDir, isPersistent),
215
204
  handleSIGINT,
216
205
  handleSIGTERM,
217
206
  handleSIGHUP,
218
207
  log: (message) => {
219
- readyState?.onBrowserOutput(message);
220
208
  progress.log(message);
221
209
  browserLogsCollector.log(message);
222
210
  },
223
211
  stdio: "pipe",
224
- tempDirectories,
212
+ tempDirectories: prepared.tempDirectories,
225
213
  attemptToGracefullyClose: async () => {
226
214
  if (options.__testHookGracefullyClose)
227
215
  await options.__testHookGracefullyClose();
228
- this.attemptToGracefullyCloseBrowser(transport);
216
+ if (transport) {
217
+ this.attemptToGracefullyCloseBrowser(transport);
218
+ } else {
219
+ throw new Error("Force-killing the browser because no transport is available to gracefully close it.");
220
+ }
229
221
  },
230
222
  onExit: (exitCode, signal) => {
231
- readyState?.onBrowserExit();
223
+ exitPromise.resolve();
232
224
  if (browserProcess && browserProcess.onclose)
233
225
  browserProcess.onclose(exitCode, signal);
234
226
  }
@@ -250,18 +242,26 @@ class BrowserType extends import_instrumentation.SdkObject {
250
242
  browserProcess = {
251
243
  onclose: void 0,
252
244
  process: launchedProcess,
253
- close: () => closeOrKill(options.__testHookBrowserCloseTimeout || import_timeoutSettings.DEFAULT_TIMEOUT),
245
+ close: () => closeOrKill(options.__testHookBrowserCloseTimeout || import_time.DEFAULT_PLAYWRIGHT_TIMEOUT),
254
246
  kill
255
247
  };
256
- progress.cleanupWhenAborted(() => closeOrKill(progress.timeUntilDeadline()));
257
- const wsEndpoint = (await readyState?.waitUntilReady())?.wsEndpoint;
258
- if (options.useWebSocket) {
259
- transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
260
- } else {
261
- const stdio = launchedProcess.stdio;
262
- transport = new import_pipeTransport.PipeTransport(stdio[3], stdio[4]);
248
+ try {
249
+ const { wsEndpoint } = await progress.race([
250
+ this.waitForReadyState(options, browserLogsCollector),
251
+ exitPromise.then(() => ({ wsEndpoint: void 0 }))
252
+ ]);
253
+ if (options.cdpPort !== void 0 || !this.supportsPipeTransport()) {
254
+ transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
255
+ } else {
256
+ const stdio = launchedProcess.stdio;
257
+ transport = new import_pipeTransport.PipeTransport(stdio[3], stdio[4]);
258
+ }
259
+ return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport };
260
+ } catch (error) {
261
+ await closeOrKill(import_time.DEFAULT_PLAYWRIGHT_TIMEOUT).catch(() => {
262
+ });
263
+ throw error;
263
264
  }
264
- return { browserProcess, artifactsDir, userDataDir, transport };
265
265
  }
266
266
  async _createArtifactDirs(options) {
267
267
  if (options.downloadsPath)
@@ -269,7 +269,7 @@ class BrowserType extends import_instrumentation.SdkObject {
269
269
  if (options.tracesDir)
270
270
  await import_fs.default.promises.mkdir(options.tracesDir, { recursive: true });
271
271
  }
272
- async connectOverCDP(metadata, endpointURL, options) {
272
+ async connectOverCDP(progress, endpointURL, options) {
273
273
  throw new Error("CDP connections are only supported by Chromium");
274
274
  }
275
275
  async _launchWithSeleniumHub(progress, hubUrl, options) {
@@ -278,12 +278,12 @@ class BrowserType extends import_instrumentation.SdkObject {
278
278
  _validateLaunchOptions(options) {
279
279
  const { devtools = false } = options;
280
280
  let { headless = !devtools, downloadsPath, proxy } = options;
281
- if ((0, import_debug.debugMode)())
281
+ if ((0, import_debug.debugMode)() === "inspector")
282
282
  headless = false;
283
283
  if (downloadsPath && !import_path.default.isAbsolute(downloadsPath))
284
284
  downloadsPath = import_path.default.join(process.cwd(), downloadsPath);
285
- if (this.attribution.playwright.options.socksProxyPort)
286
- proxy = { server: `socks5://127.0.0.1:${this.attribution.playwright.options.socksProxyPort}` };
285
+ if (options.socksProxyPort)
286
+ proxy = { server: `socks5://127.0.0.1:${options.socksProxyPort}` };
287
287
  return { ...options, devtools, headless, downloadsPath, proxy };
288
288
  }
289
289
  _createUserDataDirArgMisuseError(userDataDirArg) {
@@ -303,11 +303,14 @@ class BrowserType extends import_instrumentation.SdkObject {
303
303
  return error;
304
304
  return this.doRewriteStartupLog(error);
305
305
  }
306
- readyState(options) {
307
- return void 0;
306
+ async waitForReadyState(options, browserLogsCollector) {
307
+ return {};
308
308
  }
309
309
  async prepareUserDataDir(options, userDataDir) {
310
310
  }
311
+ supportsPipeTransport() {
312
+ return true;
313
+ }
311
314
  getExecutableName(options) {
312
315
  return options.channel || this._name;
313
316
  }
@@ -320,7 +323,6 @@ function copyTestHooks(from, to) {
320
323
  }
321
324
  // Annotate the CommonJS export names for ESM import in node:
322
325
  0 && (module.exports = {
323
- BrowserReadyState,
324
326
  BrowserType,
325
327
  kNoXServerRunningError
326
328
  });
@@ -28,7 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var chromium_exports = {};
30
30
  __export(chromium_exports, {
31
- Chromium: () => Chromium
31
+ Chromium: () => Chromium,
32
+ waitForReadyState: () => waitForReadyState
32
33
  });
33
34
  module.exports = __toCommonJS(chromium_exports);
34
35
  var import_fs = __toESM(require("fs"));
@@ -37,7 +38,6 @@ var import_path = __toESM(require("path"));
37
38
  var import_chromiumSwitches = require("./chromiumSwitches");
38
39
  var import_crBrowser = require("./crBrowser");
39
40
  var import_crConnection = require("./crConnection");
40
- var import_timeoutSettings = require("../timeoutSettings");
41
41
  var import_utils = require("../../utils");
42
42
  var import_ascii = require("../utils/ascii");
43
43
  var import_debugLogger = require("../utils/debugLogger");
@@ -46,7 +46,6 @@ var import_network = require("../utils/network");
46
46
  var import_userAgent = require("../utils/userAgent");
47
47
  var import_browserContext = require("../browserContext");
48
48
  var import_browserType = require("../browserType");
49
- var import_browserType2 = require("../browserType");
50
49
  var import_helper = require("../helper");
51
50
  var import_registry = require("../registry");
52
51
  var import_transport = require("../transport");
@@ -54,20 +53,15 @@ var import_crDevTools = require("./crDevTools");
54
53
  var import_browser = require("../browser");
55
54
  var import_fileUtils = require("../utils/fileUtils");
56
55
  var import_processLauncher = require("../utils/processLauncher");
57
- var import_progress = require("../progress");
58
56
  const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
59
57
  class Chromium extends import_browserType.BrowserType {
60
58
  constructor(parent) {
61
59
  super(parent, "chromium");
62
- if ((0, import_utils.debugMode)())
60
+ if ((0, import_utils.debugMode)() === "inspector")
63
61
  this._devtools = this._createDevTools();
64
62
  }
65
- async connectOverCDP(metadata, endpointURL, options) {
66
- const controller = new import_progress.ProgressController(metadata, this);
67
- controller.setLogName("browser");
68
- return controller.run(async (progress) => {
69
- return await this._connectOverCDPInternal(progress, endpointURL, options);
70
- }, import_timeoutSettings.TimeoutSettings.timeout(options));
63
+ async connectOverCDP(progress, endpointURL, options) {
64
+ return await this._connectOverCDPInternal(progress, endpointURL, options);
71
65
  }
72
66
  async _connectOverCDPInternal(progress, endpointURL, options, onClose) {
73
67
  let headersMap;
@@ -77,53 +71,67 @@ class Chromium extends import_browserType.BrowserType {
77
71
  headersMap = { "User-Agent": (0, import_userAgent.getUserAgent)() };
78
72
  else if (headersMap && !Object.keys(headersMap).some((key) => key.toLowerCase() === "user-agent"))
79
73
  headersMap["User-Agent"] = (0, import_userAgent.getUserAgent)();
80
- const artifactsDir = await import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER);
81
- const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
82
- progress.throwIfAborted();
83
- const chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
84
- const cleanedUp = new import_manualPromise.ManualPromise();
74
+ const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
85
75
  const doCleanup = async () => {
86
76
  await (0, import_fileUtils.removeFolders)([artifactsDir]);
87
- await onClose?.();
88
- cleanedUp.resolve();
77
+ const cb = onClose;
78
+ onClose = void 0;
79
+ await cb?.();
89
80
  };
81
+ let chromeTransport;
90
82
  const doClose = async () => {
91
- await chromeTransport.closeAndWait();
92
- await cleanedUp;
83
+ await chromeTransport?.closeAndWait();
84
+ await doCleanup();
93
85
  };
94
- const browserProcess = { close: doClose, kill: doClose };
95
- const persistent = { noDefaultViewport: true };
96
- const browserOptions = {
97
- slowMo: options.slowMo,
98
- name: "chromium",
99
- isChromium: true,
100
- persistent,
101
- browserProcess,
102
- protocolLogger: import_helper.helper.debugProtocolLogger(),
103
- browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
104
- artifactsDir,
105
- downloadsPath: options.downloadsPath || artifactsDir,
106
- tracesDir: options.tracesDir || artifactsDir,
107
- originalLaunchOptions: {}
108
- };
109
- (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
110
- progress.throwIfAborted();
111
- const browser = await import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions);
112
- browser._isCollocatedWithServer = false;
113
- browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
114
- return browser;
86
+ try {
87
+ const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
88
+ chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
89
+ const browserProcess = { close: doClose, kill: doClose };
90
+ const persistent = { noDefaultViewport: true };
91
+ const browserOptions = {
92
+ slowMo: options.slowMo,
93
+ name: "chromium",
94
+ isChromium: true,
95
+ persistent,
96
+ browserProcess,
97
+ protocolLogger: import_helper.helper.debugProtocolLogger(),
98
+ browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
99
+ artifactsDir,
100
+ downloadsPath: options.downloadsPath || artifactsDir,
101
+ tracesDir: options.tracesDir || artifactsDir,
102
+ originalLaunchOptions: {}
103
+ };
104
+ (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
105
+ const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
106
+ browser._isCollocatedWithServer = false;
107
+ browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
108
+ return browser;
109
+ } catch (error) {
110
+ await doClose().catch(() => {
111
+ });
112
+ throw error;
113
+ }
115
114
  }
116
115
  _createDevTools() {
117
116
  const directory = import_registry.registry.findExecutable("chromium").directory;
118
117
  return directory ? new import_crDevTools.CRDevTools(import_path.default.join(directory, "devtools-preferences.json")) : void 0;
119
118
  }
120
- async connectToTransport(transport, options) {
119
+ async connectToTransport(transport, options, browserLogsCollector) {
121
120
  let devtools = this._devtools;
122
121
  if (options.__testHookForDevTools) {
123
122
  devtools = this._createDevTools();
124
123
  await options.__testHookForDevTools(devtools);
125
124
  }
126
- return import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, options, devtools);
125
+ try {
126
+ return await import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, options, devtools);
127
+ } catch (e) {
128
+ if (browserLogsCollector.recentLogs().some((log) => log.includes("Failed to create a ProcessSingleton for your profile directory."))) {
129
+ throw new Error(
130
+ "Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."
131
+ );
132
+ }
133
+ throw e;
134
+ }
127
135
  }
128
136
  doRewriteStartupLog(error) {
129
137
  if (!error.logs)
@@ -143,7 +151,7 @@ class Chromium extends import_browserType.BrowserType {
143
151
  ].join("\n");
144
152
  return error;
145
153
  }
146
- amendEnvironment(env, userDataDir, executable, browserArguments) {
154
+ amendEnvironment(env) {
147
155
  return env;
148
156
  }
149
157
  attemptToGracefullyCloseBrowser(transport) {
@@ -151,7 +159,7 @@ class Chromium extends import_browserType.BrowserType {
151
159
  transport.send(message);
152
160
  }
153
161
  async _launchWithSeleniumHub(progress, hubUrl, options) {
154
- await this._createArtifactDirs(options);
162
+ await progress.race(this._createArtifactDirs(options));
155
163
  if (!hubUrl.endsWith("/"))
156
164
  hubUrl = hubUrl + "/";
157
165
  const args = this._innerDefaultArgs(options);
@@ -173,7 +181,7 @@ class Chromium extends import_browserType.BrowserType {
173
181
  headers = remoteHeaders;
174
182
  }
175
183
  progress.log(`<selenium> connecting to ${hubUrl}`);
176
- const response = await (0, import_network.fetchData)({
184
+ const response = await (0, import_network.fetchData)(progress, {
177
185
  url: hubUrl + "session",
178
186
  method: "POST",
179
187
  headers: {
@@ -182,15 +190,14 @@ class Chromium extends import_browserType.BrowserType {
182
190
  },
183
191
  data: JSON.stringify({
184
192
  capabilities: { alwaysMatch: desiredCapabilities }
185
- }),
186
- timeout: progress.timeUntilDeadline()
193
+ })
187
194
  }, seleniumErrorHandler);
188
195
  const value = JSON.parse(response).value;
189
196
  const sessionId = value.sessionId;
190
197
  progress.log(`<selenium> connected to sessionId=${sessionId}`);
191
198
  const disconnectFromSelenium = async () => {
192
199
  progress.log(`<selenium> disconnecting from sessionId=${sessionId}`);
193
- await (0, import_network.fetchData)({
200
+ await (0, import_network.fetchData)(void 0, {
194
201
  url: hubUrl + "session/" + sessionId,
195
202
  method: "DELETE",
196
203
  headers
@@ -221,10 +228,9 @@ class Chromium extends import_browserType.BrowserType {
221
228
  if (endpointURL.hostname === "localhost" || endpointURL.hostname === "127.0.0.1") {
222
229
  const sessionInfoUrl = new URL(hubUrl).origin + "/grid/api/testsession?session=" + sessionId;
223
230
  try {
224
- const sessionResponse = await (0, import_network.fetchData)({
231
+ const sessionResponse = await (0, import_network.fetchData)(progress, {
225
232
  url: sessionInfoUrl,
226
233
  method: "GET",
227
- timeout: progress.timeUntilDeadline(),
228
234
  headers
229
235
  }, seleniumErrorHandler);
230
236
  const proxyId = JSON.parse(sessionResponse).proxyId;
@@ -247,8 +253,8 @@ class Chromium extends import_browserType.BrowserType {
247
253
  defaultArgs(options, isPersistent, userDataDir) {
248
254
  const chromeArguments = this._innerDefaultArgs(options);
249
255
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
250
- if (options.useWebSocket)
251
- chromeArguments.push("--remote-debugging-port=0");
256
+ if (options.cdpPort !== void 0)
257
+ chromeArguments.push(`--remote-debugging-port=${options.cdpPort}`);
252
258
  else
253
259
  chromeArguments.push("--remote-debugging-pipe");
254
260
  if (isPersistent)
@@ -266,11 +272,9 @@ class Chromium extends import_browserType.BrowserType {
266
272
  throw new Error("Playwright manages remote debugging connection itself.");
267
273
  if (args.find((arg) => !arg.startsWith("-")))
268
274
  throw new Error("Arguments can not specify page to be opened");
269
- const chromeArguments = [...import_chromiumSwitches.chromiumSwitches];
275
+ const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode, options.channel)];
270
276
  if (import_os.default.platform() === "darwin") {
271
- chromeArguments.push("--enable-use-zoom-for-dsf=false");
272
- if (options.headless && (!options.channel || options.channel === "chromium-headless-shell"))
273
- chromeArguments.push("--use-angle");
277
+ chromeArguments.push("--enable-unsafe-swiftshader");
274
278
  }
275
279
  if (options.devtools)
276
280
  chromeArguments.push("--auto-open-devtools-for-tabs");
@@ -288,12 +292,12 @@ class Chromium extends import_browserType.BrowserType {
288
292
  if (proxy) {
289
293
  const proxyURL = new URL(proxy.server);
290
294
  const isSocks = proxyURL.protocol === "socks5:";
291
- if (isSocks && !this.attribution.playwright.options.socksProxyPort) {
295
+ if (isSocks && !options.socksProxyPort) {
292
296
  chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
293
297
  }
294
298
  chromeArguments.push(`--proxy-server=${proxy.server}`);
295
299
  const proxyBypassRules = [];
296
- if (this.attribution.playwright.options.socksProxyPort)
300
+ if (options.socksProxyPort)
297
301
  proxyBypassRules.push("<-loopback>");
298
302
  if (proxy.bypass)
299
303
  proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
@@ -305,10 +309,8 @@ class Chromium extends import_browserType.BrowserType {
305
309
  chromeArguments.push(...args);
306
310
  return chromeArguments;
307
311
  }
308
- readyState(options) {
309
- if (options.useWebSocket || options.args?.some((a) => a.startsWith("--remote-debugging-port")))
310
- return new ChromiumReadyState();
311
- return void 0;
312
+ async waitForReadyState(options, browserLogsCollector) {
313
+ return waitForReadyState(options, browserLogsCollector);
312
314
  }
313
315
  getExecutableName(options) {
314
316
  if (options.channel)
@@ -316,19 +318,31 @@ class Chromium extends import_browserType.BrowserType {
316
318
  return options.headless ? "chromium-headless-shell" : "chromium";
317
319
  }
318
320
  }
319
- class ChromiumReadyState extends import_browserType2.BrowserReadyState {
320
- onBrowserOutput(message) {
321
+ async function waitForReadyState(options, browserLogsCollector) {
322
+ if (options.cdpPort === void 0 && !options.args?.some((a) => a.startsWith("--remote-debugging-port")))
323
+ return {};
324
+ const result = new import_manualPromise.ManualPromise();
325
+ browserLogsCollector.onMessage((message) => {
326
+ if (message.includes("Failed to create a ProcessSingleton for your profile directory.")) {
327
+ result.reject(new Error("Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."));
328
+ }
321
329
  const match = message.match(/DevTools listening on (.*)/);
322
330
  if (match)
323
- this._wsEndpoint.resolve(match[1]);
324
- }
331
+ result.resolve({ wsEndpoint: match[1] });
332
+ });
333
+ return result;
325
334
  }
326
335
  async function urlToWSEndpoint(progress, endpointURL, headers) {
327
336
  if (endpointURL.startsWith("ws"))
328
337
  return endpointURL;
329
338
  progress.log(`<ws preparing> retrieving websocket url from ${endpointURL}`);
330
- const httpURL = endpointURL.endsWith("/") ? `${endpointURL}json/version/` : `${endpointURL}/json/version/`;
339
+ const url = new URL(endpointURL);
340
+ if (!url.pathname.endsWith("/"))
341
+ url.pathname += "/";
342
+ url.pathname += "json/version/";
343
+ const httpURL = url.toString();
331
344
  const json = await (0, import_network.fetchData)(
345
+ progress,
332
346
  {
333
347
  url: httpURL,
334
348
  headers
@@ -372,5 +386,6 @@ function parseSeleniumRemoteParams(env, progress) {
372
386
  }
373
387
  // Annotate the CommonJS export names for ESM import in node:
374
388
  0 && (module.exports = {
375
- Chromium
389
+ Chromium,
390
+ waitForReadyState
376
391
  });