patchright-core 1.57.0 → 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 (148) hide show
  1. package/ThirdPartyNotices.txt +3223 -308
  2. package/browsers.json +21 -22
  3. package/lib/cli/program.js +4 -5
  4. package/lib/client/api.js +3 -0
  5. package/lib/client/browser.js +3 -5
  6. package/lib/client/browserContext.js +40 -4
  7. package/lib/client/browserType.js +4 -3
  8. package/lib/client/connection.js +4 -0
  9. package/lib/client/elementHandle.js +3 -0
  10. package/lib/client/events.js +3 -0
  11. package/lib/client/fetch.js +3 -4
  12. package/lib/client/frame.js +10 -1
  13. package/lib/client/locator.js +8 -0
  14. package/lib/client/network.js +5 -1
  15. package/lib/client/page.js +29 -1
  16. package/lib/client/pageAgent.js +64 -0
  17. package/lib/client/platform.js +3 -0
  18. package/lib/client/tracing.js +1 -1
  19. package/lib/generated/injectedScriptSource.js +1 -1
  20. package/lib/generated/pollingRecorderSource.js +1 -1
  21. package/lib/mcpBundle.js +84 -0
  22. package/lib/mcpBundleImpl/index.js +147 -0
  23. package/lib/protocol/serializers.js +5 -0
  24. package/lib/protocol/validator.js +88 -4
  25. package/lib/remote/playwrightServer.js +1 -2
  26. package/lib/server/agent/actionRunner.js +335 -0
  27. package/lib/server/agent/actions.js +128 -0
  28. package/lib/server/agent/codegen.js +111 -0
  29. package/lib/server/agent/context.js +150 -0
  30. package/lib/server/agent/expectTools.js +156 -0
  31. package/lib/server/agent/pageAgent.js +204 -0
  32. package/lib/server/agent/performTools.js +262 -0
  33. package/lib/server/agent/tool.js +109 -0
  34. package/lib/server/artifact.js +1 -1
  35. package/lib/server/bidi/bidiBrowser.js +56 -12
  36. package/lib/server/bidi/bidiChromium.js +8 -12
  37. package/lib/server/bidi/bidiConnection.js +1 -0
  38. package/lib/server/bidi/bidiDeserializer.js +116 -0
  39. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  40. package/lib/server/bidi/bidiFirefox.js +6 -8
  41. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  42. package/lib/server/bidi/bidiPage.js +39 -28
  43. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  44. package/lib/server/browserContext.js +34 -26
  45. package/lib/server/browserType.js +12 -4
  46. package/lib/server/chromium/chromium.js +14 -20
  47. package/lib/server/chromium/chromiumSwitches.js +2 -2
  48. package/lib/server/chromium/crBrowser.js +22 -12
  49. package/lib/server/chromium/crConnection.js +0 -5
  50. package/lib/server/chromium/crCoverage.js +13 -1
  51. package/lib/server/chromium/crDevTools.js +0 -2
  52. package/lib/server/chromium/crNetworkManager.js +92 -12
  53. package/lib/server/chromium/crPage.js +62 -116
  54. package/lib/server/codegen/javascript.js +6 -29
  55. package/lib/server/deviceDescriptorsSource.json +56 -56
  56. package/lib/server/dispatchers/browserContextDispatcher.js +3 -2
  57. package/lib/server/dispatchers/dispatcher.js +6 -13
  58. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  59. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  60. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  61. package/lib/server/dispatchers/pageDispatcher.js +4 -0
  62. package/lib/server/dom.js +12 -3
  63. package/lib/server/electron/electron.js +5 -2
  64. package/lib/server/firefox/ffBrowser.js +10 -20
  65. package/lib/server/firefox/ffConnection.js +0 -5
  66. package/lib/server/firefox/ffNetworkManager.js +2 -2
  67. package/lib/server/firefox/ffPage.js +15 -18
  68. package/lib/server/firefox/firefox.js +6 -8
  69. package/lib/server/frameSelectors.js +16 -4
  70. package/lib/server/frames.js +251 -86
  71. package/lib/server/instrumentation.js +3 -0
  72. package/lib/server/javascript.js +8 -4
  73. package/lib/server/launchApp.js +2 -1
  74. package/lib/server/network.js +50 -12
  75. package/lib/server/page.js +61 -91
  76. package/lib/server/progress.js +26 -6
  77. package/lib/server/recorder/recorderApp.js +79 -100
  78. package/lib/server/registry/browserFetcher.js +6 -4
  79. package/lib/server/registry/index.js +172 -149
  80. package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
  81. package/lib/server/screencast.js +190 -0
  82. package/lib/server/screenshotter.js +6 -0
  83. package/lib/server/trace/recorder/snapshotter.js +17 -8
  84. package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
  85. package/lib/server/trace/recorder/tracing.js +29 -21
  86. package/lib/server/trace/viewer/traceParser.js +72 -0
  87. package/lib/server/trace/viewer/traceViewer.js +21 -17
  88. package/lib/server/utils/expectUtils.js +87 -2
  89. package/lib/server/utils/hostPlatform.js +15 -0
  90. package/lib/server/utils/httpServer.js +5 -20
  91. package/lib/server/utils/network.js +37 -28
  92. package/lib/server/utils/nodePlatform.js +6 -0
  93. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +22 -13
  94. package/lib/server/webkit/webkit.js +4 -6
  95. package/lib/server/webkit/wkBrowser.js +2 -6
  96. package/lib/server/webkit/wkConnection.js +1 -6
  97. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  98. package/lib/server/webkit/wkPage.js +75 -46
  99. package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
  100. package/lib/utils/isomorphic/lruCache.js +51 -0
  101. package/lib/utils/isomorphic/protocolMetainfo.js +9 -1
  102. package/lib/utils/isomorphic/stringUtils.js +49 -0
  103. package/lib/utils/isomorphic/trace/entries.js +16 -0
  104. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  105. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  106. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  107. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  108. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  109. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  110. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  111. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  112. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  113. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  114. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  115. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  116. package/lib/utils/isomorphic/yaml.js +84 -0
  117. package/lib/utils.js +2 -0
  118. package/lib/utilsBundle.js +2 -5
  119. package/lib/utilsBundleImpl/index.js +165 -165
  120. package/lib/vite/htmlReport/index.html +21 -21
  121. package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
  122. package/lib/vite/{traceViewer/codeMirrorModule.C3UTv-Ge.css → recorder/assets/codeMirrorModule-DYBRYzYX.css} +1 -1
  123. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  124. package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
  125. package/lib/vite/recorder/index.html +2 -2
  126. package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
  127. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
  128. package/lib/vite/{recorder/assets/codeMirrorModule-C3UTv-Ge.css → traceViewer/codeMirrorModule.DYBRYzYX.css} +1 -1
  129. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  130. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  131. package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
  132. package/lib/vite/traceViewer/index.html +4 -4
  133. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  134. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
  135. package/lib/vite/traceViewer/uiMode.html +3 -3
  136. package/package.json +2 -1
  137. package/types/protocol.d.ts +738 -159
  138. package/types/types.d.ts +25 -38
  139. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  140. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  141. package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
  142. package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
  143. package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
  144. package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
  145. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
  146. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
  147. package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
  148. package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
