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.
- package/README.md +1 -1
- package/browsers.json +14 -10
- package/lib/cli/program.js +26 -14
- package/lib/client/api.js +6 -0
- package/lib/client/browserContext.js +20 -2
- package/lib/client/channelOwner.js +5 -1
- package/lib/client/connection.js +3 -0
- package/lib/client/fetch.js +16 -21
- package/lib/client/jsHandle.js +0 -8
- package/lib/client/localUtils.js +1 -0
- package/lib/client/network.js +175 -17
- package/lib/client/page.js +21 -0
- package/lib/client/playwright.js +6 -3
- package/lib/client/tracing.js +16 -20
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +7 -0
- package/lib/generated/webSocketMockSource.js +7 -0
- package/lib/protocol/validator.js +80 -14
- package/lib/server/bidi/bidiBrowser.js +23 -8
- package/lib/server/bidi/bidiChromium.js +124 -0
- package/lib/server/bidi/bidiConnection.js +1 -1
- package/lib/server/bidi/bidiExecutionContext.js +0 -3
- package/lib/server/bidi/bidiFirefox.js +15 -21
- package/lib/server/bidi/bidiInput.js +16 -32
- package/lib/server/bidi/bidiNetworkManager.js +39 -5
- package/lib/server/bidi/bidiOverCdp.js +103 -0
- package/lib/server/bidi/bidiPage.js +98 -25
- package/lib/server/bidi/bidiPdf.js +140 -0
- package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
- package/lib/server/browser.js +13 -2
- package/lib/server/browserContext.js +6 -23
- package/lib/server/browserType.js +39 -11
- package/lib/server/chromium/chromium.js +3 -15
- package/lib/server/chromium/chromiumSwitches.js +3 -1
- package/lib/server/chromium/crBrowser.js +4 -3
- package/lib/server/chromium/crExecutionContext.js +0 -7
- package/lib/server/chromium/crPage.js +16 -6
- package/lib/server/chromium/videoRecorder.js +1 -1
- package/lib/server/codegen/csharp.js +1 -1
- package/lib/server/codegen/java.js +1 -1
- package/lib/server/codegen/javascript.js +1 -1
- package/lib/server/codegen/language.js +14 -2
- package/lib/server/codegen/python.js +1 -1
- package/lib/server/cookieStore.js +73 -0
- package/lib/server/debugController.js +2 -2
- package/lib/server/deviceDescriptorsSource.json +50 -50
- package/lib/server/dialog.js +1 -0
- package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
- package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
- package/lib/server/dispatchers/pageDispatcher.js +9 -0
- package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
- package/lib/server/download.js +9 -2
- package/lib/server/fetch.js +90 -94
- package/lib/server/firefox/ffBrowser.js +6 -4
- package/lib/server/firefox/ffExecutionContext.js +0 -3
- package/lib/server/firefox/ffPage.js +6 -3
- package/lib/server/firefox/firefox.js +2 -13
- package/lib/server/frameSelectors.js +1 -1
- package/lib/server/frames.js +158 -27
- package/lib/server/har/harTracer.js +11 -0
- package/lib/server/input.js +0 -1
- package/lib/server/javascript.js +0 -7
- package/lib/server/page.js +5 -1
- package/lib/server/playwright.js +5 -2
- package/lib/server/recorder/contextRecorder.js +33 -50
- package/lib/server/recorder/recorderApp.js +16 -10
- package/lib/server/recorder/recorderCollection.js +68 -79
- package/lib/server/recorder/recorderInTraceViewer.js +144 -0
- package/lib/server/recorder/recorderRunner.js +75 -97
- package/lib/server/recorder/recorderUtils.js +47 -6
- package/lib/server/recorder.js +30 -25
- package/lib/server/registry/index.js +85 -4
- package/lib/server/socksClientCertificatesInterceptor.js +15 -3
- package/lib/server/trace/recorder/snapshotter.js +1 -0
- package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
- package/lib/server/trace/recorder/tracing.js +58 -2
- package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
- package/lib/server/trace/viewer/traceViewer.js +2 -5
- package/lib/server/webkit/webkit.js +1 -1
- package/lib/server/webkit/wkBrowser.js +6 -5
- package/lib/server/webkit/wkExecutionContext.js +0 -3
- package/lib/server/webkit/wkPage.js +7 -4
- package/lib/utils/happy-eyeballs.js +13 -0
- package/lib/utils/hostPlatform.js +2 -2
- package/lib/utils/httpServer.js +1 -0
- package/lib/utils/isomorphic/locatorGenerators.js +9 -18
- package/lib/utils/isomorphic/locatorParser.js +2 -2
- package/lib/utils/isomorphic/recorderUtils.js +195 -0
- package/lib/vite/htmlReport/index.html +12 -12
- package/lib/vite/recorder/assets/{codeMirrorModule-aW6Vz3gf.js → codeMirrorModule-baozm8ur.js} +1 -1
- package/lib/vite/recorder/assets/{index-DCpXOVIh.js → index-2ElAIWFB.js} +10 -15
- package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/{codeMirrorModule-eFKCUIu2.js → codeMirrorModule-Bh1rfd2w.js} +1 -1
- package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
- package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
- package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
- package/lib/vite/traceViewer/embedded.html +5 -3
- package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
- package/lib/vite/traceViewer/index.html +5 -3
- package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
- package/lib/vite/traceViewer/recorder.html +17 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.CAYqod-m.css} +1 -1
- package/lib/vite/traceViewer/uiMode.html +6 -4
- package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
- package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +79 -8
- package/types/types.d.ts +2037 -949
- package/lib/generated/recorderSource.js +0 -7
- package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
- package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
- package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
- package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
- package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
- /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": "
|
|
6
|
+
"revision": "1140",
|
|
7
7
|
"installByDefault": true,
|
|
8
|
-
"browserVersion": "
|
|
8
|
+
"browserVersion": "130.0.6723.31"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"name": "chromium-tip-of-tree",
|
|
12
|
-
"revision": "
|
|
12
|
+
"revision": "1264",
|
|
13
13
|
"installByDefault": false,
|
|
14
|
-
"browserVersion": "
|
|
14
|
+
"browserVersion": "131.0.6740.0"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"name": "firefox",
|
|
18
|
-
"revision": "
|
|
18
|
+
"revision": "1465",
|
|
19
19
|
"installByDefault": true,
|
|
20
|
-
"browserVersion": "
|
|
20
|
+
"browserVersion": "131.0"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"name": "firefox-beta",
|
|
24
|
-
"revision": "
|
|
24
|
+
"revision": "1464",
|
|
25
25
|
"installByDefault": false,
|
|
26
|
-
"browserVersion": "
|
|
26
|
+
"browserVersion": "131.0b2"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
"name": "webkit",
|
|
30
|
-
"revision": "
|
|
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",
|
package/lib/cli/program.js
CHANGED
|
@@ -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,
|
|
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))
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
},
|
|
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.
|
|
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.
|
|
170
|
+
isInternal = isInternal || this._isInternalType;
|
|
167
171
|
if (isInternal) apiName = undefined;
|
|
168
172
|
|
|
169
173
|
// Enclosing zone could have provided the apiName and wallTime.
|
package/lib/client/connection.js
CHANGED
|
@@ -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;
|
package/lib/client/fetch.js
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
package/lib/client/jsHandle.js
CHANGED
|
@@ -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
|
}
|
package/lib/client/localUtils.js
CHANGED
package/lib/client/network.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
326
|
+
async _innerContinue(isFallback) {
|
|
328
327
|
const options = this.request()._fallbackOverridesForContinue();
|
|
329
|
-
return await this.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
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;
|