patchright-core 1.56.1 → 1.58.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/ThirdPartyNotices.txt +3134 -560
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +21 -22
  4. package/lib/cli/program.js +16 -60
  5. package/lib/client/api.js +3 -3
  6. package/lib/client/browser.js +3 -5
  7. package/lib/client/browserContext.js +62 -8
  8. package/lib/client/browserType.js +4 -3
  9. package/lib/client/connection.js +4 -0
  10. package/lib/client/consoleMessage.js +5 -1
  11. package/lib/client/electron.js +1 -1
  12. package/lib/client/elementHandle.js +3 -0
  13. package/lib/client/events.js +5 -1
  14. package/lib/client/fetch.js +3 -4
  15. package/lib/client/frame.js +10 -1
  16. package/lib/client/locator.js +12 -1
  17. package/lib/client/network.js +5 -1
  18. package/lib/client/page.js +31 -6
  19. package/lib/client/pageAgent.js +64 -0
  20. package/lib/client/platform.js +3 -0
  21. package/lib/client/playwright.js +1 -5
  22. package/lib/client/tracing.js +7 -5
  23. package/lib/client/worker.js +22 -0
  24. package/lib/generated/clockSource.js +1 -1
  25. package/lib/generated/injectedScriptSource.js +1 -1
  26. package/lib/generated/pollingRecorderSource.js +1 -1
  27. package/lib/inProcessFactory.js +0 -2
  28. package/lib/mcpBundle.js +84 -0
  29. package/lib/mcpBundleImpl/index.js +147 -0
  30. package/lib/protocol/serializers.js +5 -0
  31. package/lib/protocol/validator.js +112 -50
  32. package/lib/remote/playwrightServer.js +1 -2
  33. package/lib/server/agent/actionRunner.js +335 -0
  34. package/lib/server/agent/actions.js +128 -0
  35. package/lib/server/agent/codegen.js +111 -0
  36. package/lib/server/agent/context.js +150 -0
  37. package/lib/server/agent/expectTools.js +156 -0
  38. package/lib/server/agent/pageAgent.js +204 -0
  39. package/lib/server/agent/performTools.js +262 -0
  40. package/lib/server/agent/tool.js +109 -0
  41. package/lib/server/android/android.js +1 -1
  42. package/lib/server/artifact.js +1 -1
  43. package/lib/server/bidi/bidiBrowser.js +81 -22
  44. package/lib/server/bidi/bidiChromium.js +9 -13
  45. package/lib/server/bidi/bidiConnection.js +1 -0
  46. package/lib/server/bidi/bidiDeserializer.js +116 -0
  47. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  48. package/lib/server/bidi/bidiFirefox.js +7 -9
  49. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  50. package/lib/server/bidi/bidiPage.js +61 -30
  51. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  52. package/lib/server/browserContext.js +43 -36
  53. package/lib/server/browserType.js +12 -4
  54. package/lib/server/chromium/chromium.js +26 -21
  55. package/lib/server/chromium/chromiumSwitches.js +12 -3
  56. package/lib/server/chromium/crBrowser.js +30 -12
  57. package/lib/server/chromium/crConnection.js +0 -5
  58. package/lib/server/chromium/crCoverage.js +13 -1
  59. package/lib/server/chromium/crDevTools.js +0 -2
  60. package/lib/server/chromium/crNetworkManager.js +107 -18
  61. package/lib/server/chromium/crPage.js +68 -124
  62. package/lib/server/chromium/crServiceWorker.js +14 -1
  63. package/lib/server/codegen/javascript.js +6 -29
  64. package/lib/server/console.js +5 -1
  65. package/lib/server/deviceDescriptorsSource.json +56 -56
  66. package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
  67. package/lib/server/dispatchers/dispatcher.js +6 -13
  68. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  69. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  70. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  71. package/lib/server/dispatchers/pageDispatcher.js +14 -22
  72. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  73. package/lib/server/dom.js +12 -3
  74. package/lib/server/electron/electron.js +6 -3
  75. package/lib/server/firefox/ffBrowser.js +10 -20
  76. package/lib/server/firefox/ffConnection.js +0 -5
  77. package/lib/server/firefox/ffNetworkManager.js +2 -2
  78. package/lib/server/firefox/ffPage.js +18 -24
  79. package/lib/server/firefox/firefox.js +18 -9
  80. package/lib/server/frameSelectors.js +18 -8
  81. package/lib/server/frames.js +257 -87
  82. package/lib/server/input.js +7 -3
  83. package/lib/server/instrumentation.js +3 -0
  84. package/lib/server/javascript.js +8 -4
  85. package/lib/server/launchApp.js +2 -1
  86. package/lib/server/localUtils.js +4 -8
  87. package/lib/server/network.js +50 -12
  88. package/lib/server/page.js +112 -126
  89. package/lib/server/playwright.js +2 -4
  90. package/lib/server/progress.js +26 -6
  91. package/lib/server/recorder/recorderApp.js +80 -101
  92. package/lib/server/recorder.js +3 -2
  93. package/lib/server/registry/browserFetcher.js +6 -4
  94. package/lib/server/registry/index.js +278 -189
  95. package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
  96. package/lib/server/screencast.js +190 -0
  97. package/lib/server/screenshotter.js +6 -0
  98. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  99. package/lib/server/trace/recorder/snapshotter.js +17 -8
  100. package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
  101. package/lib/server/trace/recorder/tracing.js +31 -21
  102. package/lib/server/trace/viewer/traceParser.js +72 -0
  103. package/lib/server/trace/viewer/traceViewer.js +45 -40
  104. package/lib/server/utils/comparators.js +3 -25
  105. package/lib/server/utils/expectUtils.js +87 -2
  106. package/lib/server/utils/hostPlatform.js +30 -3
  107. package/lib/server/utils/httpServer.js +5 -20
  108. package/lib/server/utils/imageUtils.js +141 -0
  109. package/lib/server/utils/network.js +55 -40
  110. package/lib/server/utils/nodePlatform.js +6 -0
  111. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
  112. package/lib/server/webkit/webkit.js +5 -16
  113. package/lib/server/webkit/wkBrowser.js +2 -6
  114. package/lib/server/webkit/wkConnection.js +1 -6
  115. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  116. package/lib/server/webkit/wkPage.js +76 -51
  117. package/lib/server/webkit/wkWorkers.js +2 -1
  118. package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
  119. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  120. package/lib/utils/isomorphic/lruCache.js +51 -0
  121. package/lib/utils/isomorphic/mimeType.js +1 -1
  122. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  123. package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
  124. package/lib/utils/isomorphic/stringUtils.js +49 -0
  125. package/lib/utils/isomorphic/trace/entries.js +16 -0
  126. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  127. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  128. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  129. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  130. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  131. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  132. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  133. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  134. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  135. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  136. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  137. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  138. package/lib/utils/isomorphic/urlMatch.js +19 -5
  139. package/lib/utils/isomorphic/yaml.js +84 -0
  140. package/lib/utils.js +4 -0
  141. package/lib/utilsBundle.js +1 -1
  142. package/lib/utilsBundleImpl/index.js +124 -124
  143. package/lib/vite/htmlReport/index.html +21 -21
  144. package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
  145. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  146. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  147. package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
  148. package/lib/vite/recorder/index.html +2 -2
  149. package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
  150. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
  151. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  152. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  153. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  154. package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
  155. package/lib/vite/traceViewer/index.html +6 -6
  156. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  157. package/lib/vite/traceViewer/snapshot.html +3 -3
  158. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  159. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
  160. package/lib/vite/traceViewer/uiMode.html +3 -3
  161. package/package.json +2 -1
  162. package/types/protocol.d.ts +939 -245
  163. package/types/types.d.ts +143 -153
  164. package/lib/client/accessibility.js +0 -49
  165. package/lib/server/accessibility.js +0 -69
  166. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  167. package/lib/server/chromium/crAccessibility.js +0 -263
  168. package/lib/server/firefox/ffAccessibility.js +0 -238
  169. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  170. package/lib/server/webkit/wkAccessibility.js +0 -237
  171. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  172. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  173. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  174. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
  175. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  176. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  177. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  178. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  179. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
  180. package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