@@ -33,6 +33,9 @@ class SdkObject extends import_events.EventEmitter {
33
33
  this.attribution = { ...parent.attribution };
34
34
  this.instrumentation = parent.instrumentation;
35
35
  }
36
+ closeReason() {
37
+ return this.attribution.page?._closeReason || this.attribution.context?._closeReason || this.attribution.browser?._closeReason;
38
+ }
36
39
  }
37
40
  function createRootSdkObject() {
38
41
  const fakeParent = { attribution: {}, instrumentation: createInstrumentation() };
@@ -118,10 +118,12 @@ class JSHandle extends import_instrumentation.SdkObject {
118
118
  if (context.constructor.name === "FrameExecutionContext") {
119
119
  const frame = context.frame;
120
120
  if (frame) {
121
- if (isolatedContext) context = await frame._utilityContext();
122
- else if (!isolatedContext) context = await frame._mainContext();
121
+ if (isolatedContext === true) context = await frame._utilityContext();
122
+ else if (isolatedContext === false) context = await frame._mainContext();
123
123
  }
124
124
  }
125
+ if (context !== this._context && context.adoptIfNeeded(this) === null)
126
+ context = this._context;
125
127
  const value = await evaluateExpression(context, expression, { ...options, returnByValue: true }, this, arg);
126
128
  await context.doSlowMo();
127
129
  return value;
@@ -131,10 +133,12 @@ class JSHandle extends import_instrumentation.SdkObject {
131
133
  if (context.constructor.name === "FrameExecutionContext") {
132
134
  const frame = this._context.frame;
133
135
  if (frame) {
134
- if (isolatedContext) context = await frame._utilityContext();
135
- else if (!isolatedContext) context = await frame._mainContext();
136
+ if (isolatedContext === true) context = await frame._utilityContext();
137
+ else if (isolatedContext === false) context = await frame._mainContext();
136
138
  }
137
139
  }
140
+ if (context !== this._context && context.adoptIfNeeded(this) === null)
141
+ context = this._context;
138
142
  const value = await evaluateExpression(context, expression, { ...options, returnByValue: false }, this, arg);
139
143
  await context.doSlowMo();
140
144
  return value;
@@ -114,7 +114,8 @@ async function syncLocalStorageWithSettings(page, appName) {
114
114
  return;
115
115
  Object.entries(settings2).map(([k, v]) => localStorage[k] = v);
116
116
  window.saveSettings = () => {
117
- window._saveSerializedSettings(JSON.stringify({ ...localStorage }));
117
+ if (typeof window._saveSerializedSettings === "function")
118
+ window._saveSerializedSettings(JSON.stringify({ ...localStorage }));
118
119
  };
119
120
  })})(${settings});
