@checkly/playwright-core 1.47.20-alpha → 1.48.20
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/checkly/escapeRegExp.js +33 -0
- package/lib/checkly/secretsFilter.js +23 -0
- 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 -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 +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 +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 +16 -10
- 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 +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 +70 -5
- 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-d0KhC1qL.js +24 -0
- package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
- package/lib/vite/recorder/assets/{index-D-5S5PPN.js → index-Bxxcmxlu.js} +10 -15
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BTYWvxEC.js +16437 -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-Ca-1BNel.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-CcviAl53.js +16831 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DS3v0XrQ.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DZoSgqUd.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DblsdhjA.js +16449 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DtXZtbmO.js +16437 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-EhKN7Okm.js +16449 -0
- package/lib/vite/{recorder/assets/codeMirrorModule-C-fQ5QZD.js → traceViewer/assets/codeMirrorModule-MzSmL4X2.js} +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-U6XMqGkV.js +16437 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-lDjkI8Ax.js +24 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BABZNwlH.js +17351 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BB2Bm-wy.js +17361 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BHcfR9dD.js +64 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BPzVEZSf.js +17351 -0
- package/lib/vite/traceViewer/assets/inspectorTab-BPzhNk9r.js +64 -0
- package/lib/vite/traceViewer/assets/inspectorTab-Bbgq0hgt.js +64 -0
- package/lib/vite/traceViewer/assets/inspectorTab-C_OTuI8x.js +17361 -0
- package/lib/vite/traceViewer/assets/inspectorTab-DOc4D3cX.js +17361 -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/workbench-B13nfocr.js +9 -0
- package/lib/vite/traceViewer/assets/workbench-BcgGQnKb.js +1473 -0
- 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-CWtpwfKK.js +1473 -0
- package/lib/vite/traceViewer/assets/workbench-Crj6jzdv.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-DLv_q9ji.js +9 -0
- package/lib/vite/traceViewer/assets/workbench-DZqNXdoV.js +9 -0
- package/lib/vite/traceViewer/assets/workbench-DhqI6jeL.js +1473 -0
- package/lib/vite/traceViewer/assets/workbench-I4s6sWjN.js +1473 -0
- package/lib/vite/traceViewer/assets/workbench-M-Dh_RgU.js +1473 -0
- package/lib/vite/traceViewer/assets/workbench-Pa1v1Ojh.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-gtYcQBNA.js +9 -0
- package/lib/vite/traceViewer/assets/xtermModule-DZP0glxx.js +5982 -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.BIubxTi3.js +2 -0
- package/lib/vite/traceViewer/embedded.CHH7D63q.js +106 -0
- package/lib/vite/traceViewer/embedded.CorI3dFX.js +104 -0
- package/lib/vite/traceViewer/embedded.D4lqGydT.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.Dxe2heQk.js +2 -0
- package/lib/vite/traceViewer/embedded.SsjKHrxC.js +105 -0
- package/lib/vite/traceViewer/embedded.Zu332ZC1.js +106 -0
- package/lib/vite/traceViewer/embedded.f-PLGsBT.js +2 -0
- package/lib/vite/traceViewer/embedded.html +5 -3
- package/lib/vite/traceViewer/embedded.ymLJ2mBS.js +106 -0
- package/lib/vite/traceViewer/index.B7aiTMfZ.js +2 -0
- package/lib/vite/traceViewer/index.BSak5QT9.js +2 -0
- package/lib/vite/traceViewer/index.Bfh46hDK.js +197 -0
- package/lib/vite/traceViewer/index.BrT2kfuc.js +2 -0
- package/lib/vite/traceViewer/index.C8ZWP1Qw.js +197 -0
- package/lib/vite/traceViewer/index.CB297BuW.js +2 -0
- package/lib/vite/traceViewer/index.CLxsp2W_.js +197 -0
- package/lib/vite/traceViewer/index.DPD22sZn.js +2 -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.html +5 -3
- 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.BHq8OXiu.js +551 -0
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.BaRuS6Pc.js +2 -0
- package/lib/vite/traceViewer/recorder.BufKu9Hp.js +550 -0
- package/lib/vite/traceViewer/recorder.C88JDknq.js +2 -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.Fwf59ZKh.js +551 -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/recorder.zV_xPHM4.js +551 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.2tr9k625.js +5 -0
- package/lib/vite/traceViewer/uiMode.B11wexdJ.js +5 -0
- package/lib/vite/traceViewer/uiMode.BEZVCe5O.js +5 -0
- package/lib/vite/traceViewer/uiMode.BH2Nj2h0.js +1724 -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.CBRJkC_K.js +1724 -0
- package/lib/vite/traceViewer/uiMode.CpC2B27N.js +1724 -0
- package/lib/vite/traceViewer/uiMode.DRmgrHSk.css +1462 -0
- package/lib/vite/traceViewer/uiMode.DdtUZZVS.js +5 -0
- package/lib/vite/traceViewer/uiMode.Dlo9s_YX.js +1723 -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 +6 -4
- package/lib/vite/traceViewer/uiMode.wsGnVMQK.js +1723 -0
- package/lib/vite/traceViewer/workbench.9Es1K_T7.css +549 -0
- package/lib/vite/traceViewer/workbench.BQNDbcQ0.css +550 -0
- package/lib/vite/traceViewer/workbench.DjbIuxix.css +1 -0
- package/lib/vite/traceViewer/workbench.DlsCx8k5.css +1 -0
- package/lib/vite/traceViewer/workbench.wuxQoE2z.css +3703 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +610 -173
- package/types/types.d.ts +2037 -949
|
@@ -13,6 +13,7 @@ var _jsHandleDispatcher = require("./jsHandleDispatcher");
|
|
|
13
13
|
var _elementHandlerDispatcher = require("./elementHandlerDispatcher");
|
|
14
14
|
var _artifactDispatcher = require("./artifactDispatcher");
|
|
15
15
|
var _utils = require("../../utils");
|
|
16
|
+
var _webSocketRouteDispatcher = require("./webSocketRouteDispatcher");
|
|
16
17
|
/**
|
|
17
18
|
* Copyright (c) Microsoft Corporation.
|
|
18
19
|
*
|
|
@@ -54,6 +55,7 @@ class PageDispatcher extends _dispatcher.Dispatcher {
|
|
|
54
55
|
this._type_Page = true;
|
|
55
56
|
this._page = void 0;
|
|
56
57
|
this._subscriptions = new Set();
|
|
58
|
+
this._webSocketInterceptionPatterns = [];
|
|
57
59
|
this.adopt(mainFrame);
|
|
58
60
|
this._page = page;
|
|
59
61
|
this.addObjectListener(_page.Page.Events.Close, () => {
|
|
@@ -133,6 +135,9 @@ class PageDispatcher extends _dispatcher.Dispatcher {
|
|
|
133
135
|
response: _networkDispatchers.ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goForward(metadata, params))
|
|
134
136
|
};
|
|
135
137
|
}
|
|
138
|
+
async requestGC(params, metadata) {
|
|
139
|
+
await this._page.requestGC();
|
|
140
|
+
}
|
|
136
141
|
async registerLocatorHandler(params, metadata) {
|
|
137
142
|
const uid = this._page.registerLocatorHandler(params.selector, params.noWaitAfter);
|
|
138
143
|
return {
|
|
@@ -174,6 +179,10 @@ class PageDispatcher extends _dispatcher.Dispatcher {
|
|
|
174
179
|
return true;
|
|
175
180
|
});
|
|
176
181
|
}
|
|
182
|
+
async setWebSocketInterceptionPatterns(params, metadata) {
|
|
183
|
+
this._webSocketInterceptionPatterns = params.patterns;
|
|
184
|
+
if (params.patterns.length) await _webSocketRouteDispatcher.WebSocketRouteDispatcher.installIfNeeded(this.parentScope(), this._page);
|
|
185
|
+
}
|
|
177
186
|
async expectScreenshot(params, metadata) {
|
|
178
187
|
const mask = (params.mask || []).map(({
|
|
179
188
|
frame,
|
|
@@ -39,9 +39,10 @@ class PlaywrightDispatcher extends _dispatcher.Dispatcher {
|
|
|
39
39
|
const prelaunchedAndroidDeviceDispatcher = prelaunchedAndroidDevice ? new _androidDispatcher.AndroidDeviceDispatcher(android, prelaunchedAndroidDevice) : undefined;
|
|
40
40
|
super(scope, playwright, 'Playwright', {
|
|
41
41
|
chromium: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium),
|
|
42
|
-
bidi: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidi),
|
|
43
42
|
firefox: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox),
|
|
44
43
|
webkit: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit),
|
|
44
|
+
bidiChromium: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiChromium),
|
|
45
|
+
bidiFirefox: new _browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiFirefox),
|
|
45
46
|
android,
|
|
46
47
|
electron: new _electronDispatcher.ElectronDispatcher(scope, playwright.electron),
|
|
47
48
|
utils: playwright.options.isServer ? undefined : new _localUtilsDispatcher.LocalUtilsDispatcher(scope, playwright),
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.WebSocketRouteDispatcher = void 0;
|
|
7
|
+
var _page = require("../page");
|
|
8
|
+
var _dispatcher = require("./dispatcher");
|
|
9
|
+
var _utils = require("../../utils");
|
|
10
|
+
var _pageDispatcher = require("./pageDispatcher");
|
|
11
|
+
var webSocketMockSource = _interopRequireWildcard(require("../../generated/webSocketMockSource"));
|
|
12
|
+
var _eventsHelper = require("../../utils/eventsHelper");
|
|
13
|
+
var _class;
|
|
14
|
+
/**
|
|
15
|
+
* Copyright (c) Microsoft Corporation.
|
|
16
|
+
*
|
|
17
|
+
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
18
|
+
* you may not use this file except in compliance with the License.
|
|
19
|
+
* You may obtain a copy of the License at
|
|
20
|
+
*
|
|
21
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
*
|
|
23
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
24
|
+
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
25
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
26
|
+
* See the License for the specific language governing permissions and
|
|
27
|
+
* limitations under the License.
|
|
28
|
+
*/
|
|
29
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
30
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
31
|
+
const kBindingInstalledSymbol = Symbol('webSocketRouteBindingInstalled');
|
|
32
|
+
const kInitScriptInstalledSymbol = Symbol('webSocketRouteInitScriptInstalled');
|
|
33
|
+
class WebSocketRouteDispatcher extends _dispatcher.Dispatcher {
|
|
34
|
+
constructor(scope, id, url, frame) {
|
|
35
|
+
super(scope, {
|
|
36
|
+
guid: 'webSocketRoute@' + (0, _utils.createGuid)()
|
|
37
|
+
}, 'WebSocketRoute', {
|
|
38
|
+
url
|
|
39
|
+
});
|
|
40
|
+
this._type_WebSocketRoute = true;
|
|
41
|
+
this._id = void 0;
|
|
42
|
+
this._frame = void 0;
|
|
43
|
+
this._id = id;
|
|
44
|
+
this._frame = frame;
|
|
45
|
+
this._eventListeners.push(
|
|
46
|
+
// When the frame navigates or detaches, there will be no more communication
|
|
47
|
+
// from the mock websocket, so pretend like it was closed.
|
|
48
|
+
_eventsHelper.eventsHelper.addEventListener(frame._page, _page.Page.Events.InternalFrameNavigatedToNewDocument, frame => {
|
|
49
|
+
if (frame === this._frame) this._executionContextGone();
|
|
50
|
+
}), _eventsHelper.eventsHelper.addEventListener(frame._page, _page.Page.Events.FrameDetached, frame => {
|
|
51
|
+
if (frame === this._frame) this._executionContextGone();
|
|
52
|
+
}), _eventsHelper.eventsHelper.addEventListener(frame._page, _page.Page.Events.Close, () => this._executionContextGone()), _eventsHelper.eventsHelper.addEventListener(frame._page, _page.Page.Events.Crash, () => this._executionContextGone()));
|
|
53
|
+
WebSocketRouteDispatcher._idToDispatcher.set(this._id, this);
|
|
54
|
+
scope._dispatchEvent('webSocketRoute', {
|
|
55
|
+
webSocketRoute: this
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
static async installIfNeeded(contextDispatcher, target) {
|
|
59
|
+
const context = target instanceof _page.Page ? target.context() : target;
|
|
60
|
+
if (!context[kBindingInstalledSymbol]) {
|
|
61
|
+
context[kBindingInstalledSymbol] = true;
|
|
62
|
+
await context.exposeBinding('__pwWebSocketBinding', false, (source, payload) => {
|
|
63
|
+
if (payload.type === 'onCreate') {
|
|
64
|
+
const pageDispatcher = _pageDispatcher.PageDispatcher.fromNullable(contextDispatcher, source.page);
|
|
65
|
+
let scope;
|
|
66
|
+
if (pageDispatcher && matchesPattern(pageDispatcher, context._options.baseURL, payload.url)) scope = pageDispatcher;else if (matchesPattern(contextDispatcher, context._options.baseURL, payload.url)) scope = contextDispatcher;
|
|
67
|
+
if (scope) {
|
|
68
|
+
new WebSocketRouteDispatcher(scope, payload.id, payload.url, source.frame);
|
|
69
|
+
} else {
|
|
70
|
+
const request = {
|
|
71
|
+
id: payload.id,
|
|
72
|
+
type: 'passthrough'
|
|
73
|
+
};
|
|
74
|
+
source.frame.evaluateExpression(`globalThis.__pwWebSocketDispatch(${JSON.stringify(request)})`).catch(() => {});
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const dispatcher = WebSocketRouteDispatcher._idToDispatcher.get(payload.id);
|
|
79
|
+
if (payload.type === 'onMessageFromPage') dispatcher === null || dispatcher === void 0 || dispatcher._dispatchEvent('messageFromPage', {
|
|
80
|
+
message: payload.data.data,
|
|
81
|
+
isBase64: payload.data.isBase64
|
|
82
|
+
});
|
|
83
|
+
if (payload.type === 'onMessageFromServer') dispatcher === null || dispatcher === void 0 || dispatcher._dispatchEvent('messageFromServer', {
|
|
84
|
+
message: payload.data.data,
|
|
85
|
+
isBase64: payload.data.isBase64
|
|
86
|
+
});
|
|
87
|
+
if (payload.type === 'onClosePage') dispatcher === null || dispatcher === void 0 || dispatcher._dispatchEvent('closePage', {
|
|
88
|
+
code: payload.code,
|
|
89
|
+
reason: payload.reason,
|
|
90
|
+
wasClean: payload.wasClean
|
|
91
|
+
});
|
|
92
|
+
if (payload.type === 'onCloseServer') dispatcher === null || dispatcher === void 0 || dispatcher._dispatchEvent('closeServer', {
|
|
93
|
+
code: payload.code,
|
|
94
|
+
reason: payload.reason,
|
|
95
|
+
wasClean: payload.wasClean
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (!target[kInitScriptInstalledSymbol]) {
|
|
100
|
+
target[kInitScriptInstalledSymbol] = true;
|
|
101
|
+
await target.addInitScript(`
|
|
102
|
+
(() => {
|
|
103
|
+
const module = {};
|
|
104
|
+
${webSocketMockSource.source}
|
|
105
|
+
(module.exports.inject())(globalThis);
|
|
106
|
+
})();
|
|
107
|
+
`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async connect(params) {
|
|
111
|
+
await this._evaluateAPIRequest({
|
|
112
|
+
id: this._id,
|
|
113
|
+
type: 'connect'
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async ensureOpened(params) {
|
|
117
|
+
await this._evaluateAPIRequest({
|
|
118
|
+
id: this._id,
|
|
119
|
+
type: 'ensureOpened'
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async sendToPage(params) {
|
|
123
|
+
await this._evaluateAPIRequest({
|
|
124
|
+
id: this._id,
|
|
125
|
+
type: 'sendToPage',
|
|
126
|
+
data: {
|
|
127
|
+
data: params.message,
|
|
128
|
+
isBase64: params.isBase64
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async sendToServer(params) {
|
|
133
|
+
await this._evaluateAPIRequest({
|
|
134
|
+
id: this._id,
|
|
135
|
+
type: 'sendToServer',
|
|
136
|
+
data: {
|
|
137
|
+
data: params.message,
|
|
138
|
+
isBase64: params.isBase64
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async closePage(params) {
|
|
143
|
+
await this._evaluateAPIRequest({
|
|
144
|
+
id: this._id,
|
|
145
|
+
type: 'closePage',
|
|
146
|
+
code: params.code,
|
|
147
|
+
reason: params.reason,
|
|
148
|
+
wasClean: params.wasClean
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async closeServer(params) {
|
|
152
|
+
await this._evaluateAPIRequest({
|
|
153
|
+
id: this._id,
|
|
154
|
+
type: 'closeServer',
|
|
155
|
+
code: params.code,
|
|
156
|
+
reason: params.reason,
|
|
157
|
+
wasClean: params.wasClean
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async _evaluateAPIRequest(request) {
|
|
161
|
+
await this._frame.evaluateExpression(`globalThis.__pwWebSocketDispatch(${JSON.stringify(request)})`).catch(() => {});
|
|
162
|
+
}
|
|
163
|
+
_onDispose() {
|
|
164
|
+
WebSocketRouteDispatcher._idToDispatcher.delete(this._id);
|
|
165
|
+
}
|
|
166
|
+
_executionContextGone() {
|
|
167
|
+
// We could enter here after being disposed upon page closure:
|
|
168
|
+
// - first from the recursive dispose inintiated by PageDispatcher;
|
|
169
|
+
// - then from our own page.on('close') listener.
|
|
170
|
+
if (!this._disposed) {
|
|
171
|
+
this._dispatchEvent('closePage', {
|
|
172
|
+
wasClean: true
|
|
173
|
+
});
|
|
174
|
+
this._dispatchEvent('closeServer', {
|
|
175
|
+
wasClean: true
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.WebSocketRouteDispatcher = WebSocketRouteDispatcher;
|
|
181
|
+
_class = WebSocketRouteDispatcher;
|
|
182
|
+
WebSocketRouteDispatcher._idToDispatcher = new Map();
|
|
183
|
+
function matchesPattern(dispatcher, baseURL, url) {
|
|
184
|
+
for (const pattern of dispatcher._webSocketInterceptionPatterns || []) {
|
|
185
|
+
const urlMatch = pattern.regexSource ? new RegExp(pattern.regexSource, pattern.regexFlags) : pattern.glob;
|
|
186
|
+
if ((0, _utils.urlMatches)(baseURL, url, urlMatch)) return true;
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
}
|
package/lib/server/download.js
CHANGED
|
@@ -39,15 +39,22 @@ class Download {
|
|
|
39
39
|
this.url = url;
|
|
40
40
|
this._suggestedFilename = suggestedFilename;
|
|
41
41
|
page._browserContext._downloads.add(this);
|
|
42
|
-
if (suggestedFilename !== undefined) this.
|
|
42
|
+
if (suggestedFilename !== undefined) this._fireDownloadEvent();
|
|
43
|
+
}
|
|
44
|
+
page() {
|
|
45
|
+
return this._page;
|
|
43
46
|
}
|
|
44
47
|
_filenameSuggested(suggestedFilename) {
|
|
45
48
|
(0, _utils.assert)(this._suggestedFilename === undefined);
|
|
46
49
|
this._suggestedFilename = suggestedFilename;
|
|
47
|
-
this.
|
|
50
|
+
this._fireDownloadEvent();
|
|
48
51
|
}
|
|
49
52
|
suggestedFilename() {
|
|
50
53
|
return this._suggestedFilename;
|
|
51
54
|
}
|
|
55
|
+
_fireDownloadEvent() {
|
|
56
|
+
this._page.instrumentation.onDownload(this._page, this);
|
|
57
|
+
this._page.emit(_page.Page.Events.Download, this);
|
|
58
|
+
}
|
|
52
59
|
}
|
|
53
60
|
exports.Download = Download;
|
package/lib/server/fetch.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.GlobalAPIRequestContext = exports.BrowserContextAPIRequestContext = exports.APIRequestContext = void 0;
|
|
7
|
+
exports.createProxyAgent = createProxyAgent;
|
|
7
8
|
var _http = _interopRequireDefault(require("http"));
|
|
8
9
|
var _https = _interopRequireDefault(require("https"));
|
|
9
10
|
var _stream = require("stream");
|
|
@@ -21,8 +22,8 @@ var _happyEyeballs = require("../utils/happy-eyeballs");
|
|
|
21
22
|
var _instrumentation = require("./instrumentation");
|
|
22
23
|
var _progress = require("./progress");
|
|
23
24
|
var _tracing = require("./trace/recorder/tracing");
|
|
24
|
-
var _network = require("./network");
|
|
25
25
|
var _socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
|
|
26
|
+
var _tls = require("tls");
|
|
26
27
|
var _fetch = require("../checkly/fetch");
|
|
27
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
29
|
/**
|
|
@@ -73,7 +74,7 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
73
74
|
return uid;
|
|
74
75
|
}
|
|
75
76
|
async fetch(params, metadata) {
|
|
76
|
-
var _params$method
|
|
77
|
+
var _params$method;
|
|
77
78
|
const defaults = this._defaultOptions();
|
|
78
79
|
const headers = {
|
|
79
80
|
'user-agent': defaults.userAgent,
|
|
@@ -93,7 +94,9 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
93
94
|
} of params.headers) setHeader(headers, name, value);
|
|
94
95
|
}
|
|
95
96
|
const requestUrl = new URL(params.url, defaults.baseURL);
|
|
96
|
-
if (params.
|
|
97
|
+
if (params.encodedParams) {
|
|
98
|
+
requestUrl.search = params.encodedParams;
|
|
99
|
+
} else if (params.params) {
|
|
97
100
|
for (const {
|
|
98
101
|
name,
|
|
99
102
|
value
|
|
@@ -104,23 +107,9 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
104
107
|
const method = ((_params$method = params.method) === null || _params$method === void 0 ? void 0 : _params$method.toUpperCase()) || 'GET';
|
|
105
108
|
const proxy = defaults.proxy;
|
|
106
109
|
let agent;
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
if (proxy && !((_defaults$clientCerti = defaults.clientCertificates) !== null && _defaults$clientCerti !== void 0 && _defaults$clientCerti.length) && proxy.server !== 'per-context' && !shouldBypassProxy(requestUrl, proxy.bypass)) {
|
|
111
|
-
var _proxyOpts$protocol;
|
|
112
|
-
const proxyOpts = _url.default.parse(proxy.server);
|
|
113
|
-
if ((_proxyOpts$protocol = proxyOpts.protocol) !== null && _proxyOpts$protocol !== void 0 && _proxyOpts$protocol.startsWith('socks')) {
|
|
114
|
-
agent = new _utilsBundle.SocksProxyAgent({
|
|
115
|
-
host: proxyOpts.hostname,
|
|
116
|
-
port: proxyOpts.port || undefined
|
|
117
|
-
});
|
|
118
|
-
} else {
|
|
119
|
-
if (proxy.username) proxyOpts.auth = `${proxy.username}:${proxy.password || ''}`;
|
|
120
|
-
// TODO: We should use HttpProxyAgent conditional on proxyOpts.protocol instead of always using CONNECT method.
|
|
121
|
-
agent = new _utilsBundle.HttpsProxyAgent(proxyOpts);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
110
|
+
// We skip 'per-context' in order to not break existing users. 'per-context' was previously used to
|
|
111
|
+
// workaround an upstream Chromium bug. Can be removed in the future.
|
|
112
|
+
if (proxy && proxy.server !== 'per-context' && !shouldBypassProxy(requestUrl, proxy.bypass)) agent = createProxyAgent(proxy);
|
|
124
113
|
const timeout = defaults.timeoutSettings.timeout(params);
|
|
125
114
|
const deadline = timeout && (0, _utils.monotonicTime)() + timeout;
|
|
126
115
|
const options = {
|
|
@@ -202,6 +191,7 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
202
191
|
try {
|
|
203
192
|
return await this._sendRequest(progress, url, options, postData);
|
|
204
193
|
} catch (e) {
|
|
194
|
+
e = (0, _socksClientCertificatesInterceptor.rewriteOpenSSLErrorIfNeeded)(e);
|
|
205
195
|
if (maxRetries === 0) throw e;
|
|
206
196
|
if (i === maxRetries || options.deadline && (0, _utils.monotonicTime)() + backoff > options.deadline) throw new Error(`Failed after ${i + 1} attempt(s): ${e}`);
|
|
207
197
|
// Retry on connection reset only.
|
|
@@ -239,10 +229,33 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
239
229
|
...options,
|
|
240
230
|
agent
|
|
241
231
|
};
|
|
242
|
-
const
|
|
232
|
+
const checklyTimings = (0, _fetch.initializeTimings)();
|
|
233
|
+
const startAt = (0, _utils.monotonicTime)();
|
|
234
|
+
let dnsLookupAt;
|
|
235
|
+
let tcpConnectionAt;
|
|
236
|
+
let tlsHandshakeAt;
|
|
237
|
+
let requestFinishAt;
|
|
238
|
+
let serverIPAddress;
|
|
239
|
+
let serverPort;
|
|
240
|
+
let securityDetails;
|
|
241
|
+
const listeners = [];
|
|
243
242
|
const request = requestConstructor(url, requestOptions, async response => {
|
|
244
|
-
|
|
243
|
+
const responseAt = (0, _utils.monotonicTime)();
|
|
244
|
+
checklyTimings.values.response = _perf_hooks.performance.now() - checklyTimings.values.startTimeNow;
|
|
245
245
|
const notifyRequestFinished = body => {
|
|
246
|
+
var _tlsHandshakeAt;
|
|
247
|
+
const endAt = (0, _utils.monotonicTime)();
|
|
248
|
+
// spec: http://www.softwareishard.com/blog/har-12-spec/#timings
|
|
249
|
+
const timings = {
|
|
250
|
+
send: requestFinishAt - startAt,
|
|
251
|
+
wait: responseAt - requestFinishAt,
|
|
252
|
+
receive: endAt - responseAt,
|
|
253
|
+
dns: dnsLookupAt ? dnsLookupAt - startAt : -1,
|
|
254
|
+
connect: ((_tlsHandshakeAt = tlsHandshakeAt) !== null && _tlsHandshakeAt !== void 0 ? _tlsHandshakeAt : tcpConnectionAt) - startAt,
|
|
255
|
+
// "If [ssl] is defined then the time is also included in the connect field "
|
|
256
|
+
ssl: tlsHandshakeAt ? tlsHandshakeAt - tcpConnectionAt : -1,
|
|
257
|
+
blocked: -1
|
|
258
|
+
};
|
|
246
259
|
const requestFinishedEvent = {
|
|
247
260
|
requestEvent,
|
|
248
261
|
httpVersion: response.httpVersion,
|
|
@@ -251,7 +264,11 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
251
264
|
headers: response.headers,
|
|
252
265
|
rawHeaders: response.rawHeaders,
|
|
253
266
|
cookies,
|
|
254
|
-
body
|
|
267
|
+
body,
|
|
268
|
+
timings,
|
|
269
|
+
serverIPAddress,
|
|
270
|
+
serverPort,
|
|
271
|
+
securityDetails
|
|
255
272
|
};
|
|
256
273
|
this.emit(APIRequestContext.Events.RequestFinished, requestFinishedEvent);
|
|
257
274
|
};
|
|
@@ -338,7 +355,7 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
338
355
|
response.on('aborted', () => reject(new Error('aborted')));
|
|
339
356
|
const chunks = [];
|
|
340
357
|
const notifyBodyFinished = () => {
|
|
341
|
-
|
|
358
|
+
checklyTimings.values.endAt = _perf_hooks.performance.now();
|
|
342
359
|
const body = Buffer.concat(chunks);
|
|
343
360
|
notifyRequestFinished(body);
|
|
344
361
|
fulfill({
|
|
@@ -350,10 +367,10 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
350
367
|
timings: {
|
|
351
368
|
//@ts-ignore
|
|
352
369
|
values: {
|
|
353
|
-
...
|
|
370
|
+
...checklyTimings.values,
|
|
354
371
|
..._happyEyeballs.httpHappyEyeballsTimings.values
|
|
355
372
|
},
|
|
356
|
-
agent: _happyEyeballs.httpHappyEyeballsTimings.agent ||
|
|
373
|
+
agent: _happyEyeballs.httpHappyEyeballsTimings.agent || checklyTimings.agent
|
|
357
374
|
}
|
|
358
375
|
});
|
|
359
376
|
};
|
|
@@ -386,14 +403,44 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
386
403
|
body.on('data', chunk => chunks.push(chunk));
|
|
387
404
|
body.on('end', notifyBodyFinished);
|
|
388
405
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
406
|
+
(0, _fetch.addRequestListeners)(request, checklyTimings);
|
|
407
|
+
request.on('error', reject);
|
|
408
|
+
listeners.push(_utils.eventsHelper.addEventListener(this, APIRequestContext.Events.Dispose, () => {
|
|
392
409
|
reject(new Error('Request context disposed.'));
|
|
393
410
|
request.destroy();
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
request.on('
|
|
411
|
+
}));
|
|
412
|
+
request.on('close', () => _utils.eventsHelper.removeEventListeners(listeners));
|
|
413
|
+
request.on('socket', socket => {
|
|
414
|
+
// happy eyeballs don't emit lookup and connect events, so we use our custom ones
|
|
415
|
+
const happyEyeBallsTimings = (0, _happyEyeballs.timingForSocket)(socket);
|
|
416
|
+
dnsLookupAt = happyEyeBallsTimings.dnsLookupAt;
|
|
417
|
+
tcpConnectionAt = happyEyeBallsTimings.tcpConnectionAt;
|
|
418
|
+
|
|
419
|
+
// non-happy-eyeballs sockets
|
|
420
|
+
listeners.push(_utils.eventsHelper.addEventListener(socket, 'lookup', () => {
|
|
421
|
+
dnsLookupAt = (0, _utils.monotonicTime)();
|
|
422
|
+
}), _utils.eventsHelper.addEventListener(socket, 'connect', () => {
|
|
423
|
+
tcpConnectionAt = (0, _utils.monotonicTime)();
|
|
424
|
+
}), _utils.eventsHelper.addEventListener(socket, 'secureConnect', () => {
|
|
425
|
+
tlsHandshakeAt = (0, _utils.monotonicTime)();
|
|
426
|
+
if (socket instanceof _tls.TLSSocket) {
|
|
427
|
+
var _socket$getProtocol;
|
|
428
|
+
const peerCertificate = socket.getPeerCertificate();
|
|
429
|
+
securityDetails = {
|
|
430
|
+
protocol: (_socket$getProtocol = socket.getProtocol()) !== null && _socket$getProtocol !== void 0 ? _socket$getProtocol : undefined,
|
|
431
|
+
subjectName: peerCertificate.subject.CN,
|
|
432
|
+
validFrom: new Date(peerCertificate.valid_from).getTime() / 1000,
|
|
433
|
+
validTo: new Date(peerCertificate.valid_to).getTime() / 1000,
|
|
434
|
+
issuer: peerCertificate.issuer.CN
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}));
|
|
438
|
+
serverIPAddress = socket.remoteAddress;
|
|
439
|
+
serverPort = socket.remotePort;
|
|
440
|
+
});
|
|
441
|
+
request.on('finish', () => {
|
|
442
|
+
requestFinishAt = (0, _utils.monotonicTime)();
|
|
443
|
+
});
|
|
397
444
|
progress.log(`→ ${options.method} ${url.toString()}`);
|
|
398
445
|
if (options.headers) {
|
|
399
446
|
for (const [name, value] of Object.entries(options.headers)) progress.log(` ${name}: ${value}`);
|
|
@@ -539,6 +586,19 @@ class GlobalAPIRequestContext extends APIRequestContext {
|
|
|
539
586
|
}
|
|
540
587
|
}
|
|
541
588
|
exports.GlobalAPIRequestContext = GlobalAPIRequestContext;
|
|
589
|
+
function createProxyAgent(proxy) {
|
|
590
|
+
var _proxyOpts$protocol;
|
|
591
|
+
const proxyOpts = _url.default.parse(proxy.server);
|
|
592
|
+
if ((_proxyOpts$protocol = proxyOpts.protocol) !== null && _proxyOpts$protocol !== void 0 && _proxyOpts$protocol.startsWith('socks')) {
|
|
593
|
+
return new _utilsBundle.SocksProxyAgent({
|
|
594
|
+
host: proxyOpts.hostname,
|
|
595
|
+
port: proxyOpts.port || undefined
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
if (proxy.username) proxyOpts.auth = `${proxy.username}:${proxy.password || ''}`;
|
|
599
|
+
// TODO: We should use HttpProxyAgent conditional on proxyOpts.protocol instead of always using CONNECT method.
|
|
600
|
+
return new _utilsBundle.HttpsProxyAgent(proxyOpts);
|
|
601
|
+
}
|
|
542
602
|
function toHeadersArray(rawHeaders) {
|
|
543
603
|
const result = [];
|
|
544
604
|
for (let i = 0; i < rawHeaders.length; i += 2) result.push({
|
|
@@ -549,26 +609,9 @@ function toHeadersArray(rawHeaders) {
|
|
|
549
609
|
}
|
|
550
610
|
const redirectStatus = [301, 302, 303, 307, 308];
|
|
551
611
|
function parseCookie(header) {
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
let value = '';
|
|
555
|
-
const separatorPos = p.indexOf('=');
|
|
556
|
-
if (separatorPos === -1) {
|
|
557
|
-
// If only a key is specified, the value is left undefined.
|
|
558
|
-
key = p.trim();
|
|
559
|
-
} else {
|
|
560
|
-
// Otherwise we assume that the key is the element before the first `=`
|
|
561
|
-
key = p.slice(0, separatorPos).trim();
|
|
562
|
-
// And the value is the rest of the string.
|
|
563
|
-
value = p.slice(separatorPos + 1).trim();
|
|
564
|
-
}
|
|
565
|
-
return [key, value];
|
|
566
|
-
});
|
|
567
|
-
if (!pairs.length) return null;
|
|
568
|
-
const [name, value] = pairs[0];
|
|
612
|
+
const raw = (0, _cookieStore.parseRawCookie)(header);
|
|
613
|
+
if (!raw) return null;
|
|
569
614
|
const cookie = {
|
|
570
|
-
name,
|
|
571
|
-
value,
|
|
572
615
|
domain: '',
|
|
573
616
|
path: '',
|
|
574
617
|
expires: -1,
|
|
@@ -576,55 +619,9 @@ function parseCookie(header) {
|
|
|
576
619
|
secure: false,
|
|
577
620
|
// From https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
|
578
621
|
// The cookie-sending behavior if SameSite is not specified is SameSite=Lax.
|
|
579
|
-
sameSite: 'Lax'
|
|
622
|
+
sameSite: 'Lax',
|
|
623
|
+
...raw
|
|
580
624
|
};
|
|
581
|
-
for (let i = 1; i < pairs.length; i++) {
|
|
582
|
-
const [name, value] = pairs[i];
|
|
583
|
-
switch (name.toLowerCase()) {
|
|
584
|
-
case 'expires':
|
|
585
|
-
const expiresMs = +new Date(value);
|
|
586
|
-
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.1
|
|
587
|
-
if (isFinite(expiresMs)) {
|
|
588
|
-
if (expiresMs <= 0) cookie.expires = 0;else cookie.expires = Math.min(expiresMs / 1000, _network.kMaxCookieExpiresDateInSeconds);
|
|
589
|
-
}
|
|
590
|
-
break;
|
|
591
|
-
case 'max-age':
|
|
592
|
-
const maxAgeSec = parseInt(value, 10);
|
|
593
|
-
if (isFinite(maxAgeSec)) {
|
|
594
|
-
// From https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.2
|
|
595
|
-
// If delta-seconds is less than or equal to zero (0), let expiry-time
|
|
596
|
-
// be the earliest representable date and time.
|
|
597
|
-
if (maxAgeSec <= 0) cookie.expires = 0;else cookie.expires = Math.min(Date.now() / 1000 + maxAgeSec, _network.kMaxCookieExpiresDateInSeconds);
|
|
598
|
-
}
|
|
599
|
-
break;
|
|
600
|
-
case 'domain':
|
|
601
|
-
cookie.domain = value.toLocaleLowerCase() || '';
|
|
602
|
-
if (cookie.domain && !cookie.domain.startsWith('.') && cookie.domain.includes('.')) cookie.domain = '.' + cookie.domain;
|
|
603
|
-
break;
|
|
604
|
-
case 'path':
|
|
605
|
-
cookie.path = value || '';
|
|
606
|
-
break;
|
|
607
|
-
case 'secure':
|
|
608
|
-
cookie.secure = true;
|
|
609
|
-
break;
|
|
610
|
-
case 'httponly':
|
|
611
|
-
cookie.httpOnly = true;
|
|
612
|
-
break;
|
|
613
|
-
case 'samesite':
|
|
614
|
-
switch (value.toLowerCase()) {
|
|
615
|
-
case 'none':
|
|
616
|
-
cookie.sameSite = 'None';
|
|
617
|
-
break;
|
|
618
|
-
case 'lax':
|
|
619
|
-
cookie.sameSite = 'Lax';
|
|
620
|
-
break;
|
|
621
|
-
case 'strict':
|
|
622
|
-
cookie.sameSite = 'Strict';
|
|
623
|
-
break;
|
|
624
|
-
}
|
|
625
|
-
break;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
625
|
return cookie;
|
|
629
626
|
}
|
|
630
627
|
function serializePostData(params, headers) {
|
|
@@ -53,7 +53,8 @@ class FFBrowser extends _browser.Browser {
|
|
|
53
53
|
browser._defaultContext = new FFBrowserContext(browser, undefined, options.persistent);
|
|
54
54
|
promises.push(browser._defaultContext._initialize());
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
const proxy = options.originalLaunchOptions.proxyOverride || options.proxy;
|
|
57
|
+
if (proxy) promises.push(browser.session.send('Browser.setBrowserProxy', toJugglerProxyOptions(proxy)));
|
|
57
58
|
await Promise.all(promises);
|
|
58
59
|
return browser;
|
|
59
60
|
}
|
|
@@ -205,7 +206,7 @@ class FFBrowserContext extends _browserContext.BrowserContext {
|
|
|
205
206
|
browserContextId,
|
|
206
207
|
bypassCSP: true
|
|
207
208
|
}));
|
|
208
|
-
if (this._options.ignoreHTTPSErrors) promises.push(this._browser.session.send('Browser.setIgnoreHTTPSErrors', {
|
|
209
|
+
if (this._options.ignoreHTTPSErrors || this._options.internalIgnoreHTTPSErrors) promises.push(this._browser.session.send('Browser.setIgnoreHTTPSErrors', {
|
|
209
210
|
browserContextId,
|
|
210
211
|
ignoreHTTPSErrors: true
|
|
211
212
|
}));
|
|
@@ -255,10 +256,11 @@ class FFBrowserContext extends _browserContext.BrowserContext {
|
|
|
255
256
|
});
|
|
256
257
|
}));
|
|
257
258
|
}
|
|
258
|
-
|
|
259
|
+
const proxy = this._options.proxyOverride || this._options.proxy;
|
|
260
|
+
if (proxy) {
|
|
259
261
|
promises.push(this._browser.session.send('Browser.setContextProxy', {
|
|
260
262
|
browserContextId: this._browserContextId,
|
|
261
|
-
...toJugglerProxyOptions(
|
|
263
|
+
...toJugglerProxyOptions(proxy)
|
|
262
264
|
}));
|
|
263
265
|
}
|
|
264
266
|
await Promise.all(promises);
|
|
@@ -101,9 +101,6 @@ class FFExecutionContext {
|
|
|
101
101
|
objectId
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
|
-
objectCount(objectId) {
|
|
105
|
-
throw new Error('Method not implemented in Firefox.');
|
|
106
|
-
}
|
|
107
104
|
}
|
|
108
105
|
exports.FFExecutionContext = FFExecutionContext;
|
|
109
106
|
function checkException(exceptionDetails) {
|
|
@@ -92,19 +92,8 @@ class Firefox extends _browserType.BrowserType {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
exports.Firefox = Firefox;
|
|
95
|
-
class JugglerReadyState {
|
|
96
|
-
constructor() {
|
|
97
|
-
this._jugglerPromise = new _utils.ManualPromise();
|
|
98
|
-
}
|
|
95
|
+
class JugglerReadyState extends _browserType.BrowserReadyState {
|
|
99
96
|
onBrowserOutput(message) {
|
|
100
|
-
if (message.includes('Juggler listening to the pipe')) this.
|
|
101
|
-
}
|
|
102
|
-
onBrowserExit() {
|
|
103
|
-
// Unblock launch when browser prematurely exits.
|
|
104
|
-
this._jugglerPromise.resolve();
|
|
105
|
-
}
|
|
106
|
-
async waitUntilReady() {
|
|
107
|
-
await this._jugglerPromise;
|
|
108
|
-
return {};
|
|
97
|
+
if (message.includes('Juggler listening to the pipe')) this._wsEndpoint.resolve(undefined);
|
|
109
98
|
}
|
|
110
99
|
}
|
|
@@ -165,7 +165,7 @@ class FrameSelectors {
|
|
|
165
165
|
exports.FrameSelectors = FrameSelectors;
|
|
166
166
|
async function adoptIfNeeded(handle, context) {
|
|
167
167
|
if (handle._context === context) return handle;
|
|
168
|
-
const adopted = handle._page._delegate.adoptElementHandle(handle, context);
|
|
168
|
+
const adopted = await handle._page._delegate.adoptElementHandle(handle, context);
|
|
169
169
|
handle.dispose();
|
|
170
170
|
return adopted;
|
|
171
171
|
}
|
package/lib/server/frames.js
CHANGED
|
@@ -623,14 +623,15 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
623
623
|
if (!['attached', 'detached', 'visible', 'hidden'].includes(state)) throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
|
|
624
624
|
return controller.run(async progress => {
|
|
625
625
|
progress.log(`waiting for ${this._asLocator(selector)}${state === 'attached' ? '' : ' to be ' + state}`);
|
|
626
|
-
return await this.waitForSelectorInternal(progress, selector, options, scope);
|
|
626
|
+
return await this.waitForSelectorInternal(progress, selector, true, options, scope);
|
|
627
627
|
}, this._page._timeoutSettings.timeout(options));
|
|
628
628
|
}
|
|
629
|
-
async waitForSelectorInternal(progress, selector, options, scope) {
|
|
629
|
+
async waitForSelectorInternal(progress, selector, performLocatorHandlersCheckpoint, options, scope) {
|
|
630
630
|
const {
|
|
631
631
|
state = 'visible'
|
|
632
632
|
} = options;
|
|
633
633
|
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
634
|
+
if (performLocatorHandlersCheckpoint) await this._page.performLocatorHandlersCheckpoint(progress);
|
|
634
635
|
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
|
|
635
636
|
progress.throwIfAborted();
|
|
636
637
|
if (!resolved) {
|