rebrowser-playwright-core 1.47.2 → 1.48.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 (121) hide show
  1. package/README.md +2 -0
  2. package/browsers.json +14 -10
  3. package/lib/cli/program.js +26 -14
  4. package/lib/client/api.js +6 -0
  5. package/lib/client/browserContext.js +20 -2
  6. package/lib/client/channelOwner.js +5 -1
  7. package/lib/client/connection.js +3 -0
  8. package/lib/client/fetch.js +16 -21
  9. package/lib/client/jsHandle.js +0 -8
  10. package/lib/client/localUtils.js +1 -0
  11. package/lib/client/network.js +175 -17
  12. package/lib/client/page.js +21 -0
  13. package/lib/client/playwright.js +6 -3
  14. package/lib/client/tracing.js +16 -20
  15. package/lib/generated/consoleApiSource.js +1 -1
  16. package/lib/generated/injectedScriptSource.js +1 -1
  17. package/lib/generated/pollingRecorderSource.js +7 -0
  18. package/lib/generated/webSocketMockSource.js +7 -0
  19. package/lib/protocol/validator.js +80 -14
  20. package/lib/server/bidi/bidiBrowser.js +23 -8
  21. package/lib/server/bidi/bidiChromium.js +124 -0
  22. package/lib/server/bidi/bidiConnection.js +1 -1
  23. package/lib/server/bidi/bidiExecutionContext.js +0 -3
  24. package/lib/server/bidi/bidiFirefox.js +15 -21
  25. package/lib/server/bidi/bidiInput.js +16 -32
  26. package/lib/server/bidi/bidiNetworkManager.js +39 -5
  27. package/lib/server/bidi/bidiOverCdp.js +103 -0
  28. package/lib/server/bidi/bidiPage.js +98 -25
  29. package/lib/server/bidi/bidiPdf.js +140 -0
  30. package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  31. package/lib/server/browser.js +13 -2
  32. package/lib/server/browserContext.js +6 -23
  33. package/lib/server/browserType.js +39 -11
  34. package/lib/server/chromium/chromium.js +3 -15
  35. package/lib/server/chromium/chromiumSwitches.js +3 -1
  36. package/lib/server/chromium/crBrowser.js +4 -3
  37. package/lib/server/chromium/crExecutionContext.js +0 -7
  38. package/lib/server/chromium/crPage.js +16 -6
  39. package/lib/server/chromium/videoRecorder.js +1 -1
  40. package/lib/server/codegen/csharp.js +1 -1
  41. package/lib/server/codegen/java.js +1 -1
  42. package/lib/server/codegen/javascript.js +1 -1
  43. package/lib/server/codegen/language.js +14 -2
  44. package/lib/server/codegen/python.js +1 -1
  45. package/lib/server/cookieStore.js +73 -0
  46. package/lib/server/debugController.js +2 -2
  47. package/lib/server/deviceDescriptorsSource.json +50 -50
  48. package/lib/server/dialog.js +1 -0
  49. package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
  50. package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
  51. package/lib/server/dispatchers/pageDispatcher.js +9 -0
  52. package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
  53. package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  54. package/lib/server/download.js +9 -2
  55. package/lib/server/fetch.js +90 -94
  56. package/lib/server/firefox/ffBrowser.js +6 -4
  57. package/lib/server/firefox/ffExecutionContext.js +0 -3
  58. package/lib/server/firefox/ffPage.js +6 -3
  59. package/lib/server/firefox/firefox.js +2 -13
  60. package/lib/server/frameSelectors.js +1 -1
  61. package/lib/server/frames.js +164 -28
  62. package/lib/server/har/harTracer.js +11 -0
  63. package/lib/server/input.js +0 -1
  64. package/lib/server/javascript.js +0 -7
  65. package/lib/server/page.js +5 -1
  66. package/lib/server/playwright.js +5 -2
  67. package/lib/server/recorder/contextRecorder.js +33 -50
  68. package/lib/server/recorder/recorderApp.js +16 -10
  69. package/lib/server/recorder/recorderCollection.js +68 -79
  70. package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  71. package/lib/server/recorder/recorderRunner.js +75 -97
  72. package/lib/server/recorder/recorderUtils.js +47 -6
  73. package/lib/server/recorder.js +30 -25
  74. package/lib/server/registry/index.js +85 -4
  75. package/lib/server/socksClientCertificatesInterceptor.js +15 -3
  76. package/lib/server/trace/recorder/snapshotter.js +1 -0
  77. package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
  78. package/lib/server/trace/recorder/tracing.js +58 -2
  79. package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
  80. package/lib/server/trace/viewer/traceViewer.js +2 -5
  81. package/lib/server/webkit/webkit.js +1 -1
  82. package/lib/server/webkit/wkBrowser.js +6 -5
  83. package/lib/server/webkit/wkExecutionContext.js +0 -3
  84. package/lib/server/webkit/wkPage.js +7 -4
  85. package/lib/utils/happy-eyeballs.js +13 -0
  86. package/lib/utils/hostPlatform.js +2 -2
  87. package/lib/utils/httpServer.js +1 -0
  88. package/lib/utils/isomorphic/locatorGenerators.js +9 -18
  89. package/lib/utils/isomorphic/locatorParser.js +2 -2
  90. package/lib/utils/isomorphic/recorderUtils.js +195 -0
  91. package/lib/vite/htmlReport/index.html +12 -12
  92. package/lib/vite/recorder/assets/{codeMirrorModule-aW6Vz3gf.js → codeMirrorModule-baozm8ur.js} +1 -1
  93. package/lib/vite/recorder/assets/{index-DCpXOVIh.js → index-2ElAIWFB.js} +10 -15
  94. package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
  95. package/lib/vite/recorder/index.html +2 -2
  96. package/lib/vite/traceViewer/assets/{codeMirrorModule-eFKCUIu2.js → codeMirrorModule-Bh1rfd2w.js} +1 -1
  97. package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
  98. package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
  99. package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
  100. package/lib/vite/traceViewer/embedded.html +5 -3
  101. package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
  102. package/lib/vite/traceViewer/index.html +5 -3
  103. package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  104. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  105. package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
  106. package/lib/vite/traceViewer/recorder.html +17 -0
  107. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  108. package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.CAYqod-m.css} +1 -1
  109. package/lib/vite/traceViewer/uiMode.html +6 -4
  110. package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
  111. package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
  112. package/package.json +1 -1
  113. package/types/protocol.d.ts +79 -8
  114. package/types/types.d.ts +2037 -949
  115. package/lib/generated/recorderSource.js +0 -7
  116. package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
  117. package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
  118. package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
  119. package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
  120. package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
  121. /package/lib/server/recorder/{recorderActions.js → recorderFrontend.js} +0 -0
