patchright-core 1.56.1 → 1.58.2

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 (180) hide show
  1. package/ThirdPartyNotices.txt +3134 -560
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +21 -22
  4. package/lib/cli/program.js +16 -60
  5. package/lib/client/api.js +3 -3
  6. package/lib/client/browser.js +3 -5
  7. package/lib/client/browserContext.js +62 -8
  8. package/lib/client/browserType.js +4 -3
  9. package/lib/client/connection.js +4 -0
  10. package/lib/client/consoleMessage.js +5 -1
  11. package/lib/client/electron.js +1 -1
  12. package/lib/client/elementHandle.js +3 -0
  13. package/lib/client/events.js +5 -1
  14. package/lib/client/fetch.js +3 -4
  15. package/lib/client/frame.js +10 -1
  16. package/lib/client/locator.js +12 -1
  17. package/lib/client/network.js +5 -1
  18. package/lib/client/page.js +31 -6
  19. package/lib/client/pageAgent.js +64 -0
  20. package/lib/client/platform.js +3 -0
  21. package/lib/client/playwright.js +1 -5
  22. package/lib/client/tracing.js +7 -5
  23. package/lib/client/worker.js +22 -0
  24. package/lib/generated/clockSource.js +1 -1
  25. package/lib/generated/injectedScriptSource.js +1 -1
  26. package/lib/generated/pollingRecorderSource.js +1 -1
  27. package/lib/inProcessFactory.js +0 -2
  28. package/lib/mcpBundle.js +84 -0
  29. package/lib/mcpBundleImpl/index.js +147 -0
  30. package/lib/protocol/serializers.js +5 -0
  31. package/lib/protocol/validator.js +112 -50
  32. package/lib/remote/playwrightServer.js +1 -2
  33. package/lib/server/agent/actionRunner.js +335 -0
  34. package/lib/server/agent/actions.js +128 -0
  35. package/lib/server/agent/codegen.js +111 -0
  36. package/lib/server/agent/context.js +150 -0
  37. package/lib/server/agent/expectTools.js +156 -0
  38. package/lib/server/agent/pageAgent.js +204 -0
  39. package/lib/server/agent/performTools.js +262 -0
  40. package/lib/server/agent/tool.js +109 -0
  41. package/lib/server/android/android.js +1 -1
  42. package/lib/server/artifact.js +1 -1
  43. package/lib/server/bidi/bidiBrowser.js +81 -22
  44. package/lib/server/bidi/bidiChromium.js +9 -13
  45. package/lib/server/bidi/bidiConnection.js +1 -0
  46. package/lib/server/bidi/bidiDeserializer.js +116 -0
  47. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  48. package/lib/server/bidi/bidiFirefox.js +7 -9
  49. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  50. package/lib/server/bidi/bidiPage.js +61 -30
  51. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  52. package/lib/server/browserContext.js +43 -36
  53. package/lib/server/browserType.js +12 -4
  54. package/lib/server/chromium/chromium.js +26 -21
  55. package/lib/server/chromium/chromiumSwitches.js +12 -3
  56. package/lib/server/chromium/crBrowser.js +30 -12
  57. package/lib/server/chromium/crConnection.js +0 -5
  58. package/lib/server/chromium/crCoverage.js +13 -1
  59. package/lib/server/chromium/crDevTools.js +0 -2
  60. package/lib/server/chromium/crNetworkManager.js +107 -18
  61. package/lib/server/chromium/crPage.js +68 -124
  62. package/lib/server/chromium/crServiceWorker.js +14 -1
  63. package/lib/server/codegen/javascript.js +6 -29
  64. package/lib/server/console.js +5 -1
  65. package/lib/server/deviceDescriptorsSource.json +56 -56
  66. package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
  67. package/lib/server/dispatchers/dispatcher.js +6 -13
  68. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  69. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  70. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  71. package/lib/server/dispatchers/pageDispatcher.js +14 -22
  72. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  73. package/lib/server/dom.js +12 -3
  74. package/lib/server/electron/electron.js +6 -3
  75. package/lib/server/firefox/ffBrowser.js +10 -20
  76. package/lib/server/firefox/ffConnection.js +0 -5
  77. package/lib/server/firefox/ffNetworkManager.js +2 -2
  78. package/lib/server/firefox/ffPage.js +18 -24
  79. package/lib/server/firefox/firefox.js +18 -9
  80. package/lib/server/frameSelectors.js +18 -8
  81. package/lib/server/frames.js +257 -87
  82. package/lib/server/input.js +7 -3
  83. package/lib/server/instrumentation.js +3 -0
  84. package/lib/server/javascript.js +8 -4
  85. package/lib/server/launchApp.js +2 -1
  86. package/lib/server/localUtils.js +4 -8
  87. package/lib/server/network.js +50 -12
  88. package/lib/server/page.js +112 -126
  89. package/lib/server/playwright.js +2 -4
  90. package/lib/server/progress.js +26 -6
  91. package/lib/server/recorder/recorderApp.js +80 -101
  92. package/lib/server/recorder.js +3 -2
  93. package/lib/server/registry/browserFetcher.js +6 -4
  94. package/lib/server/registry/index.js +278 -189
  95. package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
  96. package/lib/server/screencast.js +190 -0
  97. package/lib/server/screenshotter.js +6 -0
  98. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  99. package/lib/server/trace/recorder/snapshotter.js +17 -8
  100. package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
  101. package/lib/server/trace/recorder/tracing.js +31 -21
  102. package/lib/server/trace/viewer/traceParser.js +72 -0
  103. package/lib/server/trace/viewer/traceViewer.js +45 -40
  104. package/lib/server/utils/comparators.js +3 -25
  105. package/lib/server/utils/expectUtils.js +87 -2
  106. package/lib/server/utils/hostPlatform.js +30 -3
  107. package/lib/server/utils/httpServer.js +5 -20
  108. package/lib/server/utils/imageUtils.js +141 -0
  109. package/lib/server/utils/network.js +55 -40
  110. package/lib/server/utils/nodePlatform.js +6 -0
  111. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
  112. package/lib/server/webkit/webkit.js +5 -16
  113. package/lib/server/webkit/wkBrowser.js +2 -6
  114. package/lib/server/webkit/wkConnection.js +1 -6
  115. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  116. package/lib/server/webkit/wkPage.js +76 -51
  117. package/lib/server/webkit/wkWorkers.js +2 -1
  118. package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
  119. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  120. package/lib/utils/isomorphic/lruCache.js +51 -0
  121. package/lib/utils/isomorphic/mimeType.js +1 -1
  122. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  123. package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
  124. package/lib/utils/isomorphic/stringUtils.js +49 -0
  125. package/lib/utils/isomorphic/trace/entries.js +16 -0
  126. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  127. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  128. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  129. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  130. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  131. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  132. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  133. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  134. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  135. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  136. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  137. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  138. package/lib/utils/isomorphic/urlMatch.js +19 -5
  139. package/lib/utils/isomorphic/yaml.js +84 -0
  140. package/lib/utils.js +4 -0
  141. package/lib/utilsBundle.js +1 -1
  142. package/lib/utilsBundleImpl/index.js +124 -124
  143. package/lib/vite/htmlReport/index.html +21 -21
  144. package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
  145. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  146. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  147. package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
  148. package/lib/vite/recorder/index.html +2 -2
  149. package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
  150. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
  151. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  152. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  153. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  154. package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
  155. package/lib/vite/traceViewer/index.html +6 -6
  156. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  157. package/lib/vite/traceViewer/snapshot.html +3 -3
  158. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  159. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
  160. package/lib/vite/traceViewer/uiMode.html +3 -3
  161. package/package.json +2 -1
  162. package/types/protocol.d.ts +939 -245
  163. package/types/types.d.ts +143 -153
  164. package/lib/client/accessibility.js +0 -49
  165. package/lib/server/accessibility.js +0 -69
  166. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  167. package/lib/server/chromium/crAccessibility.js +0 -263
  168. package/lib/server/firefox/ffAccessibility.js +0 -238
  169. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  170. package/lib/server/webkit/wkAccessibility.js +0 -237
  171. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  172. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  173. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  174. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
  175. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  176. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  177. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  178. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  179. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
  180. package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
