brave-real-playwright-core 1.55.1-patch.1 → 1.56.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 (94) hide show
  1. package/README.md +5 -5
  2. package/advanced-stealth.js +1 -1
  3. package/lib/browserServerImpl.js +3 -6
  4. package/lib/client/browser.js +0 -10
  5. package/lib/client/browserContext.js +2 -8
  6. package/lib/client/channelOwner.js +0 -7
  7. package/lib/client/consoleMessage.js +2 -3
  8. package/lib/client/electron.js +1 -1
  9. package/lib/client/events.js +1 -0
  10. package/lib/client/network.js +3 -0
  11. package/lib/client/page.js +13 -1
  12. package/lib/generated/bindingsControllerSource.js +1 -1
  13. package/lib/generated/injectedScriptSource.js +1 -1
  14. package/lib/generated/pollingRecorderSource.js +1 -1
  15. package/lib/generated/utilityScriptSource.js +1 -1
  16. package/lib/protocol/validator.js +26 -15
  17. package/lib/remote/playwrightServer.js +12 -14
  18. package/lib/server/bidi/bidiBrowser.js +54 -10
  19. package/lib/server/bidi/bidiChromium.js +1 -1
  20. package/lib/server/bidi/bidiConnection.js +31 -6
  21. package/lib/server/bidi/bidiExecutionContext.js +4 -4
  22. package/lib/server/bidi/bidiFirefox.js +16 -1
  23. package/lib/server/bidi/bidiNetworkManager.js +82 -16
  24. package/lib/server/bidi/bidiPage.js +84 -18
  25. package/lib/server/browserType.js +3 -3
  26. package/lib/server/chromium/chromium.js +1 -1
  27. package/lib/server/chromium/chromiumSwitches.js +3 -1
  28. package/lib/server/chromium/crBrowser.js +2 -33
  29. package/lib/server/chromium/crPage.js +22 -31
  30. package/lib/server/codegen/csharp.js +19 -26
  31. package/lib/server/codegen/java.js +4 -0
  32. package/lib/server/codegen/javascript.js +3 -1
  33. package/lib/server/codegen/python.js +2 -0
  34. package/lib/server/debugController.js +8 -36
  35. package/lib/server/deviceDescriptorsSource.json +62 -62
  36. package/lib/server/dispatchers/androidDispatcher.js +17 -0
  37. package/lib/server/dispatchers/browserContextDispatcher.js +1 -15
  38. package/lib/server/dispatchers/networkDispatchers.js +6 -3
  39. package/lib/server/dispatchers/pageDispatcher.js +24 -0
  40. package/lib/server/dom.js +8 -3
  41. package/lib/server/firefox/ffPage.js +1 -2
  42. package/lib/server/firefox/firefox.js +1 -1
  43. package/lib/server/frames.js +12 -4
  44. package/lib/server/har/harTracer.js +7 -8
  45. package/lib/server/network.js +12 -0
  46. package/lib/server/page.js +39 -17
  47. package/lib/server/recorder/chat.js +2 -2
  48. package/lib/server/recorder/recorderRunner.js +4 -0
  49. package/lib/server/registry/browserFetcher.js +3 -3
  50. package/lib/server/registry/index.js +27 -0
  51. package/lib/server/trace/recorder/snapshotter.js +13 -2
  52. package/lib/server/trace/recorder/snapshotterInjected.js +3 -1
  53. package/lib/server/utils/comparators.js +2 -2
  54. package/lib/server/utils/env.js +7 -2
  55. package/lib/server/utils/wsServer.js +2 -7
  56. package/lib/server/webkit/webkit.js +24 -8
  57. package/lib/server/webkit/wkBrowser.js +7 -3
  58. package/lib/server/webkit/wkPage.js +7 -8
  59. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +74 -0
  60. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +113 -0
  61. package/lib/utils/isomorphic/ariaSnapshot.js +12 -10
  62. package/lib/utils/isomorphic/protocolMetainfo.js +3 -0
  63. package/lib/utils/isomorphic/urlMatch.js +3 -8
  64. package/lib/utilsBundle.js +3 -0
  65. package/lib/utilsBundleImpl/index.js +80 -80
  66. package/lib/vite/htmlReport/index.html +37 -28
  67. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +24 -0
  68. package/lib/vite/recorder/assets/index-Ri0uHF7I.css +1 -0
  69. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +193 -0
  70. package/lib/vite/recorder/index.html +2 -2
  71. package/lib/vite/traceViewer/assets/codeMirrorModule-eyVcHN77.js +24 -0
  72. package/lib/vite/traceViewer/assets/defaultSettingsView-w0zYjHsW.js +265 -0
  73. package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
  74. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +1 -0
  75. package/lib/vite/traceViewer/index.Bx16ehp1.js +2 -0
  76. package/lib/vite/traceViewer/index.I8N9v4jT.css +1 -0
  77. package/lib/vite/traceViewer/index.html +4 -4
  78. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  79. package/lib/vite/traceViewer/uiMode.Btcz36p_.css +1 -0
  80. package/lib/vite/traceViewer/uiMode.DRQ310U5.js +5 -0
  81. package/lib/vite/traceViewer/uiMode.html +4 -4
  82. package/lib/vite/traceViewer/{xtermModule.Beg8tuEN.css → xtermModule.DYP7pi_n.css} +1 -1
  83. package/package.json +9 -9
  84. package/lib/vite/recorder/assets/codeMirrorModule-DzQ0k89p.js +0 -24
  85. package/lib/vite/recorder/assets/index-CI4HQ-Zb.css +0 -1
  86. package/lib/vite/recorder/assets/index-D7C7daHH.js +0 -184
  87. package/lib/vite/traceViewer/assets/codeMirrorModule-CEFqZ5b3.js +0 -24
  88. package/lib/vite/traceViewer/assets/defaultSettingsView-BA25Usqk.js +0 -256
  89. package/lib/vite/traceViewer/assets/xtermModule-BoAIEibi.js +0 -9
  90. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +0 -1
  91. package/lib/vite/traceViewer/index.BFsek2M6.css +0 -1
  92. package/lib/vite/traceViewer/index.CheexZ4_.js +0 -2
  93. package/lib/vite/traceViewer/uiMode.BatfzHMG.css +0 -1
  94. package/lib/vite/traceViewer/uiMode.Dy4dnPNW.js +0 -5