120
121
  `
@@ -22,6 +22,7 @@ __export(network_exports, {
22
22
  Response: () => Response,
23
23
  Route: () => Route,
24
24
  WebSocket: () => WebSocket,
25
+ applyHeadersOverrides: () => applyHeadersOverrides,
25
26
  filterCookies: () => filterCookies,
26
27
  isLocalHostname: () => isLocalHostname,
27
28
  kMaxCookieExpiresDateInSeconds: () => kMaxCookieExpiresDateInSeconds,
@@ -61,6 +62,48 @@ function filterCookies(cookies, urls) {
61
62
  function isLocalHostname(hostname) {
62
63
  return hostname === "localhost" || hostname.endsWith(".localhost");
63
64
  }
65
+ const FORBIDDEN_HEADER_NAMES = /* @__PURE__ */ new Set([
66
+ "accept-charset",
67
+ "accept-encoding",
68
+ "access-control-request-headers",
69
+ "access-control-request-method",
70
+ "connection",
71
+ "content-length",
72
+ "cookie",
73
+ "date",
74
+ "dnt",
75
+ "expect",
76
+ "host",
77
+ "keep-alive",
78
+ "origin",
79
+ "referer",
80
+ "set-cookie",
81
+ "te",
82
+ "trailer",
83
+ "transfer-encoding",
84
+ "upgrade",
85
+ "via"
86
+ ]);
87
+ const FORBIDDEN_METHODS = /* @__PURE__ */ new Set(["CONNECT", "TRACE", "TRACK"]);
88
+ function isForbiddenHeader(name, value) {
89
+ const lowerName = name.toLowerCase();
90
+ if (FORBIDDEN_HEADER_NAMES.has(lowerName))
91
+ return true;
92
+ if (lowerName.startsWith("proxy-"))
93
+ return true;
94
+ if (lowerName.startsWith("sec-"))
95
+ return true;
96
+ if (lowerName === "x-http-method" || lowerName === "x-http-method-override" || lowerName === "x-method-override") {
97
+ if (value && FORBIDDEN_METHODS.has(value.toUpperCase()))
98
+ return true;
99
+ }
100
+ return false;
101
+ }
102
+ function applyHeadersOverrides(original, overrides) {
103
+ const forbiddenHeaders = original.filter((header) => isForbiddenHeader(header.name, header.value));
104
+ const allowedHeaders = overrides.filter((header) => !isForbiddenHeader(header.name, header.value));
105
+ return mergeHeaders([allowedHeaders, forbiddenHeaders]);
106
+ }
64
107
  const kMaxCookieExpiresDateInSeconds = 253402300799;
65
108
  function rewriteCookies(cookies) {
66
109
  return cookies.map((c) => {
@@ -99,7 +142,6 @@ class Request extends import_instrumentation.SdkObject {
99
142
  this._response = null;
100
143
  this._redirectedTo = null;
101
144
  this._failureText = null;
102
- this._headersMap = /* @__PURE__ */ new Map();
103
145
  this._frame = null;
104
146
  this._serviceWorker = null;
105
147
  this._rawRequestHeadersPromise = new import_manualPromise.ManualPromise();
@@ -118,7 +160,6 @@ class Request extends import_instrumentation.SdkObject {
118
160
  this._method = method;
119
161
  this._postData = postData;
120
162
  this._headers = headers;
121
- this._updateHeadersMap();
122
163
  this._isFavicon = url.endsWith("/favicon.ico") || !!redirectedFrom?._isFavicon;
123
164
  }
124
165
  static {
@@ -132,13 +173,8 @@ class Request extends import_instrumentation.SdkObject {
132
173
  }
133
174
  _applyOverrides(overrides) {
134
175
  this._overrides = { ...this._overrides, ...overrides };
135
- this._updateHeadersMap();
136
176
  return this._overrides;
137
177
  }
138
- _updateHeadersMap() {
139
- for (const { name, value } of this.headers())
140
- this._headersMap.set(name.toLowerCase(), value);
141
- }
142
178
  overrides() {
143
179
  return this._overrides;
144
180
  }
@@ -158,7 +194,8 @@ class Request extends import_instrumentation.SdkObject {
158
194
  return this._overrides?.headers || this._headers;
159
195
  }
160
196
  headerValue(name) {
161
- return this._headersMap.get(name);
197
+ const lowerCaseName = name.toLowerCase();
198
+ return this.headers().find((h) => h.name.toLowerCase() === lowerCaseName)?.value;
162
199
  }
163
200
  // "null" means no raw headers available - we'll use provisional headers as raw headers.
164
201
  setRawRequestHeaders(headers) {
@@ -309,10 +346,7 @@ class Route extends import_instrumentation.SdkObject {
309
346
  throw new Error("New URL must have same protocol as overridden URL");
310
347
  }
311
348
  if (overrides.headers) {
312
- overrides.headers = overrides.headers?.filter((header) => {
313
- const headerName = header.name.toLowerCase();
314
- return headerName !== "cookie" && headerName !== "host";
315
- });
349
+ overrides.headers = applyHeadersOverrides(this._request._headers, overrides.headers);
316
350
  }
317
351
  overrides = this._request._applyOverrides(overrides);
318
352
  const nextHandler = this._futureHandlers.shift();
@@ -436,6 +470,9 @@ class Response extends import_instrumentation.SdkObject {
436
470
  request() {
437
471
  return this._request;
438
472
  }
473
+ finished() {
474
+ return this._finishedPromise;
475
+ }
439
476
  frame() {
440
477
  return this._request.frame();
441
478
  }
@@ -617,6 +654,7 @@ function mergeHeaders(headers) {
617
654
  Response,
618
655
  Route,
619
656
  WebSocket,
657
+ applyHeadersOverrides,
620
658
  filterCookies,
621
659
  isLocalHostname,
622
660
  kMaxCookieExpiresDateInSeconds,
@@ -31,7 +31,8 @@ __export(page_exports, {
31
31
  InitScript: () => InitScript,
32
32
  Page: () => Page,
33
33
  PageBinding: () => PageBinding,
34
- Worker: () => Worker
34
+ Worker: () => Worker,
35
+ WorkerEvent: () => WorkerEvent
35
36
  });
36
37
  module.exports = __toCommonJS(page_exports);
37
38
  var import_pageBinding = require("./pageBinding");
@@ -53,6 +54,22 @@ var import_selectorParser = require("../utils/isomorphic/selectorParser");
53
54
  var import_manualPromise = require("../utils/isomorphic/manualPromise");
54
55
  var import_utilityScriptSerializers = require("../utils/isomorphic/utilityScriptSerializers");
55
56
  var import_callLog = require("./callLog");
57
+ var import_screencast = require("./screencast");
58
+ const PageEvent = {
59
+ Close: "close",
60
+ Crash: "crash",
61
+ Download: "download",
62
+ EmulatedSizeChanged: "emulatedsizechanged",
63
+ FileChooser: "filechooser",
64
+ FrameAttached: "frameattached",
65
+ FrameDetached: "framedetached",
66
+ InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument",
67
+ LocatorHandlerTriggered: "locatorhandlertriggered",
68
+ ScreencastFrame: "screencastframe",
69
+ Video: "video",
70
+ WebSocket: "websocket",
71
+ Worker: "worker"
72
+ };
56
73
  class Page extends import_instrumentation.SdkObject {
57
74
  constructor(delegate, browserContext) {
58
75
  super(browserContext, "page");
@@ -74,9 +91,6 @@ class Page extends import_instrumentation.SdkObject {
74
91
  this._lastLocatorHandlerUid = 0;
75
92
  this._locatorHandlerRunningCounter = 0;
76
93
  this._networkRequests = [];
77
- // Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
78
- // When throttling for tracing, 200ms between frames, except for 10 frames around the action.
79
- this._frameThrottler = new FrameThrottler(10, 35, 200);
80
94
  this.attribution.page = this;
81
95
  this.delegate = delegate;
82
96
  this.browserContext = browserContext;
@@ -85,27 +99,14 @@ class Page extends import_instrumentation.SdkObject {
85
99
  this.touchscreen = new input.Touchscreen(delegate.rawTouchscreen, this);
86
100
  this.screenshotter = new import_screenshotter.Screenshotter(this);
87
101
  this.frameManager = new frames.FrameManager(this);
102
+ this.screencast = new import_screencast.Screencast(this);
88
103
  if (delegate.pdf)
89
104
  this.pdf = delegate.pdf.bind(delegate);
90
105
  this.coverage = delegate.coverage ? delegate.coverage() : null;
91
106
  this.isStorageStatePage = browserContext.isCreatingStorageStatePage();
92
107
  }
93
108
  static {
94
- this.Events = {
95
- Close: "close",
96
- Crash: "crash",
97
- Download: "download",
98
- EmulatedSizeChanged: "emulatedsizechanged",
99
- FileChooser: "filechooser",
100
- FrameAttached: "frameattached",
101
- FrameDetached: "framedetached",
102
- InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument",
103
- LocatorHandlerTriggered: "locatorhandlertriggered",
104
- ScreencastFrame: "screencastframe",
105
- Video: "video",
106
- WebSocket: "websocket",
107
- Worker: "worker"
108
- };
109
+ this.Events = PageEvent;
109
110
  }
110
111
  async reportAsNew(opener, error) {
111
112
  if (opener) {
@@ -158,17 +159,17 @@ class Page extends import_instrumentation.SdkObject {
158
159
  }
159
160
  _didClose() {
160
161
  this.frameManager.dispose();
161
- this._frameThrottler.dispose();
162
+ this.screencast.stopFrameThrottler();
162
163
  (0, import_utils.assert)(this._closedState !== "closed", "Page closed twice");
163
164
  this._closedState = "closed";
164
165
  this.emit(Page.Events.Close);
165
166
  this._closedPromise.resolve();
166
167
  this.instrumentation.onPageClose(this);
167
- this.openScope.close(new import_errors.TargetClosedError());
168
+ this.openScope.close(new import_errors.TargetClosedError(this.closeReason()));
168
169
  }
169
170
  _didCrash() {
170
171
  this.frameManager.dispose();
171
- this._frameThrottler.dispose();
172
+ this.screencast.stopFrameThrottler();
172
173
  this.emit(Page.Events.Crash);
173
174
  this._crashed = true;
174
175
  this.instrumentation.onPageClose(this);
@@ -567,7 +568,7 @@ class Page extends import_instrumentation.SdkObject {
567
568
  if (this._closedState === "closed")
568
569
  return;
569
570
  if (options.reason)
570
- this.closeReason = options.reason;
571
+ this._closeReason = options.reason;
571
572
  const runBeforeUnload = !!options.runBeforeUnload;
572
573
  if (this._closedState !== "closing") {
573
574
  if (!runBeforeUnload)
@@ -624,16 +625,6 @@ class Page extends import_instrumentation.SdkObject {
624
625
  getBinding(name) {
625
626
  return this._pageBindings.get(name) || this.browserContext._pageBindings.get(name);
626
627
  }
627
- setScreencastOptions(options) {
628
- this.delegate.setScreencastOptions(options).catch((e) => import_debugLogger.debugLogger.log("error", e));
629
- this._frameThrottler.setThrottlingEnabled(!!options);
630
- }
631
- throttleScreencastFrameAck(ack) {
632
- this._frameThrottler.ack(ack);
633
- }
634
- temporarilyDisableTracingScreencastThrottling() {
635
- this._frameThrottler.recharge();
636
- }
637
628
  async safeNonStallingEvaluateInAllFrames(expression, world, options = {}) {
638
629
  await Promise.all(this.frames().map(async (frame) => {
639
630
  try {
@@ -648,7 +639,7 @@ class Page extends import_instrumentation.SdkObject {
648
639
  await Promise.all(this.frames().map((frame) => frame.hideHighlight().catch(() => {
649
640
  })));
650
641
  }
651
- async snapshotForAI(progress, options) {
642
+ async snapshotForAI(progress, options = {}) {
652
643
  const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), options);
653
644
  return { full: snapshot.full.join("\n"), incremental: snapshot.incremental?.join("\n") };
654
645
  }
@@ -656,6 +647,9 @@ class Page extends import_instrumentation.SdkObject {
656
647
  return [...this.browserContext._pageBindings.values(), ...this._pageBindings.values()];
657
648
  }
658
649
  }
650
+ const WorkerEvent = {
651
+ Close: "close"
652
+ };
659
653
  class Worker extends import_instrumentation.SdkObject {
660
654
  constructor(parent, url) {
661
655
  super(parent, "worker");
@@ -666,9 +660,7 @@ class Worker extends import_instrumentation.SdkObject {
666
660
  this.url = url;
667
661
  }
668
662
  static {
669
- this.Events = {
670
- Close: "close"
671
- };
663
+ this.Events = WorkerEvent;
672
664
  }
673
665
  createExecutionContext(delegate) {
674
666
  this.existingExecutionContext = new js.ExecutionContext(this, delegate, "worker");
@@ -719,6 +711,32 @@ class PageBinding {
719
711
  }
720
712
  static async dispatch(page, payload, context) {
721
713
  const { name, seq, serializedArgs } = JSON.parse(payload);
714
+ const deliver = async (deliverPayload) => {
715
+ let deliveryError;
716
+ try {
717
+ await context.evaluate(import_pageBinding.deliverBindingResult, deliverPayload);
718
+ return;
719
+ } catch (e) {
720
+ deliveryError = e;
721
+ }
722
+ const frame = context.frame;
723
+ if (!frame) {
724
+ import_debugLogger.debugLogger.log("error", deliveryError);
725
+ return;
726
+ }
727
+ const mainContext = await frame._mainContext().catch(() => null);
728
+ const utilityContext = await frame._utilityContext().catch(() => null);
729
+ for (const ctx of [mainContext, utilityContext]) {
730
+ if (!ctx || ctx === context)
731
+ continue;
732
+ try {
733
+ await ctx.evaluate(import_pageBinding.deliverBindingResult, deliverPayload);
734
+ return;
735
+ } catch {
736
+ }
737
+ }
738
+ import_debugLogger.debugLogger.log("error", deliveryError);
739
+ };
722
740
  try {
723
741
  (0, import_utils.assert)(context.world);
724
742
  const binding = page.getBinding(name);
@@ -734,9 +752,9 @@ class PageBinding {
734
752
  const args = serializedArgs.map((a) => (0, import_utilityScriptSerializers.parseEvaluationResultValue)(a));
735
753
  result = await binding.playwrightFunction({ frame: context.frame, page, context: page._browserContext }, ...args);
736
754
  }
737
- context.evaluate(import_pageBinding.deliverBindingResult, { name, seq, result }).catch((e) => import_debugLogger.debugLogger.log("error", e));
755
+ await deliver({ name, seq, result });
738
756
  } catch (error) {
739
- context.evaluate(import_pageBinding.deliverBindingResult, { name, seq, error }).catch((e) => import_debugLogger.debugLogger.log("error", e));
757
+ await deliver({ name, seq, error });
740
758
  }
741
759
  }
742
760
  }
@@ -745,56 +763,7 @@ class InitScript {
745
763
  this.source = `(() => { ${source} })();`;
746
764
  }
747
765
  }
748
- class FrameThrottler {
749
- constructor(nonThrottledFrames, defaultInterval, throttlingInterval) {
750
- this._acks = [];
751
- this._throttlingEnabled = false;
752
- this._nonThrottledFrames = nonThrottledFrames;
753
- this._budget = nonThrottledFrames;
754
- this._defaultInterval = defaultInterval;
755
- this._throttlingInterval = throttlingInterval;
756
- this._tick();
757
- }
758
- dispose() {
759
- if (this._timeoutId) {
760
- clearTimeout(this._timeoutId);
761
- this._timeoutId = void 0;
762
- }
763
- }
764
- setThrottlingEnabled(enabled) {
765
- this._throttlingEnabled = enabled;
766
- }
767
- recharge() {
768
- for (const ack of this._acks)
769
- ack();
770
- this._acks = [];
771
- this._budget = this._nonThrottledFrames;
772
- if (this._timeoutId) {
773
- clearTimeout(this._timeoutId);
774
- this._tick();
775
- }
776
- }
777
- ack(ack) {
778
- if (!this._timeoutId) {
779
- ack();
780
- return;
781
- }
782
- this._acks.push(ack);
783
- }
784
- _tick() {
785
- const ack = this._acks.shift();
786
- if (ack) {
787
- --this._budget;
788
- ack();
789
- }
790
- if (this._throttlingEnabled && this._budget <= 0) {
791
- this._timeoutId = setTimeout(() => this._tick(), this._throttlingInterval);
792
- } else {
793
- this._timeoutId = setTimeout(() => this._tick(), this._defaultInterval);
794
- }
795
- }
796
- }
797
- async function snapshotFrameForAI(progress, frame, options) {
766
+ async function snapshotFrameForAI(progress, frame, options = {}) {
798
767
  const snapshot = await frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
799
768
  try {
800
769
  const context = await progress.race(frame._utilityContext());
@@ -804,7 +773,7 @@ async function snapshotFrameForAI(progress, frame, options) {
804
773
  if (!node)
805
774
  return true;
806
775
  return injected.incrementalAriaSnapshot(node, { mode: "ai", ...options2 });
807
- }, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track }));
776
+ }, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track, doNotRenderActive: options.doNotRenderActive }));
808
777
  if (snapshotOrRetry === true)
809
778
  return continuePolling;
810
779
  return snapshotOrRetry;
@@ -864,5 +833,6 @@ function ensureArrayLimit(array, limit) {
864
833
  InitScript,
865
834
  Page,
866
835
  PageBinding,
867
- Worker
836
+ Worker,
837
+ WorkerEvent
868
838
  });
@@ -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;