@@ -34,19 +34,35 @@ class ProgressController {
34
34
  this.metadata = metadata || { id: "", startTime: 0, endTime: 0, type: "Internal", method: "", params: {}, log: [], internal: true };
35
35
  this._onCallLog = onCallLog;
36
36
  this._forceAbortPromise.catch((e) => null);
37
+ this._controller = new AbortController();
38
+ }
39
+ static createForSdkObject(sdkObject, callMetadata) {
40
+ const logName = sdkObject.logName || "api";
41
+ return new ProgressController(callMetadata, (message) => {
42
+ import_utils.debugLogger.log(logName, message);
43
+ sdkObject.instrumentation.onCallLog(sdkObject, callMetadata, logName, message);
44
+ });
37
45
  }
38
46
  async abort(error) {
39
47
  if (this._state === "running") {
40
48
  error[kAbortErrorSymbol] = true;
41
49
  this._state = { error };
42
50
  this._forceAbortPromise.reject(error);
51
+ this._controller.abort(error);
43
52
  }
44
53
  await this._donePromise;
45
54
  }
46
55
  async run(task, timeout) {
56
+ const deadline = timeout ? (0, import_utils.monotonicTime)() + timeout : 0;
47
57
  (0, import_utils.assert)(this._state === "before");
48
58
  this._state = "running";
59
+ let timer;
49
60
  const progress = {
61
+ timeout: timeout ?? 0,
62
+ deadline,
63
+ disableTimeout: () => {
64
+ clearTimeout(timer);
65
+ },
50
66
  log: (message) => {
51
67
  if (this._state === "running")
52
68
  this.metadata.log.push(message);
@@ -55,24 +71,28 @@ class ProgressController {
55
71
  metadata: this.metadata,
56
72
  race: (promise) => {
57
73
  const promises = Array.isArray(promise) ? promise : [promise];
74
+ if (!promises.length)
75
+ return Promise.resolve();
58
76
  return Promise.race([...promises, this._forceAbortPromise]);
59
77
  },
60
78
  wait: async (timeout2) => {
61
79
  let timer2;
62
80
  const promise = new Promise((f) => timer2 = setTimeout(f, timeout2));
63
81
  return progress.race(promise).finally(() => clearTimeout(timer2));
64
- }
82
+ },
83
+ signal: this._controller.signal
65
84
  };
66
- let timer;
67
- if (timeout) {
85
+ if (deadline) {
68
86
  const timeoutError = new import_errors.TimeoutError(`Timeout ${timeout}ms exceeded.`);
69
87
  timer = setTimeout(() => {
88
+ if (this.metadata.pauseStartTime && !this.metadata.pauseEndTime)
89
+ return;
70
90
  if (this._state === "running") {
71
- timeoutError[kAbortErrorSymbol] = true;
72
91
  this._state = { error: timeoutError };
73
92
  this._forceAbortPromise.reject(timeoutError);
93
+ this._controller.abort(timeoutError);
74
94
  }
75
- }, timeout);
95
+ }, deadline - (0, import_utils.monotonicTime)());
76
96
  }
77
97
  try {
78
98
  const result = await task(progress);
@@ -89,7 +109,7 @@ class ProgressController {
89
109
  }
90
110
  const kAbortErrorSymbol = Symbol("kAbortError");
91
111
  function isAbortError(error) {
92
- return !!error[kAbortErrorSymbol];
112
+ return error instanceof import_errors.TimeoutError || !!error[kAbortErrorSymbol];
93
113
  }
94
114
  async function raceUncancellableOperationWithCleanup(progress, run, cleanup) {
95
115
  let aborted = false;
@@ -53,6 +53,7 @@ class RecorderApp {
53
53
  this._recorderSources = [];
54
54
  this._page = page;
55
55
  this._recorder = recorder;
56
+ this._frontend = createRecorderFrontend(page);
56
57
  this.wsEndpointForTest = wsEndpointForTest;
57
58
  this._languageGeneratorOptions = {
58
59
  browserName: params.browserName,
@@ -64,6 +65,10 @@ class RecorderApp {
64
65
  this._throttledOutputFile = params.outputFile ? new import_throttledFile.ThrottledFile(params.outputFile) : null;
65
66
  this._primaryGeneratorId = process.env.TEST_INSPECTOR_LANGUAGE || params.language || determinePrimaryGeneratorId(params.sdkLanguage);
66
67
  this._selectedGeneratorId = this._primaryGeneratorId;
68
+ for (const languageGenerator of (0, import_languages.languageSet)()) {
69
+ if (languageGenerator.id === this._primaryGeneratorId)
70
+ this._recorder.setLanguage(languageGenerator.highlighter);
71
+ }
67
72
  }
68
73
  async _init(inspectedContext) {
69
74
  await (0, import_launchApp.syncLocalStorageWithSettings)(this._page, "recorder");
@@ -89,70 +94,67 @@ class RecorderApp {
89
94
  });
90
95
  });
91
96
  });
92
- await this._page.exposeBinding(progress, "dispatch", false, (_, data) => this._handleUIEvent(data));
97
+ await this._createDispatcher(progress);
93
98
  this._page.once("close", () => {
94
99
  this._recorder.close();
95
100
  this._page.browserContext.close({ reason: "Recorder window closed" }).catch(() => {
96
101
  });
97
102
  delete inspectedContext[recorderAppSymbol];
98
103
  });
99
- await this._page.mainFrame().goto(progress, process.env.PW_HMR ? "http://localhost:44225" : "https://playwright/index.html");
104
+ await this._page.mainFrame().goto(progress, "https://playwright/index.html");
100
105
  });
