rebrowser-playwright-core 1.47.100 → 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 +1 -1
  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 +158 -27
  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
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  > 🕵️ The ultimate goal is to pass all automation detection tests presented in [`rebrowser-bot-detector`](https://github.com/rebrowser/rebrowser-bot-detector).
5
5
  >
6
6
  > 🪄 It's designed to be a drop-in replacement for the original `playwright-core` without changing your codebase. Each major and minor version of this repo matches the original repo, patch version could differ due to changes related to the patch itself.
7
- >
7
+ >
8
8
  > ☝️ Make sure to read: [How to Access Main Context Objects from Isolated Context](https://rebrowser.net/blog/how-to-access-main-context-objects-from-isolated-context-in-puppeteer-and-playwright-23741)
9
9
  >
10
10
  > 🐛 Please report any issues in the [`rebrowser-patches`](https://github.com/rebrowser/rebrowser-patches/issues) repo.
package/browsers.json CHANGED
@@ -3,31 +3,31 @@
3
3
  "browsers": [
4
4
  {
5
5
  "name": "chromium",
6
- "revision": "1134",
6
+ "revision": "1140",
7
7
  "installByDefault": true,
8
- "browserVersion": "129.0.6668.29"
8
+ "browserVersion": "130.0.6723.31"
9
9
  },
10
10
  {
11
11
  "name": "chromium-tip-of-tree",
12
- "revision": "1256",
12
+ "revision": "1264",
13
13
  "installByDefault": false,
14
- "browserVersion": "130.0.6695.0"
14
+ "browserVersion": "131.0.6740.0"
15
15
  },
16
16
  {
17
17
  "name": "firefox",
18
- "revision": "1463",
18
+ "revision": "1465",
19
19
  "installByDefault": true,
20
- "browserVersion": "130.0"
20
+ "browserVersion": "131.0"
21
21
  },
22
22
  {
23
23
  "name": "firefox-beta",
24
- "revision": "1462",
24
+ "revision": "1464",
25
25
  "installByDefault": false,
26
- "browserVersion": "130.0b2"
26
+ "browserVersion": "131.0b2"
27
27
  },
28
28
  {
29
29
  "name": "webkit",
30
- "revision": "2070",
30
+ "revision": "2083",
31
31
  "installByDefault": true,
32
32
  "revisionOverrides": {
33
33
  "mac10.14": "1446",
@@ -42,7 +42,11 @@
42
42
  {
43
43
  "name": "ffmpeg",
44
44
  "revision": "1010",
45
- "installByDefault": true
45
+ "installByDefault": true,
46
+ "revisionOverrides": {
47
+ "mac12": "1010",
48
+ "mac12-arm64": "1010"
49
+ }
46
50
  },
47
51
  {
48
52
  "name": "android",
@@ -238,13 +238,10 @@ _utilsBundle.program.command('show-trace [trace...]').option('-b, --browser <bro
238
238
  Examples:
239
239
 
240
240
  $ show-trace https://example.com/trace.zip`);
241
- async function launchContext(options, headless, executablePath) {
241
+ async function launchContext(options, extraOptions) {
242
242
  validateOptions(options);
243
243
  const browserType = lookupBrowserType(options);
244
- const launchOptions = {
245
- headless,
246
- executablePath
247
- };
244
+ const launchOptions = extraOptions;
248
245
  if (options.channel) launchOptions.channel = options.channel;
249
246
  launchOptions.handleSIGINT = false;
250
247
  const contextOptions =
@@ -256,7 +253,7 @@ async function launchContext(options, headless, executablePath) {
256
253
  // In headful mode, use host device scale factor for things to look nice.
257
254
  // In headless, keep things the way it works in Playwright by default.
258
255
  // Assume high-dpi on MacOS. TODO: this is not perfect.
259
- if (!headless) contextOptions.deviceScaleFactor = _os.default.platform() === 'darwin' ? 2 : 1;
256
+ if (!extraOptions.headless) contextOptions.deviceScaleFactor = _os.default.platform() === 'darwin' ? 2 : 1;
260
257
 
261
258
  // Work around the WebKit GTK scrolling issue.
262
259
  if (browserType.name() === 'webkit' && process.platform === 'linux') {
@@ -281,7 +278,7 @@ async function launchContext(options, headless, executablePath) {
281
278
  process.stdout.write(text);
282
279
  process.stdout.write('\n-------------8<-------------\n');
283
280
  const autoExitCondition = process.env.PWTEST_CLI_AUTO_EXIT_WHEN;
284
- if (autoExitCondition && text.includes(autoExitCondition)) Promise.all(context.pages().map(async p => p.close()));
281
+ if (autoExitCondition && text.includes(autoExitCondition)) closeBrowser();
285
282
  };
286
283
  // Make sure we exit abnormally when browser crashes.
287
284
  const logs = [];
@@ -383,7 +380,7 @@ async function launchContext(options, headless, executablePath) {
383
380
  const hasPage = browser.contexts().some(context => context.pages().length > 0);
384
381
  if (hasPage) return;
385
382
  // Avoid the error when the last page is closed because the browser has been closed.
386
- closeBrowser().catch(e => null);
383
+ closeBrowser().catch(() => {});
387
384
  });
388
385
  });
389
386
  process.on('SIGINT', async () => {
@@ -431,13 +428,17 @@ async function open(options, url, language) {
431
428
  context,
432
429
  launchOptions,
433
430
  contextOptions
434
- } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);
431
+ } = await launchContext(options, {
432
+ headless: !!process.env.PWTEST_CLI_HEADLESS,
433
+ executablePath: process.env.PWTEST_CLI_EXECUTABLE_PATH
434
+ });
435
435
  await context._enableRecorder({
436
436
  language,
437
437
  launchOptions,
438
438
  contextOptions,
439
439
  device: options.device,
440
- saveStorage: options.saveStorage
440
+ saveStorage: options.saveStorage,
441
+ handleSIGINT: false
441
442
  });
442
443
  await openPage(context, url);
443
444
  }
@@ -447,11 +448,16 @@ async function codegen(options, url) {
447
448
  output: outputFile,
448
449
  testIdAttribute: testIdAttributeName
449
450
  } = options;
451
+ const tracesDir = _path.default.join(_os.default.tmpdir(), `playwright-recorder-trace-${Date.now()}`);
450
452
  const {
451
453
  context,
452
454
  launchOptions,
453
455
  contextOptions
454
- } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);
456
+ } = await launchContext(options, {
457
+ headless: !!process.env.PWTEST_CLI_HEADLESS,
458
+ executablePath: process.env.PWTEST_CLI_EXECUTABLE_PATH,
459
+ tracesDir
460
+ });
455
461
  _utilsBundle.dotenv.config({
456
462
  path: 'playwright.env'
457
463
  });
@@ -462,8 +468,10 @@ async function codegen(options, url) {
462
468
  device: options.device,
463
469
  saveStorage: options.saveStorage,
464
470
  mode: 'recording',
471
+ codegenMode: process.env.PW_RECORDER_IS_TRACE_VIEWER ? 'trace-events' : 'actions',
465
472
  testIdAttributeName,
466
- outputFile: outputFile ? _path.default.resolve(outputFile) : undefined
473
+ outputFile: outputFile ? _path.default.resolve(outputFile) : undefined,
474
+ handleSIGINT: false
467
475
  });
468
476
  await openPage(context, url);
469
477
  }
@@ -480,7 +488,9 @@ async function waitForPage(page, captureOptions) {
480
488
  async function screenshot(options, captureOptions, url, path) {
481
489
  const {
482
490
  context
483
- } = await launchContext(options, true);
491
+ } = await launchContext(options, {
492
+ headless: true
493
+ });
484
494
  console.log('Navigating to ' + url);
485
495
  const page = await openPage(context, url);
486
496
  await waitForPage(page, captureOptions);
@@ -499,7 +509,9 @@ async function pdf(options, captureOptions, url, path) {
499
509
  } = await launchContext({
500
510
  ...options,
501
511
  browser: 'chromium'
502
- }, true);
512
+ }, {
513
+ headless: true
514
+ });
503
515
  console.log('Navigating to ' + url);
504
516
  const page = await openPage(context, url);
505
517
  await waitForPage(page, captureOptions);
package/lib/client/api.js CHANGED
@@ -243,6 +243,12 @@ Object.defineProperty(exports, "WebSocket", {
243
243
  return _network.WebSocket;
244
244
  }
245
245
  });
246
+ Object.defineProperty(exports, "WebSocketRoute", {
247
+ enumerable: true,
248
+ get: function () {
249
+ return _network.WebSocketRoute;
250
+ }
251
+ });
246
252
  Object.defineProperty(exports, "Worker", {
247
253
  enumerable: true,
248
254
  get: function () {
@@ -63,6 +63,7 @@ class BrowserContext extends _channelOwner.ChannelOwner {
63
63
  super(parent, type, guid, initializer);
64
64
  this._pages = new Set();
65
65
  this._routes = [];
66
+ this._webSocketRoutes = [];
66
67
  this._browser = null;
67
68
  this._browserType = void 0;
68
69
  this._bindings = new Map();
@@ -96,6 +97,9 @@ class BrowserContext extends _channelOwner.ChannelOwner {
96
97
  this._channel.on('route', ({
97
98
  route
98
99
  }) => this._onRoute(network.Route.from(route)));
100
+ this._channel.on('webSocketRoute', ({
101
+ webSocketRoute
102
+ }) => this._onWebSocketRoute(network.WebSocketRoute.from(webSocketRoute)));
99
103
  this._channel.on('backgroundPage', ({
100
104
  page
101
105
  }) => {
@@ -215,7 +219,11 @@ class BrowserContext extends _channelOwner.ChannelOwner {
215
219
  }
216
220
  // If the page is closed or unrouteAll() was called without waiting and interception disabled,
217
221
  // the method will throw an error - silence it.
218
- await route._innerContinue(true).catch(() => {});
222
+ await route._innerContinue(true /* isFallback */).catch(() => {});
223
+ }
224
+ async _onWebSocketRoute(webSocketRoute) {
225
+ const routeHandler = this._webSocketRoutes.find(route => route.matches(webSocketRoute.url()));
226
+ if (routeHandler) await routeHandler.handle(webSocketRoute);else webSocketRoute.connectToServer();
219
227
  }
220
228
  async _onBinding(bindingCall) {
221
229
  const func = this._bindings.get(bindingCall._initializer.name);
@@ -327,6 +335,10 @@ class BrowserContext extends _channelOwner.ChannelOwner {
327
335
  this._routes.unshift(new network.RouteHandler(this._options.baseURL, url, handler, options.times));
328
336
  await this._updateInterceptionPatterns();
329
337
  }
338
+ async routeWebSocket(url, handler) {
339
+ this._webSocketRoutes.unshift(new network.WebSocketRouteHandler(this._options.baseURL, url, handler));
340
+ await this._updateWebSocketInterceptionPatterns();
341
+ }
330
342
  async _recordIntoHAR(har, page, options = {}) {
331
343
  var _options$updateConten, _options$updateMode, _options$updateConten2;
332
344
  const {
@@ -385,6 +397,12 @@ class BrowserContext extends _channelOwner.ChannelOwner {
385
397
  patterns
386
398
  });
387
399
  }
400
+ async _updateWebSocketInterceptionPatterns() {
401
+ const patterns = network.WebSocketRouteHandler.prepareInterceptionPatterns(this._webSocketRoutes);
402
+ await this._channel.setWebSocketInterceptionPatterns({
403
+ patterns
404
+ });
405
+ }
388
406
  _effectiveCloseReason() {
389
407
  var _this$_browser3;
390
408
  return this._closeReason || ((_this$_browser3 = this._browser) === null || _this$_browser3 === void 0 ? void 0 : _this$_browser3._closeReason);
@@ -470,7 +488,7 @@ class BrowserContext extends _channelOwner.ChannelOwner {
470
488
  await this._closedPromise;
471
489
  }
472
490
  async _enableRecorder(params) {
473
- await this._channel.recorderSupplementEnable(params);
491
+ await this._channel.enableRecorder(params);
474
492
  }
475
493
  }
476
494
  exports.BrowserContext = BrowserContext;
@@ -39,6 +39,7 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
39
39
  this._logger = void 0;
40
40
  this._instrumentation = void 0;
41
41
  this._eventToSubscriptionMapping = new Map();
42
+ this._isInternalType = false;
42
43
  this._wasCollected = false;
43
44
  this.setMaxListeners(0);
44
45
  this._connection = parent instanceof ChannelOwner ? parent._connection : parent;
@@ -54,6 +55,9 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
54
55
  this._channel = this._createChannel(new _eventEmitter.EventEmitter());
55
56
  this._initializer = initializer;
56
57
  }
58
+ markAsInternalType() {
59
+ this._isInternalType = true;
60
+ }
57
61
  _setEventToSubscriptionMapping(mapping) {
58
62
  this._eventToSubscriptionMapping = mapping;
59
63
  }
@@ -163,7 +167,7 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
163
167
  const stackTrace = (0, _stackTrace.captureLibraryStackTrace)();
164
168
  let apiName = stackTrace.apiName;
165
169
  const frames = stackTrace.frames;
166
- isInternal = isInternal || this._type === 'LocalUtils';
170
+ isInternal = isInternal || this._isInternalType;
167
171
  if (isInternal) apiName = undefined;
168
172
 
169
173
  // Enclosing zone could have provided the apiName and wallTime.
@@ -315,6 +315,9 @@ class Connection extends _events.EventEmitter {
315
315
  case 'WebSocket':
316
316
  result = new _network.WebSocket(parent, type, guid, initializer);
317
317
  break;
318
+ case 'WebSocketRoute':
319
+ result = new _network.WebSocketRoute(parent, type, guid, initializer);
320
+ break;
318
321
  case 'Worker':
319
322
  result = new _worker.Worker(parent, type, guid, initializer);
320
323
  break;
@@ -147,8 +147,9 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
147
147
  (0, _utils.assert)(options.maxRedirects === undefined || options.maxRedirects >= 0, `'maxRedirects' must be greater than or equal to '0'`);
148
148
  (0, _utils.assert)(options.maxRetries === undefined || options.maxRetries >= 0, `'maxRetries' must be greater than or equal to '0'`);
149
149
  const url = options.url !== undefined ? options.url : options.request.url();
150
- const params = mapParamsToArray(options.params);
151
150
  const method = options.method || ((_options$request = options.request) === null || _options$request === void 0 ? void 0 : _options$request.method());
151
+ let encodedParams = undefined;
152
+ if (typeof options.params === 'string') encodedParams = options.params;else if (options.params instanceof URLSearchParams) encodedParams = options.params.toString();
152
153
  // Cannot call allHeaders() here as the request may be paused inside route handler.
153
154
  const headersObj = options.headers || ((_options$request2 = options.request) === null || _options$request2 === void 0 ? void 0 : _options$request2.headers());
154
155
  const headers = headersObj ? (0, _utils.headersObjectToArray)(headersObj) : undefined;
@@ -167,7 +168,18 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
167
168
  throw new Error(`Unexpected 'data' type`);
168
169
  }
169
170
  } else if (options.form) {
170
- formData = objectToArray(options.form);
171
+ if (globalThis.FormData && options.form instanceof FormData) {
172
+ formData = [];
173
+ for (const [name, value] of options.form.entries()) {
174
+ if (typeof value !== 'string') throw new Error(`Expected string for options.form["${name}"], found File. Please use options.multipart instead.`);
175
+ formData.push({
176
+ name,
177
+ value
178
+ });
179
+ }
180
+ } else {
181
+ formData = objectToArray(options.form);
182
+ }
171
183
  } else if (options.multipart) {
172
184
  multipartData = [];
173
185
  if (globalThis.FormData && options.multipart instanceof FormData) {
@@ -201,7 +213,8 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
201
213
  };
202
214
  const result = await this._channel.fetch({
203
215
  url,
204
- params,
216
+ params: typeof options.params === 'object' ? objectToArray(options.params) : undefined,
217
+ encodedParams,
205
218
  method,
206
219
  headers,
207
220
  postData: postDataBuffer,
@@ -373,24 +386,6 @@ function objectToArray(map) {
373
386
  });
374
387
  return result;
375
388
  }
376
- function queryStringToArray(queryString) {
377
- const searchParams = new URLSearchParams(queryString);
378
- return searchParamsToArray(searchParams);
379
- }
380
- function searchParamsToArray(searchParams) {
381
- if (searchParams.size === 0) return undefined;
382
- const result = [];
383
- for (const [name, value] of searchParams.entries()) result.push({
384
- name,
385
- value
386
- });
387
- return result;
388
- }
389
- function mapParamsToArray(params) {
390
- if (params instanceof URLSearchParams) return searchParamsToArray(params);
391
- if (typeof params === 'string') return queryStringToArray(params);
392
- return objectToArray(params);
393
- }
394
389
  function isFilePayload(value) {
395
390
  return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer'];
396
391
  }
@@ -86,14 +86,6 @@ class JSHandle extends _channelOwner.ChannelOwner {
86
86
  throw e;
87
87
  }
88
88
  }
89
- async _objectCount() {
90
- return await this._wrapApiCall(async () => {
91
- const {
92
- count
93
- } = await this._channel.objectCount();
94
- return count;
95
- });
96
- }
97
89
  toString() {
98
90
  return this._preview;
99
91
  }
@@ -25,6 +25,7 @@ class LocalUtils extends _channelOwner.ChannelOwner {
25
25
  constructor(parent, type, guid, initializer) {
26
26
  super(parent, type, guid, initializer);
27
27
  this.devices = void 0;
28
+ this.markAsInternalType();
28
29
  this.devices = {};
29
30
  for (const {
30
31
  name,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.WebSocket = exports.RouteHandler = exports.Route = exports.Response = exports.Request = exports.RawHeaders = void 0;
6
+ exports.WebSocketRouteHandler = exports.WebSocketRoute = exports.WebSocket = exports.RouteHandler = exports.Route = exports.Response = exports.Request = exports.RawHeaders = void 0;
7
7
  exports.validateHeaders = validateHeaders;
8
8
  var _url = require("url");
9
9
  var _channelOwner = require("./channelOwner");
@@ -17,7 +17,7 @@ var _events = require("./events");
17
17
  var _waiter = require("./waiter");
18
18
  var _fetch = require("./fetch");
19
19
  var _errors = require("./errors");
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
+ let _Symbol$asyncDispose;
21
21
  /**
22
22
  * Copyright (c) Microsoft Corporation.
23
23
  *
@@ -33,7 +33,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
33
33
  * See the License for the specific language governing permissions and
34
34
  * limitations under the License.
35
35
  */
36
-
36
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
37
  class Request extends _channelOwner.ChannelOwner {
38
38
  static from(request) {
39
39
  return request._object;
@@ -203,6 +203,7 @@ class Route extends _channelOwner.ChannelOwner {
203
203
  this._handlingPromise = null;
204
204
  this._context = void 0;
205
205
  this._didThrow = false;
206
+ this.markAsInternalType();
206
207
  }
207
208
  request() {
208
209
  return Request.from(this._initializer.request);
@@ -225,7 +226,6 @@ class Route extends _channelOwner.ChannelOwner {
225
226
  async abort(errorCode) {
226
227
  await this._handleRoute(async () => {
227
228
  await this._raceWithTargetClose(this._channel.abort({
228
- requestUrl: this.request()._initializer.url,
229
229
  errorCode
230
230
  }));
231
231
  });
@@ -302,7 +302,6 @@ class Route extends _channelOwner.ChannelOwner {
302
302
  if (options.contentType) headers['content-type'] = String(options.contentType);else if (options.json) headers['content-type'] = 'application/json';else if (options.path) headers['content-type'] = _utilsBundle.mime.getType(options.path) || 'application/octet-stream';
303
303
  if (length && !('content-length' in headers)) headers['content-length'] = String(length);
304
304
  await this._raceWithTargetClose(this._channel.fulfill({
305
- requestUrl: this.request()._initializer.url,
306
305
  status: statusOption || 200,
307
306
  headers: (0, _utils.headersObjectToArray)(headers),
308
307
  body,
@@ -313,7 +312,7 @@ class Route extends _channelOwner.ChannelOwner {
313
312
  async continue(options = {}) {
314
313
  await this._handleRoute(async () => {
315
314
  this.request()._applyFallbackOverrides(options);
316
- await this._innerContinue();
315
+ await this._innerContinue(false /* isFallback */);
317
316
  });
318
317
  }
319
318
  _checkNotHandled() {
@@ -324,21 +323,180 @@ class Route extends _channelOwner.ChannelOwner {
324
323
  this._handlingPromise = null;
325
324
  chain.resolve(done);
326
325
  }
327
- async _innerContinue(internal = false) {
326
+ async _innerContinue(isFallback) {
328
327
  const options = this.request()._fallbackOverridesForContinue();
329
- return await this._wrapApiCall(async () => {
330
- await this._raceWithTargetClose(this._channel.continue({
331
- requestUrl: this.request()._initializer.url,
332
- url: options.url,
333
- method: options.method,
334
- headers: options.headers ? (0, _utils.headersObjectToArray)(options.headers) : undefined,
335
- postData: options.postDataBuffer,
336
- isFallback: internal
337
- }));
338
- }, !!internal);
328
+ return await this._raceWithTargetClose(this._channel.continue({
329
+ url: options.url,
330
+ method: options.method,
331
+ headers: options.headers ? (0, _utils.headersObjectToArray)(options.headers) : undefined,
332
+ postData: options.postDataBuffer,
333
+ isFallback
334
+ }));
339
335
  }
340
336
  }
341
337
  exports.Route = Route;
338
+ _Symbol$asyncDispose = Symbol.asyncDispose;
339
+ class WebSocketRoute extends _channelOwner.ChannelOwner {
340
+ static from(route) {
341
+ return route._object;
342
+ }
343
+ constructor(parent, type, guid, initializer) {
344
+ super(parent, type, guid, initializer);
345
+ this._onPageMessage = void 0;
346
+ this._onPageClose = void 0;
347
+ this._onServerMessage = void 0;
348
+ this._onServerClose = void 0;
349
+ this._server = void 0;
350
+ this._connected = false;
351
+ this.markAsInternalType();
352
+ this._server = {
353
+ onMessage: handler => {
354
+ this._onServerMessage = handler;
355
+ },
356
+ onClose: handler => {
357
+ this._onServerClose = handler;
358
+ },
359
+ connectToServer: () => {
360
+ throw new Error(`connectToServer must be called on the page-side WebSocketRoute`);
361
+ },
362
+ url: () => {
363
+ return this._initializer.url;
364
+ },
365
+ close: async (options = {}) => {
366
+ await this._channel.closeServer({
367
+ ...options,
368
+ wasClean: true
369
+ }).catch(() => {});
370
+ },
371
+ send: message => {
372
+ if ((0, _utils.isString)(message)) this._channel.sendToServer({
373
+ message,
374
+ isBase64: false
375
+ }).catch(() => {});else this._channel.sendToServer({
376
+ message: message.toString('base64'),
377
+ isBase64: true
378
+ }).catch(() => {});
379
+ },
380
+ async [Symbol.asyncDispose]() {
381
+ await this.close();
382
+ }
383
+ };
384
+ this._channel.on('messageFromPage', ({
385
+ message,
386
+ isBase64
387
+ }) => {
388
+ if (this._onPageMessage) this._onPageMessage(isBase64 ? Buffer.from(message, 'base64') : message);else if (this._connected) this._channel.sendToServer({
389
+ message,
390
+ isBase64
391
+ }).catch(() => {});
392
+ });
393
+ this._channel.on('messageFromServer', ({
394
+ message,
395
+ isBase64
396
+ }) => {
397
+ if (this._onServerMessage) this._onServerMessage(isBase64 ? Buffer.from(message, 'base64') : message);else this._channel.sendToPage({
398
+ message,
399
+ isBase64
400
+ }).catch(() => {});
401
+ });
402
+ this._channel.on('closePage', ({
403
+ code,
404
+ reason,
405
+ wasClean
406
+ }) => {
407
+ if (this._onPageClose) this._onPageClose(code, reason);else this._channel.closeServer({
408
+ code,
409
+ reason,
410
+ wasClean
411
+ }).catch(() => {});
412
+ });
413
+ this._channel.on('closeServer', ({
414
+ code,
415
+ reason,
416
+ wasClean
417
+ }) => {
418
+ if (this._onServerClose) this._onServerClose(code, reason);else this._channel.closePage({
419
+ code,
420
+ reason,
421
+ wasClean
422
+ }).catch(() => {});
423
+ });
424
+ }
425
+ url() {
426
+ return this._initializer.url;
427
+ }
428
+ async close(options = {}) {
429
+ await this._channel.closePage({
430
+ ...options,
431
+ wasClean: true
432
+ }).catch(() => {});
433
+ }
434
+ connectToServer() {
435
+ if (this._connected) throw new Error('Already connected to the server');
436
+ this._connected = true;
437
+ this._channel.connect().catch(() => {});
438
+ return this._server;
439
+ }
440
+ send(message) {
441
+ if ((0, _utils.isString)(message)) this._channel.sendToPage({
442
+ message,
443
+ isBase64: false
444
+ }).catch(() => {});else this._channel.sendToPage({
445
+ message: message.toString('base64'),
446
+ isBase64: true
447
+ }).catch(() => {});
448
+ }
449
+ onMessage(handler) {
450
+ this._onPageMessage = handler;
451
+ }
452
+ onClose(handler) {
453
+ this._onPageClose = handler;
454
+ }
455
+ async [_Symbol$asyncDispose]() {
456
+ await this.close();
457
+ }
458
+ async _afterHandle() {
459
+ if (this._connected) return;
460
+ // Ensure that websocket is "open" and can send messages without an actual server connection.
461
+ await this._channel.ensureOpened();
462
+ }
463
+ }
464
+ exports.WebSocketRoute = WebSocketRoute;
465
+ class WebSocketRouteHandler {
466
+ constructor(baseURL, url, handler) {
467
+ this._baseURL = void 0;
468
+ this.url = void 0;
469
+ this.handler = void 0;
470
+ this._baseURL = baseURL;
471
+ this.url = url;
472
+ this.handler = handler;
473
+ }
474
+ static prepareInterceptionPatterns(handlers) {
475
+ const patterns = [];
476
+ let all = false;
477
+ for (const handler of handlers) {
478
+ if ((0, _utils.isString)(handler.url)) patterns.push({
479
+ glob: handler.url
480
+ });else if ((0, _utils.isRegExp)(handler.url)) patterns.push({
481
+ regexSource: handler.url.source,
482
+ regexFlags: handler.url.flags
483
+ });else all = true;
484
+ }
485
+ if (all) return [{
486
+ glob: '**/*'
487
+ }];
488
+ return patterns;
489
+ }
490
+ matches(wsURL) {
491
+ return (0, _utils.urlMatches)(this._baseURL, wsURL, this.url);
492
+ }
493
+ async handle(webSocketRoute) {
494
+ const handler = this.handler;
495
+ await handler(webSocketRoute);
496
+ await webSocketRoute._afterHandle();
497
+ }
498
+ }
499
+ exports.WebSocketRouteHandler = WebSocketRouteHandler;
342
500
  class Response extends _channelOwner.ChannelOwner {
343
501
  static from(response) {
344
502
  return response._object;