@@ -12,6 +12,7 @@ var _browserContext = require("./browserContext");
12
12
  var _debugger = require("./debugger");
13
13
  var _contextRecorder = require("./recorder/contextRecorder");
14
14
  var _recorderUtils = require("./recorder/recorderUtils");
15
+ var _recorderUtils2 = require("../utils/isomorphic/recorderUtils");
15
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
18
  /**
@@ -32,26 +33,29 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
32
33
 
33
34
  const recorderSymbol = Symbol('recorderSymbol');
34
35
  class Recorder {
35
- static showInspector(context, recorderAppFactory) {
36
- const params = {};
36
+ static async showInspector(context, params, recorderAppFactory) {
37
37
  if ((0, _utils.isUnderTest)()) params.language = process.env.TEST_INSPECTOR_LANGUAGE;
38
- Recorder.show(context, recorderAppFactory, params).catch(() => {});
38
+ return await Recorder.show('actions', context, recorderAppFactory, params);
39
39
  }
40
- static show(context, recorderAppFactory, params = {}) {
40
+ static showInspectorNoReply(context, recorderAppFactory) {
41
+ Recorder.showInspector(context, {}, recorderAppFactory).catch(() => {});
42
+ }
43
+ static show(codegenMode, context, recorderAppFactory, params) {
41
44
  let recorderPromise = context[recorderSymbol];
42
45
  if (!recorderPromise) {
43
- recorderPromise = Recorder._create(context, recorderAppFactory, params);
46
+ recorderPromise = Recorder._create(codegenMode, context, recorderAppFactory, params);
44
47
  context[recorderSymbol] = recorderPromise;
45
48
  }
46
49
  return recorderPromise;
47
50
  }
48
- static async _create(context, recorderAppFactory, params = {}) {
49
- const recorder = new Recorder(context, params);
51
+ static async _create(codegenMode, context, recorderAppFactory, params = {}) {
52
+ const recorder = new Recorder(codegenMode, context, params);
50
53
  const recorderApp = await recorderAppFactory(recorder);
51
54
  await recorder._install(recorderApp);
52
55
  return recorder;
53
56
  }
54
- constructor(context, params) {
57
+ constructor(codegenMode, context, params) {
58
+ this.handleSIGINT = void 0;
55
59
  this._context = void 0;
56
60
  this._mode = void 0;
57
61
  this._highlightedSelector = '';
@@ -67,7 +71,8 @@ class Recorder {
67
71
  this._omitCallTracking = false;
68
72
  this._currentLanguage = void 0;
69
73
  this._mode = params.mode || 'none';
70
- this._contextRecorder = new _contextRecorder.ContextRecorder(context, params, {});
74
+ this.handleSIGINT = params.handleSIGINT;
75
+ this._contextRecorder = new _contextRecorder.ContextRecorder(codegenMode, context, params, {});
71
76
  this._context = context;
72
77
  this._omitCallTracking = !!params.omitCallTracking;
73
78
  this._debugger = context.debugger();
@@ -123,10 +128,10 @@ class Recorder {
123
128
  (_this$_recorderApp = this._recorderApp) === null || _this$_recorderApp === void 0 || _this$_recorderApp.close().catch(() => {});
124
129
  });
125
130
  this._contextRecorder.on(_contextRecorder.ContextRecorder.Events.Change, data => {
126
- var _this$_recorderApp2;
127
131
  this._recorderSources = data.sources;
132
+ recorderApp.setActions(data.actions, data.sources);
133
+ recorderApp.setRunningFile(undefined);
128
134
  this._pushAllSources();
129
- (_this$_recorderApp2 = this._recorderApp) === null || _this$_recorderApp2 === void 0 || _this$_recorderApp2.setFileIfNeeded(data.primaryFileName);
130
135
  });
131
136
  await this._context.exposeBinding('__pw_recorderState', false, source => {
132
137
  let actionSelector = '';
@@ -154,9 +159,9 @@ class Recorder {
154
159
  await this._context.exposeBinding('__pw_recorderSetSelector', false, async ({
155
160
  frame
156
161
  }, selector) => {
157
- var _this$_recorderApp3;
162
+ var _this$_recorderApp2;
158
163
  const selectorChain = await (0, _contextRecorder.generateFrameSelector)(frame);
159
- await ((_this$_recorderApp3 = this._recorderApp) === null || _this$_recorderApp3 === void 0 ? void 0 : _this$_recorderApp3.setSelector((0, _recorderUtils.buildFullSelector)(selectorChain, selector), true));
164
+ await ((_this$_recorderApp2 = this._recorderApp) === null || _this$_recorderApp2 === void 0 ? void 0 : _this$_recorderApp2.setSelector((0, _recorderUtils2.buildFullSelector)(selectorChain, selector), true));
160
165
  });
161
166
  await this._context.exposeBinding('__pw_recorderSetMode', false, async ({
162
167
  frame
@@ -180,7 +185,7 @@ class Recorder {
180
185
  this._context.recorderAppForTest = this._recorderApp;
181
186
  }
182
187
  _pausedStateChanged() {
183
- var _this$_recorderApp4;
188
+ var _this$_recorderApp3;
184
189
  // If we are called upon page.pause, we don't have metadatas, populate them.
185
190
  for (const {
186
191
  metadata,
@@ -188,16 +193,16 @@ class Recorder {
188
193
  } of this._debugger.pausedDetails()) {
189
194
  if (!this._currentCallsMetadata.has(metadata)) this.onBeforeCall(sdkObject, metadata);
190
195
  }
191
- (_this$_recorderApp4 = this._recorderApp) === null || _this$_recorderApp4 === void 0 || _this$_recorderApp4.setPaused(this._debugger.isPaused());
196
+ (_this$_recorderApp3 = this._recorderApp) === null || _this$_recorderApp3 === void 0 || _this$_recorderApp3.setPaused(this._debugger.isPaused());
192
197
  this._updateUserSources();
193
198
  this.updateCallLog([...this._currentCallsMetadata.keys()]);
194
199
  }
195
200
  setMode(mode) {
196
- var _this$_recorderApp5;
201
+ var _this$_recorderApp4;
197
202
  if (this._mode === mode) return;
198
203
  this._highlightedSelector = '';
199
204
  this._mode = mode;
200
- (_this$_recorderApp5 = this._recorderApp) === null || _this$_recorderApp5 === void 0 || _this$_recorderApp5.setMode(this._mode);
205
+ (_this$_recorderApp4 = this._recorderApp) === null || _this$_recorderApp4 === void 0 || _this$_recorderApp4.setMode(this._mode);
201
206
  this._contextRecorder.setEnabled(this._mode === 'recording' || this._mode === 'assertingText' || this._mode === 'assertingVisibility' || this._mode === 'assertingValue');
202
207
  this._debugger.setMuted(this._mode === 'recording' || this._mode === 'assertingText' || this._mode === 'assertingVisibility' || this._mode === 'assertingValue');
203
208
  if (this._mode !== 'none' && this._mode !== 'standby' && this._context.pages().length === 1) this._context.pages()[0].bringToFront().catch(() => {});
@@ -231,9 +236,9 @@ class Recorder {
231
236
  if (isScreenshotCommand(metadata)) {
232
237
  this.hideHighlightedSelector();
233
238
  } else if (metadata.params && metadata.params.selector) {
234
- var _this$_recorderApp6;
239
+ var _this$_recorderApp5;
235
240
  this._highlightedSelector = metadata.params.selector;
236
- (_this$_recorderApp6 = this._recorderApp) === null || _this$_recorderApp6 === void 0 || _this$_recorderApp6.setSelector(this._highlightedSelector).catch(() => {});
241
+ (_this$_recorderApp5 = this._recorderApp) === null || _this$_recorderApp5 === void 0 || _this$_recorderApp5.setSelector(this._highlightedSelector).catch(() => {});
237
242
  }
238
243
  }
239
244
  async onAfterCall(sdkObject, metadata) {
@@ -243,7 +248,7 @@ class Recorder {
243
248
  this.updateCallLog([metadata]);
244
249
  }
245
250
  _updateUserSources() {
246
- var _this$_recorderApp7;
251
+ var _this$_recorderApp6;
247
252
  // Remove old decorations.
248
253
  for (const source of this._userSources.values()) {
249
254
  source.highlight = [];
@@ -281,18 +286,18 @@ class Recorder {
281
286
  }
282
287
  }
283
288
  this._pushAllSources();
284
- if (fileToSelect) (_this$_recorderApp7 = this._recorderApp) === null || _this$_recorderApp7 === void 0 || _this$_recorderApp7.setFileIfNeeded(fileToSelect);
289
+ if (fileToSelect) (_this$_recorderApp6 = this._recorderApp) === null || _this$_recorderApp6 === void 0 || _this$_recorderApp6.setRunningFile(fileToSelect);
285
290
  }
286
291
  _pushAllSources() {
287
- var _this$_recorderApp8;
288
- (_this$_recorderApp8 = this._recorderApp) === null || _this$_recorderApp8 === void 0 || _this$_recorderApp8.setSources([...this._recorderSources, ...this._userSources.values()]);
292
+ var _this$_recorderApp7;
293
+ (_this$_recorderApp7 = this._recorderApp) === null || _this$_recorderApp7 === void 0 || _this$_recorderApp7.setSources([...this._recorderSources, ...this._userSources.values()]);
289
294
  }
290
295
  async onBeforeInputAction(sdkObject, metadata) {}
291
296
  async onCallLog(sdkObject, metadata, logName, message) {
292
297
  this.updateCallLog([metadata]);
293
298
  }
294
299
  updateCallLog(metadatas) {
295
- var _this$_recorderApp9;
300
+ var _this$_recorderApp8;
296
301
  if (this._mode === 'recording' || this._mode === 'assertingText' || this._mode === 'assertingVisibility' || this._mode === 'assertingValue') return;
297
302
  const logs = [];
298
303
  for (const metadata of metadatas) {
@@ -302,7 +307,7 @@ class Recorder {
302
307
  if (this._debugger.isPaused(metadata)) status = 'paused';
303
308
  logs.push((0, _recorderUtils.metadataToCallLog)(metadata, status));
304
309
  }
305
- (_this$_recorderApp9 = this._recorderApp) === null || _this$_recorderApp9 === void 0 || _this$_recorderApp9.updateCallLogs(logs);
310
+ (_this$_recorderApp8 = this._recorderApp) === null || _this$_recorderApp8 === void 0 || _this$_recorderApp8.updateCallLogs(logs);
306
311
  }
307
312
  _readSource(fileName) {
308
313
  try {
@@ -107,6 +107,8 @@ const DOWNLOAD_PATHS = {
107
107
  'mac13-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
108
108
  'mac14': 'builds/chromium/%s/chromium-mac.zip',
109
109
  'mac14-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
110
+ 'mac15': 'builds/chromium/%s/chromium-mac.zip',
111
+ 'mac15-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
110
112
  'win64': 'builds/chromium/%s/chromium-win64.zip'
111
113
  },
112
114
  'chromium-tip-of-tree': {
@@ -134,6 +136,8 @@ const DOWNLOAD_PATHS = {
134
136
  'mac13-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
135
137
  'mac14': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip',
136
138
  'mac14-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
139
+ 'mac15': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip',
140
+ 'mac15-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
137
141
  'win64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-win64.zip'
138
142
  },
139
143
  'firefox': {
@@ -161,6 +165,8 @@ const DOWNLOAD_PATHS = {
161
165
  'mac13-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
162
166
  'mac14': 'builds/firefox/%s/firefox-mac.zip',
163
167
  'mac14-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
168
+ 'mac15': 'builds/firefox/%s/firefox-mac.zip',
169
+ 'mac15-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
164
170
  'win64': 'builds/firefox/%s/firefox-win64.zip'
165
171
  },
166
172
  'firefox-beta': {
@@ -188,6 +194,8 @@ const DOWNLOAD_PATHS = {
188
194
  'mac13-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
189
195
  'mac14': 'builds/firefox-beta/%s/firefox-beta-mac.zip',
190
196
  'mac14-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
197
+ 'mac15': 'builds/firefox-beta/%s/firefox-beta-mac.zip',
198
+ 'mac15-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
191
199
  'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip'
192
200
  },
193
201
  'webkit': {
@@ -215,6 +223,8 @@ const DOWNLOAD_PATHS = {
215
223
  'mac13-arm64': 'builds/webkit/%s/webkit-mac-13-arm64.zip',
216
224
  'mac14': 'builds/webkit/%s/webkit-mac-14.zip',
217
225
  'mac14-arm64': 'builds/webkit/%s/webkit-mac-14-arm64.zip',
226
+ 'mac15': 'builds/webkit/%s/webkit-mac-15.zip',
227
+ 'mac15-arm64': 'builds/webkit/%s/webkit-mac-15-arm64.zip',
218
228
  'win64': 'builds/webkit/%s/webkit-win64.zip'
219
229
  },
220
230
  'ffmpeg': {
@@ -242,6 +252,8 @@ const DOWNLOAD_PATHS = {
242
252
  'mac13-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
243
253
  'mac14': 'builds/ffmpeg/%s/ffmpeg-mac.zip',
244
254
  'mac14-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
255
+ 'mac15': 'builds/ffmpeg/%s/ffmpeg-mac.zip',
256
+ 'mac15-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
245
257
  'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip'
246
258
  },
247
259
  'android': {
@@ -269,6 +281,8 @@ const DOWNLOAD_PATHS = {
269
281
  'mac13-arm64': 'builds/android/%s/android.zip',
270
282
  'mac14': 'builds/android/%s/android.zip',
271
283
  'mac14-arm64': 'builds/android/%s/android.zip',
284
+ 'mac15': 'builds/android/%s/android.zip',
285
+ 'mac15-arm64': 'builds/android/%s/android.zip',
272
286
  'win64': 'builds/android/%s/android.zip'
273
287
  },
274
288
  // TODO(bidi): implement downloads.
@@ -442,11 +456,46 @@ class Registry {
442
456
  'darwin': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary',
443
457
  'win32': `\\Microsoft\\Edge SxS\\Application\\msedge.exe`
444
458
  }));
445
- this._executables.push(this._createBidiChannel('bidi-firefox-stable', {
446
- 'linux': '/usr/bin/firefox',
447
- 'darwin': '/Applications/Firefox.app/Contents/MacOS/firefox',
448
- 'win32': '\\Mozilla Firefox\\firefox.exe'
459
+ this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-stable', {
460
+ 'linux': '/firefox/firefox',
461
+ 'darwin': '/Firefox.app/Contents/MacOS/firefox',
462
+ 'win32': '\\core\\firefox.exe'
449
463
  }));
464
+ this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-beta', {
465
+ 'linux': '/firefox/firefox',
466
+ 'darwin': '/Firefox.app/Contents/MacOS/firefox',
467
+ 'win32': '\\core\\firefox.exe'
468
+ }));
469
+ this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-nightly', {
470
+ 'linux': '/firefox/firefox',
471
+ 'darwin': '/Firefox Nightly.app/Contents/MacOS/firefox',
472
+ 'win32': '\\firefox\\firefox.exe'
473
+ }));
474
+ this._executables.push(this._createBidiChannel('bidi-chrome-stable', {
475
+ 'linux': '/opt/google/chrome/chrome',
476
+ 'darwin': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
477
+ 'win32': `\\Google\\Chrome\\Application\\chrome.exe`
478
+ }));
479
+ this._executables.push(this._createBidiChannel('bidi-chrome-canary', {
480
+ 'linux': '',
481
+ 'darwin': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
482
+ 'win32': `\\Google\\Chrome SxS\\Application\\chrome.exe`
483
+ }));
484
+ this._executables.push({
485
+ type: 'browser',
486
+ name: 'bidi-chromium',
487
+ browserName: 'bidi',
488
+ directory: chromium.dir,
489
+ executablePath: () => chromiumExecutable,
490
+ executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
491
+ installType: 'download-on-demand',
492
+ _validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromium.dir, ['chrome-linux'], [], ['chrome-win']),
493
+ downloadURLs: this._downloadURLs(chromium),
494
+ browserVersion: chromium.browserVersion,
495
+ _install: () => this._downloadExecutable(chromium, chromiumExecutable),
496
+ _dependencyGroup: 'chromium',
497
+ _isHermeticInstallation: true
498
+ });
450
499
  const firefox = descriptors.find(d => d.name === 'firefox');
451
500
  const firefoxExecutable = findExecutablePath(firefox.dir, 'firefox');
452
501
  this._executables.push({
@@ -575,6 +624,38 @@ class Registry {
575
624
  _install: install
576
625
  };
577
626
  }
627
+ _createBidiFirefoxChannel(name, lookAt, install) {
628
+ const executablePath = (sdkLanguage, shouldThrow) => {
629
+ const suffix = lookAt[process.platform];
630
+ if (!suffix) {
631
+ if (shouldThrow) throw new Error(`Firefox distribution '${name}' is not supported on ${process.platform}`);
632
+ return undefined;
633
+ }
634
+ const folder = _path.default.resolve('firefox');
635
+ let channelName = 'stable';
636
+ if (name.includes('beta')) channelName = 'beta';else if (name.includes('nightly')) channelName = 'nightly';
637
+ const installedVersions = fs.readdirSync(folder);
638
+ const found = installedVersions.filter(e => e.includes(channelName));
639
+ if (found.length === 1) return _path.default.join(folder, found[0], suffix);
640
+ if (found.length > 1) {
641
+ if (shouldThrow) throw new Error(`Multiple Firefox installations found for channel '${name}': ${found.join(', ')}`);else return undefined;
642
+ }
643
+ if (shouldThrow) throw new Error(`Cannot find Firefox installation for channel '${name}' under ${folder}`);
644
+ return undefined;
645
+ };
646
+ return {
647
+ type: 'channel',
648
+ name,
649
+ browserName: 'bidi',
650
+ directory: undefined,
651
+ executablePath: sdkLanguage => executablePath(sdkLanguage, false),
652
+ executablePathOrDie: sdkLanguage => executablePath(sdkLanguage, true),
653
+ installType: 'none',
654
+ _validateHostRequirements: () => Promise.resolve(),
655
+ _isHermeticInstallation: true,
656
+ _install: install
657
+ };
658
+ }
578
659
  _createBidiChannel(name, lookAt, install) {
579
660
  const executablePath = (sdkLanguage, shouldThrow) => {
580
661
  const suffix = lookAt[process.platform];
@@ -14,6 +14,9 @@ var _happyEyeballs = require("../utils/happy-eyeballs");
14
14
  var _utils = require("../utils");
15
15
  var _socksProxy = require("../common/socksProxy");
16
16
  var _debugLogger = require("../utils/debugLogger");
17
+ var _fetch = require("./fetch");
18
+ var _events = require("events");
19
+ var _browserContext = require("./browserContext");
17
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
21
  /**
19
22
  * Copyright (c) Microsoft Corporation.
@@ -104,7 +107,11 @@ class SocksProxyConnection {
104
107
  };
105
108
  }
106
109
  async connect() {
107
- this.target = await (0, _happyEyeballs.createSocket)(rewriteToLocalhostIfNeeded(this.host), this.port);
110
+ if (this.socksProxy.proxyAgentFromOptions) this.target = await this.socksProxy.proxyAgentFromOptions.callback(new _events.EventEmitter(), {
111
+ host: rewriteToLocalhostIfNeeded(this.host),
112
+ port: this.port,
113
+ secureEndpoint: false
114
+ });else this.target = await (0, _happyEyeballs.createSocket)(rewriteToLocalhostIfNeeded(this.host), this.port);
108
115
  this.target.once('close', this._targetCloseEventListener);
109
116
  this.target.once('error', error => this.socksProxy._socksProxy.sendSocketError({
110
117
  uid: this.uid,
@@ -231,8 +238,11 @@ class ClientCertificatesProxy {
231
238
  this.ignoreHTTPSErrors = void 0;
232
239
  this.secureContextMap = new Map();
233
240
  this.alpnCache = void 0;
241
+ this.proxyAgentFromOptions = void 0;
242
+ (0, _browserContext.verifyClientCertificates)(contextOptions.clientCertificates);
234
243
  this.alpnCache = new ALPNCache();
235
244
  this.ignoreHTTPSErrors = contextOptions.ignoreHTTPSErrors;
245
+ this.proxyAgentFromOptions = contextOptions.proxy ? (0, _fetch.createProxyAgent)(contextOptions.proxy) : undefined;
236
246
  this._initSecureContexts(contextOptions.clientCertificates);
237
247
  this._socksProxy = new _socksProxy.SocksProxy();
238
248
  this._socksProxy.setPattern('*');
@@ -281,7 +291,9 @@ class ClientCertificatesProxy {
281
291
  }
282
292
  async listen() {
283
293
  const port = await this._socksProxy.listen(0, '127.0.0.1');
284
- return `socks5://127.0.0.1:${port}`;
294
+ return {
295
+ server: `socks5://127.0.0.1:${port}`
296
+ };
285
297
  }
286
298
  async close() {
287
299
  await this._socksProxy.close();
@@ -323,6 +335,6 @@ function rewriteToLocalhostIfNeeded(host) {
323
335
  return host === 'local.playwright' ? 'localhost' : host;
324
336
  }
325
337
  function rewriteOpenSSLErrorIfNeeded(error) {
326
- if (error.message !== 'unsupported') return error;
338
+ if (error.message !== 'unsupported' && error.code !== 'ERR_CRYPTO_UNSUPPORTED_OPERATION') return error;
327
339
  return (0, _utils.rewriteErrorMessage)(error, ['Unsupported TLS certificate.', 'Most likely, the security algorithm of the given certificate was deprecated by OpenSSL.', 'For more details, see https://github.com/openssl/openssl/blob/master/README-PROVIDERS.md#the-legacy-provider', 'You could probably modernize the certificate by following the steps at https://github.com/nodejs/node/issues/40672#issuecomment-1243648223'].join('\n'));
328
340
  }
@@ -111,6 +111,7 @@ class Snapshotter {
111
111
  html: data.html,
112
112
  viewport: data.viewport,
113
113
  timestamp: (0, _utils.monotonicTime)(),
114
+ wallTime: data.wallTime,
114
115
  collectionTime: data.collectionTime,
115
116
  resourceOverrides: [],
116
117
  isMainFrame: page.mainFrame() === frame
@@ -467,7 +467,7 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
467
467
  height: window.innerHeight
468
468
  },
469
469
  url: location.href,
470
- timestamp,
470
+ wallTime: Date.now(),
471
471
  collectionTime: 0
472
472
  };
473
473
  for (const sheet of this._staleStyleSheets) {
@@ -485,7 +485,7 @@ function frameSnapshotStreamer(snapshotStreamer, removeNoScript) {
485
485
  contentType: 'text/css'
486
486
  });
487
487
  }
488
- result.collectionTime = performance.now() - result.timestamp;
488
+ result.collectionTime = performance.now() - timestamp;
489
489
  return result;
490
490
  }
491
491
  }
@@ -146,7 +146,7 @@ class Tracing extends _instrumentation.SdkObject {
146
146
  wallTime: Date.now(),
147
147
  monotonicTime: (0, _utils.monotonicTime)()
148
148
  };
149
- this._fs.appendFile(this._state.traceFile, JSON.stringify(event) + '\n');
149
+ this._appendTraceEvent(event);
150
150
  this._context.instrumentation.addListener(this, this._context);
151
151
  this._eventListeners.push(_utils.eventsHelper.addEventListener(this._context, _browserContext.BrowserContext.Events.Console, this._onConsoleMessage.bind(this)), _utils.eventsHelper.addEventListener(this._context, _browserContext.BrowserContext.Events.PageError, this._onPageError.bind(this)));
152
152
  if (this._state.options.screenshots) this._startScreencast();
@@ -374,6 +374,61 @@ class Tracing extends _instrumentation.SdkObject {
374
374
  };
375
375
  this._appendTraceEvent(event);
376
376
  }
377
+ onDialog(dialog) {
378
+ const event = {
379
+ type: 'event',
380
+ time: (0, _utils.monotonicTime)(),
381
+ class: 'BrowserContext',
382
+ method: 'dialog',
383
+ params: {
384
+ pageId: dialog.page().guid,
385
+ type: dialog.type(),
386
+ message: dialog.message(),
387
+ defaultValue: dialog.defaultValue()
388
+ }
389
+ };
390
+ this._appendTraceEvent(event);
391
+ }
392
+ onDownload(page, download) {
393
+ const event = {
394
+ type: 'event',
395
+ time: (0, _utils.monotonicTime)(),
396
+ class: 'BrowserContext',
397
+ method: 'download',
398
+ params: {
399
+ pageId: page.guid,
400
+ url: download.url,
401
+ suggestedFilename: download.suggestedFilename()
402
+ }
403
+ };
404
+ this._appendTraceEvent(event);
405
+ }
406
+ onPageOpen(page) {
407
+ var _page$opener;
408
+ const event = {
409
+ type: 'event',
410
+ time: (0, _utils.monotonicTime)(),
411
+ class: 'BrowserContext',
412
+ method: 'page',
413
+ params: {
414
+ pageId: page.guid,
415
+ openerPageId: (_page$opener = page.opener()) === null || _page$opener === void 0 ? void 0 : _page$opener.guid
416
+ }
417
+ };
418
+ this._appendTraceEvent(event);
419
+ }
420
+ onPageClose(page) {
421
+ const event = {
422
+ type: 'event',
423
+ time: (0, _utils.monotonicTime)(),
424
+ class: 'BrowserContext',
425
+ method: 'pageClosed',
426
+ params: {
427
+ pageId: page.guid
428
+ }
429
+ };
430
+ this._appendTraceEvent(event);
431
+ }
377
432
  _onPageError(error, page) {
378
433
  const event = {
379
434
  type: 'event',
@@ -399,7 +454,8 @@ class Tracing extends _instrumentation.SdkObject {
399
454
  sha1,
400
455
  width: params.width,
401
456
  height: params.height,
402
- timestamp: (0, _utils.monotonicTime)()
457
+ timestamp: (0, _utils.monotonicTime)(),
458
+ frameSwapWallTime: params.frameSwapWallTime
403
459
  };
404
460
  // Make sure to write the screencast frame before adding a reference to it.
405
461
  this._appendResource(sha1, params.buffer);
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.InMemorySnapshotter = void 0;
7
- var _snapshotStorage = require("../../../../../trace-viewer/src/snapshotStorage");
7
+ var _snapshotStorage = require("../../../../../trace-viewer/src/sw/snapshotStorage");
8
8
  var _snapshotter = require("../recorder/snapshotter");
9
9
  var _harTracer = require("../../har/harTracer");
10
10
  var _utils = require("../../../utils");
@@ -84,6 +84,7 @@ async function startTraceViewerServer(options) {
84
84
  }
85
85
  async function installRootRedirect(server, traceUrls, options) {
86
86
  const params = new URLSearchParams();
87
+ if (_path.default.sep !== _path.default.posix.sep) params.set('pathSeparator', _path.default.sep);
87
88
  for (const traceUrl of traceUrls) params.append('trace', traceUrl);
88
89
  if (server.wsGuid()) params.append('ws', server.wsGuid());
89
90
  if (options !== null && options !== void 0 && options.isServer) params.append('isServer', '');
@@ -92,11 +93,6 @@ async function installRootRedirect(server, traceUrls, options) {
92
93
  if (options.grep) params.append('grep', options.grep);
93
94
  if (options.grepInvert) params.append('grepInvert', options.grepInvert);
94
95
  for (const project of options.project || []) params.append('project', project);
95
- if (options.workers) params.append('workers', String(options.workers));
96
- if (options.timeout) params.append('timeout', String(options.timeout));
97
- if (options.headed) params.append('headed', '');
98
- if (options.outputDir) params.append('outputDir', options.outputDir);
99
- if (options.updateSnapshots) params.append('updateSnapshots', options.updateSnapshots);
100
96
  for (const reporter of options.reporter || []) params.append('reporter', reporter);
101
97
  const urlPath = `./trace/${options.webApp || 'index.html'}?${params.toString()}`;
102
98
  server.routePath('/', (_, response) => {
@@ -172,6 +168,7 @@ class StdinServer {
172
168
  });
173
169
  process.stdin.on('close', () => (0, _utils.gracefullyProcessExitDoNotHang)(0));
174
170
  }
171
+ onconnect() {}
175
172
  async dispatch(method, params) {
176
173
  if (method === 'initialize') {
177
174
  if (this._traceUrl) this._loadTrace(this._traceUrl);
@@ -55,7 +55,6 @@ class WebKit extends _browserType.BrowserType {
55
55
  defaultArgs(options, isPersistent, userDataDir) {
56
56
  const {
57
57
  args = [],
58
- proxy,
59
58
  headless
60
59
  } = options;
61
60
  const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir'));
@@ -65,6 +64,7 @@ class WebKit extends _browserType.BrowserType {
65
64
  if (process.platform === 'win32') webkitArguments.push('--disable-accelerated-compositing');
66
65
  if (headless) webkitArguments.push('--headless');
67
66
  if (isPersistent) webkitArguments.push(`--user-data-dir=${userDataDir}`);else webkitArguments.push(`--no-startup-window`);
67
+ const proxy = options.proxyOverride || options.proxy;
68
68
  if (proxy) {
69
69
  if (process.platform === 'darwin') {
70
70
  webkitArguments.push(`--proxy=${proxy.server}`);
@@ -72,11 +72,12 @@ class WKBrowser extends _browser.Browser {
72
72
  this._didClose();
73
73
  }
74
74
  async doCreateNewContext(options) {
75
- const createOptions = options.proxy ? {
76
- // Enable socks5 hostname resolution on Windows. Workaround can be removed once fixed upstream.
75
+ const proxy = options.proxyOverride || options.proxy;
76
+ const createOptions = proxy ? {
77
+ // Enable socks5 hostname resolution on Windows.
77
78
  // See https://github.com/microsoft/playwright/issues/20451
78
- proxyServer: process.platform === 'win32' ? options.proxy.server.replace(/^socks5:\/\//, 'socks5h://') : options.proxy.server,
79
- proxyBypassList: options.proxy.bypass
79
+ proxyServer: process.platform === 'win32' ? proxy.server.replace(/^socks5:\/\//, 'socks5h://') : proxy.server,
80
+ proxyBypassList: proxy.bypass
80
81
  } : undefined;
81
82
  const {
82
83
  browserContextId
@@ -192,7 +193,7 @@ class WKBrowserContext extends _browserContext.BrowserContext {
192
193
  downloadPath: this._browser.options.downloadsPath,
193
194
  browserContextId
194
195
  }));
195
- if (this._options.ignoreHTTPSErrors) promises.push(this._browser._browserSession.send('Playwright.setIgnoreCertificateErrors', {
196
+ if (this._options.ignoreHTTPSErrors || this._options.internalIgnoreHTTPSErrors) promises.push(this._browser._browserSession.send('Playwright.setIgnoreCertificateErrors', {
196
197
  browserContextId,
197
198
  ignore: true
198
199
  }));
@@ -116,9 +116,6 @@ class WKExecutionContext {
116
116
  objectId
117
117
  });
118
118
  }
119
- objectCount(objectId) {
120
- throw new Error('Method not implemented in WebKit.');
121
- }
122
119
  }
123
120
  exports.WKExecutionContext = WKExecutionContext;
124
121
  function potentiallyUnserializableValue(remoteObject) {
@@ -461,11 +461,11 @@ class WKPage {
461
461
  const frame = this._page._frameManager.frame(contextPayload.frameId);
462
462
  if (!frame) return;
463
463
  const delegate = new _wkExecutionContext.WKExecutionContext(this._session, contextPayload.id);
464
- let worldName;
465
- if (contextPayload.type === 'normal') worldName = 'main';else if (contextPayload.type === 'user' && contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';else return;
464
+ let worldName = null;
465
+ if (contextPayload.type === 'normal') worldName = 'main';else if (contextPayload.type === 'user' && contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';
466
466
  const context = new dom.FrameExecutionContext(delegate, frame, worldName);
467
467
  context[contextDelegateSymbol] = delegate;
468
- frame._contextCreated(worldName, context);
468
+ if (worldName) frame._contextCreated(worldName, context);
469
469
  this._contextIdToContext.set(contextPayload.id, context);
470
470
  }
471
471
  async _onBindingCalled(contextId, argument) {
@@ -746,6 +746,9 @@ class WKPage {
746
746
  throw error;
747
747
  });
748
748
  }
749
+ async requestGC() {
750
+ await this._session.send('Heap.gc');
751
+ }
749
752
  async addInitScript(initScript) {
750
753
  await this._updateBootstrapScript();
751
754
  }
@@ -1070,7 +1073,7 @@ class WKPage {
1070
1073
  this._requestIdToResponseReceivedPayloadEvent.set(event.requestId, event);
1071
1074
  const response = request.createResponse(event.response);
1072
1075
  this._page._frameManager.requestReceivedResponse(response);
1073
- if (response.status() === 204) {
1076
+ if (response.status() === 204 && request.request.isNavigationRequest()) {
1074
1077
  this._onLoadingFailed(session, {
1075
1078
  requestId: event.requestId,
1076
1079
  errorText: 'Aborted: 204 No Content',