@@ -51,7 +51,6 @@ class CRBrowser extends import_browser.Browser {
51
51
  this._clientRootSessionPromise = null;
52
52
  this._contexts = /* @__PURE__ */ new Map();
53
53
  this._crPages = /* @__PURE__ */ new Map();
54
- this._backgroundPages = /* @__PURE__ */ new Map();
55
54
  this._serviceWorkers = /* @__PURE__ */ new Map();
56
55
  this._version = "";
57
56
  this._tracingRecording = false;
@@ -133,7 +132,7 @@ class CRBrowser extends import_browser.Browser {
133
132
  async _waitForAllPagesToBeInitialized() {
134
133
  await Promise.all([...this._crPages.values()].map((crPage) => crPage._page.waitForInitializedOrError()));
135
134
  }
136
- _onAttachedToTarget({ targetInfo, sessionId }) {
135
+ _onAttachedToTarget({ targetInfo, sessionId, waitingForDebugger }) {
137
136
  if (targetInfo.type === "browser")
138
137
  return;
139
138
  const session = this._session.createChildSession(sessionId);
@@ -153,16 +152,10 @@ class CRBrowser extends import_browser.Browser {
153
152
  return;
154
153
  }
155
154
  (0, import_assert.assert)(!this._crPages.has(targetInfo.targetId), "Duplicate target " + targetInfo.targetId);
156
- (0, import_assert.assert)(!this._backgroundPages.has(targetInfo.targetId), "Duplicate target " + targetInfo.targetId);
157
155
  (0, import_assert.assert)(!this._serviceWorkers.has(targetInfo.targetId), "Duplicate target " + targetInfo.targetId);
158
- if (targetInfo.type === "background_page") {
159
- const backgroundPage = new import_crPage.CRPage(session, targetInfo.targetId, context, null, { hasUIWindow: false, isBackgroundPage: true });
160
- this._backgroundPages.set(targetInfo.targetId, backgroundPage);
161
- return;
162
- }
163
156
  if (targetInfo.type === "page" || treatOtherAsPage) {
164
157
  const opener = targetInfo.openerId ? this._crPages.get(targetInfo.openerId) || null : null;
165
- const crPage = new import_crPage.CRPage(session, targetInfo.targetId, context, opener, { hasUIWindow: targetInfo.type === "page", isBackgroundPage: false });
158
+ const crPage = new import_crPage.CRPage(session, targetInfo.targetId, context, opener, { hasUIWindow: targetInfo.type === "page" });
166
159
  this._crPages.set(targetInfo.targetId, crPage);
167
160
  return;
168
161
  }
@@ -183,12 +176,6 @@ class CRBrowser extends import_browser.Browser {
183
176
  crPage.didClose();
184
177
  return;
185
178
  }
186
- const backgroundPage = this._backgroundPages.get(targetId);
187
- if (backgroundPage) {
188
- this._backgroundPages.delete(targetId);
189
- backgroundPage.didClose();
190
- return;
191
- }
192
179
  const serviceWorker = this._serviceWorkers.get(targetId);
193
180
  if (serviceWorker) {
194
181
  this._serviceWorkers.delete(targetId);
@@ -200,9 +187,6 @@ class CRBrowser extends import_browser.Browser {
200
187
  for (const crPage of this._crPages.values())
201
188
  crPage.didClose();
202
189
  this._crPages.clear();
203
- for (const backgroundPage of this._backgroundPages.values())
204
- backgroundPage.didClose();
205
- this._backgroundPages.clear();
206
190
  for (const serviceWorker of this._serviceWorkers.values())
207
191
  serviceWorker.didClose();
208
192
  this._serviceWorkers.clear();
@@ -295,7 +279,6 @@ class CRBrowser extends import_browser.Browser {
295
279
  class CRBrowserContext extends import_browserContext.BrowserContext {
296
280
  static {
297
281
  this.CREvents = {
298
- BackgroundPage: "backgroundpage",
299
282
  ServiceWorker: "serviceworker"
300
283
  };
301
284
  }
@@ -481,12 +464,6 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
481
464
  await Promise.all(this._crPages().map((crPage) => crPage._mainFrameSession._stopVideoRecording()));
482
465
  }
483
466
  onClosePersistent() {
484
- for (const [targetId, backgroundPage] of this._browser._backgroundPages.entries()) {
485
- if (backgroundPage._browserContext === this && backgroundPage._page.initializedOrUndefined()) {
486
- backgroundPage.didClose();
487
- this._browser._backgroundPages.delete(targetId);
488
- }
489
- }
490
467
  }
491
468
  async clearCache() {
492
469
  for (const page of this._crPages())
@@ -498,14 +475,6 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
498
475
  browserContextId: this._browserContextId
499
476
  });
500
477
  }
501
- backgroundPages() {
502
- const result = [];
503
- for (const backgroundPage of this._browser._backgroundPages.values()) {
504
- if (backgroundPage._browserContext === this && backgroundPage._page.initializedOrUndefined())
505
- result.push(backgroundPage._page);
506
- }
507
- return result;
508
- }
509
478
  serviceWorkers() {
510
479
  return Array.from(this._browser._serviceWorkers.values()).filter((serviceWorker) => serviceWorker.browserContext === this);
511
480
  }
@@ -44,7 +44,6 @@ var network = __toESM(require("../network"));
44
44
  var import_page = require("../page");
45
45
  var import_registry = require("../registry");
46
46
  var import_crAccessibility = require("./crAccessibility");
47
- var import_crBrowser = require("./crBrowser");
48
47
  var import_crCoverage = require("./crCoverage");
49
48
  var import_crDragDrop = require("./crDragDrop");
50
49
  var import_crExecutionContext = require("./crExecutionContext");
@@ -54,7 +53,6 @@ var import_crPdf = require("./crPdf");
54
53
  var import_crProtocolHelper = require("./crProtocolHelper");
55
54
  var import_defaultFontFamilies = require("./defaultFontFamilies");
56
55
  var import_videoRecorder = require("./videoRecorder");
57
- var import_browserContext = require("../browserContext");
58
56
  var import_errors = require("../errors");
59
57
  var import_protocolError = require("../protocolError");
60
58
  class CRPage {
@@ -68,7 +66,6 @@ class CRPage {
68
66
  this._nextWindowOpenPopupFeatures = [];
69
67
  this._targetId = targetId;
70
68
  this._opener = opener;
71
- this._isBackgroundPage = bits.isBackgroundPage;
72
69
  const dragManager = new import_crDragDrop.DragManager(this);
73
70
  this.rawKeyboard = new import_crInput.RawKeyboardImpl(client, browserContext._browser._platform() === "mac", dragManager);
74
71
  this.rawMouse = new import_crInput.RawMouseImpl(this, client, dragManager);
@@ -91,10 +88,9 @@ class CRPage {
91
88
  if (viewportSize)
92
89
  this._page.setEmulatedSizeFromWindowOpen({ viewport: viewportSize, screen: viewportSize });
93
90
  }
94
- const createdEvent = this._isBackgroundPage ? import_crBrowser.CRBrowserContext.CREvents.BackgroundPage : import_browserContext.BrowserContext.Events.Page;
95
91
  this._mainFrameSession._initialize(bits.hasUIWindow).then(
96
- () => this._page.reportAsNew(this._opener?._page, void 0, createdEvent),
97
- (error) => this._page.reportAsNew(this._opener?._page, error, createdEvent)
92
+ () => this._page.reportAsNew(this._opener?._page, void 0),
93
+ (error) => this._page.reportAsNew(this._opener?._page, error)
98
94
  );
99
95
  }
100
96
  static mainFrameSession(page) {
@@ -356,13 +352,13 @@ class FrameSession {
356
352
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.exceptionThrown", (exception) => this._handleException(exception.exceptionDetails)),
357
353
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextCreated", (event) => this._onExecutionContextCreated(event.context)),
358
354
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextDestroyed", (event) => this._onExecutionContextDestroyed(event.executionContextId)),
359
- import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", (event) => this._onExecutionContextsCleared()),
360
- import_eventsHelper.eventsHelper.addEventListener(this._client, "Target.attachedToTarget", (event) => this._onAttachedToTarget(event)),
361
- import_eventsHelper.eventsHelper.addEventListener(this._client, "Target.detachedFromTarget", (event) => this._onDetachedFromTarget(event))
355
+ import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", (event) => this._onExecutionContextsCleared())
362
356
  ]);
363
357
  }
364
358
  _addBrowserListeners() {
365
359
  this._eventListeners.push(...[
360
+ import_eventsHelper.eventsHelper.addEventListener(this._client, "Target.attachedToTarget", (event) => this._onAttachedToTarget(event)),
361
+ import_eventsHelper.eventsHelper.addEventListener(this._client, "Target.detachedFromTarget", (event) => this._onDetachedFromTarget(event)),
366
362
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Inspector.targetCrashed", (event) => this._onTargetCrashed()),
367
363
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.screencastFrame", (event) => this._onScreencastFrame(event)),
368
364
  import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.windowOpen", (event) => this._onWindowOpen(event))
@@ -394,6 +390,7 @@ class FrameSession {
394
390
  if (!this._isMainFrame())
395
391
  this._addRendererListeners();
396
392
  this._addBrowserListeners();
393
+ this._bufferedAttachedToTargetEvents = [];
397
394
  const promises = [
398
395
  this._client.send("Page.enable"),
399
396
  this._client.send("Page.getFrameTree").then(({ frameTree }) => {
@@ -401,6 +398,10 @@ class FrameSession {
401
398
  this._handleFrameTree(frameTree);
402
399
  this._addRendererListeners();
403
400
  }
401
+ const attachedToTargetEvents = this._bufferedAttachedToTargetEvents || [];
402
+ this._bufferedAttachedToTargetEvents = void 0;
403
+ for (const event of attachedToTargetEvents)
404
+ this._onAttachedToTarget(event);
404
405
  const localFrames = this._isMainFrame() ? this._page.frames() : [this._page.frameManager.frame(this._targetId)];
405
406
  for (const frame of localFrames) {
406
407
  this._client._sendMayFail("Page.createIsolatedWorld", {
@@ -428,16 +429,7 @@ class FrameSession {
428
429
  worldName: this._crPage.utilityWorldName
429
430
  }),
430
431
  this._crPage._networkManager.addSession(this._client, void 0, this._isMainFrame()),
431
- this._client.send("Target.setAutoAttach", {
432
- autoAttach: true,
433
- waitForDebuggerOnStart: true,
434
- flatten: true,
435
- filter: [
436
- { type: "iframe" },
437
- { type: "worker" },
438
- { type: "service_worker", exclude: !process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS }
439
- ]
440
- })
432
+ this._client.send("Target.setAutoAttach", { autoAttach: true, waitForDebuggerOnStart: true, flatten: true })
441
433
  ];
442
434
  if (!this._page.isStorageStatePage) {
443
435
  if (this._crPage._browserContext.needsPlaywrightBinding())
@@ -593,10 +585,17 @@ class FrameSession {
593
585
  this._onExecutionContextDestroyed(contextId);
594
586
  }
595
587
  _onAttachedToTarget(event) {
588
+ if (this._bufferedAttachedToTargetEvents) {
589
+ this._bufferedAttachedToTargetEvents.push(event);
590
+ return;
591
+ }
596
592
  const session = this._client.createChildSession(event.sessionId);
597
593
  if (event.targetInfo.type === "iframe") {
598
594
  const targetId = event.targetInfo.targetId;
599
- const frame = this._page.frameManager.frame(targetId);
595
+ let frame = this._page.frameManager.frame(targetId);
596
+ if (!frame && event.targetInfo.parentFrameId) {
597
+ frame = this._page.frameManager.frameAttached(targetId, event.targetInfo.parentFrameId);
598
+ }
600
599
  if (!frame)
601
600
  return;
602
601
  this._page.frameManager.removeChildFramesRecursively(frame);
@@ -625,22 +624,14 @@ class FrameSession {
625
624
  this._crPage._networkManager.addSession(session, this._page.frameManager.frame(this._targetId) ?? void 0).catch(() => {
626
625
  });
627
626
  session._sendMayFail("Runtime.runIfWaitingForDebugger");
628
- session._sendMayFail("Target.setAutoAttach", {
629
- autoAttach: true,
630
- waitForDebuggerOnStart: true,
631
- flatten: true,
632
- filter: [
633
- { type: "worker" },
634
- { type: "service_worker", exclude: !process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS }
635
- ]
636
- });
627
+ session._sendMayFail("Target.setAutoAttach", { autoAttach: true, waitForDebuggerOnStart: true, flatten: true });
637
628
  session.on("Target.attachedToTarget", (event2) => this._onAttachedToTarget(event2));
638
629
  session.on("Target.detachedFromTarget", (event2) => this._onDetachedFromTarget(event2));
639
630
  session.on("Runtime.consoleAPICalled", (event2) => {
640
631
  const args = event2.args.map((o) => (0, import_crExecutionContext.createHandle)(worker.existingExecutionContext, o));
641
632
  this._page.addConsoleMessage(event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
642
633
  });
643
- session.on("Runtime.exceptionThrown", (exception) => this._page.emitOnContextOnceInitialized(import_browserContext.BrowserContext.Events.PageError, (0, import_crProtocolHelper.exceptionToError)(exception.exceptionDetails), this._page));
634
+ session.on("Runtime.exceptionThrown", (exception) => this._page.addPageError((0, import_crProtocolHelper.exceptionToError)(exception.exceptionDetails)));
644
635
  }
645
636
  _onDetachedFromTarget(event) {
646
637
  const workerSession = this._workerSessions.get(event.sessionId);
@@ -699,7 +690,7 @@ class FrameSession {
699
690
  ));
700
691
  }
701
692
  _handleException(exceptionDetails) {
702
- this._page.emitOnContextOnceInitialized(import_browserContext.BrowserContext.Events.PageError, (0, import_crProtocolHelper.exceptionToError)(exceptionDetails), this._page);
693
+ this._page.addPageError((0, import_crProtocolHelper.exceptionToError)(exceptionDetails));
703
694
  }
704
695
  async _onTargetCrashed() {
705
696
  this._client._markAsCrashed();
@@ -109,9 +109,13 @@ class CSharpLanguageGenerator {
109
109
  const options = (0, import_language.toClickOptionsForSourceCode)(action);
110
110
  if (!Object.entries(options).length)
111
111
  return `await ${subject}.${this._asLocator(action.selector)}.${method}Async();`;
112
- const optionsString = formatObject(options, " ", "Locator" + method + "Options");
112
+ const optionsString = formatObject(options, " ");
113
113
  return `await ${subject}.${this._asLocator(action.selector)}.${method}Async(${optionsString});`;
114
114
  }
115
+ case "hover": {
116
+ const optionsString = action.position ? formatObject({ position: action.position }, " ") : "";
117
+ return `await ${subject}.${this._asLocator(action.selector)}.HoverAsync(${optionsString});`;
118
+ }
115
119
  case "check":
116
120
  return `await ${subject}.${this._asLocator(action.selector)}.CheckAsync();`;
117
121
  case "uncheck":
@@ -159,11 +163,11 @@ class CSharpLanguageGenerator {
159
163
  using System.Threading.Tasks;
160
164
 
161
165
  using var playwright = await Playwright.CreateAsync();
162
- await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, " ", "BrowserTypeLaunchOptions")});
166
+ await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, " ")});
163
167
  var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);
164
168
  if (options.contextOptions.recordHar) {
165
169
  const url = options.contextOptions.recordHar.urlFilter;
166
- formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ", "BrowserContextRouteFromHAROptions")}` : ""});`);
170
+ formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
167
171
  }
168
172
  formatter.newLine();
169
173
  return formatter.format();
@@ -191,14 +195,14 @@ class CSharpLanguageGenerator {
191
195
  {`);
192
196
  if (options.contextOptions.recordHar) {
193
197
  const url = options.contextOptions.recordHar.urlFilter;
194
- formatter.add(` await Context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ", "BrowserContextRouteFromHAROptions")}` : ""});`);
198
+ formatter.add(` await Context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
195
199
  }
196
200
  return formatter.format();
197
201
  }
198
202
  generateFooter(saveStorage) {
199
203
  const offset = this._mode === "library" ? "" : " ";
200
204
  let storageStateLine = saveStorage ? `
201
- ${offset}await context.StorageStateAsync(new BrowserContextStorageStateOptions
205
+ ${offset}await context.StorageStateAsync(new()
202
206
  ${offset}{
203
207
  ${offset} Path = ${quote(saveStorage)}
204
208
  ${offset}});
@@ -212,8 +216,8 @@ ${offset}});
212
216
  }
213
217
  function formatObject(value, indent = " ", name = "") {
214
218
  if (typeof value === "string") {
215
- if (["permissions", "colorScheme", "modifiers", "button", "recordHarContent", "recordHarMode", "serviceWorkers"].includes(name))
216
- return `${getClassName(name)}.${toPascal(value)}`;
219
+ if (["colorScheme", "modifiers", "button", "recordHarContent", "recordHarMode", "serviceWorkers"].includes(name))
220
+ return `${getEnumName(name)}.${toPascal(value)}`;
217
221
  return quote(value);
218
222
  }
219
223
  if (Array.isArray(value))
@@ -221,35 +225,24 @@ function formatObject(value, indent = " ", name = "") {
221
225
  if (typeof value === "object") {
222
226
  const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
223
227
  if (!keys.length)
224
- return name ? `new ${getClassName(name)}` : "";
228
+ return `new()`;
225
229
  const tokens = [];
226
230
  for (const key of keys) {
227
231
  const property = getPropertyName(key);
228
232
  tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);
229
233
  }
230
- if (name)
231
- return `new ${getClassName(name)}
234
+ return `new()
232
235
  {
233
236
  ${indent}${tokens.join(`
234
237
  ${indent}`)}
235
- ${indent}}`;
236
- return `{
237
- ${indent}${tokens.join(`
238
- ${indent}`)}
239
238
  ${indent}}`;
240
239
  }
241
240
  if (name === "latitude" || name === "longitude")
242
241
  return String(value) + "m";
243
242
  return String(value);
244
243
  }
245
- function getClassName(value) {
244
+ function getEnumName(value) {
246
245
  switch (value) {
247
- case "viewport":
248
- return "ViewportSize";
249
- case "proxy":
250
- return "ProxySettings";
251
- case "permissions":
252
- return "ContextPermission";
253
246
  case "modifiers":
254
247
  return "KeyboardModifier";
255
248
  case "button":
@@ -278,18 +271,18 @@ function toPascal(value) {
278
271
  return value[0].toUpperCase() + value.slice(1);
279
272
  }
280
273
  function formatContextOptions(contextOptions, deviceName) {
281
- let options = { ...contextOptions };
274
+ const options = { ...contextOptions };
282
275
  delete options.recordHar;
283
276
  const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
284
277
  if (!device) {
285
278
  if (!Object.entries(options).length)
286
279
  return "";
287
- return formatObject(options, " ", "BrowserNewContextOptions");
280
+ return formatObject(options, " ");
288
281
  }
289
- options = (0, import_language.sanitizeDeviceOptions)(device, options);
290
- if (!Object.entries(options).length)
282
+ if (!Object.entries((0, import_language.sanitizeDeviceOptions)(device, options)).length)
291
283
  return `playwright.Devices[${quote(deviceName)}]`;
292
- return formatObject(options, " ", `BrowserNewContextOptions(playwright.Devices[${quote(deviceName)}])`);
284
+ delete options["defaultBrowserType"];
285
+ return formatObject(options, " ");
293
286
  }
294
287
  class CSharpFormatter {
295
288
  constructor(offset = 0) {
@@ -91,6 +91,10 @@ class JavaLanguageGenerator {
91
91
  const optionsText = formatClickOptions(options);
92
92
  return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.${method}(${optionsText});`;
93
93
  }
94
+ case "hover": {
95
+ const optionsText = action.position ? `new Locator.HoverOptions().setPosition(${action.position.x}, ${action.position.y})` : "";
96
+ return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.hover(${optionsText});`;
97
+ }
94
98
  case "check":
95
99
  return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.check();`;
96
100
  case "uncheck":
@@ -81,6 +81,8 @@ class JavaScriptLanguageGenerator {
81
81
  const optionsString = formatOptions(options, false);
82
82
  return `await ${subject}.${this._asLocator(action.selector)}.${method}(${optionsString});`;
83
83
  }
84
+ case "hover":
85
+ return `await ${subject}.${this._asLocator(action.selector)}.hover(${formatOptions({ position: action.position }, false)});`;
84
86
  case "check":
85
87
  return `await ${subject}.${this._asLocator(action.selector)}.check();`;
86
88
  case "uncheck":
@@ -166,7 +168,7 @@ ${useText ? "\ntest.use(" + useText + ");\n" : ""}
166
168
  }
167
169
  }
168
170
  function formatOptions(value, hasArguments) {
169
- const keys = Object.keys(value);
171
+ const keys = Object.keys(value).filter((key) => value[key] !== void 0);
170
172
  if (!keys.length)
171
173
  return "";
172
174
  return (hasArguments ? ", " : "") + formatObject(value);
@@ -83,6 +83,8 @@ class PythonLanguageGenerator {
83
83
  const optionsString = formatOptions(options, false);
84
84
  return `${subject}.${this._asLocator(action.selector)}.${method}(${optionsString})`;
85
85
  }
86
+ case "hover":
87
+ return `${subject}.${this._asLocator(action.selector)}.hover(${formatOptions({ position: action.position }, false)})`;
86
88
  case "check":
87
89
  return `${subject}.${this._asLocator(action.selector)}.check()`;
88
90
  case "uncheck":
@@ -31,13 +31,9 @@ var import_locatorParser = require("../utils/isomorphic/locatorParser");
31
31
  var import_language = require("./codegen/language");
32
32
  var import_recorderUtils = require("./recorder/recorderUtils");
33
33
  var import_javascript = require("./codegen/javascript");
34
- var import_frames = require("./frames");
35
- var import_page = require("./page");
36
34
  class DebugController extends import_instrumentation.SdkObject {
37
35
  constructor(playwright) {
38
36
  super({ attribution: { isInternalPlaywright: true }, instrumentation: (0, import_instrumentation.createInstrumentation)() }, void 0, "DebugController");
39
- this._reportState = false;
40
- this._disposeListeners = /* @__PURE__ */ new Set();
41
37
  this._sdkLanguage = "javascript";
42
38
  this._generateAutoExpect = false;
43
39
  this._playwright = playwright;
@@ -58,28 +54,16 @@ class DebugController extends import_instrumentation.SdkObject {
58
54
  this.setReportStateChanged(false);
59
55
  }
60
56
  setReportStateChanged(enabled) {
61
- if (this._reportState === enabled)
62
- return;
63
- this._reportState = enabled;
64
- if (enabled) {
65
- const listener = {
66
- onPageOpen: (page) => {
67
- this._emitSnapshot(false);
68
- const handleNavigation = () => this._emitSnapshot(false);
69
- page.mainFrame().on(import_frames.Frame.Events.InternalNavigation, handleNavigation);
70
- const dispose = () => page.mainFrame().off(import_frames.Frame.Events.InternalNavigation, handleNavigation);
71
- this._disposeListeners.add(dispose);
72
- page.on(import_page.Page.Events.Close, () => this._disposeListeners.delete(dispose));
73
- },
57
+ if (enabled && !this._trackHierarchyListener) {
58
+ this._trackHierarchyListener = {
59
+ onPageOpen: () => this._emitSnapshot(false),
74
60
  onPageClose: () => this._emitSnapshot(false)
75
61
  };
76
- this._playwright.instrumentation.addListener(listener, null);
77
- this._disposeListeners.add(() => this._playwright.instrumentation.removeListener(listener));
62
+ this._playwright.instrumentation.addListener(this._trackHierarchyListener, null);
78
63
  this._emitSnapshot(true);
79
- } else {
80
- for (const dispose of this._disposeListeners)
81
- dispose();
82
- this._disposeListeners.clear();
64
+ } else if (!enabled && this._trackHierarchyListener) {
65
+ this._playwright.instrumentation.removeListener(this._trackHierarchyListener);
66
+ this._trackHierarchyListener = void 0;
83
67
  }
84
68
  }
85
69
  async setRecorderMode(progress, params) {
@@ -137,19 +121,7 @@ class DebugController extends import_instrumentation.SdkObject {
137
121
  const pageCount = this._playwright.allPages().length;
138
122
  if (initial && !pageCount)
139
123
  return;
140
- this.emit(DebugController.Events.StateChanged, {
141
- pageCount,
142
- browsers: this._playwright.allBrowsers().map((browser) => ({
143
- id: browser.guid,
144
- name: browser.options.name,
145
- channel: browser.options.channel,
146
- contexts: browser.contexts().map((context) => ({
147
- pages: context.pages().map((page) => ({
148
- url: page.mainFrame().url()
149
- }))
150
- }))
151
- }))
152
- });
124
+ this.emit(DebugController.Events.StateChanged, { pageCount });
153
125
  }
154
126
  async _allRecorders() {
155
127
  const contexts = /* @__PURE__ */ new Set();