brave-real-playwright-core 1.56.1 → 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 (96) hide show
  1. package/README.md +5 -5
  2. package/advanced-stealth.js +1 -1
  3. package/lib/cli/program.js +14 -57
  4. package/lib/client/api.js +0 -3
  5. package/lib/client/browserContext.js +22 -4
  6. package/lib/client/consoleMessage.js +5 -1
  7. package/lib/client/electron.js +1 -1
  8. package/lib/client/events.js +2 -1
  9. package/lib/client/locator.js +4 -1
  10. package/lib/client/page.js +2 -5
  11. package/lib/client/playwright.js +1 -5
  12. package/lib/client/tracing.js +6 -4
  13. package/lib/client/worker.js +22 -0
  14. package/lib/generated/clockSource.js +1 -1
  15. package/lib/generated/injectedScriptSource.js +1 -1
  16. package/lib/generated/pollingRecorderSource.js +1 -1
  17. package/lib/inProcessFactory.js +0 -2
  18. package/lib/protocol/validator.js +24 -46
  19. package/lib/server/android/android.js +1 -1
  20. package/lib/server/bidi/bidiBrowser.js +26 -11
  21. package/lib/server/bidi/bidiChromium.js +1 -1
  22. package/lib/server/bidi/bidiFirefox.js +1 -1
  23. package/lib/server/bidi/bidiPage.js +25 -5
  24. package/lib/server/browserContext.js +9 -10
  25. package/lib/server/chromium/chromium.js +12 -1
  26. package/lib/server/chromium/chromiumSwitches.js +11 -2
  27. package/lib/server/chromium/crBrowser.js +8 -0
  28. package/lib/server/chromium/crPage.js +7 -7
  29. package/lib/server/chromium/crServiceWorker.js +16 -5
  30. package/lib/server/chromium/videoRecorder.js +14 -12
  31. package/lib/server/console.js +5 -1
  32. package/lib/server/deviceDescriptorsSource.json +56 -56
  33. package/lib/server/dispatchers/browserContextDispatcher.js +23 -6
  34. package/lib/server/dispatchers/pageDispatcher.js +10 -22
  35. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  36. package/lib/server/electron/electron.js +1 -1
  37. package/lib/server/firefox/ffPage.js +3 -6
  38. package/lib/server/firefox/firefox.js +12 -1
  39. package/lib/server/frameSelectors.js +2 -4
  40. package/lib/server/frames.js +10 -3
  41. package/lib/server/input.js +7 -3
  42. package/lib/server/localUtils.js +4 -8
  43. package/lib/server/page.js +54 -40
  44. package/lib/server/playwright.js +2 -4
  45. package/lib/server/recorder/recorderApp.js +1 -1
  46. package/lib/server/recorder.js +3 -2
  47. package/lib/server/registry/index.js +113 -47
  48. package/lib/server/registry/oopDownloadBrowserMain.js +6 -2
  49. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  50. package/lib/server/trace/recorder/tracing.js +2 -0
  51. package/lib/server/trace/viewer/traceViewer.js +37 -36
  52. package/lib/server/utils/comparators.js +3 -25
  53. package/lib/server/utils/hostPlatform.js +15 -3
  54. package/lib/server/utils/imageUtils.js +141 -0
  55. package/lib/server/utils/network.js +22 -16
  56. package/lib/server/webkit/webkit.js +1 -10
  57. package/lib/server/webkit/wkPage.js +1 -5
  58. package/lib/server/webkit/wkWorkers.js +2 -1
  59. package/lib/utils/isomorphic/ariaSnapshot.js +5 -0
  60. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  61. package/lib/utils/isomorphic/mimeType.js +1 -1
  62. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  63. package/lib/utils/isomorphic/protocolMetainfo.js +2 -1
  64. package/lib/utils/isomorphic/urlMatch.js +19 -5
  65. package/lib/utils.js +2 -0
  66. package/lib/utilsBundle.js +6 -3
  67. package/lib/utilsBundleImpl/index.js +171 -171
  68. package/lib/vite/htmlReport/index.html +18 -18
  69. package/lib/vite/recorder/assets/codeMirrorModule-BoWUGj0J.js +25 -0
  70. package/lib/vite/recorder/assets/{index-Y-X2TGJv.js → index-DJqDAOZp.js} +32 -32
  71. package/lib/vite/recorder/index.html +1 -1
  72. package/lib/vite/traceViewer/assets/codeMirrorModule-Bucv2d7q.js +25 -0
  73. package/lib/vite/traceViewer/assets/defaultSettingsView-BEpdCv1S.js +266 -0
  74. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
  75. package/lib/vite/traceViewer/index.BxQ34UMZ.js +2 -0
  76. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
  77. package/lib/vite/traceViewer/index.html +6 -6
  78. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  79. package/lib/vite/traceViewer/snapshot.html +3 -3
  80. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  81. package/lib/vite/traceViewer/{uiMode.DRQ310U5.js → uiMode.BWTwXl41.js} +3 -3
  82. package/lib/vite/traceViewer/uiMode.html +3 -3
  83. package/package.json +9 -9
  84. package/lib/client/accessibility.js +0 -49
  85. package/lib/server/accessibility.js +0 -69
  86. package/lib/server/chromium/crAccessibility.js +0 -263
  87. package/lib/server/firefox/ffAccessibility.js +0 -238
  88. package/lib/server/webkit/wkAccessibility.js +0 -237
  89. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  90. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  91. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  92. package/lib/vite/traceViewer/assets/codeMirrorModule-eyVcHN77.js +0 -24
  93. package/lib/vite/traceViewer/assets/defaultSettingsView-w0zYjHsW.js +0 -265
  94. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  95. package/lib/vite/traceViewer/index.Bx16ehp1.js +0 -2
  96. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
