patchright-core 1.56.0 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/ThirdPartyNotices.txt +40 -381
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +13 -13
  4. package/lib/cli/program.js +14 -57
  5. package/lib/client/api.js +0 -3
  6. package/lib/client/browserContext.js +22 -4
  7. package/lib/client/consoleMessage.js +5 -1
  8. package/lib/client/electron.js +1 -1
  9. package/lib/client/events.js +2 -1
  10. package/lib/client/locator.js +4 -1
  11. package/lib/client/page.js +2 -5
  12. package/lib/client/playwright.js +1 -5
  13. package/lib/client/tracing.js +6 -4
  14. package/lib/client/worker.js +22 -0
  15. package/lib/generated/clockSource.js +1 -1
  16. package/lib/generated/injectedScriptSource.js +1 -1
  17. package/lib/generated/pollingRecorderSource.js +1 -1
  18. package/lib/inProcessFactory.js +0 -2
  19. package/lib/protocol/validator.js +24 -46
  20. package/lib/server/android/android.js +1 -1
  21. package/lib/server/bidi/bidiBrowser.js +26 -11
  22. package/lib/server/bidi/bidiChromium.js +1 -1
  23. package/lib/server/bidi/bidiFirefox.js +1 -1
  24. package/lib/server/bidi/bidiPage.js +25 -5
  25. package/lib/server/browserContext.js +9 -10
  26. package/lib/server/chromium/chromium.js +12 -1
  27. package/lib/server/chromium/chromiumSwitches.js +10 -1
  28. package/lib/server/chromium/crBrowser.js +10 -1
  29. package/lib/server/chromium/crNetworkManager.js +15 -6
  30. package/lib/server/chromium/crPage.js +7 -9
  31. package/lib/server/chromium/crServiceWorker.js +14 -1
  32. package/lib/server/chromium/videoRecorder.js +14 -12
  33. package/lib/server/console.js +5 -1
  34. package/lib/server/deviceDescriptorsSource.json +56 -56
  35. package/lib/server/dispatchers/browserContextDispatcher.js +23 -6
  36. package/lib/server/dispatchers/pageDispatcher.js +10 -22
  37. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  38. package/lib/server/electron/electron.js +1 -1
  39. package/lib/server/firefox/ffPage.js +3 -6
  40. package/lib/server/firefox/firefox.js +12 -1
  41. package/lib/server/frameSelectors.js +2 -4
  42. package/lib/server/frames.js +6 -1
  43. package/lib/server/input.js +7 -3
  44. package/lib/server/localUtils.js +4 -8
  45. package/lib/server/page.js +54 -38
  46. package/lib/server/playwright.js +2 -4
  47. package/lib/server/recorder/recorderApp.js +1 -1
  48. package/lib/server/recorder.js +3 -2
  49. package/lib/server/registry/index.js +114 -48
  50. package/lib/server/registry/oopDownloadBrowserMain.js +6 -2
  51. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  52. package/lib/server/trace/recorder/tracing.js +2 -0
  53. package/lib/server/trace/viewer/traceViewer.js +37 -36
  54. package/lib/server/utils/comparators.js +3 -25
  55. package/lib/server/utils/hostPlatform.js +15 -3
  56. package/lib/server/utils/imageUtils.js +141 -0
  57. package/lib/server/utils/network.js +22 -16
  58. package/lib/server/webkit/webkit.js +1 -10
  59. package/lib/server/webkit/wkPage.js +1 -5
  60. package/lib/server/webkit/wkWorkers.js +2 -1
  61. package/lib/utils/isomorphic/ariaSnapshot.js +5 -0
  62. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  63. package/lib/utils/isomorphic/mimeType.js +1 -1
  64. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  65. package/lib/utils/isomorphic/protocolMetainfo.js +2 -1
  66. package/lib/utils/isomorphic/urlMatch.js +19 -5
  67. package/lib/utils.js +2 -0
  68. package/lib/utilsBundle.js +6 -3
  69. package/lib/utilsBundleImpl/index.js +171 -171
  70. package/lib/vite/htmlReport/index.html +18 -18
  71. package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +25 -0
  72. package/lib/vite/recorder/assets/{index-Y-X2TGJv.js → index-CpZVd2nA.js} +32 -32
  73. package/lib/vite/recorder/index.html +1 -1
  74. package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +25 -0
  75. package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +266 -0
  76. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
  77. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
  78. package/lib/vite/traceViewer/index.C8xAeo93.js +2 -0
  79. package/lib/vite/traceViewer/index.html +6 -6
  80. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  81. package/lib/vite/traceViewer/snapshot.html +3 -3
  82. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  83. package/lib/vite/traceViewer/{uiMode.B_CpmIpF.js → uiMode.BltraIJB.js} +3 -3
  84. package/lib/vite/traceViewer/uiMode.html +3 -3
  85. package/package.json +1 -1
  86. package/types/protocol.d.ts +213 -98
  87. package/types/types.d.ts +122 -118
  88. package/lib/client/accessibility.js +0 -49
  89. package/lib/server/accessibility.js +0 -69
  90. package/lib/server/chromium/crAccessibility.js +0 -263
  91. package/lib/server/firefox/ffAccessibility.js +0 -238
  92. package/lib/server/webkit/wkAccessibility.js +0 -237
  93. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  94. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  95. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  96. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  97. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  98. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  99. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  100. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