@@ -32,9 +32,7 @@ __export(crPage_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(crPage_exports);
34
34
  var import_crypto = __toESM(require("crypto"));
35
- var import_path = __toESM(require("path"));
36
35
  var import_assert = require("../../utils/isomorphic/assert");
37
- var import_crypto2 = require("../utils/crypto");
38
36
  var import_eventsHelper = require("../utils/eventsHelper");
39
37
  var import_stackTrace = require("../../utils/isomorphic/stackTrace");
40
38
  var dialog = __toESM(require("../dialog"));
@@ -43,8 +41,6 @@ var frames = __toESM(require("../frames"));
43
41
  var import_helper = require("../helper");
44
42
  var network = __toESM(require("../network"));
45
43
  var import_page = require("../page");
46
- var import_registry = require("../registry");
47
- var import_crAccessibility = require("./crAccessibility");
48
44
  var import_crCoverage = require("./crCoverage");
49
45
  var import_crDragDrop = require("./crDragDrop");
50
46
  var import_crExecutionContext = require("./crExecutionContext");
@@ -53,7 +49,6 @@ var import_crNetworkManager = require("./crNetworkManager");
53
49
  var import_crPdf = require("./crPdf");
54
50
  var import_crProtocolHelper = require("./crProtocolHelper");
55
51
  var import_defaultFontFamilies = require("./defaultFontFamilies");
56
- var import_videoRecorder = require("./videoRecorder");
57
52
  var import_errors = require("../errors");
58
53
  var import_protocolError = require("../protocolError");
59
54
  class CRPage {
@@ -115,7 +110,7 @@ class CRPage {
115
110
  while (!this._sessions.has(frame._id)) {
116
111
  const parent = frame.parentFrame();
117
112
  if (!parent)
118
- throw new Error(`Frame has been detached.`);
113
+ throw new Error(`Frame was detached`);
119
114
  frame = parent;
120
115
  }
121
116
  return this._sessions.get(frame._id);
@@ -240,17 +235,16 @@ class CRPage {
240
235
  async scrollRectIntoViewIfNeeded(handle, rect) {
241
236
  return this._sessionForHandle(handle)._scrollRectIntoViewIfNeeded(handle, rect);
242
237
  }
243
- async setScreencastOptions(options) {
244
- if (options) {
245
- await this._mainFrameSession._startScreencast(this, {
246
- format: "jpeg",
247
- quality: options.quality,
248
- maxWidth: options.width,
249
- maxHeight: options.height
250
- });
251
- } else {
252
- await this._mainFrameSession._stopScreencast(this);
253
- }
238
+ async startScreencast(options) {
239
+ await this._mainFrameSession._client.send("Page.startScreencast", {
240
+ format: "jpeg",
241
+ quality: options.quality,
242
+ maxWidth: options.width,
243
+ maxHeight: options.height
244
+ });
245
+ }
246
+ async stopScreencast() {
247
+ await this._mainFrameSession._client._sendMayFail("Page.stopScreencast");
254
248
  }
255
249
  rafCountForStablePosition() {
256
250
  return 1;
@@ -271,9 +265,6 @@ class CRPage {
271
265
  async adoptElementHandle(handle, to) {
272
266
  return this._sessionForHandle(handle)._adoptElementHandle(handle, to);
273
267
  }
274
- async getAccessibilityTree(needle) {
275
- return (0, import_crAccessibility.getAccessibilityTree)(this._mainFrameSession._client, needle);
276
- }
277
268
  async inputActionEpilogue() {
278
269
  await this._mainFrameSession._client.send("Page.enable").catch((e) => {
279
270
  });
@@ -326,9 +317,6 @@ class FrameSession {
326
317
  // Marks the oopif session that remote -> local transition has happened in the parent.
327
318
  // See Target.detachedFromTarget handler for details.
328
319
  this._swappedIn = false;
329
- this._videoRecorder = null;
330
- this._screencastId = null;
331
- this._screencastClients = /* @__PURE__ */ new Set();
332
320
  this._workerSessions = /* @__PURE__ */ new Map();
333
321
  this._initScriptIds = /* @__PURE__ */ new Map();
334
322
  this._exposedBindingNames = [];
@@ -380,38 +368,32 @@ class FrameSession {
380
368
  ]);
381
369
  }
382
370
  async _initialize(hasUIWindow) {
371
+ const pageEnablePromise = this._client.send("Page.enable");
383
372
  if (!this._page.isStorageStatePage && hasUIWindow && !this._crPage._browserContext._browser.isClank() && !this._crPage._browserContext._options.noDefaultViewport) {
384
373
  const { windowId } = await this._client.send("Browser.getWindowForTarget");
385
374
  this._windowId = windowId;
386
375
  }
387
- let screencastOptions;
388
- if (!this._page.isStorageStatePage && this._isMainFrame() && this._crPage._browserContext._options.recordVideo && hasUIWindow) {
389
- const screencastId = (0, import_crypto2.createGuid)();
390
- const outputFile = import_path.default.join(this._crPage._browserContext._options.recordVideo.dir, screencastId + ".webm");
391
- screencastOptions = {
392
- // validateBrowserContextOptions ensures correct video size.
393
- ...this._crPage._browserContext._options.recordVideo.size,
394
- outputFile
395
- };
396
- await this._crPage._browserContext._ensureVideosPath();
397
- await this._createVideoRecorder(screencastId, screencastOptions);
398
- this._crPage._page.waitForInitializedOrError().then((p) => {
399
- if (p instanceof Error)
400
- this._stopVideoRecording().catch(() => {
401
- });
402
- });
403
- }
376
+ let videoOptions;
377
+ if (!this._page.isStorageStatePage && this._isMainFrame() && hasUIWindow)
378
+ videoOptions = this._crPage._page.screencast.launchVideoRecorder();
404
379
  let lifecycleEventsEnabled;
405
380
  if (!this._isMainFrame())
406
381
  this._addRendererListeners();
382
+ let bufferedDialogEvents = this._isMainFrame() ? [] : void 0;
383
+ if (bufferedDialogEvents)
384
+ this._eventListeners.push(import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.javascriptDialogOpening", (event) => bufferedDialogEvents ? bufferedDialogEvents.push(event) : void 0));
407
385
  this._addBrowserListeners();
408
386
  this._bufferedAttachedToTargetEvents = [];
409
387
  const promises = [
410
- this._client.send("Page.enable"),
388
+ pageEnablePromise,
411
389
  this._client.send("Page.getFrameTree").then(({ frameTree }) => {
412
390
  if (this._isMainFrame()) {
413
391
  this._handleFrameTree(frameTree);
414
392
  this._addRendererListeners();
393
+ const pendingDialogEvents = bufferedDialogEvents || [];
394
+ bufferedDialogEvents = void 0;
395
+ for (const event of pendingDialogEvents)
396
+ this._onDialog(event);
415
397
  }
416
398
  const attachedToTargetEvents = this._bufferedAttachedToTargetEvents || [];
417
399
  this._bufferedAttachedToTargetEvents = void 0;
@@ -426,12 +408,16 @@ class FrameSession {
426
408
  } else {
427
409
  const localFrames = this._isMainFrame() ? this._page.frames() : [this._page.frameManager.frame(this._targetId)];
428
410
  for (const frame of localFrames) {
429
- this._page.frameManager.frame(frame._id)._context("utility");
411
+ this._page.frameManager.frame(frame._id)._context("utility").catch(() => {
412
+ });
430
413
  for (const binding of this._crPage._browserContext._pageBindings.values())
431
414
  frame.evaluateExpression(binding.source).catch((e) => {
432
415
  });
433
416
  for (const source of this._crPage._browserContext.initScripts)
434
- frame.evaluateExpression(source).catch((e) => {
417
+ frame.evaluateExpression(source.source).catch((e) => {
418
+ });
419
+ for (const source of this._crPage._page.initScripts)
420
+ frame.evaluateExpression(source.source).catch((e) => {
435
421
  });
436
422
  }
437
423
  this._firstNonInitialNavigationCommittedFulfill();
@@ -450,7 +436,7 @@ class FrameSession {
450
436
  if (!this._page.isStorageStatePage) {
451
437
  if (this._crPage._browserContext.needsPlaywrightBinding())
452
438
  promises.push(this.exposePlaywrightBinding());
453
- if (this._isMainFrame())
439
+ if (this._isMainFrame() && !this._crPage._browserContext._options.focusControl)
454
440
  promises.push(this._client.send("Emulation.setFocusEmulationEnabled", { enabled: true }));
455
441
  const options = this._crPage._browserContext._options;
456
442
  if (options.bypassCSP)
@@ -477,18 +463,15 @@ class FrameSession {
477
463
  for (const binding of this._crPage._page.allBindings()) promises.push(this._initBinding(binding));
478
464
  for (const initScript of this._crPage._browserContext.initScripts) promises.push(this._evaluateOnNewDocument(initScript, "main"));
479
465
  for (const initScript of this._crPage._page.initScripts) promises.push(this._evaluateOnNewDocument(initScript, "main"));
480
- if (screencastOptions)
481
- promises.push(this._startVideoRecording(screencastOptions));
466
+ if (videoOptions)
467
+ promises.push(this._crPage._page.screencast.startVideoRecording(videoOptions));
482
468
  }
483
- if (!(this._crPage._page._pageBindings.size || this._crPage._browserContext._pageBindings.size))
484
- promises.push(this._client.send("Runtime.runIfWaitingForDebugger"));
469
+ promises.push(this._client.send("Runtime.runIfWaitingForDebugger"));
485
470
  promises.push(this._firstNonInitialNavigationCommittedPromise);
486
471
  await Promise.all(promises);
487
- if (this._crPage._page._pageBindings.size || this._crPage._browserContext._pageBindings.size)
488
- await this._client.send("Runtime.runIfWaitingForDebugger");
489
472
  }
490
473
  dispose() {
491
- this._firstNonInitialNavigationCommittedReject(new import_errors.TargetClosedError());
474
+ this._firstNonInitialNavigationCommittedReject(new import_errors.TargetClosedError(this._page.closeReason()));
492
475
  for (const childSession of this._childSessions)
493
476
  childSession.dispose();
494
477
  if (this._parentSession)
@@ -513,6 +496,10 @@ class FrameSession {
513
496
  this._page.frameManager.frameLifecycleEvent(event.frameId, "load");
514
497
  else if (event.name === "DOMContentLoaded")
515
498
  this._page.frameManager.frameLifecycleEvent(event.frameId, "domcontentloaded");
499
+ if (event.name !== "load") {
500
+ await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
501
+ return;
502
+ }
516
503
  await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
517
504
  var document = await this._client._sendMayFail("DOM.getDocument");
518
505
  if (!document) return;
@@ -565,6 +552,14 @@ class FrameSession {
565
552
  if (!initial)
566
553
  this._firstNonInitialNavigationCommittedFulfill();
567
554
  await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
555
+ if (!initial) {
556
+ try {
557
+ await this._page.frameManager.frame(this._targetId)._context("utility");
558
+ } catch {
559
+ }
560
+ ;
561
+ return;
562
+ }
568
563
  var document = await this._client._sendMayFail("DOM.getDocument");
569
564
  if (!document) return;
570
565
  var query = await this._client._sendMayFail("DOM.querySelectorAll", {
@@ -613,7 +608,7 @@ class FrameSession {
613
608
  const delegate = new import_crExecutionContext.CRExecutionContext(this._client, contextPayload);
614
609
  let worldName = contextPayload.name;
615
610
  const context = new dom.FrameExecutionContext(delegate, frame, worldName);
616
- if (worldName)
611
+ if (worldName && (worldName === "main" || worldName === "utility"))
617
612
  frame._contextCreated(worldName, context);
618
613
  this._contextIdToContext.set(contextPayload.id, context);
619
614
  for (const source of this._exposedBindingScripts) {
@@ -680,6 +675,10 @@ class FrameSession {
680
675
  var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
681
676
  worker.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, { id: executionContextId }));
682
677
  }
678
+ if (this._crPage._browserContext._browser.majorVersion() >= 143)
679
+ session.on("Inspector.workerScriptLoaded", () => worker.workerScriptLoaded());
680
+ else
681
+ worker.workerScriptLoaded();
683
682
  this._crPage._networkManager.addSession(session, this._page.frameManager.frame(this._targetId) ?? void 0).catch(() => {
684
683
  });
685
684
  session._sendMayFail("Runtime.runIfWaitingForDebugger");
@@ -688,7 +687,7 @@ class FrameSession {
688
687
  session.on("Target.detachedFromTarget", (event2) => this._onDetachedFromTarget(event2));
689
688
  session.on("Runtime.consoleAPICalled", (event2) => {
690
689
  const args = event2.args.map((o) => (0, import_crExecutionContext.createHandle)(worker.existingExecutionContext, o));
691
- this._page.addConsoleMessage(event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
690
+ this._page.addConsoleMessage(worker, event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
692
691
  });
693
692
  session.on("Runtime.exceptionThrown", (exception) => this._page.addPageError((0, import_crProtocolHelper.exceptionToError)(exception.exceptionDetails)));
694
693
  }
@@ -723,7 +722,7 @@ class FrameSession {
723
722
  if (!context)
724
723
  return;
725
724
  const values = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(context, arg));
726
- this._page.addConsoleMessage(event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
725
+ this._page.addConsoleMessage(null, event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
727
726
  }
728
727
  async _onBindingCalled(event) {
729
728
  const pageOrError = await this._crPage._page.waitForInitializedOrError();
@@ -765,7 +764,7 @@ class FrameSession {
765
764
  lineNumber: lineNumber || 0,
766
765
  columnNumber: 0
767
766
  };
768
- this._page.addConsoleMessage(level, [], location, text);
767
+ this._page.addConsoleMessage(null, level, [], location, text);
769
768
  }
770
769
  }
771
770
  async _onFileChooserOpened(event) {
@@ -789,63 +788,17 @@ class FrameSession {
789
788
  }
790
789
  }
791
790
  _onScreencastFrame(payload) {
792
- this._page.throttleScreencastFrameAck(() => {
793
- this._client.send("Page.screencastFrameAck", { sessionId: payload.sessionId }).catch(() => {
794
- });
791
+ this._page.screencast.throttleFrameAck(() => {
792
+ this._client._sendMayFail("Page.screencastFrameAck", { sessionId: payload.sessionId });
795
793
  });
796
794
  const buffer = Buffer.from(payload.data, "base64");
797
795
  this._page.emit(import_page.Page.Events.ScreencastFrame, {
798
796
  buffer,
799
- frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1e3 : void 0,
797
+ frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1e3 : Date.now(),
800
798
  width: payload.metadata.deviceWidth,
801
799
  height: payload.metadata.deviceHeight
802
800
  });
803
801
  }
804
- async _createVideoRecorder(screencastId, options) {
805
- (0, import_assert.assert)(!this._screencastId);
806
- const ffmpegPath = import_registry.registry.findExecutable("ffmpeg").executablePathOrDie(this._page.browserContext._browser.sdkLanguage());
807
- this._videoRecorder = await import_videoRecorder.VideoRecorder.launch(this._crPage._page, ffmpegPath, options);
808
- this._screencastId = screencastId;
809
- }
810
- async _startVideoRecording(options) {
811
- const screencastId = this._screencastId;
812
- (0, import_assert.assert)(screencastId);
813
- this._page.once(import_page.Page.Events.Close, () => this._stopVideoRecording().catch(() => {
814
- }));
815
- const gotFirstFrame = new Promise((f) => this._client.once("Page.screencastFrame", f));
816
- await this._startScreencast(this._videoRecorder, {
817
- format: "jpeg",
818
- quality: 90,
819
- maxWidth: options.width,
820
- maxHeight: options.height
821
- });
822
- gotFirstFrame.then(() => {
823
- this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage._page.waitForInitializedOrError());
824
- });
825
- }
826
- async _stopVideoRecording() {
827
- if (!this._screencastId)
828
- return;
829
- const screencastId = this._screencastId;
830
- this._screencastId = null;
831
- const recorder = this._videoRecorder;
832
- this._videoRecorder = null;
833
- await this._stopScreencast(recorder);
834
- await recorder.stop().catch(() => {
835
- });
836
- const video = this._crPage._browserContext._browser._takeVideo(screencastId);
837
- video?.reportFinished();
838
- }
839
- async _startScreencast(client, options = {}) {
840
- this._screencastClients.add(client);
841
- if (this._screencastClients.size === 1)
842
- await this._client.send("Page.startScreencast", options);
843
- }
844
- async _stopScreencast(client) {
845
- this._screencastClients.delete(client);
846
- if (!this._screencastClients.size)
847
- await this._client._sendMayFail("Page.stopScreencast");
848
- }
849
802
  async _updateGeolocation(initial) {
850
803
  const geolocation = this._crPage._browserContext._options.geolocation;
851
804
  if (!initial || geolocation)
@@ -1049,29 +1002,20 @@ class FrameSession {
1049
1002
  return (0, import_crExecutionContext.createHandle)(to, result.object).asElement();
1050
1003
  }
1051
1004
  async _initBinding(binding = import_page.PageBinding) {
1052
- var result = await this._client._sendMayFail("Page.createIsolatedWorld", {
1053
- frameId: this._targetId,
1054
- grantUniveralAccess: true,
1055
- worldName: "utility"
1056
- });
1057
- if (!result) return;
1058
- var isolatedContextId = result.executionContextId;
1059
- var globalThis = await this._client._sendMayFail("Runtime.evaluate", {
1060
- expression: "globalThis",
1061
- serializationOptions: { serialization: "idOnly" }
1062
- });
1063
- if (!globalThis) return;
1064
- var globalThisObjId = globalThis["result"]["objectId"];
1065
- var mainContextId = parseInt(globalThisObjId.split(".")[1], 10);
1005
+ this._exposedBindingNames.push(binding.name);
1006
+ this._exposedBindingScripts.push(binding.source);
1007
+ const contextIds = Array.from(this._contextIdToContext.keys());
1066
1008
  await Promise.all([
1067
1009
  this._client._sendMayFail("Runtime.addBinding", { name: binding.name }),
1068
- this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId: mainContextId }),
1069
- this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId: isolatedContextId })
1070
- // this._client._sendMayFail("Runtime.evaluate", { expression: binding.source, contextId: mainContextId, awaitPromise: true })
1010
+ ...contextIds.map((executionContextId) => this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId }))
1071
1011
  ]);
1072
- this._exposedBindingNames.push(binding.name);
1073
- this._exposedBindingScripts.push(binding.source);
1074
- await this._crPage.addInitScript(binding.source);
1012
+ for (const contextId of contextIds) {
1013
+ this._client._sendMayFail("Runtime.evaluate", {
1014
+ expression: binding.source,
1015
+ contextId,
1016
+ awaitPromise: true
1017
+ });
1018
+ }
1075
1019
  }
1076
1020
  async _removeExposedBindings() {
1077
1021
  const toRetain = [];
@@ -36,16 +36,22 @@ var import_crExecutionContext = require("./crExecutionContext");
36
36
  var import_crNetworkManager = require("./crNetworkManager");
37
37
  var import_browserContext = require("../browserContext");
38
38
  var network = __toESM(require("../network"));
39
+ var import_console = require("../console");
40
+ var import_crProtocolHelper = require("./crProtocolHelper");
39
41
  class CRServiceWorker extends import_page.Worker {
40
42
  constructor(browserContext, session, url) {
41
43
  super(browserContext, url);
42
44
  this._session = session;
43
45
  this.browserContext = browserContext;
44
- if (!!process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS)
46
+ if (!process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_NETWORK)
45
47
  this._networkManager = new import_crNetworkManager.CRNetworkManager(null, this);
46
48
  session.once("Runtime.executionContextCreated", (event) => {
47
49
  this.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, event.context));
48
50
  });
51
+ if (this.browserContext._browser.majorVersion() >= 143)
52
+ session.on("Inspector.workerScriptLoaded", () => this.workerScriptLoaded());
53
+ else
54
+ this.workerScriptLoaded();
49
55
  if (this._networkManager && this._isNetworkInspectionEnabled()) {
50
56
  this.updateRequestInterception();
51
57
  this.updateExtraHTTPHeaders();
@@ -59,6 +65,13 @@ class CRServiceWorker extends import_page.Worker {
59
65
  ).catch(() => {
60
66
  });
61
67
  }
68
+ session.on("Runtime.consoleAPICalled", (event) => {
69
+ if (!this.existingExecutionContext || process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_CONSOLE)
70
+ return;
71
+ const args = event.args.map((o) => (0, import_crExecutionContext.createHandle)(this.existingExecutionContext, o));
72
+ const message = new import_console.ConsoleMessage(null, this, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
73
+ this.browserContext.emit(import_browserContext.BrowserContext.Events.Console, message);
74
+ });
62
75
  session.send("Runtime.runIfWaitingForDebugger").catch((e) => {
63
76
  });
64
77
  session.on("Inspector.targetReloadedAfterCrash", () => {
@@ -90,7 +90,7 @@ class JavaScriptLanguageGenerator {
90
90
  case "fill":
91
91
  return `await ${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)});`;
92
92
  case "setInputFiles":
93
- return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${formatObject(action.files.length === 1 ? action.files[0] : action.files)});`;
93
+ return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${(0, import_utils.formatObject)(action.files.length === 1 ? action.files[0] : action.files)});`;
94
94
  case "press": {
95
95
  const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
96
96
  const shortcut = [...modifiers, action.key].join("+");
@@ -99,7 +99,7 @@ class JavaScriptLanguageGenerator {
99
99
  case "navigate":
100
100
  return `await ${subject}.goto(${quote(action.url)});`;
101
101
  case "select":
102
- return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${formatObject(action.options.length === 1 ? action.options[0] : action.options)});`;
102
+ return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${(0, import_utils.formatObject)(action.options.length === 1 ? action.options[0] : action.options)});`;
103
103
  case "assertText":
104
104
  return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "toContainText" : "toHaveText"}(${quote(action.text)});`;
105
105
  case "assertChecked":
@@ -151,7 +151,7 @@ ${useText ? "\ntest.use(" + useText + ");\n" : ""}
151
151
  const { ${options.browserName}${options.deviceName ? ", devices" : ""} } = require('playwright');
152
152
 
153
153
  (async () => {
154
- const browser = await ${options.browserName}.launch(${formatObjectOrVoid(options.launchOptions)});
154
+ const browser = await ${options.browserName}.launch(${(0, import_utils.formatObjectOrVoid)(options.launchOptions)});
155
155
  const context = await browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName, false)});`);
156
156
  if (options.contextOptions.recordHar)
157
157
  formatter.add(` await context.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
@@ -171,37 +171,14 @@ function formatOptions(value, hasArguments) {
171
171
  const keys = Object.keys(value).filter((key) => value[key] !== void 0);
172
172
  if (!keys.length)
173
173
  return "";
174
- return (hasArguments ? ", " : "") + formatObject(value);
175
- }
176
- function formatObject(value, indent = " ") {
177
- if (typeof value === "string")
178
- return quote(value);
179
- if (Array.isArray(value))
180
- return `[${value.map((o) => formatObject(o)).join(", ")}]`;
181
- if (typeof value === "object") {
182
- const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
183
- if (!keys.length)
184
- return "{}";
185
- const tokens = [];
186
- for (const key of keys)
187
- tokens.push(`${key}: ${formatObject(value[key])}`);
188
- return `{
189
- ${indent}${tokens.join(`,
190
- ${indent}`)}
191
- }`;
192
- }
193
- return String(value);
194
- }
195
- function formatObjectOrVoid(value, indent = " ") {
196
- const result = formatObject(value, indent);
197
- return result === "{}" ? "" : result;
174
+ return (hasArguments ? ", " : "") + (0, import_utils.formatObject)(value);
198
175
  }
199
176
  function formatContextOptions(options, deviceName, isTest) {
200
177
  const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
201
178
  options = { ...options, recordHar: void 0 };
202
179
  if (!device)
203
- return formatObjectOrVoid(options);
204
- let serializedObject = formatObjectOrVoid((0, import_language.sanitizeDeviceOptions)(device, options));
180
+ return (0, import_utils.formatObjectOrVoid)(options);
181
+ let serializedObject = (0, import_utils.formatObjectOrVoid)((0, import_language.sanitizeDeviceOptions)(device, options));
205
182
  if (!serializedObject)
206
183
  serializedObject = "{\n}";
207
184
  const lines = serializedObject.split("\n");
@@ -22,8 +22,9 @@ __export(console_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(console_exports);
24
24
  class ConsoleMessage {
25
- constructor(page, type, text, args, location) {
25
+ constructor(page, worker, type, text, args, location) {
26
26
  this._page = page;
27
+ this._worker = worker;
27
28
  this._type = type;
28
29
  this._text = text;
29
30
  this._args = args;
@@ -32,6 +33,9 @@ class ConsoleMessage {
32
33
  page() {
33
34
  return this._page;
34
35
  }
36
+ worker() {
37
+ return this._worker;
38
+ }
35
39
  type() {
36
40
  return this._type;
37
41
  }