@@ -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);
@@ -89,10 +89,8 @@ class FrameSelectors {
89
89
  const match = body.match(/^f(\d+)e\d+$/);
90
90
  if (!match)
91
91
  return frame;
92
- const frameIndex = +match[1];
93
- const page = this.frame._page;
94
- const frameId = page.lastSnapshotFrameIds[frameIndex - 1];
95
- const jumptToFrame = frameId ? page.frameManager.frame(frameId) : null;
92
+ const frameSeq = +match[1];
93
+ const jumptToFrame = this.frame._page.frameManager.frames().find((frame2) => frame2.seq === frameSeq);
96
94
  if (!jumptToFrame)
97
95
  throw new import_selectorParser.InvalidSelectorError(`Invalid frame in aria-ref selector "${selector}"`);
98
96
  return jumptToFrame;
@@ -65,9 +65,13 @@ class FrameManager {
65
65
  this._consoleMessageTags = /* @__PURE__ */ new Map();
66
66
  this._signalBarriers = /* @__PURE__ */ new Set();
67
67
  this._webSockets = /* @__PURE__ */ new Map();
68
+ this._nextFrameSeq = 0;
68
69
  this._page = page;
69
70
  this._mainFrame = void 0;
70
71
  }
72
+ nextFrameSeq() {
73
+ return this._nextFrameSeq++;
74
+ }
71
75
  createDummyMainFrameIfNeeded() {
72
76
  if (!this._mainFrame)
73
77
  this.frameAttached(kDummyFrameId, null);
@@ -361,6 +365,7 @@ class Frame extends import_instrumentation.SdkObject {
361
365
  this._raceAgainstEvaluationStallingEventsPromises = /* @__PURE__ */ new Set();
362
366
  this._redirectedNavigations = /* @__PURE__ */ new Map();
363
367
  this.attribution.frame = this;
368
+ this.seq = page.frameManager.nextFrameSeq();
364
369
  this._id = id;
365
370
  this._page = page;
366
371
  this._parentFrame = parentFrame;
@@ -989,7 +994,7 @@ class Frame extends import_instrumentation.SdkObject {
989
994
  }));
990
995
  dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
991
996
  return handle._retryPointerAction(progress, "move and up", false, async (point) => {
992
- await this._page.mouse.move(progress, point.x, point.y);
997
+ await this._page.mouse.move(progress, point.x, point.y, { steps: options.steps });
993
998
  await this._page.mouse.up(progress);
994
999
  }, {
995
1000
  ...options,
@@ -1220,10 +1225,12 @@ class Frame extends import_instrumentation.SdkObject {
1220
1225
  if (log)
1221
1226
  progress.log(log);
1222
1227
  if (matches === options.isNot) {
1223
- if (missingReceived)
1228
+ if (missingReceived) {
1224
1229
  lastIntermediateResult.errorMessage = "Error: element(s) not found";
1225
- else
1230
+ } else {
1231
+ lastIntermediateResult.errorMessage = void 0;
1226
1232
  lastIntermediateResult.received = received;
1233
+ }
1227
1234
  lastIntermediateResult.isSet = true;
1228
1235
  if (!missingReceived && !Array.isArray(received))
1229
1236
  progress.log(` unexpected value "${renderUnexpectedValue(options.expression, received)}"`);
@@ -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);
@@ -34,7 +34,6 @@ __export(page_exports, {
34
34
  Worker: () => Worker
35
35
  });
36
36
  module.exports = __toCommonJS(page_exports);
37
- var accessibility = __toESM(require("./accessibility"));
38
37
  var import_browserContext = require("./browserContext");
39
38
  var import_console = require("./console");
40
39
  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);
@@ -253,8 +250,8 @@ class Page extends import_instrumentation.SdkObject {
253
250
  return;
254
251
  await PageBinding.dispatch(this, payload, context);
255
252
  }
256
- addConsoleMessage(type, args, location, text) {
257
- const message = new import_console.ConsoleMessage(this, type, text, args, location);
253
+ addConsoleMessage(worker, type, args, location, text) {
254
+ const message = new import_console.ConsoleMessage(this, worker, type, text, args, location);
258
255
  const intercepted = this.frameManager.interceptConsoleMessage(message);
259
256
  if (intercepted) {
260
257
  args.forEach((arg) => arg.dispose());
@@ -351,6 +348,8 @@ class Page extends import_instrumentation.SdkObject {
351
348
  await this._performWaitForNavigationCheck(progress);
352
349
  }
353
350
  async _performWaitForNavigationCheck(progress) {
351
+ if (process.env.PLAYWRIGHT_SKIP_NAVIGATION_CHECK)
352
+ return;
354
353
  const mainFrame = this.frameManager.mainFrame();
355
354
  if (!mainFrame || !mainFrame.pendingDocument())
356
355
  return;
@@ -582,7 +581,8 @@ class Page extends import_instrumentation.SdkObject {
582
581
  this.closeReason = options.reason;
583
582
  const runBeforeUnload = !!options.runBeforeUnload;
584
583
  if (this._closedState !== "closing") {
585
- this._closedState = "closing";
584
+ if (!runBeforeUnload)
585
+ this._closedState = "closing";
586
586
  await this.delegate.closePage(runBeforeUnload).catch((e) => import_debugLogger.debugLogger.log("error", e));
587
587
  }
588
588
  if (!runBeforeUnload)
@@ -665,23 +665,19 @@ class Page extends import_instrumentation.SdkObject {
665
665
  await Promise.all(this.frames().map((frame) => frame.hideHighlight().catch(() => {
666
666
  })));
667
667
  }
668
- async snapshotForAI(progress) {
669
- this.lastSnapshotFrameIds = [];
670
- const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), 0, this.lastSnapshotFrameIds);
671
- return snapshot.join("\n");
668
+ async snapshotForAI(progress, options) {
669
+ const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), options);
670
+ return { full: snapshot.full.join("\n"), incremental: snapshot.incremental?.join("\n") };
672
671
  }
673
672
  }
674
673
  class Worker extends import_instrumentation.SdkObject {
675
674
  constructor(parent, url, targetId, session) {
676
675
  super(parent, "worker");
676
+ this._executionContextPromise = new import_manualPromise.ManualPromise();
677
+ this._workerScriptLoaded = false;
677
678
  this.existingExecutionContext = null;
678
679
  this.openScope = new import_utils.LongStandingScope();
679
680
  this.url = url;
680
- this._executionContextCallback = () => {
681
- };
682
- this._executionContextPromise = new Promise((x) => this._executionContextCallback = x);
683
- this._targetId = targetId;
684
- this._session = session;
685
681
  }
686
682
  static {
687
683
  this.Events = {
@@ -690,9 +686,15 @@ class Worker extends import_instrumentation.SdkObject {
690
686
  }
691
687
  createExecutionContext(delegate) {
692
688
  this.existingExecutionContext = new js.ExecutionContext(this, delegate, "worker");
693
- this._executionContextCallback(this.existingExecutionContext);
689
+ if (this._workerScriptLoaded)
690
+ this._executionContextPromise.resolve(this.existingExecutionContext);
694
691
  return this.existingExecutionContext;
695
692
  }
693
+ workerScriptLoaded() {
694
+ this._workerScriptLoaded = true;
695
+ if (this.existingExecutionContext)
696
+ this._executionContextPromise.resolve(this.existingExecutionContext);
697
+ }
696
698
  didClose() {
697
699
  if (this.existingExecutionContext)
698
700
  this.existingExecutionContext.contextDestroyed("Worker was closed");
@@ -822,17 +824,17 @@ class FrameThrottler {
822
824
  }
823
825
  }
824
826
  }
825
- async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
827
+ async function snapshotFrameForAI(progress, frame, options) {
826
828
  const snapshot = await frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
827
829
  try {
828
830
  const context = await progress.race(frame._utilityContext());
829
831
  const injectedScript = await progress.race(context.injectedScript());
830
- const snapshotOrRetry = await progress.race(injectedScript.evaluate((injected, refPrefix) => {
832
+ const snapshotOrRetry = await progress.race(injectedScript.evaluate((injected, options2) => {
831
833
  const node = injected.document.body;
832
834
  if (!node)
833
835
  return true;
834
- return injected.ariaSnapshot(node, { mode: "ai", refPrefix });
835
- }, frameOrdinal ? "f" + frameOrdinal : ""));
836
+ return injected.incrementalAriaSnapshot(node, { mode: "ai", ...options2 });
837
+ }, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track }));
836
838
  if (snapshotOrRetry === true)
837
839
  return continuePolling;
838
840
  return snapshotOrRetry;
@@ -842,33 +844,45 @@ async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
842
844
  return continuePolling;
843
845
  }
844
846
  });
845
- const lines = snapshot.split("\n");
846
- const result = [];
847
- for (const line of lines) {
847
+ const childSnapshotPromises = snapshot.iframeRefs.map((ref) => snapshotFrameRefForAI(progress, frame, ref, options));
848
+ const childSnapshots = await Promise.all(childSnapshotPromises);
849
+ const full = [];
850
+ let incremental;
851
+ if (snapshot.incremental !== void 0) {
852
+ incremental = snapshot.incremental.split("\n");
853
+ for (let i = 0; i < snapshot.iframeRefs.length; i++) {
854
+ const childSnapshot = childSnapshots[i];
855
+ if (childSnapshot.incremental)
856
+ incremental.push(...childSnapshot.incremental);
857
+ else if (childSnapshot.full.length)
858
+ incremental.push("- <changed> iframe [ref=" + snapshot.iframeRefs[i] + "]:", ...childSnapshot.full.map((l) => " " + l));
859
+ }
860
+ }
861
+ for (const line of snapshot.full.split("\n")) {
848
862
  const match = line.match(/^(\s*)- iframe (?:\[active\] )?\[ref=([^\]]*)\]/);
849
863
  if (!match) {
850
- result.push(line);
864
+ full.push(line);
851
865
  continue;
852
866
  }
853
867
  const leadingSpace = match[1];
854
868
  const ref = match[2];
855
- const frameSelector = `aria-ref=${ref} >> internal:control=enter-frame`;
856
- const frameBodySelector = `${frameSelector} >> body`;
857
- const child = await progress.race(frame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true }));
858
- if (!child) {
859
- result.push(line);
860
- continue;
861
- }
862
- const frameOrdinal2 = frameIds.length + 1;
863
- frameIds.push(child.frame._id);
864
- try {
865
- const childSnapshot = await snapshotFrameForAI(progress, child.frame, frameOrdinal2, frameIds);
866
- result.push(line + ":", ...childSnapshot.map((l) => leadingSpace + " " + l));
867
- } catch {
868
- result.push(line);
869
- }
869
+ const childSnapshot = childSnapshots[snapshot.iframeRefs.indexOf(ref)] ?? { full: [] };
870
+ full.push(childSnapshot.full.length ? line + ":" : line);
871
+ full.push(...childSnapshot.full.map((l) => leadingSpace + " " + l));
872
+ }
873
+ return { full, incremental };
874
+ }
875
+ async function snapshotFrameRefForAI(progress, parentFrame, frameRef, options) {
876
+ const frameSelector = `aria-ref=${frameRef} >> internal:control=enter-frame`;
877
+ const frameBodySelector = `${frameSelector} >> body`;
878
+ const child = await progress.race(parentFrame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true }));
879
+ if (!child)
880
+ return { full: [] };
881
+ try {
882
+ return await snapshotFrameForAI(progress, child.frame, options);
883
+ } catch {
884
+ return { full: [] };
870
885
  }
871
- return result;
872
886
  }
873
887
  function ensureArrayLimit(array, limit) {
874
888
  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);