@@ -39,15 +39,11 @@ class PlaywrightDispatcher extends import_dispatcher.Dispatcher {
39
39
  const chromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium, denyLaunch);
40
40
  const firefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox, denyLaunch);
41
41
  const webkit = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit, denyLaunch);
42
- const _bidiChromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright._bidiChromium, denyLaunch);
43
- const _bidiFirefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright._bidiFirefox, denyLaunch);
44
42
  const android = new import_androidDispatcher.AndroidDispatcher(scope, playwright.android);
45
43
  const initializer = {
46
44
  chromium,
47
45
  firefox,
48
46
  webkit,
49
- _bidiChromium,
50
- _bidiFirefox,
51
47
  android,
52
48
  electron: new import_electronDispatcher.ElectronDispatcher(scope, playwright.electron, denyLaunch),
53
49
  utils: playwright.options.isServer ? void 0 : new import_localUtilsDispatcher.LocalUtilsDispatcher(scope, playwright),
@@ -97,7 +97,7 @@ class ElectronApplication extends import_instrumentation.SdkObject {
97
97
  if (!this._nodeExecutionContext)
98
98
  return;
99
99
  const args = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(this._nodeExecutionContext, arg));
100
- const message = new import_console.ConsoleMessage(null, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
100
+ const message = new import_console.ConsoleMessage(null, null, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
101
101
  this.emit(ElectronApplication.Events.Console, message);
102
102
  }
103
103
  async initialize() {
@@ -37,7 +37,6 @@ var dialog = __toESM(require("../dialog"));
37
37
  var dom = __toESM(require("../dom"));
38
38
  var import_page = require("../page");
39
39
  var import_page2 = require("../page");
40
- var import_ffAccessibility = require("./ffAccessibility");
41
40
  var import_ffConnection = require("./ffConnection");
42
41
  var import_ffExecutionContext = require("./ffExecutionContext");
43
42
  var import_ffInput = require("./ffInput");
@@ -201,7 +200,7 @@ class FFPage {
201
200
  const context = this._contextIdToContext.get(executionContextId);
202
201
  if (!context)
203
202
  return;
204
- this._page.addConsoleMessage(type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
203
+ this._page.addConsoleMessage(null, type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
205
204
  }
206
205
  _onDialogOpened(params) {
207
206
  this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
@@ -246,11 +245,12 @@ class FFPage {
246
245
  this._page.addWorker(workerId, worker);
247
246
  workerSession.once("Runtime.executionContextCreated", (event2) => {
248
247
  worker.createExecutionContext(new import_ffExecutionContext.FFExecutionContext(workerSession, event2.executionContextId));
248
+ worker.workerScriptLoaded();
249
249
  });
250
250
  workerSession.on("Runtime.console", (event2) => {
251
251
  const { type, args, location } = event2;
252
252
  const context = worker.existingExecutionContext;
253
- this._page.addConsoleMessage(type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
253
+ this._page.addConsoleMessage(worker, type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
254
254
  });
255
255
  }
256
256
  _onWorkerDestroyed(event) {
@@ -468,9 +468,6 @@ class FFPage {
468
468
  throw new Error(dom.kUnableToAdoptErrorMessage);
469
469
  return (0, import_ffExecutionContext.createHandle)(to, result.remoteObject);
470
470
  }
471
- async getAccessibilityTree(needle) {
472
- return (0, import_ffAccessibility.getAccessibilityTree)(this._session, needle);
473
- }
474
471
  async inputActionEpilogue() {
475
472
  }
476
473
  async resetForReuse(progress) {
@@ -39,8 +39,19 @@ var import_ascii = require("../utils/ascii");
39
39
  var import_browserType = require("../browserType");
40
40
  var import_manualPromise = require("../../utils/isomorphic/manualPromise");
41
41
  class Firefox extends import_browserType.BrowserType {
42
- constructor(parent) {
42
+ constructor(parent, bidiFirefox) {
43
43
  super(parent, "firefox");
44
+ this._bidiFirefox = bidiFirefox;
45
+ }
46
+ launch(progress, options, protocolLogger) {
47
+ if (options.channel?.startsWith("moz-"))
48
+ return this._bidiFirefox.launch(progress, options, protocolLogger);
49
+ return super.launch(progress, options, protocolLogger);
50
+ }
51
+ async launchPersistentContext(progress, userDataDir, options) {
52
+ if (options.channel?.startsWith("moz-"))
53
+ return this._bidiFirefox.launchPersistentContext(progress, userDataDir, options);
54
+ return super.launchPersistentContext(progress, userDataDir, options);
44
55
  }
45
56
  connectToTransport(transport, options) {
46
57
  return import_ffBrowser.FFBrowser.connect(this.attribution.playwright, transport, options);
@@ -90,10 +90,8 @@ class FrameSelectors {
90
90
  const match = body.match(/^f(\d+)e\d+$/);
91
91
  if (!match)
92
92
  return frame;
93
- const frameIndex = +match[1];
94
- const page = this.frame._page;
95
- const frameId = page.lastSnapshotFrameIds[frameIndex - 1];
96
- const jumptToFrame = frameId ? page.frameManager.frame(frameId) : null;
93
+ const frameSeq = +match[1];
94
+ const jumptToFrame = this.frame._page.frameManager.frames().find((frame2) => frame2.seq === frameSeq);
97
95
  if (!jumptToFrame)
98
96
  throw new import_selectorParser.InvalidSelectorError(`Invalid frame in aria-ref selector "${selector}"`);
99
97
  return jumptToFrame;
@@ -67,9 +67,13 @@ class FrameManager {
67
67
  this._consoleMessageTags = /* @__PURE__ */ new Map();
68
68
  this._signalBarriers = /* @__PURE__ */ new Set();
69
69
  this._webSockets = /* @__PURE__ */ new Map();
70
+ this._nextFrameSeq = 0;
70
71
  this._page = page;
71
72
  this._mainFrame = void 0;
72
73
  }
74
+ nextFrameSeq() {
75
+ return this._nextFrameSeq++;
76
+ }
73
77
  createDummyMainFrameIfNeeded() {
74
78
  if (!this._mainFrame)
75
79
  this.frameAttached(kDummyFrameId, null);
@@ -363,6 +367,7 @@ class Frame extends import_instrumentation.SdkObject {
363
367
  this._raceAgainstEvaluationStallingEventsPromises = /* @__PURE__ */ new Set();
364
368
  this._redirectedNavigations = /* @__PURE__ */ new Map();
365
369
  this.attribution.frame = this;
370
+ this.seq = page.frameManager.nextFrameSeq();
366
371
  this._id = id;
367
372
  this._page = page;
368
373
  this._parentFrame = parentFrame;
@@ -994,7 +999,7 @@ class Frame extends import_instrumentation.SdkObject {
994
999
  }));
995
1000
  dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
996
1001
  return handle._retryPointerAction(progress, "move and up", false, async (point) => {
997
- await this._page.mouse.move(progress, point.x, point.y);
1002
+ await this._page.mouse.move(progress, point.x, point.y, { steps: options.steps });
998
1003
  await this._page.mouse.up(progress);
999
1004
  }, {
1000
1005
  ...options,
@@ -182,9 +182,9 @@ class Mouse {
182
182
  await this._raw.up(progress, this._x, this._y, button, this._buttons, this._keyboard._modifiers(), clickCount);
183
183
  }
184
184
  async click(progress, x, y, options = {}) {
185
- const { delay = null, clickCount = 1 } = options;
185
+ const { delay = null, clickCount = 1, steps } = options;
186
186
  if (delay) {
187
- this.move(progress, x, y, { forClick: true });
187
+ await this.move(progress, x, y, { forClick: true, steps });
188
188
  for (let cc = 1; cc <= clickCount; ++cc) {
189
189
  await this.down(progress, { ...options, clickCount: cc });
190
190
  await progress.wait(delay);
@@ -194,7 +194,11 @@ class Mouse {
194
194
  }
195
195
  } else {
196
196
  const promises = [];
197
- promises.push(this.move(progress, x, y, { forClick: true }));
197
+ const movePromise = this.move(progress, x, y, { forClick: true, steps });
198
+ if (steps !== void 0 && steps > 1)
199
+ await movePromise;
200
+ else
201
+ promises.push(movePromise);
198
202
  for (let cc = 1; cc <= clickCount; ++cc) {
199
203
  promises.push(this.down(progress, { ...options, clickCount: cc }));
200
204
  promises.push(this.up(progress, { ...options, clickCount: cc }));
@@ -65,12 +65,8 @@ async function zip(progress, stackSessions, params) {
65
65
  const stackSession = params.stacksId ? stackSessions.get(params.stacksId) : void 0;
66
66
  if (stackSession?.callStacks.length) {
67
67
  await progress.race(stackSession.writer);
68
- if (process.env.PW_LIVE_TRACE_STACKS) {
69
- zipFile.addFile(stackSession.file, "trace.stacks");
70
- } else {
71
- const buffer = Buffer.from(JSON.stringify((0, import_traceUtils.serializeClientSideCallMetadata)(stackSession.callStacks)));
72
- zipFile.addBuffer(buffer, "trace.stacks");
73
- }
68
+ const buffer = Buffer.from(JSON.stringify((0, import_traceUtils.serializeClientSideCallMetadata)(stackSession.callStacks)));
69
+ zipFile.addBuffer(buffer, "trace.stacks");
74
70
  }
75
71
  if (params.includeSources) {
76
72
  const sourceFiles = /* @__PURE__ */ new Set();
@@ -188,7 +184,7 @@ async function tracingStarted(progress, stackSessions, params) {
188
184
  if (!params.tracesDir)
189
185
  tmpDir = await progress.race(import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-tracing-")));
190
186
  const traceStacksFile = import_path.default.join(params.tracesDir || tmpDir, params.traceName + ".stacks");
191
- stackSessions.set(traceStacksFile, { callStacks: [], file: traceStacksFile, writer: Promise.resolve(), tmpDir });
187
+ stackSessions.set(traceStacksFile, { callStacks: [], file: traceStacksFile, writer: Promise.resolve(), tmpDir, live: params.live });
192
188
  return { stacksId: traceStacksFile };
193
189
  }
194
190
  async function traceDiscarded(progress, stackSessions, params) {
@@ -197,7 +193,7 @@ async function traceDiscarded(progress, stackSessions, params) {
197
193
  function addStackToTracingNoReply(stackSessions, params) {
198
194
  for (const session of stackSessions.values()) {
199
195
  session.callStacks.push(params.callData);
200
- if (process.env.PW_LIVE_TRACE_STACKS) {
196
+ if (session.live) {
201
197
  session.writer = session.writer.then(() => {
202
198
  const buffer = Buffer.from(JSON.stringify((0, import_traceUtils.serializeClientSideCallMetadata)(session.callStacks)));
203
199
  return import_fs.default.promises.writeFile(session.file, buffer);
@@ -35,7 +35,6 @@ __export(page_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(page_exports);
37
37
  var import_pageBinding = require("./pageBinding");
38
- var accessibility = __toESM(require("./accessibility"));
39
38
  var import_browserContext = require("./browserContext");
40
39
  var import_console = require("./console");
41
40
  var import_errors = require("./errors");
@@ -78,11 +77,9 @@ class Page extends import_instrumentation.SdkObject {
78
77
  // Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
79
78
  // When throttling for tracing, 200ms between frames, except for 10 frames around the action.
80
79
  this._frameThrottler = new FrameThrottler(10, 35, 200);
81
- this.lastSnapshotFrameIds = [];
82
80
  this.attribution.page = this;
83
81
  this.delegate = delegate;
84
82
  this.browserContext = browserContext;
85
- this.accessibility = new accessibility.Accessibility(delegate.getAccessibilityTree.bind(delegate));
86
83
  this.keyboard = new input.Keyboard(delegate.rawKeyboard, this);
87
84
  this.mouse = new input.Mouse(delegate.rawMouse, this);
88
85
  this.touchscreen = new input.Touchscreen(delegate.rawTouchscreen, this);
@@ -243,8 +240,8 @@ class Page extends import_instrumentation.SdkObject {
243
240
  return;
244
241
  await PageBinding.dispatch(this, payload, context);
245
242
  }
246
- addConsoleMessage(type, args, location, text) {
247
- const message = new import_console.ConsoleMessage(this, type, text, args, location);
243
+ addConsoleMessage(worker, type, args, location, text) {
244
+ const message = new import_console.ConsoleMessage(this, worker, type, text, args, location);
248
245
  const intercepted = this.frameManager.interceptConsoleMessage(message);
249
246
  if (intercepted) {
250
247
  args.forEach((arg) => arg.dispose());
@@ -341,6 +338,8 @@ class Page extends import_instrumentation.SdkObject {
341
338
  await this._performWaitForNavigationCheck(progress);
342
339
  }
343
340
  async _performWaitForNavigationCheck(progress) {
341
+ if (process.env.PLAYWRIGHT_SKIP_NAVIGATION_CHECK)
342
+ return;
344
343
  const mainFrame = this.frameManager.mainFrame();
345
344
  if (!mainFrame || !mainFrame.pendingDocument())
346
345
  return;
@@ -571,7 +570,8 @@ class Page extends import_instrumentation.SdkObject {
571
570
  this.closeReason = options.reason;
572
571
  const runBeforeUnload = !!options.runBeforeUnload;
573
572
  if (this._closedState !== "closing") {
574
- this._closedState = "closing";
573
+ if (!runBeforeUnload)
574
+ this._closedState = "closing";
575
575
  await this.delegate.closePage(runBeforeUnload).catch((e) => import_debugLogger.debugLogger.log("error", e));
576
576
  }
577
577
  if (!runBeforeUnload)
@@ -648,10 +648,9 @@ class Page extends import_instrumentation.SdkObject {
648
648
  await Promise.all(this.frames().map((frame) => frame.hideHighlight().catch(() => {
649
649
  })));
650
650
  }
651
- async snapshotForAI(progress) {
652
- this.lastSnapshotFrameIds = [];
653
- const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), 0, this.lastSnapshotFrameIds);
654
- return snapshot.join("\n");
651
+ async snapshotForAI(progress, options) {
652
+ const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), options);
653
+ return { full: snapshot.full.join("\n"), incremental: snapshot.incremental?.join("\n") };
655
654
  }
656
655
  allBindings() {
657
656
  return [...this.browserContext._pageBindings.values(), ...this._pageBindings.values()];
@@ -660,12 +659,11 @@ class Page extends import_instrumentation.SdkObject {
660
659
  class Worker extends import_instrumentation.SdkObject {
661
660
  constructor(parent, url) {
662
661
  super(parent, "worker");
662
+ this._executionContextPromise = new import_manualPromise.ManualPromise();
663
+ this._workerScriptLoaded = false;
663
664
  this.existingExecutionContext = null;
664
665
  this.openScope = new import_utils.LongStandingScope();
665
666
  this.url = url;
666
- this._executionContextCallback = () => {
667
- };
668
- this._executionContextPromise = new Promise((x) => this._executionContextCallback = x);
669
667
  }
670
668
  static {
671
669
  this.Events = {
@@ -674,9 +672,15 @@ class Worker extends import_instrumentation.SdkObject {
674
672
  }
675
673
  createExecutionContext(delegate) {
676
674
  this.existingExecutionContext = new js.ExecutionContext(this, delegate, "worker");
677
- this._executionContextCallback(this.existingExecutionContext);
675
+ if (this._workerScriptLoaded)
676
+ this._executionContextPromise.resolve(this.existingExecutionContext);
678
677
  return this.existingExecutionContext;
679
678
  }
679
+ workerScriptLoaded() {
680
+ this._workerScriptLoaded = true;
681
+ if (this.existingExecutionContext)
682
+ this._executionContextPromise.resolve(this.existingExecutionContext);
683
+ }
680
684
  didClose() {
681
685
  if (this.existingExecutionContext)
682
686
  this.existingExecutionContext.contextDestroyed("Worker was closed");
@@ -790,17 +794,17 @@ class FrameThrottler {
790
794
  }
791
795
  }
792
796
  }
793
- async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
797
+ async function snapshotFrameForAI(progress, frame, options) {
794
798
  const snapshot = await frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
795
799
  try {
796
800
  const context = await progress.race(frame._utilityContext());
797
801
  const injectedScript = await progress.race(context.injectedScript());
798
- const snapshotOrRetry = await progress.race(injectedScript.evaluate((injected, refPrefix) => {
802
+ const snapshotOrRetry = await progress.race(injectedScript.evaluate((injected, options2) => {
799
803
  const node = injected.document.body;
800
804
  if (!node)
801
805
  return true;
802
- return injected.ariaSnapshot(node, { mode: "ai", refPrefix });
803
- }, frameOrdinal ? "f" + frameOrdinal : ""));
806
+ return injected.incrementalAriaSnapshot(node, { mode: "ai", ...options2 });
807
+ }, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track }));
804
808
  if (snapshotOrRetry === true)
805
809
  return continuePolling;
806
810
  return snapshotOrRetry;
@@ -810,33 +814,45 @@ async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
810
814
  return continuePolling;
811
815
  }
812
816
  });
813
- const lines = snapshot.split("\n");
814
- const result = [];
815
- for (const line of lines) {
817
+ const childSnapshotPromises = snapshot.iframeRefs.map((ref) => snapshotFrameRefForAI(progress, frame, ref, options));
818
+ const childSnapshots = await Promise.all(childSnapshotPromises);
819
+ const full = [];
820
+ let incremental;
821
+ if (snapshot.incremental !== void 0) {
822
+ incremental = snapshot.incremental.split("\n");
823
+ for (let i = 0; i < snapshot.iframeRefs.length; i++) {
824
+ const childSnapshot = childSnapshots[i];
825
+ if (childSnapshot.incremental)
826
+ incremental.push(...childSnapshot.incremental);
827
+ else if (childSnapshot.full.length)
828
+ incremental.push("- <changed> iframe [ref=" + snapshot.iframeRefs[i] + "]:", ...childSnapshot.full.map((l) => " " + l));
829
+ }
830
+ }
831
+ for (const line of snapshot.full.split("\n")) {
816
832
  const match = line.match(/^(\s*)- iframe (?:\[active\] )?\[ref=([^\]]*)\]/);
817
833
  if (!match) {
818
- result.push(line);
834
+ full.push(line);
819
835
  continue;
820
836
  }
821
837
  const leadingSpace = match[1];
822
838
  const ref = match[2];
823
- const frameSelector = `aria-ref=${ref} >> internal:control=enter-frame`;
824
- const frameBodySelector = `${frameSelector} >> body`;
825
- const child = await progress.race(frame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true }));
826
- if (!child) {
827
- result.push(line);
828
- continue;
829
- }
830
- const frameOrdinal2 = frameIds.length + 1;
831
- frameIds.push(child.frame._id);
832
- try {
833
- const childSnapshot = await snapshotFrameForAI(progress, child.frame, frameOrdinal2, frameIds);
834
- result.push(line + ":", ...childSnapshot.map((l) => leadingSpace + " " + l));
835
- } catch {
836
- result.push(line);
837
- }
839
+ const childSnapshot = childSnapshots[snapshot.iframeRefs.indexOf(ref)] ?? { full: [] };
840
+ full.push(childSnapshot.full.length ? line + ":" : line);
841
+ full.push(...childSnapshot.full.map((l) => leadingSpace + " " + l));
842
+ }
843
+ return { full, incremental };
844
+ }
845
+ async function snapshotFrameRefForAI(progress, parentFrame, frameRef, options) {
846
+ const frameSelector = `aria-ref=${frameRef} >> internal:control=enter-frame`;
847
+ const frameBodySelector = `${frameSelector} >> body`;
848
+ const child = await progress.race(parentFrame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true }));
849
+ if (!child)
850
+ return { full: [] };
851
+ try {
852
+ return await snapshotFrameForAI(progress, child.frame, options);
853
+ } catch {
854
+ return { full: [] };
838
855
  }
839
- return result;
840
856
  }
841
857
  function ensureArrayLimit(array, limit) {
842
858
  if (array.length > limit)
@@ -45,10 +45,8 @@ class Playwright extends import_instrumentation.SdkObject {
45
45
  onPageOpen: (page) => this._allPages.add(page),
46
46
  onPageClose: (page) => this._allPages.delete(page)
47
47
  }, null);
48
- this.chromium = new import_chromium.Chromium(this);
49
- this._bidiChromium = new import_bidiChromium.BidiChromium(this);
50
- this._bidiFirefox = new import_bidiFirefox.BidiFirefox(this);
51
- this.firefox = new import_firefox.Firefox(this);
48
+ this.chromium = new import_chromium.Chromium(this, new import_bidiChromium.BidiChromium(this));
49
+ this.firefox = new import_firefox.Firefox(this, new import_bidiFirefox.BidiFirefox(this));
52
50
  this.webkit = new import_webkit.WebKit(this);
53
51
  this.electron = new import_electron.Electron(this);
54
52
  this.android = new import_android.Android(this, new import_backendAdb.AdbBackend());
@@ -96,7 +96,7 @@ class RecorderApp {
96
96
  });
97
97
  delete inspectedContext[recorderAppSymbol];
98
98
  });
99
- await this._page.mainFrame().goto(progress, process.env.PW_HMR ? "http://localhost:44225" : "https://playwright/index.html");
99
+ await this._page.mainFrame().goto(progress, "https://playwright/index.html");
100
100
  });
101
101
  const url = this._recorder.url();
102
102
  if (url)
@@ -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);