101
106
  const url = this._recorder.url();
102
107
  if (url)
103
- this._onPageNavigated(url);
104
- this._onModeChanged(this._recorder.mode());
105
- this._onPausedStateChanged(this._recorder.paused());
108
+ this._frontend.pageNavigated({ url });
109
+ this._frontend.modeChanged({ mode: this._recorder.mode() });
110
+ this._frontend.pauseStateChanged({ paused: this._recorder.paused() });
106
111
  this._updateActions("reveal");
107
112
  this._onUserSourcesChanged(this._recorder.userSources(), this._recorder.pausedSourceId());
108
- this._onCallLogsUpdated(this._recorder.callLog());
113
+ this._frontend.callLogsUpdated({ callLogs: this._recorder.callLog() });
109
114
  this._wireListeners(this._recorder);
110
115
  }
111
- _handleUIEvent(data) {
112
- if (data.event === "clear") {
113
- this._actions = [];
114
- this._updateActions("reveal");
115
- this._recorder.clear();
116
- return;
117
- }
118
- if (data.event === "fileChanged") {
119
- const source = [...this._recorderSources, ...this._userSources].find((s) => s.id === data.params.fileId);
120
- if (source) {
121
- if (source.isRecorded)
122
- this._selectedGeneratorId = source.id;
123
- this._recorder.setLanguage(source.language);
116
+ async _createDispatcher(progress) {
117
+ const dispatcher = {
118
+ clear: async () => {
119
+ this._actions = [];
120
+ this._updateActions("reveal");
121
+ this._recorder.clear();
122
+ },
123
+ fileChanged: async (params) => {
124
+ const source = [...this._recorderSources, ...this._userSources].find((s) => s.id === params.fileId);
125
+ if (source) {
126
+ if (source.isRecorded)
127
+ this._selectedGeneratorId = source.id;
128
+ this._recorder.setLanguage(source.language);
129
+ }
130
+ },
131
+ setAutoExpect: async (params) => {
132
+ this._languageGeneratorOptions.generateAutoExpect = params.autoExpect;
133
+ this._updateActions();
134
+ },
135
+ setMode: async (params) => {
136
+ this._recorder.setMode(params.mode);
137
+ },
138
+ resume: async () => {
139
+ this._recorder.resume();
140
+ },
141
+ pause: async () => {
142
+ this._recorder.pause();
143
+ },
144
+ step: async () => {
145
+ this._recorder.step();
146
+ },
147
+ highlightRequested: async (params) => {
148
+ if (params.selector)
149
+ this._recorder.setHighlightedSelector(params.selector);
150
+ if (params.ariaTemplate)
151
+ this._recorder.setHighlightedAriaTemplate(params.ariaTemplate);
124
152
  }
125
- return;
126
- }
127
- if (data.event === "setAutoExpect") {
128
- this._languageGeneratorOptions.generateAutoExpect = data.params.autoExpect;
129
- this._updateActions();
130
- return;
131
- }
132
- if (data.event === "setMode") {
133
- this._recorder.setMode(data.params.mode);
134
- return;
135
- }
136
- if (data.event === "resume") {
137
- this._recorder.resume();
138
- return;
139
- }
140
- if (data.event === "pause") {
141
- this._recorder.pause();
142
- return;
143
- }
144
- if (data.event === "step") {
145
- this._recorder.step();
146
- return;
147
- }
148
- if (data.event === "highlightRequested") {
149
- if (data.params.selector)
150
- this._recorder.setHighlightedSelector(data.params.selector);
151
- if (data.params.ariaTemplate)
152
- this._recorder.setHighlightedAriaTemplate(data.params.ariaTemplate);
153
- return;
154
- }
155
- throw new Error(`Unknown event: ${data.event}`);
153
+ };
154
+ await this._page.exposeBinding(progress, "sendCommand", false, async (_, data) => {
155
+ const { method, params } = data;
156
+ return await dispatcher[method].call(dispatcher, params);
157
+ });
156
158
  }
157
159
  static async show(context, params) {
158
160
  if (process.env.PW_CODEGEN_NO_INSPECTOR)
@@ -220,25 +222,29 @@ class RecorderApp {
220
222
  this._onSignalAdded(signal);
221
223
  });
222
224
  recorder.on(import_recorder.RecorderEvent.PageNavigated, (url) => {
223
- this._onPageNavigated(url);
225
+ this._frontend.pageNavigated({ url });
224
226
  });
225
227
  recorder.on(import_recorder.RecorderEvent.ContextClosed, () => {
226
- this._onContextClosed();
228
+ this._throttledOutputFile?.flush();
229
+ this._page.browserContext.close({ reason: "Recorder window closed" }).catch(() => {
230
+ });
227
231
  });
228
232
  recorder.on(import_recorder.RecorderEvent.ModeChanged, (mode) => {
229
- this._onModeChanged(mode);
233
+ this._frontend.modeChanged({ mode });
230
234
  });
231
235
  recorder.on(import_recorder.RecorderEvent.PausedStateChanged, (paused) => {
232
- this._onPausedStateChanged(paused);
236
+ this._frontend.pauseStateChanged({ paused });
233
237
  });
234
238
  recorder.on(import_recorder.RecorderEvent.UserSourcesChanged, (sources, pausedSourceId) => {
235
239
  this._onUserSourcesChanged(sources, pausedSourceId);
236
240
  });
237
241
  recorder.on(import_recorder.RecorderEvent.ElementPicked, (elementInfo, userGesture) => {
238
- this._onElementPicked(elementInfo, userGesture);
242
+ if (userGesture)
243
+ this._page.bringToFront();
244
+ this._frontend.elementPicked({ elementInfo, userGesture });
239
245
  });
240
246
  recorder.on(import_recorder.RecorderEvent.CallLogsUpdated, (callLogs) => {
241
- this._onCallLogsUpdated(callLogs);
247
+ this._frontend.callLogsUpdated({ callLogs });
242
248
  });
243
249
  }
244
250
  _onActionAdded(action) {
@@ -251,29 +257,6 @@ class RecorderApp {
251
257
  lastAction.action.signals.push(signal.signal);
252
258
  this._updateActions();
253
259
  }
254
- _onPageNavigated(url) {
255
- this._page.mainFrame().evaluateExpression((({ url: url2 }) => {
256
- window.playwrightSetPageURL(url2);
257
- }).toString(), { isFunction: true }, { url }).catch(() => {
258
- });
259
- }
260
- _onContextClosed() {
261
- this._throttledOutputFile?.flush();
262
- this._page.browserContext.close({ reason: "Recorder window closed" }).catch(() => {
263
- });
264
- }
265
- _onModeChanged(mode) {
266
- this._page.mainFrame().evaluateExpression(((mode2) => {
267
- window.playwrightSetMode(mode2);
268
- }).toString(), { isFunction: true }, mode).catch(() => {
269
- });
270
- }
271
- _onPausedStateChanged(paused) {
272
- this._page.mainFrame().evaluateExpression(((paused2) => {
273
- window.playwrightSetPaused(paused2);
274
- }).toString(), { isFunction: true }, paused).catch(() => {
275
- });
276
- }
277
260
  _onUserSourcesChanged(sources, pausedSourceId) {
278
261
  if (!sources.length && !this._userSources.length)
279
262
  return;
@@ -281,34 +264,14 @@ class RecorderApp {
281
264
  this._pushAllSources();
282
265
  this._revealSource(pausedSourceId);
283
266
  }
284
- _onElementPicked(elementInfo, userGesture) {
285
- if (userGesture)
286
- this._page.bringToFront();
287
- this._page.mainFrame().evaluateExpression(((param) => {
288
- window.playwrightElementPicked(param.elementInfo, param.userGesture);
289
- }).toString(), { isFunction: true }, { elementInfo, userGesture }).catch(() => {
290
- });
291
- }
292
- _onCallLogsUpdated(callLogs) {
293
- this._page.mainFrame().evaluateExpression(((callLogs2) => {
294
- window.playwrightUpdateLogs(callLogs2);
295
- }).toString(), { isFunction: true }, callLogs).catch(() => {
296
- });
297
- }
298
267
  _pushAllSources() {
299
268
  const sources = [...this._userSources, ...this._recorderSources];
300
- this._page.mainFrame().evaluateExpression((({ sources: sources2 }) => {
301
- window.playwrightSetSources(sources2);
302
- }).toString(), { isFunction: true }, { sources }).catch(() => {
303
- });
269
+ this._frontend.sourcesUpdated({ sources });
304
270
  }
305
271
  _revealSource(sourceId) {
306
272
  if (!sourceId)
307
273
  return;
308
- this._page.mainFrame().evaluateExpression((({ sourceId: sourceId2 }) => {
309
- window.playwrightSelectSource(sourceId2);
310
- }).toString(), { isFunction: true }, { sourceId }).catch(() => {
311
- });
274
+ this._frontend.sourceRevealRequested({ sourceId });
312
275
  }
313
276
  _updateActions(reveal) {
314
277
  const recorderSources = [];
@@ -372,6 +335,8 @@ class ProgrammaticRecorderApp {
372
335
  });
373
336
  recorder.on(import_recorder.RecorderEvent.SignalAdded, (signal) => {
374
337
  const page = findPageByGuid(inspectedContext, signal.frame.pageGuid);
338
+ if (!page)
339
+ return;
375
340
  inspectedContext.emit(import_browserContext.BrowserContext.Events.RecorderEvent, { event: "signalAdded", data: signal, page, code: "" });
376
341
  });
377
342
  }
@@ -379,6 +344,20 @@ class ProgrammaticRecorderApp {
379
344
  function findPageByGuid(context, guid) {
380
345
  return context.pages().find((p) => p.guid === guid);
381
346
  }
347
+ function createRecorderFrontend(page) {
348
+ return new Proxy({}, {
349
+ get: (_target, prop) => {
350
+ if (typeof prop !== "string")
351
+ return void 0;
352
+ return (params) => {
353
+ page.mainFrame().evaluateExpression(((event) => {
354
+ window.dispatch(event);
355
+ }).toString(), { isFunction: true }, { method: prop, params }).catch(() => {
356
+ });
357
+ };
358
+ }
359
+ });
360
+ }
382
361
  const recorderAppSymbol = Symbol("recorderApp");
383
362
  // Annotate the CommonJS export names for ESM import in node:
384
363
  0 && (module.exports = {
@@ -112,8 +112,9 @@ class Recorder extends import_events.default {
112
112
  }
113
113
  return recorderPromise;
114
114
  }
115
- static existingForContext(context) {
116
- return context[recorderSymbol];
115
+ static async existingForContext(context) {
116
+ const recorderPromise = context[recorderSymbol];
117
+ return await recorderPromise;
117
118
  }
118
119
  static async _create(context, params = {}) {
119
120
  const recorder = new Recorder(context, params);
@@ -42,10 +42,13 @@ var import_userAgent = require("../utils/userAgent");
42
42
  var import_utilsBundle = require("../../utilsBundle");
43
43
  var import_fileUtils = require("../utils/fileUtils");
44
44
  var import__ = require(".");
45
- async function downloadBrowserWithProgressBar(title, browserDirectory, executablePath, downloadURLs, downloadFileName, downloadSocketTimeout) {
45
+ async function downloadBrowserWithProgressBar(title, browserDirectory, executablePath, downloadURLs, downloadFileName, downloadSocketTimeout, force) {
46
46
  if (await (0, import_fileUtils.existsAsync)((0, import__.browserDirectoryToMarkerFilePath)(browserDirectory))) {
47
47
  import_debugLogger.debugLogger.log("install", `${title} is already downloaded.`);
48
- return false;
48
+ if (force)
49
+ import_debugLogger.debugLogger.log("install", `force-downloading ${title}.`);
50
+ else
51
+ return;
49
52
  }
50
53
  const uniqueTempDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-download-"));
51
54
  const zipPath = import_path.default.join(uniqueTempDir, downloadFileName);
@@ -63,7 +66,7 @@ async function downloadBrowserWithProgressBar(title, browserDirectory, executabl
63
66
  if (await (0, import_fileUtils.existsAsync)(zipPath))
64
67
  await import_fs.default.promises.unlink(zipPath);
65
68
  if (await (0, import_fileUtils.existsAsync)(browserDirectory))
66
- await import_fs.default.promises.rmdir(browserDirectory, { recursive: true });
69
+ await (0, import_fileUtils.removeFolders)([browserDirectory]);
67
70
  const errorMessage = error?.message || "";
68
71
  import_debugLogger.debugLogger.log("install", `attempt #${attempt} - ERROR: ${errorMessage}`);
69
72
  if (attempt >= retryCount)
@@ -77,7 +80,6 @@ async function downloadBrowserWithProgressBar(title, browserDirectory, executabl
77
80
  await (0, import_fileUtils.removeFolders)([uniqueTempDir]);
78
81
  }
79
82
  logPolitely(`${title} downloaded to ${browserDirectory}`);
80
- return true;
81
83
  }
82
84
  function downloadBrowserWithProgressBarOutOfProcess(title, browserDirectory, url, zipPath, executablePath, socketTimeout) {
83
85
  const cp = childProcess.fork(import_path.default.join(__dirname, "oopDownloadBrowserMain.js"));