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
@@ -29,6 +29,7 @@ var import_path = __toESM(require("path"));
29
29
  var import_manualPromise = require("../../utils/isomorphic/manualPromise");
30
30
  var import_network = require("../utils/network");
31
31
  var import_zipBundle = require("../../zipBundle");
32
+ var import_fileUtils = require("../utils/fileUtils");
32
33
  function log(message) {
33
34
  process.send?.({ method: "log", params: { message } });
34
35
  }
@@ -41,6 +42,7 @@ function browserDirectoryToMarkerFilePath(browserDirectory) {
41
42
  function downloadFile(options) {
42
43
  let downloadedBytes = 0;
43
44
  let totalBytes = 0;
45
+ let chunked = false;
44
46
  const promise = new import_manualPromise.ManualPromise();
45
47
  (0, import_network.httpRequest)({
46
48
  url: options.url,
@@ -60,11 +62,13 @@ function downloadFile(options) {
60
62
  response.on("data", (chunk) => content += chunk).on("end", handleError).on("error", handleError);
61
63
  return;
62
64
  }
65
+ chunked = response.headers["transfer-encoding"] === "chunked";
66
+ log(`-- is chunked: ${chunked}`);
63
67
  totalBytes = parseInt(response.headers["content-length"] || "0", 10);
64
68
  log(`-- total bytes: ${totalBytes}`);
65
69
  const file = import_fs.default.createWriteStream(options.zipPath);
66
70
  file.on("finish", () => {
67
- if (downloadedBytes !== totalBytes) {
71
+ if (!chunked && downloadedBytes !== totalBytes) {
68
72
  log(`-- download failed, size mismatch: ${downloadedBytes} != ${totalBytes}`);
69
73
  promise.reject(new Error(`Download failed: size mismatch, file size: ${downloadedBytes}, expected size: ${totalBytes} URL: ${options.url}`));
70
74
  } else {
@@ -89,12 +93,15 @@ function downloadFile(options) {
89
93
  return promise;
90
94
  function onData(chunk) {
91
95
  downloadedBytes += chunk.length;
92
- progress(downloadedBytes, totalBytes);
96
+ if (!chunked)
97
+ progress(downloadedBytes, totalBytes);
93
98
  }
94
99
  }
95
100
  async function main(options) {
96
101
  await downloadFile(options);
97
102
  log(`SUCCESS downloading ${options.title}`);
103
+ log(`removing existing browser directory if any`);
104
+ await (0, import_fileUtils.removeFolders)([options.browserDirectory]);
98
105
  log(`extracting archive`);
99
106
  await (0, import_zipBundle.extract)(options.zipPath, { dir: options.browserDirectory });
100
107
  if (options.executablePath) {
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var screencast_exports = {};
30
+ __export(screencast_exports, {
31
+ Screencast: () => Screencast
32
+ });
33
+ module.exports = __toCommonJS(screencast_exports);
34
+ var import_path = __toESM(require("path"));
35
+ var import_utils = require("../utils");
36
+ var import_utils2 = require("../utils");
37
+ var import_videoRecorder = require("./videoRecorder");
38
+ var import_page = require("./page");
39
+ var import_registry = require("./registry");
40
+ class Screencast {
41
+ constructor(page) {
42
+ this._videoRecorder = null;
43
+ this._videoId = null;
44
+ this._screencastClients = /* @__PURE__ */ new Set();
45
+ // Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
46
+ // When throttling for tracing, 200ms between frames, except for 10 frames around the action.
47
+ this._frameThrottler = new FrameThrottler(10, 35, 200);
48
+ this._frameListener = null;
49
+ this._page = page;
50
+ }
51
+ stopFrameThrottler() {
52
+ this._frameThrottler.dispose();
53
+ }
54
+ setOptions(options) {
55
+ this._setOptions(options).catch((e) => import_utils2.debugLogger.log("error", e));
56
+ this._frameThrottler.setThrottlingEnabled(!!options);
57
+ }
58
+ throttleFrameAck(ack) {
59
+ this._frameThrottler.ack(ack);
60
+ }
61
+ temporarilyDisableThrottling() {
62
+ this._frameThrottler.recharge();
63
+ }
64
+ launchVideoRecorder() {
65
+ const recordVideo = this._page.browserContext._options.recordVideo;
66
+ if (!recordVideo)
67
+ return void 0;
68
+ (0, import_utils.assert)(!this._videoId);
69
+ this._videoId = (0, import_utils.createGuid)();
70
+ const outputFile = import_path.default.join(recordVideo.dir, this._videoId + ".webm");
71
+ const videoOptions = {
72
+ // validateBrowserContextOptions ensures correct video size.
73
+ ...recordVideo.size,
74
+ outputFile
75
+ };
76
+ const ffmpegPath = import_registry.registry.findExecutable("ffmpeg").executablePathOrDie(this._page.browserContext._browser.sdkLanguage());
77
+ this._videoRecorder = new import_videoRecorder.VideoRecorder(ffmpegPath, videoOptions);
78
+ this._frameListener = import_utils.eventsHelper.addEventListener(this._page, import_page.Page.Events.ScreencastFrame, (frame) => this._videoRecorder.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3));
79
+ this._page.waitForInitializedOrError().then((p) => {
80
+ if (p instanceof Error)
81
+ this.stopVideoRecording().catch(() => {
82
+ });
83
+ });
84
+ return videoOptions;
85
+ }
86
+ async startVideoRecording(options) {
87
+ const videoId = this._videoId;
88
+ (0, import_utils.assert)(videoId);
89
+ this._page.once(import_page.Page.Events.Close, () => this.stopVideoRecording().catch(() => {
90
+ }));
91
+ const gotFirstFrame = new Promise((f) => this._page.once(import_page.Page.Events.ScreencastFrame, f));
92
+ await this._startScreencast(this._videoRecorder, {
93
+ quality: 90,
94
+ width: options.width,
95
+ height: options.height
96
+ });
97
+ gotFirstFrame.then(() => {
98
+ this._page.browserContext._browser._videoStarted(this._page.browserContext, videoId, options.outputFile, this._page.waitForInitializedOrError());
99
+ });
100
+ }
101
+ async stopVideoRecording() {
102
+ if (!this._videoId)
103
+ return;
104
+ if (this._frameListener)
105
+ import_utils.eventsHelper.removeEventListeners([this._frameListener]);
106
+ this._frameListener = null;
107
+ const videoId = this._videoId;
108
+ this._videoId = null;
109
+ const videoRecorder = this._videoRecorder;
110
+ this._videoRecorder = null;
111
+ await this._stopScreencast(videoRecorder);
112
+ await videoRecorder.stop();
113
+ const video = this._page.browserContext._browser._takeVideo(videoId);
114
+ video?.reportFinished();
115
+ }
116
+ async _setOptions(options) {
117
+ if (options)
118
+ await this._startScreencast(this, options);
119
+ else
120
+ await this._stopScreencast(this);
121
+ }
122
+ async _startScreencast(client, options) {
123
+ this._screencastClients.add(client);
124
+ if (this._screencastClients.size === 1) {
125
+ await this._page.delegate.startScreencast({
126
+ width: options.width,
127
+ height: options.height,
128
+ quality: options.quality
129
+ });
130
+ }
131
+ }
132
+ async _stopScreencast(client) {
133
+ this._screencastClients.delete(client);
134
+ if (!this._screencastClients.size)
135
+ await this._page.delegate.stopScreencast();
136
+ }
137
+ }
138
+ class FrameThrottler {
139
+ constructor(nonThrottledFrames, defaultInterval, throttlingInterval) {
140
+ this._acks = [];
141
+ this._throttlingEnabled = false;
142
+ this._nonThrottledFrames = nonThrottledFrames;
143
+ this._budget = nonThrottledFrames;
144
+ this._defaultInterval = defaultInterval;
145
+ this._throttlingInterval = throttlingInterval;
146
+ this._tick();
147
+ }
148
+ dispose() {
149
+ if (this._timeoutId) {
150
+ clearTimeout(this._timeoutId);
151
+ this._timeoutId = void 0;
152
+ }
153
+ }
154
+ setThrottlingEnabled(enabled) {
155
+ this._throttlingEnabled = enabled;
156
+ }
157
+ recharge() {
158
+ for (const ack of this._acks)
159
+ ack();
160
+ this._acks = [];
161
+ this._budget = this._nonThrottledFrames;
162
+ if (this._timeoutId) {
163
+ clearTimeout(this._timeoutId);
164
+ this._tick();
165
+ }
166
+ }
167
+ ack(ack) {
168
+ if (!this._timeoutId) {
169
+ ack();
170
+ return;
171
+ }
172
+ this._acks.push(ack);
173
+ }
174
+ _tick() {
175
+ const ack = this._acks.shift();
176
+ if (ack) {
177
+ --this._budget;
178
+ ack();
179
+ }
180
+ if (this._throttlingEnabled && this._budget <= 0) {
181
+ this._timeoutId = setTimeout(() => this._tick(), this._throttlingInterval);
182
+ } else {
183
+ this._timeoutId = setTimeout(() => this._tick(), this._defaultInterval);
184
+ }
185
+ }
186
+ }
187
+ // Annotate the CommonJS export names for ESM import in node:
188
+ 0 && (module.exports = {
189
+ Screencast
190
+ });
@@ -213,6 +213,12 @@ class Screenshotter {
213
213
  if (disableAnimations)
214
214
  progress.log(" disabled all CSS animations");
215
215
  const syncAnimations = this._page.delegate.shouldToggleStyleSheetToSyncAnimations();
216
+ await Promise.all(this._page.frames().map(async (f) => {
217
+ try {
218
+ await f._utilityContext();
219
+ } catch {
220
+ }
221
+ }));
216
222
  await progress.race(this._page.safeNonStallingEvaluateInAllFrames("(" + inPagePrepareForScreenshots.toString() + `)(${JSON.stringify(screenshotStyle)}, ${hideCaret}, ${disableAnimations}, ${syncAnimations})`, "utility"));
217
223
  try {
218
224
  if (!process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY) {
@@ -82,7 +82,7 @@ class SocksProxyConnection {
82
82
  async connect() {
83
83
  const proxyAgent = this.socksProxy.getProxyAgent(this.host, this.port);
84
84
  if (proxyAgent)
85
- this._serverEncrypted = await proxyAgent.callback(new import_events.EventEmitter(), { host: rewriteToLocalhostIfNeeded(this.host), port: this.port, secureEndpoint: false });
85
+ this._serverEncrypted = await proxyAgent.connect(new import_events.EventEmitter(), { host: rewriteToLocalhostIfNeeded(this.host), port: this.port, secureEndpoint: false });
86
86
  else
87
87
  this._serverEncrypted = await (0, import_happyEyeballs.createSocket)(rewriteToLocalhostIfNeeded(this.host), this.port);
88
88
  this._serverEncrypted.once("close", this._serverCloseEventListener);
@@ -49,7 +49,7 @@ class Snapshotter {
49
49
  }
50
50
  async reset() {
51
51
  if (this._started)
52
- await this._context.safeNonStallingEvaluateInAllFrames(`window["${this._snapshotStreamer}"].reset()`, "main");
52
+ await this._context.safeNonStallingEvaluateInAllFrames(`window["${this._snapshotStreamer}"].reset()`, "utility");
53
53
  }
54
54
  stop() {
55
55
  this._started = false;
@@ -57,20 +57,20 @@ class Snapshotter {
57
57
  async resetForReuse() {
58
58
  if (this._initScript) {
59
59
  import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
60
- await this._context.removeInitScripts([this._initScript]);
61
60
  this._initScript = void 0;
61
+ this._initScriptSource = void 0;
62
62
  }
63
63
  }
64
64
  async _initialize() {
65
+ const { javaScriptEnabled } = this._context._options;
66
+ this._initScriptSource = `(${import_snapshotterInjected.frameSnapshotStreamer})("${this._snapshotStreamer}", ${javaScriptEnabled || javaScriptEnabled === void 0})`;
67
+ this._initScript = true;
65
68
  for (const page of this._context.pages())
66
69
  this._onPage(page);
67
70
  this._eventListeners = [
68
71
  import_eventsHelper.eventsHelper.addEventListener(this._context, import_browserContext.BrowserContext.Events.Page, this._onPage.bind(this))
69
72
  ];
70
- const { javaScriptEnabled } = this._context._options;
71
- const initScriptSource = `(${import_snapshotterInjected.frameSnapshotStreamer})("${this._snapshotStreamer}", ${javaScriptEnabled || javaScriptEnabled === void 0})`;
72
- this._initScript = await this._context.addInitScript(void 0, initScriptSource);
73
- await this._context.safeNonStallingEvaluateInAllFrames(initScriptSource, "main");
73
+ await this._context.safeNonStallingEvaluateInAllFrames(this._initScriptSource, "utility");
74
74
  }
75
75
  dispose() {
76
76
  import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
@@ -80,7 +80,7 @@ class Snapshotter {
80
80
  frame[kNeedsResetSymbol] = false;
81
81
  const expression = `window["${this._snapshotStreamer}"].captureSnapshot(${needsReset ? "true" : "false"})`;
82
82
  try {
83
- return await frame.nonStallingRawEvaluateInExistingMainContext(expression);
83
+ return await frame.nonStallingEvaluateInExistingContext(expression, "utility");
84
84
  } catch (e) {
85
85
  frame[kNeedsResetSymbol] = true;
86
86
  import_debugLogger.debugLogger.log("error", e);
@@ -124,6 +124,7 @@ class Snapshotter {
124
124
  for (const frame of page.frames())
125
125
  this._annotateFrameHierarchy(frame);
126
126
  this._eventListeners.push(import_eventsHelper.eventsHelper.addEventListener(page, import_page.Page.Events.FrameAttached, (frame) => this._annotateFrameHierarchy(frame)));
127
+ this._eventListeners.push(import_eventsHelper.eventsHelper.addEventListener(page, import_page.Page.Events.InternalFrameNavigatedToNewDocument, (frame) => this._onFrameNavigated(frame)));
127
128
  }
128
129
  async _annotateFrameHierarchy(frame) {
129
130
  try {
@@ -131,7 +132,7 @@ class Snapshotter {
131
132
  const parent = frame.parentFrame();
132
133
  if (!parent)
133
134
  return;
134
- const context = await parent._mainContext();
135
+ const context = await parent._utilityContext();
135
136
  await context?.evaluate(({ snapshotStreamer, frameElement: frameElement2, frameId }) => {
136
137
  window[snapshotStreamer].markIframe(frameElement2, frameId);
137
138
  }, { snapshotStreamer: this._snapshotStreamer, frameElement, frameId: frame.guid });
@@ -139,6 +140,14 @@ class Snapshotter {
139
140
  } catch (e) {
140
141
  }
141
142
  }
143
+ async _onFrameNavigated(frame) {
144
+ if (!this._initScriptSource)
145
+ return;
146
+ try {
147
+ await frame.nonStallingEvaluateInExistingContext(this._initScriptSource, "utility");
148
+ } catch (e) {
149
+ }
150
+ }
142
151
  }
143
152
  const kNeedsResetSymbol = Symbol("kNeedsReset");
144
153
  // Annotate the CommonJS export names for ESM import in node:
@@ -60,23 +60,11 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
60
60
  class Streamer {
61
61
  constructor() {
62
62
  this._lastSnapshotNumber = 0;
63
- this._staleStyleSheets = /* @__PURE__ */ new Set();
64
- this._readingStyleSheet = false;
65
- const invalidateCSSGroupingRule = (rule) => {
66
- if (rule.parentStyleSheet)
67
- this._invalidateStyleSheet(rule.parentStyleSheet);
68
- };
69
- this._interceptNativeMethod(window.CSSStyleSheet.prototype, "insertRule", (sheet) => this._invalidateStyleSheet(sheet));
70
- this._interceptNativeMethod(window.CSSStyleSheet.prototype, "deleteRule", (sheet) => this._invalidateStyleSheet(sheet));
71
- this._interceptNativeMethod(window.CSSStyleSheet.prototype, "addRule", (sheet) => this._invalidateStyleSheet(sheet));
72
- this._interceptNativeMethod(window.CSSStyleSheet.prototype, "removeRule", (sheet) => this._invalidateStyleSheet(sheet));
73
- this._interceptNativeGetter(window.CSSStyleSheet.prototype, "rules", (sheet) => this._invalidateStyleSheet(sheet));
74
- this._interceptNativeGetter(window.CSSStyleSheet.prototype, "cssRules", (sheet) => this._invalidateStyleSheet(sheet));
75
- this._interceptNativeMethod(window.CSSStyleSheet.prototype, "replaceSync", (sheet) => this._invalidateStyleSheet(sheet));
76
- this._interceptNativeMethod(window.CSSGroupingRule.prototype, "insertRule", invalidateCSSGroupingRule);
77
- this._interceptNativeMethod(window.CSSGroupingRule.prototype, "deleteRule", invalidateCSSGroupingRule);
78
- this._interceptNativeGetter(window.CSSGroupingRule.prototype, "cssRules", invalidateCSSGroupingRule);
79
- this._interceptNativeAsyncMethod(window.CSSStyleSheet.prototype, "replace", (sheet) => this._invalidateStyleSheet(sheet));
63
+ this._modifiedStyleSheets = /* @__PURE__ */ new Set();
64
+ this._interceptNativeSetter(window.StyleSheet.prototype, "disabled", (sheet) => {
65
+ if (sheet instanceof CSSStyleSheet)
66
+ this._invalidateStyleSheet(sheet);
67
+ });
80
68
  this._fakeBase = document.createElement("base");
81
69
  this._observer = new MutationObserver((list) => this._handleMutations(list));
82
70
  const observerConfig = { attributes: true, subtree: true };
@@ -117,33 +105,13 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
117
105
  delete event.composedPath()[0].__playwright_target__;
118
106
  });
119
107
  }
120
- _interceptNativeMethod(obj, method, cb) {
121
- const native = obj[method];
122
- if (!native)
123
- return;
124
- obj[method] = function(...args) {
125
- const result = native.call(this, ...args);
126
- cb(this, result);
127
- return result;
128
- };
129
- }
130
- _interceptNativeAsyncMethod(obj, method, cb) {
131
- const native = obj[method];
132
- if (!native)
133
- return;
134
- obj[method] = async function(...args) {
135
- const result = await native.call(this, ...args);
136
- cb(this, result);
137
- return result;
138
- };
139
- }
140
- _interceptNativeGetter(obj, prop, cb) {
108
+ _interceptNativeSetter(obj, prop, cb) {
141
109
  const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
142
110
  Object.defineProperty(obj, prop, {
143
111
  ...descriptor,
144
- get: function() {
145
- const result = descriptor.get.call(this);
146
- cb(this, result);
112
+ set: function(value) {
113
+ const result = descriptor.set.call(this, value);
114
+ cb(this, value);
147
115
  return result;
148
116
  }
149
117
  });
@@ -152,42 +120,37 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
152
120
  for (const mutation of list)
153
121
  ensureCachedData(mutation.target).attributesCached = void 0;
154
122
  }
155
- _invalidateStyleSheet(sheet) {
156
- if (this._readingStyleSheet)
157
- return;
158
- this._staleStyleSheets.add(sheet);
159
- }
160
123
  _updateStyleElementStyleSheetTextIfNeeded(sheet, forceText) {
161
124
  const data = ensureCachedData(sheet);
162
- if (this._staleStyleSheets.has(sheet) || forceText && data.cssText === void 0) {
163
- this._staleStyleSheets.delete(sheet);
164
- try {
165
- data.cssText = this._getSheetText(sheet);
166
- } catch (e) {
167
- data.cssText = "";
168
- }
125
+ try {
126
+ data.cssText = this._getSheetText(sheet);
127
+ } catch (e) {
128
+ data.cssText = "";
169
129
  }
170
130
  return data.cssText;
171
131
  }
172
132
  // Returns either content, ref, or no override.
173
133
  _updateLinkStyleSheetTextIfNeeded(sheet, snapshotNumber) {
174
134
  const data = ensureCachedData(sheet);
175
- if (this._staleStyleSheets.has(sheet)) {
176
- this._staleStyleSheets.delete(sheet);
177
- try {
178
- data.cssText = this._getSheetText(sheet);
179
- data.cssRef = snapshotNumber;
180
- return data.cssText;
181
- } catch (e) {
135
+ try {
136
+ const currentText = this._getSheetText(sheet);
137
+ if (data.cssText === void 0) {
138
+ data.cssText = currentText;
139
+ return void 0;
182
140
  }
141
+ if (currentText === data.cssText)
142
+ return data.cssRef === void 0 ? void 0 : snapshotNumber - data.cssRef;
143
+ data.cssText = currentText;
144
+ data.cssRef = snapshotNumber;
145
+ return data.cssText;
146
+ } catch (e) {
147
+ return void 0;
183
148
  }
184
- return data.cssRef === void 0 ? void 0 : snapshotNumber - data.cssRef;
185
149
  }
186
150
  markIframe(iframeElement, frameId) {
187
151
  iframeElement[kSnapshotFrameId] = frameId;
188
152
  }
189
153
  reset() {
190
- this._staleStyleSheets.clear();
191
154
  const visitNode = (node) => {
192
155
  resetCachedData(node);
193
156
  if (node.nodeType === Node.ELEMENT_NODE) {
@@ -246,15 +209,10 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
246
209
  return document.baseURI;
247
210
  }
248
211
  _getSheetText(sheet) {
249
- this._readingStyleSheet = true;
250
- try {
251
- const rules = [];
252
- for (const rule of sheet.cssRules)
253
- rules.push(rule.cssText);
254
- return rules.join("\n");
255
- } finally {
256
- this._readingStyleSheet = false;
257
- }
212
+ const rules = [];
213
+ for (const rule of sheet.cssRules)
214
+ rules.push(rule.cssText);
215
+ return rules.join("\n");
258
216
  }
259
217
  captureSnapshot(needsReset) {
260
218
  const timestamp = performance.now();
@@ -518,7 +476,7 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
518
476
  wallTime: Date.now(),
519
477
  collectionTime: 0
520
478
  };
521
- for (const sheet of this._staleStyleSheets) {
479
+ for (const sheet of this._modifiedStyleSheets) {
522
480
  if (sheet.href === null)
523
481
  continue;
524
482
  const content = this._updateLinkStyleSheetTextIfNeeded(sheet, snapshotNumber);
@@ -40,6 +40,7 @@ var import_assert = require("../../../utils/isomorphic/assert");
40
40
  var import_time = require("../../../utils/isomorphic/time");
41
41
  var import_eventsHelper = require("../../utils/eventsHelper");
42
42
  var import_crypto = require("../../utils/crypto");
43
+ var import_userAgent = require("../../utils/userAgent");
43
44
  var import_artifact = require("../../artifact");
44
45
  var import_browserContext = require("../../browserContext");
45
46
  var import_dispatcher = require("../../dispatchers/dispatcher");
@@ -74,6 +75,7 @@ class Tracing extends import_instrumentation.SdkObject {
74
75
  type: "context-options",
75
76
  origin: "library",
76
77
  browserName: "",
78
+ playwrightVersion: (0, import_userAgent.getPlaywrightVersion)(),
77
79
  options: {},
78
80
  platform: process.platform,
79
81
  wallTime: 0,
@@ -220,7 +222,7 @@ class Tracing extends import_instrumentation.SdkObject {
220
222
  if (!(this._context instanceof import_browserContext.BrowserContext))
221
223
  return;
222
224
  for (const page of this._context.pages())
223
- page.setScreencastOptions(null);
225
+ page.screencast.setOptions(null);
224
226
  }
225
227
  _allocateNewTraceFile(state) {
226
228
  const suffix = state.chunkOrdinal ? `-chunk${state.chunkOrdinal}` : ``;
@@ -324,23 +326,21 @@ class Tracing extends import_instrumentation.SdkObject {
324
326
  return { artifact };
325
327
  }
326
328
  async _captureSnapshot(snapshotName, sdkObject, metadata) {
327
- if (!this._snapshotter)
329
+ if (!snapshotName || !sdkObject.attribution.page)
328
330
  return;
329
- if (!sdkObject.attribution.page)
330
- return;
331
- if (!this._snapshotter.started())
332
- return;
333
- if (!shouldCaptureSnapshot(metadata))
334
- return;
335
- await this._snapshotter.captureSnapshot(sdkObject.attribution.page, metadata.id, snapshotName).catch(() => {
331
+ await this._snapshotter?.captureSnapshot(sdkObject.attribution.page, metadata.id, snapshotName).catch(() => {
336
332
  });
337
333
  }
338
- onBeforeCall(sdkObject, metadata) {
339
- const event = createBeforeActionTraceEvent(metadata, this._currentGroupId());
334
+ _shouldCaptureSnapshot(sdkObject, metadata) {
335
+ return !!this._snapshotter?.started() && shouldCaptureSnapshot(metadata) && !!sdkObject.attribution.page;
336
+ }
337
+ onBeforeCall(sdkObject, metadata, parentId) {
338
+ const event = createBeforeActionTraceEvent(metadata, parentId ?? this._currentGroupId());
340
339
  if (!event)
341
340
  return Promise.resolve();
342
- sdkObject.attribution.page?.temporarilyDisableTracingScreencastThrottling();
343
- event.beforeSnapshot = `before@${metadata.id}`;
341
+ sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
342
+ if (this._shouldCaptureSnapshot(sdkObject, metadata))
343
+ event.beforeSnapshot = `before@${metadata.id}`;
344
344
  this._state?.callIds.add(metadata.id);
345
345
  this._appendTraceEvent(event);
346
346
  return this._captureSnapshot(event.beforeSnapshot, sdkObject, metadata);
@@ -351,8 +351,9 @@ class Tracing extends import_instrumentation.SdkObject {
351
351
  const event = createInputActionTraceEvent(metadata);
352
352
  if (!event)
353
353
  return Promise.resolve();
354
- sdkObject.attribution.page?.temporarilyDisableTracingScreencastThrottling();
355
- event.inputSnapshot = `input@${metadata.id}`;
354
+ sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
355
+ if (this._shouldCaptureSnapshot(sdkObject, metadata))
356
+ event.inputSnapshot = `input@${metadata.id}`;
356
357
  this._appendTraceEvent(event);
357
358
  return this._captureSnapshot(event.inputSnapshot, sdkObject, metadata);
358
359
  }
@@ -367,15 +368,16 @@ class Tracing extends import_instrumentation.SdkObject {
367
368
  if (event)
368
369
  this._appendTraceEvent(event);
369
370
  }
370
- async onAfterCall(sdkObject, metadata) {
371
+ onAfterCall(sdkObject, metadata) {
371
372
  if (!this._state?.callIds.has(metadata.id))
372
- return;
373
+ return Promise.resolve();
373
374
  this._state?.callIds.delete(metadata.id);
374
375
  const event = createAfterActionTraceEvent(metadata);
375
376
  if (!event)
376
- return;
377
- sdkObject.attribution.page?.temporarilyDisableTracingScreencastThrottling();
378
- event.afterSnapshot = `after@${metadata.id}`;
377
+ return Promise.resolve();
378
+ sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
379
+ if (this._shouldCaptureSnapshot(sdkObject, metadata))
380
+ event.afterSnapshot = `after@${metadata.id}`;
379
381
  this._appendTraceEvent(event);
380
382
  return this._captureSnapshot(event.afterSnapshot, sdkObject, metadata);
381
383
  }
@@ -482,7 +484,7 @@ class Tracing extends import_instrumentation.SdkObject {
482
484
  this._appendTraceEvent(event);
483
485
  }
484
486
  _startScreencastInPage(page) {
485
- page.setScreencastOptions(kScreencastOptions);
487
+ page.screencast.setOptions(kScreencastOptions);
486
488
  const prefix = page.guid;
487
489
  this._screencastListeners.push(
488
490
  import_eventsHelper.eventsHelper.addEventListener(page, import_page.Page.Events.ScreencastFrame, (params) => {
@@ -548,6 +550,8 @@ function shouldCaptureSnapshot(metadata) {
548
550
  return !!metainfo?.snapshot;
549
551
  }
550
552
  function createBeforeActionTraceEvent(metadata, parentId) {
553
+ if (metadata.type === "Route" && metadata.method === "continue" && metadata.params?.isFallback)
554
+ return null;
551
555
  if (metadata.internal || metadata.method.startsWith("tracing"))
552
556
  return null;
553
557
  const event = {
@@ -566,6 +570,8 @@ function createBeforeActionTraceEvent(metadata, parentId) {
566
570
  return event;
567
571
  }
568
572
  function createInputActionTraceEvent(metadata) {
573
+ if (metadata.type === "Route" && metadata.method === "continue" && metadata.params?.isFallback)
574
+ return null;
569
575
  if (metadata.internal || metadata.method.startsWith("tracing"))
570
576
  return null;
571
577
  return {
@@ -575,6 +581,8 @@ function createInputActionTraceEvent(metadata) {
575
581
  };
576
582
  }
577
583
  function createActionLogTraceEvent(metadata, message) {
584
+ if (metadata.type === "Route" && metadata.method === "continue" && metadata.params?.isFallback)
585
+ return null;
578
586
  if (metadata.internal || metadata.method.startsWith("tracing"))
579
587
  return null;
580
588
  return {
@@ -585,6 +593,8 @@ function createActionLogTraceEvent(metadata, message) {
585
593
  };
586
594
  }
587
595
  function createAfterActionTraceEvent(metadata) {
596
+ if (metadata.type === "Route" && metadata.method === "continue" && metadata.params?.isFallback)
597
+ return null;
588
598
  if (metadata.internal || metadata.method.startsWith("tracing"))
589
599
  return null;
590
600
  return {