@checkly/playwright-core 1.47.12 → 1.48.10-alpha
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/browsers.json +14 -10
- package/lib/cli/program.js +22 -12
- package/lib/client/api.js +6 -0
- package/lib/client/browserContext.js +20 -2
- package/lib/client/channelOwner.js +5 -2
- package/lib/client/connection.js +3 -0
- package/lib/client/fetch.js +16 -3
- 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 +79 -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 +5 -2
- package/lib/server/chromium/videoRecorder.js +1 -1
- package/lib/server/codegen/csharp.js +2 -2
- 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 +2 -2
- package/lib/server/cookieStore.js +73 -0
- package/lib/server/debugController.js +2 -2
- package/lib/server/deviceDescriptorsSource.json +51 -51
- 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 +96 -99
- package/lib/server/firefox/ffBrowser.js +6 -4
- package/lib/server/firefox/ffExecutionContext.js +0 -3
- package/lib/server/firefox/ffPage.js +3 -0
- package/lib/server/firefox/firefox.js +2 -13
- package/lib/server/frameSelectors.js +1 -1
- package/lib/server/frames.js +3 -2
- 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/recorderActions.js +2 -1
- package/lib/server/recorder/recorderApp.js +15 -9
- package/lib/server/recorder/recorderCollection.js +68 -79
- package/lib/server/recorder/recorderFrontend.js +5 -0
- 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 +28 -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 +4 -1
- 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-CND2fZ5Q.js +24 -0
- package/lib/vite/recorder/assets/{index-NC7rIA63.css → index-BW-aOBcL.css} +1 -1
- package/lib/vite/recorder/assets/{index-A2TWT47O.js → index-CEc83sSS.js} +10 -15
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-5yiV-3wl.js +16831 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-B7Z3vq11.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-BdBhzV6t.js +16443 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-BqcXH1AO.js +16838 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-C6p3E9Zg.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-Ca-1BNel.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-CcviAl53.js +16831 -0
- package/lib/vite/{recorder/assets/codeMirrorModule-vr7pfcwZ.js → traceViewer/assets/codeMirrorModule-CqYUz5ms.js} +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-DS3v0XrQ.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-Dx6AXgMV.js +16838 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-EhKN7Okm.js +16449 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-MzSmL4X2.js +24 -0
- package/lib/vite/traceViewer/assets/{codeMirrorModule-cCPLLRBo.js → codeMirrorModule-T_sdMrbM.js} +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-U6XMqGkV.js +16437 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BABZNwlH.js +17351 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BPzVEZSf.js +17351 -0
- package/lib/vite/traceViewer/assets/inspectorTab-Bbgq0hgt.js +64 -0
- package/lib/vite/traceViewer/assets/inspectorTab-DhBbZz8I.js +64 -0
- package/lib/vite/traceViewer/assets/inspectorTab-DpvLVMq5.js +17351 -0
- package/lib/vite/traceViewer/assets/testServerConnection-D-tXL3sj.js +224 -0
- package/lib/vite/traceViewer/assets/workbench-B13nfocr.js +9 -0
- package/lib/vite/traceViewer/assets/workbench-BcgGQnKb.js +1473 -0
- package/lib/vite/traceViewer/assets/{wsPort-MnTGOuCA.js → workbench-Bjkiwcr1.js} +1505 -926
- package/lib/vite/traceViewer/assets/workbench-BwodYCgl.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-ByyWxoT8.js +1473 -0
- package/lib/vite/traceViewer/assets/{workbench-z8ylMSQK.js → workbench-C43LWZEX.js} +7 -7
- package/lib/vite/traceViewer/assets/workbench-C5OQh9VX.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-Crj6jzdv.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-DhqI6jeL.js +1473 -0
- package/lib/vite/traceViewer/assets/workbench-DrQjKdyE.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-Pa1v1Ojh.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-caTaZnzx.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-gtYcQBNA.js +9 -0
- package/lib/vite/traceViewer/assets/workbench-u2lRPMOT.js +72 -0
- package/lib/vite/traceViewer/assets/xtermModule-CZ7sDYXB.js +6529 -0
- package/lib/vite/traceViewer/assets/xtermModule-DZP0glxx.js +5982 -0
- package/lib/vite/traceViewer/codeMirrorModule.Cy8X9Wtw.css +344 -0
- package/lib/vite/traceViewer/embedded.27BGR_eD.js +105 -0
- package/lib/vite/traceViewer/embedded.BBZ9gQEw.js +104 -0
- package/lib/vite/traceViewer/embedded.BQq6Psnz.js +104 -0
- package/lib/vite/traceViewer/{embedded.TOXRJZ9A.js → embedded.BVDVQOzc.js} +1 -1
- package/lib/vite/traceViewer/embedded.Bn8Ptzv6.js +2 -0
- package/lib/vite/traceViewer/embedded.CorI3dFX.js +104 -0
- package/lib/vite/traceViewer/embedded.CvhnUgIi.js +2 -0
- package/lib/vite/traceViewer/embedded.D27cnKiB.js +104 -0
- package/lib/vite/traceViewer/embedded.D4lqGydT.js +2 -0
- package/lib/vite/traceViewer/embedded.DPqrDeET.js +2 -0
- package/lib/vite/traceViewer/embedded.DTjd2aiy.js +105 -0
- package/lib/vite/traceViewer/embedded.DbzY7Q8w.js +2 -0
- package/lib/vite/traceViewer/embedded.DjZq4InJ.css +68 -0
- package/lib/vite/traceViewer/embedded.SsjKHrxC.js +105 -0
- package/lib/vite/traceViewer/embedded.f-PLGsBT.js +2 -0
- package/lib/vite/traceViewer/embedded.html +6 -4
- package/lib/vite/traceViewer/index.B7aiTMfZ.js +2 -0
- package/lib/vite/traceViewer/{index.e7qpO0B0.js → index.B8dgQwuN.js} +1 -1
- package/lib/vite/traceViewer/index.BGj8jY3H.js +2 -0
- package/lib/vite/traceViewer/index.BSak5QT9.js +2 -0
- package/lib/vite/traceViewer/index.BrT2kfuc.js +2 -0
- package/lib/vite/traceViewer/{index.RT4iItO_.js → index.C0EgJ4oW.js} +36 -21
- package/lib/vite/traceViewer/index.CUpI-BFe.js +195 -0
- package/lib/vite/traceViewer/index.DkRbtWVo.js +195 -0
- package/lib/vite/traceViewer/index.DsjmhbB6.js +195 -0
- package/lib/vite/traceViewer/index.Dz3icWJV.js +196 -0
- package/lib/vite/traceViewer/index.PqcsvBxQ.js +196 -0
- package/lib/vite/traceViewer/index.QanXxRUb.css +131 -0
- package/lib/vite/traceViewer/index._cX8k4co.js +2 -0
- package/lib/vite/traceViewer/index.html +7 -5
- package/lib/vite/traceViewer/index.pMAN88y-.js +2 -0
- package/lib/vite/traceViewer/index.yxAwzeWG.js +196 -0
- package/lib/vite/traceViewer/inspectorTab.DGJWXOSd.css +3145 -0
- package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
- package/lib/vite/traceViewer/recorder.7Wl6HrQl.js +550 -0
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.BufKu9Hp.js +550 -0
- package/lib/vite/traceViewer/recorder.Ch-WHviK.js +2 -0
- package/lib/vite/traceViewer/recorder.DBDpiNOK.css +15 -0
- package/lib/vite/traceViewer/recorder.POd-toIn.js +2 -0
- package/lib/vite/traceViewer/recorder.am-MV-DQ.js +550 -0
- package/lib/vite/traceViewer/recorder.html +17 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.BEZVCe5O.js +5 -0
- package/lib/vite/traceViewer/uiMode.BZoFj6zV.js +1723 -0
- package/lib/vite/traceViewer/uiMode.C4nbcio6.js +1730 -0
- package/lib/vite/traceViewer/uiMode.CAYqod-m.css +1 -0
- package/lib/vite/traceViewer/uiMode.D-tg1Oci.js +1730 -0
- package/lib/vite/traceViewer/uiMode.DKjMBMlc.js +1730 -0
- package/lib/vite/traceViewer/uiMode.DRmgrHSk.css +1462 -0
- package/lib/vite/traceViewer/uiMode.DVWUEIHq.css +1424 -0
- package/lib/vite/traceViewer/{uiMode.MTXOs_2V.js → uiMode.DVrL7a1K.js} +5 -5
- package/lib/vite/traceViewer/uiMode.DdtUZZVS.js +5 -0
- package/lib/vite/traceViewer/uiMode.Dg9oJCQU.js +10 -0
- package/lib/vite/traceViewer/uiMode.Dlo9s_YX.js +1723 -0
- package/lib/vite/traceViewer/uiMode.DwZAzstF.js +10 -0
- package/lib/vite/traceViewer/uiMode.O07awP3T.js +10 -0
- package/lib/vite/traceViewer/uiMode.gGHHTsyL.js +1730 -0
- package/lib/vite/traceViewer/uiMode.html +7 -5
- package/lib/vite/traceViewer/uiMode.jY2s-9ps.js +10 -0
- package/lib/vite/traceViewer/uiMode.wsGnVMQK.js +1723 -0
- package/lib/vite/traceViewer/workbench.B3X2QtYa.css +3702 -0
- package/lib/vite/traceViewer/workbench.BQNDbcQ0.css +550 -0
- package/lib/vite/traceViewer/{workbench.NokwQoMV.css → workbench.DjbIuxix.css} +1 -1
- package/lib/vite/traceViewer/workbench.DlsCx8k5.css +1 -0
- package/lib/vite/traceViewer/workbench.DyTpxWVb.css +1 -0
- package/lib/vite/traceViewer/workbench.wuxQoE2z.css +3703 -0
- package/lib/vite/traceViewer/xtermModule.4oRVGWQ-.css +209 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +610 -173
- package/types/types.d.ts +2037 -949
- package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-clyjx5sb.js +0 -15578
- package/lib/vite/traceViewer/assets/codeMirrorModule-wLpsbIhd.js +0 -24
- package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-f2dAQL4I.js +0 -69
- package/lib/vite/traceViewer/index.-_8-eHEE.js +0 -2
- package/lib/vite/traceViewer/index.-g_5lMbJ.css +0 -1
- package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
- package/lib/vite/traceViewer/uiMode.9CwNsWc6.js +0 -10
- package/lib/vite/traceViewer/uiMode.Fb0bNA4H.js +0 -10
- package/lib/vite/traceViewer/uiMode.pWy0Re7G.css +0 -1
- package/lib/vite/traceViewer/uiMode.yLNTmFO4.js +0 -1490
- package/lib/vite/traceViewer/wsPort.zR1WIy9-.css +0 -1
- /package/lib/vite/recorder/assets/{codeMirrorModule-Hs9-1ZG4.css → codeMirrorModule-ez37Vkbh.css} +0 -0
- /package/lib/vite/recorder/assets/{codicon-wpoHPmsu.ttf → codicon-DCmgc-ay.ttf} +0 -0
- /package/lib/vite/traceViewer/assets/{testServerConnection-_1gRQKgk.js → testServerConnection-DeE2kSzz.js} +0 -0
- /package/lib/vite/traceViewer/assets/{xtermModule-Yt6xwiJ_.js → xtermModule-BeNbaIVa.js} +0 -0
- /package/lib/vite/traceViewer/{codeMirrorModule.Hs9-1ZG4.css → codeMirrorModule.ez37Vkbh.css} +0 -0
- /package/lib/vite/traceViewer/{codicon.wpoHPmsu.ttf → codicon.DCmgc-ay.ttf} +0 -0
- /package/lib/vite/traceViewer/{embedded.MO1jdrtU.css → embedded.w7WN2u1R.css} +0 -0
- /package/lib/vite/traceViewer/{index.q21lh23x.css → index.CrbWWHbf.css} +0 -0
- /package/lib/vite/traceViewer/{uiMode.93DRT-rm.css → uiMode.D3cNFP6u.css} +0 -0
- /package/lib/vite/traceViewer/{xtermModule.0lwXJFHT.css → xtermModule.DSXBckUd.css} +0 -0
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,7 +428,10 @@ 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,
|
|
@@ -447,11 +447,16 @@ async function codegen(options, url) {
|
|
|
447
447
|
output: outputFile,
|
|
448
448
|
testIdAttribute: testIdAttributeName
|
|
449
449
|
} = options;
|
|
450
|
+
const tracesDir = _path.default.join(_os.default.tmpdir(), `playwright-recorder-trace-${Date.now()}`);
|
|
450
451
|
const {
|
|
451
452
|
context,
|
|
452
453
|
launchOptions,
|
|
453
454
|
contextOptions
|
|
454
|
-
} = await launchContext(options,
|
|
455
|
+
} = await launchContext(options, {
|
|
456
|
+
headless: !!process.env.PWTEST_CLI_HEADLESS,
|
|
457
|
+
executablePath: process.env.PWTEST_CLI_EXECUTABLE_PATH,
|
|
458
|
+
tracesDir
|
|
459
|
+
});
|
|
455
460
|
_utilsBundle.dotenv.config({
|
|
456
461
|
path: 'playwright.env'
|
|
457
462
|
});
|
|
@@ -462,6 +467,7 @@ async function codegen(options, url) {
|
|
|
462
467
|
device: options.device,
|
|
463
468
|
saveStorage: options.saveStorage,
|
|
464
469
|
mode: 'recording',
|
|
470
|
+
codegenMode: process.env.PW_RECORDER_IS_TRACE_VIEWER ? 'trace-events' : 'actions',
|
|
465
471
|
testIdAttributeName,
|
|
466
472
|
outputFile: outputFile ? _path.default.resolve(outputFile) : undefined
|
|
467
473
|
});
|
|
@@ -480,7 +486,9 @@ async function waitForPage(page, captureOptions) {
|
|
|
480
486
|
async function screenshot(options, captureOptions, url, path) {
|
|
481
487
|
const {
|
|
482
488
|
context
|
|
483
|
-
} = await launchContext(options,
|
|
489
|
+
} = await launchContext(options, {
|
|
490
|
+
headless: true
|
|
491
|
+
});
|
|
484
492
|
console.log('Navigating to ' + url);
|
|
485
493
|
const page = await openPage(context, url);
|
|
486
494
|
await waitForPage(page, captureOptions);
|
|
@@ -499,7 +507,9 @@ async function pdf(options, captureOptions, url, path) {
|
|
|
499
507
|
} = await launchContext({
|
|
500
508
|
...options,
|
|
501
509
|
browser: 'chromium'
|
|
502
|
-
},
|
|
510
|
+
}, {
|
|
511
|
+
headless: true
|
|
512
|
+
});
|
|
503
513
|
console.log('Navigating to ' + url);
|
|
504
514
|
const page = await openPage(context, url);
|
|
505
515
|
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.
|
|
@@ -187,7 +191,6 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
|
|
|
187
191
|
stepId
|
|
188
192
|
};
|
|
189
193
|
const result = await _zones.zones.run('apiZone', apiZone, async () => await func(apiZone));
|
|
190
|
-
// @ts-ignore
|
|
191
194
|
csi === null || csi === void 0 || csi.onApiCallEnd(callCookie, null, result);
|
|
192
195
|
logApiCall(logger, `<= ${apiName} succeeded`, isInternal);
|
|
193
196
|
return result;
|
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
|
@@ -154,8 +154,9 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
|
|
|
154
154
|
(0, _utils.assert)(options.maxRedirects === undefined || options.maxRedirects >= 0, `'maxRedirects' must be greater than or equal to '0'`);
|
|
155
155
|
(0, _utils.assert)(options.maxRetries === undefined || options.maxRetries >= 0, `'maxRetries' must be greater than or equal to '0'`);
|
|
156
156
|
const url = options.url !== undefined ? options.url : options.request.url();
|
|
157
|
-
const params = mapParamsToArray(options.params);
|
|
158
157
|
const method = options.method || ((_options$request = options.request) === null || _options$request === void 0 ? void 0 : _options$request.method());
|
|
158
|
+
let encodedParams = undefined;
|
|
159
|
+
if (typeof options.params === 'string') encodedParams = options.params;else if (options.params instanceof URLSearchParams) encodedParams = options.params.toString();
|
|
159
160
|
// Cannot call allHeaders() here as the request may be paused inside route handler.
|
|
160
161
|
const headersObj = options.headers || ((_options$request2 = options.request) === null || _options$request2 === void 0 ? void 0 : _options$request2.headers());
|
|
161
162
|
const headers = headersObj ? (0, _utils.headersObjectToArray)(headersObj) : undefined;
|
|
@@ -174,7 +175,18 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
|
|
|
174
175
|
throw new Error(`Unexpected 'data' type`);
|
|
175
176
|
}
|
|
176
177
|
} else if (options.form) {
|
|
177
|
-
|
|
178
|
+
if (globalThis.FormData && options.form instanceof FormData) {
|
|
179
|
+
formData = [];
|
|
180
|
+
for (const [name, value] of options.form.entries()) {
|
|
181
|
+
if (typeof value !== 'string') throw new Error(`Expected string for options.form["${name}"], found File. Please use options.multipart instead.`);
|
|
182
|
+
formData.push({
|
|
183
|
+
name,
|
|
184
|
+
value
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
formData = objectToArray(options.form);
|
|
189
|
+
}
|
|
178
190
|
} else if (options.multipart) {
|
|
179
191
|
multipartData = [];
|
|
180
192
|
if (globalThis.FormData && options.multipart instanceof FormData) {
|
|
@@ -208,7 +220,8 @@ class APIRequestContext extends _channelOwner.ChannelOwner {
|
|
|
208
220
|
};
|
|
209
221
|
const result = await this._channel.fetch({
|
|
210
222
|
url,
|
|
211
|
-
params,
|
|
223
|
+
params: typeof options.params === 'object' ? objectToArray(options.params) : undefined,
|
|
224
|
+
encodedParams,
|
|
212
225
|
method,
|
|
213
226
|
headers,
|
|
214
227
|
postData: postDataBuffer,
|
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;
|
package/lib/client/page.js
CHANGED
|
@@ -63,6 +63,7 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
63
63
|
this._closedOrCrashedScope = new _utils.LongStandingScope();
|
|
64
64
|
this._viewportSize = void 0;
|
|
65
65
|
this._routes = [];
|
|
66
|
+
this._webSocketRoutes = [];
|
|
66
67
|
this.accessibility = void 0;
|
|
67
68
|
this.coverage = void 0;
|
|
68
69
|
this.keyboard = void 0;
|
|
@@ -121,6 +122,9 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
121
122
|
this._channel.on('route', ({
|
|
122
123
|
route
|
|
123
124
|
}) => this._onRoute(_network.Route.from(route)));
|
|
125
|
+
this._channel.on('webSocketRoute', ({
|
|
126
|
+
webSocketRoute
|
|
127
|
+
}) => this._onWebSocketRoute(_network.WebSocketRoute.from(webSocketRoute)));
|
|
124
128
|
this._channel.on('video', ({
|
|
125
129
|
artifact
|
|
126
130
|
}) => {
|
|
@@ -166,6 +170,10 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
166
170
|
}
|
|
167
171
|
await this._browserContext._onRoute(route);
|
|
168
172
|
}
|
|
173
|
+
async _onWebSocketRoute(webSocketRoute) {
|
|
174
|
+
const routeHandler = this._webSocketRoutes.find(route => route.matches(webSocketRoute.url()));
|
|
175
|
+
if (routeHandler) await routeHandler.handle(webSocketRoute);else await this._browserContext._onWebSocketRoute(webSocketRoute);
|
|
176
|
+
}
|
|
169
177
|
async _onBinding(bindingCall) {
|
|
170
178
|
const func = this._bindings.get(bindingCall._initializer.name);
|
|
171
179
|
if (func) {
|
|
@@ -416,6 +424,9 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
416
424
|
waitUntil
|
|
417
425
|
})).response);
|
|
418
426
|
}
|
|
427
|
+
async requestGC() {
|
|
428
|
+
await this._channel.requestGC();
|
|
429
|
+
}
|
|
419
430
|
async emulateMedia(options = {}) {
|
|
420
431
|
await this._channel.emulateMedia({
|
|
421
432
|
media: options.media === null ? 'no-override' : options.media,
|
|
@@ -458,6 +469,10 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
458
469
|
this._harRouters.push(harRouter);
|
|
459
470
|
await harRouter.addPageRoute(this);
|
|
460
471
|
}
|
|
472
|
+
async routeWebSocket(url, handler) {
|
|
473
|
+
this._webSocketRoutes.unshift(new _network.WebSocketRouteHandler(this._browserContext._options.baseURL, url, handler));
|
|
474
|
+
await this._updateWebSocketInterceptionPatterns();
|
|
475
|
+
}
|
|
461
476
|
_disposeHarRouters() {
|
|
462
477
|
this._harRouters.forEach(router => router.dispose());
|
|
463
478
|
this._harRouters = [];
|
|
@@ -487,6 +502,12 @@ class Page extends _channelOwner.ChannelOwner {
|
|
|
487
502
|
patterns
|
|
488
503
|
});
|
|
489
504
|
}
|
|
505
|
+
async _updateWebSocketInterceptionPatterns() {
|
|
506
|
+
const patterns = _network.WebSocketRouteHandler.prepareInterceptionPatterns(this._webSocketRoutes);
|
|
507
|
+
await this._channel.setWebSocketInterceptionPatterns({
|
|
508
|
+
patterns
|
|
509
|
+
});
|
|
510
|
+
}
|
|
490
511
|
async screenshot(options = {}) {
|
|
491
512
|
const copy = {
|
|
492
513
|
...options,
|
package/lib/client/playwright.js
CHANGED
|
@@ -33,7 +33,8 @@ class Playwright extends _channelOwner.ChannelOwner {
|
|
|
33
33
|
super(parent, type, guid, initializer);
|
|
34
34
|
this._android = void 0;
|
|
35
35
|
this._electron = void 0;
|
|
36
|
-
this.
|
|
36
|
+
this._bidiChromium = void 0;
|
|
37
|
+
this._bidiFirefox = void 0;
|
|
37
38
|
this.chromium = void 0;
|
|
38
39
|
this.firefox = void 0;
|
|
39
40
|
this.webkit = void 0;
|
|
@@ -50,8 +51,10 @@ class Playwright extends _channelOwner.ChannelOwner {
|
|
|
50
51
|
this.webkit._playwright = this;
|
|
51
52
|
this._android = _android.Android.from(initializer.android);
|
|
52
53
|
this._electron = _electron.Electron.from(initializer.electron);
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
54
|
+
this._bidiChromium = _browserType.BrowserType.from(initializer.bidiChromium);
|
|
55
|
+
this._bidiChromium._playwright = this;
|
|
56
|
+
this._bidiFirefox = _browserType.BrowserType.from(initializer.bidiFirefox);
|
|
57
|
+
this._bidiFirefox._playwright = this;
|
|
55
58
|
this.devices = (_this$_connection$loc = (_this$_connection$loc2 = this._connection.localUtils()) === null || _this$_connection$loc2 === void 0 ? void 0 : _this$_connection$loc2.devices) !== null && _this$_connection$loc !== void 0 ? _this$_connection$loc : {};
|
|
56
59
|
this.selectors = new _selectors.Selectors();
|
|
57
60
|
this.errors = {
|