patchright-core 1.49.2 → 1.50.0
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/ThirdPartyNotices.txt +9 -9
- package/bin/reinstall_msedge_beta_linux.sh +6 -0
- package/bin/reinstall_msedge_dev_linux.sh +6 -0
- package/bin/reinstall_msedge_stable_linux.sh +6 -0
- package/browsers.json +17 -16
- package/lib/androidServerImpl.js +1 -1
- package/lib/cli/program.js +6 -30
- package/lib/client/channelOwner.js +35 -55
- package/lib/client/clientInstrumentation.js +2 -0
- package/lib/client/connection.js +3 -3
- package/lib/client/network.js +3 -1
- package/lib/client/waiter.js +1 -1
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/inProcessFactory.js +2 -0
- package/lib/protocol/debug.js +1 -1
- package/lib/protocol/validator.js +2 -2
- package/lib/remote/playwrightConnection.js +4 -3
- package/lib/remote/playwrightServer.js +2 -1
- package/lib/server/bidi/bidiBrowser.js +9 -6
- package/lib/server/bidi/bidiExecutionContext.js +20 -1
- package/lib/server/bidi/bidiInput.js +7 -5
- package/lib/server/bidi/bidiNetworkManager.js +8 -9
- package/lib/server/bidi/bidiPage.js +9 -20
- package/lib/server/bidi/third_party/bidiKeyboard.js +9 -7
- package/lib/server/browserContext.js +24 -16
- package/lib/server/chromium/crBrowser.js +10 -10
- package/lib/server/chromium/crExecutionContext.js +1 -5
- package/lib/server/chromium/crInput.js +15 -4
- package/lib/server/chromium/crPage.js +17 -31
- package/lib/server/codegen/csharp.js +12 -2
- package/lib/server/codegen/java.js +14 -3
- package/lib/server/codegen/javascript.js +10 -2
- package/lib/server/codegen/jsonl.js +1 -1
- package/lib/server/codegen/python.js +5 -4
- package/lib/server/debugController.js +15 -40
- package/lib/server/debugger.js +1 -1
- package/lib/server/deviceDescriptorsSource.json +50 -50
- package/lib/server/dispatchers/browserContextDispatcher.js +2 -13
- package/lib/server/dispatchers/debugControllerDispatcher.js +4 -2
- package/lib/server/dispatchers/frameDispatcher.js +3 -2
- package/lib/server/dispatchers/pageDispatcher.js +1 -1
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +10 -11
- package/lib/server/dom.js +7 -2
- package/lib/server/firefox/ffBrowser.js +6 -6
- package/lib/server/firefox/ffInput.js +15 -4
- package/lib/server/firefox/ffPage.js +13 -28
- package/lib/server/frames.js +25 -30
- package/lib/server/har/harTracer.js +1 -1
- package/lib/server/input.js +2 -3
- package/lib/server/network.js +2 -2
- package/lib/server/page.js +23 -16
- package/lib/server/recorder/chat.js +177 -0
- package/lib/server/recorder/contextRecorder.js +6 -15
- package/lib/server/recorder/recorderApp.js +1 -1
- package/lib/server/recorder/recorderCollection.js +4 -16
- package/lib/server/recorder/recorderRunner.js +7 -3
- package/lib/server/recorder/recorderUtils.js +5 -29
- package/lib/server/recorder.js +12 -9
- package/lib/server/registry/browserFetcher.js +1 -1
- package/lib/server/registry/dependencies.js +5 -5
- package/lib/server/registry/index.js +118 -5
- package/lib/server/registry/nativeDeps.js +7 -4
- package/lib/server/trace/recorder/snapshotterInjected.js +12 -5
- package/lib/server/trace/viewer/traceViewer.js +6 -1
- package/lib/server/transport.js +1 -0
- package/lib/server/webkit/webkit.js +1 -1
- package/lib/server/webkit/wkBrowser.js +6 -6
- package/lib/server/webkit/wkExecutionContext.js +1 -0
- package/lib/server/webkit/wkInput.js +15 -5
- package/lib/server/webkit/wkPage.js +7 -25
- package/lib/utils/comparators.js +16 -10
- package/lib/utils/debugLogger.js +3 -1
- package/lib/utils/hostPlatform.js +14 -8
- package/lib/utils/isomorphic/ariaSnapshot.js +176 -52
- package/lib/utils/isomorphic/cssParser.js +4 -4
- package/lib/utils/isomorphic/locatorGenerators.js +2 -2
- package/lib/utils/isomorphic/locatorParser.js +18 -12
- package/lib/utils/isomorphic/urlMatch.js +2 -4
- package/lib/utils/processLauncher.js +1 -1
- package/lib/utils/wsServer.js +1 -0
- package/lib/utils/zones.js +18 -20
- package/lib/utilsBundleImpl/index.js +95 -95
- package/lib/vite/htmlReport/index.html +14 -14
- package/lib/vite/{traceViewer/assets/codeMirrorModule-VZNWuWvU.js → recorder/assets/codeMirrorModule-3Qn3tPnZ.js} +1 -1
- package/lib/vite/recorder/assets/{index-CqeZmzx8.js → index-Bek6JFv8.js} +78 -78
- package/lib/vite/recorder/assets/{index-iA1aAGZg.css → index-CAQewHss.css} +1 -1
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/{recorder/assets/codeMirrorModule-DUzBrnvO.js → traceViewer/assets/codeMirrorModule-aLkSUGpW.js} +1 -1
- package/lib/vite/traceViewer/assets/defaultSettingsView-CxUo6zd3.js +243 -0
- package/lib/vite/traceViewer/defaultSettingsView.DtIkrKWn.css +1 -0
- package/lib/vite/traceViewer/index.Bhu5cv5R.js +2 -0
- package/lib/vite/traceViewer/index.html +3 -6
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.BBy7FOVd.js +5 -0
- package/lib/vite/traceViewer/{uiMode.voC1ZiOQ.css → uiMode.Be_ME-Go.css} +1 -1
- package/lib/vite/traceViewer/uiMode.html +4 -7
- package/package.json +1 -1
- package/types/protocol.d.ts +269 -20
- package/types/types.d.ts +44 -23
- package/bin/PrintDeps.exe +0 -0
- package/bin/README.md +0 -2
- package/lib/server/ariaSnapshot.js +0 -33
- package/lib/server/recorder/recorderInTraceViewer.js +0 -144
- package/lib/utils/isomorphic/recorderUtils.js +0 -227
- package/lib/vite/traceViewer/assets/inspectorTab-BV-Uf3j9.js +0 -68
- package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +0 -1
- package/lib/vite/traceViewer/assets/workbench-B4WPcYi9.js +0 -9
- package/lib/vite/traceViewer/embedded.BLPSqdbm.js +0 -2
- package/lib/vite/traceViewer/embedded.html +0 -18
- package/lib/vite/traceViewer/embedded.w7WN2u1R.css +0 -1
- package/lib/vite/traceViewer/index.BGZfFXXF.js +0 -2
- package/lib/vite/traceViewer/inspectorTab.DEOUW62d.css +0 -1
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.eWs2vuTG.js +0 -2
- package/lib/vite/traceViewer/recorder.html +0 -17
- package/lib/vite/traceViewer/uiMode.CW2d9h0S.js +0 -5
- package/lib/vite/traceViewer/workbench.C-zR9ysA.css +0 -1
|
@@ -28,8 +28,6 @@ var _class;
|
|
|
28
28
|
*/
|
|
29
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
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
31
|
class WebSocketRouteDispatcher extends _dispatcher.Dispatcher {
|
|
34
32
|
constructor(scope, id, url, frame) {
|
|
35
33
|
super(scope, {
|
|
@@ -55,15 +53,16 @@ class WebSocketRouteDispatcher extends _dispatcher.Dispatcher {
|
|
|
55
53
|
webSocketRoute: this
|
|
56
54
|
});
|
|
57
55
|
}
|
|
58
|
-
static async installIfNeeded(
|
|
56
|
+
static async installIfNeeded(target) {
|
|
57
|
+
const kBindingName = '__pwWebSocketBinding';
|
|
59
58
|
const context = target instanceof _page.Page ? target.context() : target;
|
|
60
|
-
if (!context
|
|
61
|
-
context
|
|
62
|
-
await context.exposeBinding('__pwWebSocketBinding', false, (source, payload) => {
|
|
59
|
+
if (!context.hasBinding(kBindingName)) {
|
|
60
|
+
await context.exposeBinding(kBindingName, false, (source, payload) => {
|
|
63
61
|
if (payload.type === 'onCreate') {
|
|
64
|
-
const
|
|
62
|
+
const contextDispatcher = (0, _dispatcher.existingDispatcher)(context);
|
|
63
|
+
const pageDispatcher = contextDispatcher ? _pageDispatcher.PageDispatcher.fromNullable(contextDispatcher, source.page) : undefined;
|
|
65
64
|
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;
|
|
65
|
+
if (pageDispatcher && matchesPattern(pageDispatcher, context._options.baseURL, payload.url)) scope = pageDispatcher;else if (contextDispatcher && matchesPattern(contextDispatcher, context._options.baseURL, payload.url)) scope = contextDispatcher;
|
|
67
66
|
if (scope) {
|
|
68
67
|
new WebSocketRouteDispatcher(scope, payload.id, payload.url, source.frame);
|
|
69
68
|
} else {
|
|
@@ -96,15 +95,15 @@ class WebSocketRouteDispatcher extends _dispatcher.Dispatcher {
|
|
|
96
95
|
});
|
|
97
96
|
});
|
|
98
97
|
}
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
const kInitScriptName = 'webSocketMockSource';
|
|
99
|
+
if (!target.initScripts.find(s => s.name === kInitScriptName)) {
|
|
101
100
|
await target.addInitScript(`
|
|
102
101
|
(() => {
|
|
103
102
|
const module = {};
|
|
104
103
|
${webSocketMockSource.source}
|
|
105
104
|
(module.exports.inject())(globalThis);
|
|
106
105
|
})();
|
|
107
|
-
|
|
106
|
+
`, kInitScriptName);
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
async connect(params) {
|
package/lib/server/dom.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.NonRecoverableDOMError = exports.FrameExecutionContext = exports.Element
|
|
|
7
7
|
exports.assertDone = assertDone;
|
|
8
8
|
exports.isNonRecoverableDOMError = isNonRecoverableDOMError;
|
|
9
9
|
exports.kUnableToAdoptErrorMessage = void 0;
|
|
10
|
+
exports.throwElementIsNotAttached = throwElementIsNotAttached;
|
|
10
11
|
exports.throwRetargetableDOMError = throwRetargetableDOMError;
|
|
11
12
|
var _fs = _interopRequireDefault(require("fs"));
|
|
12
13
|
var injectedScriptSource = _interopRequireWildcard(require("../generated/injectedScriptSource"));
|
|
@@ -711,7 +712,8 @@ class ElementHandle extends js.JSHandle {
|
|
|
711
712
|
async _setChecked(progress, state, options) {
|
|
712
713
|
const isChecked = async () => {
|
|
713
714
|
const result = await this.evaluateInUtility(([injected, node]) => injected.elementState(node, 'checked'), {});
|
|
714
|
-
|
|
715
|
+
if (result === 'error:notconnected' || result.received === 'error:notconnected') throwElementIsNotAttached();
|
|
716
|
+
return result.matches;
|
|
715
717
|
};
|
|
716
718
|
await this._markAsTargetElement(progress.metadata);
|
|
717
719
|
if ((await isChecked()) === state) return 'done';
|
|
@@ -837,9 +839,12 @@ class ElementHandle extends js.JSHandle {
|
|
|
837
839
|
}
|
|
838
840
|
exports.ElementHandle = ElementHandle;
|
|
839
841
|
function throwRetargetableDOMError(result) {
|
|
840
|
-
if (result === 'error:notconnected')
|
|
842
|
+
if (result === 'error:notconnected') throwElementIsNotAttached();
|
|
841
843
|
return result;
|
|
842
844
|
}
|
|
845
|
+
function throwElementIsNotAttached() {
|
|
846
|
+
throw new Error('Element is not attached to the DOM');
|
|
847
|
+
}
|
|
843
848
|
function assertDone(result) {
|
|
844
849
|
// This function converts 'done' to void and ensures typescript catches unhandled errors.
|
|
845
850
|
}
|
|
@@ -132,13 +132,13 @@ class FFBrowser extends _browser.Browser {
|
|
|
132
132
|
|
|
133
133
|
// Abort the navigation that turned into download.
|
|
134
134
|
ffPage._page._frameManager.frameAbortedNavigation(payload.frameId, 'Download is starting');
|
|
135
|
-
let originPage = ffPage.
|
|
135
|
+
let originPage = ffPage._page.initializedOrUndefined();
|
|
136
136
|
// If it's a new window download, report it on the opener page.
|
|
137
137
|
if (!originPage) {
|
|
138
138
|
// Resume the page creation with an error. The page will automatically close right
|
|
139
139
|
// after the download begins.
|
|
140
140
|
ffPage._markAsError(new Error('Starting new page download'));
|
|
141
|
-
if (ffPage._opener) originPage = ffPage._opener.
|
|
141
|
+
if (ffPage._opener) originPage = ffPage._opener._page.initializedOrUndefined();
|
|
142
142
|
}
|
|
143
143
|
if (!originPage) return;
|
|
144
144
|
this._downloadCreated(originPage, payload.uuid, payload.url, payload.suggestedFileName);
|
|
@@ -268,10 +268,10 @@ class FFBrowserContext extends _browserContext.BrowserContext {
|
|
|
268
268
|
_ffPages() {
|
|
269
269
|
return Array.from(this._browser._ffPages.values()).filter(ffPage => ffPage._browserContext === this);
|
|
270
270
|
}
|
|
271
|
-
|
|
272
|
-
return this._ffPages().map(ffPage => ffPage.
|
|
271
|
+
possiblyUninitializedPages() {
|
|
272
|
+
return this._ffPages().map(ffPage => ffPage._page);
|
|
273
273
|
}
|
|
274
|
-
async
|
|
274
|
+
async doCreateNewPage() {
|
|
275
275
|
(0, _browserContext.assertBrowserContextIsNotOwned)(this);
|
|
276
276
|
const {
|
|
277
277
|
targetId
|
|
@@ -281,7 +281,7 @@ class FFBrowserContext extends _browserContext.BrowserContext {
|
|
|
281
281
|
if (e.message.includes('Failed to override timezone')) throw new Error(`Invalid timezone ID: ${this._options.timezoneId}`);
|
|
282
282
|
throw e;
|
|
283
283
|
});
|
|
284
|
-
return this._browser._ffPages.get(targetId);
|
|
284
|
+
return this._browser._ffPages.get(targetId)._page;
|
|
285
285
|
}
|
|
286
286
|
async doGetCookies(urls) {
|
|
287
287
|
const {
|
|
@@ -47,12 +47,18 @@ class RawKeyboardImpl {
|
|
|
47
47
|
this._client = void 0;
|
|
48
48
|
this._client = client;
|
|
49
49
|
}
|
|
50
|
-
async keydown(modifiers,
|
|
50
|
+
async keydown(modifiers, keyName, description, autoRepeat) {
|
|
51
|
+
let text = description.text;
|
|
51
52
|
// Firefox will figure out Enter by itself
|
|
52
53
|
if (text === '\r') text = '';
|
|
54
|
+
const {
|
|
55
|
+
code,
|
|
56
|
+
key,
|
|
57
|
+
location
|
|
58
|
+
} = description;
|
|
53
59
|
await this._client.send('Page.dispatchKeyEvent', {
|
|
54
60
|
type: 'keydown',
|
|
55
|
-
keyCode: keyCodeWithoutLocation,
|
|
61
|
+
keyCode: description.keyCodeWithoutLocation,
|
|
56
62
|
code,
|
|
57
63
|
key,
|
|
58
64
|
repeat: autoRepeat,
|
|
@@ -60,11 +66,16 @@ class RawKeyboardImpl {
|
|
|
60
66
|
text
|
|
61
67
|
});
|
|
62
68
|
}
|
|
63
|
-
async keyup(modifiers,
|
|
69
|
+
async keyup(modifiers, keyName, description) {
|
|
70
|
+
const {
|
|
71
|
+
code,
|
|
72
|
+
key,
|
|
73
|
+
location
|
|
74
|
+
} = description;
|
|
64
75
|
await this._client.send('Page.dispatchKeyEvent', {
|
|
65
76
|
type: 'keyup',
|
|
66
77
|
key,
|
|
67
|
-
keyCode: keyCodeWithoutLocation,
|
|
78
|
+
keyCode: description.keyCodeWithoutLocation,
|
|
68
79
|
code,
|
|
69
80
|
location,
|
|
70
81
|
repeat: false
|
|
@@ -15,7 +15,6 @@ var _ffInput = require("./ffInput");
|
|
|
15
15
|
var _ffNetworkManager = require("./ffNetworkManager");
|
|
16
16
|
var _stackTrace = require("../../utils/stackTrace");
|
|
17
17
|
var _debugLogger = require("../../utils/debugLogger");
|
|
18
|
-
var _manualPromise = require("../../utils/manualPromise");
|
|
19
18
|
var _browserContext = require("../browserContext");
|
|
20
19
|
var _errors = require("../errors");
|
|
21
20
|
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); }
|
|
@@ -48,9 +47,7 @@ class FFPage {
|
|
|
48
47
|
this._page = void 0;
|
|
49
48
|
this._networkManager = void 0;
|
|
50
49
|
this._browserContext = void 0;
|
|
51
|
-
this.
|
|
52
|
-
this._initializedPage = null;
|
|
53
|
-
this._initializationFailed = false;
|
|
50
|
+
this._reportedAsNew = false;
|
|
54
51
|
this._opener = void 0;
|
|
55
52
|
this._contextIdToContext = void 0;
|
|
56
53
|
this._eventListeners = void 0;
|
|
@@ -70,34 +67,22 @@ class FFPage {
|
|
|
70
67
|
this._page.on(_page.Page.Events.FrameDetached, frame => this._removeContextsForFrame(frame));
|
|
71
68
|
// TODO: remove Page.willOpenNewWindowAsynchronously from the protocol.
|
|
72
69
|
this._eventListeners = [_eventsHelper.eventsHelper.addEventListener(this._session, 'Page.eventFired', this._onEventFired.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.frameAttached', this._onFrameAttached.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.frameDetached', this._onFrameDetached.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.navigationAborted', this._onNavigationAborted.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.navigationCommitted', this._onNavigationCommitted.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.navigationStarted', this._onNavigationStarted.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.sameDocumentNavigation', this._onSameDocumentNavigation.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Runtime.executionContextCreated', this._onExecutionContextCreated.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Runtime.executionContextDestroyed', this._onExecutionContextDestroyed.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Runtime.executionContextsCleared', this._onExecutionContextsCleared.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.linkClicked', event => this._onLinkClicked(event.phase)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.uncaughtError', this._onUncaughtError.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Runtime.console', this._onConsole.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.dialogOpened', this._onDialogOpened.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.bindingCalled', this._onBindingCalled.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.fileChooserOpened', this._onFileChooserOpened.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.workerCreated', this._onWorkerCreated.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.workerDestroyed', this._onWorkerDestroyed.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.dispatchMessageFromWorker', this._onDispatchMessageFromWorker.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.crashed', this._onCrashed.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.videoRecordingStarted', this._onVideoRecordingStarted.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.webSocketCreated', this._onWebSocketCreated.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.webSocketClosed', this._onWebSocketClosed.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.webSocketFrameReceived', this._onWebSocketFrameReceived.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.webSocketFrameSent', this._onWebSocketFrameSent.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._session, 'Page.screencastFrame', this._onScreencastFrame.bind(this))];
|
|
73
|
-
this._session.once('Page.ready',
|
|
74
|
-
|
|
75
|
-
if (this.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this._initializedPage = this._page;
|
|
79
|
-
this._page.reportAsNew();
|
|
80
|
-
this._pagePromise.resolve(this._page);
|
|
70
|
+
this._session.once('Page.ready', () => {
|
|
71
|
+
var _this$_opener;
|
|
72
|
+
if (this._reportedAsNew) return;
|
|
73
|
+
this._reportedAsNew = true;
|
|
74
|
+
this._page.reportAsNew((_this$_opener = this._opener) === null || _this$_opener === void 0 ? void 0 : _this$_opener._page);
|
|
81
75
|
});
|
|
82
76
|
// Ideally, we somehow ensure that utility world is created before Page.ready arrives, but currently it is racy.
|
|
83
77
|
// Therefore, we can end up with an initialized page without utility world, although very unlikely.
|
|
84
78
|
this.addInitScript(new _page.InitScript('', true), UTILITY_WORLD_NAME).catch(e => this._markAsError(e));
|
|
85
79
|
}
|
|
86
|
-
potentiallyUninitializedPage() {
|
|
87
|
-
return this._page;
|
|
88
|
-
}
|
|
89
80
|
async _markAsError(error) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this._page.reportAsNew(error);
|
|
96
|
-
this._pagePromise.resolve(error);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async pageOrError() {
|
|
100
|
-
return this._pagePromise;
|
|
81
|
+
var _this$_opener2;
|
|
82
|
+
// Same error may be reported twice: channel disconnected and session.send fails.
|
|
83
|
+
if (this._reportedAsNew) return;
|
|
84
|
+
this._reportedAsNew = true;
|
|
85
|
+
this._page.reportAsNew((_this$_opener2 = this._opener) === null || _this$_opener2 === void 0 ? void 0 : _this$_opener2._page, error);
|
|
101
86
|
}
|
|
102
87
|
_onWebSocketCreated(event) {
|
|
103
88
|
this._page._frameManager.onWebSocketCreated(webSocketId(event.frameId, event.wsid), event.requestURL);
|
|
@@ -213,7 +198,7 @@ class FFPage {
|
|
|
213
198
|
}, params.defaultValue));
|
|
214
199
|
}
|
|
215
200
|
async _onBindingCalled(event) {
|
|
216
|
-
const pageOrError = await this.
|
|
201
|
+
const pageOrError = await this._page.waitForInitializedOrError();
|
|
217
202
|
if (!(pageOrError instanceof Error)) {
|
|
218
203
|
const context = this._contextIdToContext.get(event.executionContextId);
|
|
219
204
|
if (context) await this._page._onBindingCalled(event.payload, context);
|
|
@@ -286,7 +271,7 @@ class FFPage {
|
|
|
286
271
|
this._page._didCrash();
|
|
287
272
|
}
|
|
288
273
|
_onVideoRecordingStarted(event) {
|
|
289
|
-
this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this.
|
|
274
|
+
this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this._page.waitForInitializedOrError());
|
|
290
275
|
}
|
|
291
276
|
didClose() {
|
|
292
277
|
this._markAsError(new _errors.TargetClosedError());
|
package/lib/server/frames.js
CHANGED
|
@@ -248,9 +248,8 @@ class FrameManager {
|
|
|
248
248
|
request
|
|
249
249
|
});
|
|
250
250
|
if (request._isFavicon) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}).catch(() => {});
|
|
251
|
+
// Abort favicon requests to avoid network access in case of interception.
|
|
252
|
+
route === null || route === void 0 || route.abort('aborted').catch(() => {});
|
|
254
253
|
return;
|
|
255
254
|
}
|
|
256
255
|
this._page.emitOnContext(_browserContext.BrowserContext.Events.Request, request);
|
|
@@ -915,9 +914,9 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
915
914
|
return this._url;
|
|
916
915
|
}
|
|
917
916
|
origin() {
|
|
918
|
-
var _network$
|
|
917
|
+
var _network$parseURL;
|
|
919
918
|
if (!this._url.startsWith('http')) return;
|
|
920
|
-
return (_network$
|
|
919
|
+
return (_network$parseURL = network.parseURL(this._url)) === null || _network$parseURL === void 0 ? void 0 : _network$parseURL.origin;
|
|
921
920
|
}
|
|
922
921
|
parentFrame() {
|
|
923
922
|
return this._parentFrame;
|
|
@@ -1244,7 +1243,8 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1244
1243
|
}, {
|
|
1245
1244
|
state
|
|
1246
1245
|
}, options, scope);
|
|
1247
|
-
|
|
1246
|
+
if (result.received === 'error:notconnected') dom.throwElementIsNotAttached();
|
|
1247
|
+
return result.matches;
|
|
1248
1248
|
}
|
|
1249
1249
|
async isVisible(metadata, selector, options = {}, scope) {
|
|
1250
1250
|
const controller = new _progress.ProgressController(metadata, this);
|
|
@@ -1262,8 +1262,11 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1262
1262
|
root
|
|
1263
1263
|
}) => {
|
|
1264
1264
|
const element = injected.querySelector(info.parsed, root || document, info.strict);
|
|
1265
|
-
const state = element ? injected.elementState(element, 'visible') :
|
|
1266
|
-
|
|
1265
|
+
const state = element ? injected.elementState(element, 'visible') : {
|
|
1266
|
+
matches: false,
|
|
1267
|
+
received: 'error:notconnected'
|
|
1268
|
+
};
|
|
1269
|
+
return state.matches;
|
|
1267
1270
|
}, {
|
|
1268
1271
|
info: resolved.info,
|
|
1269
1272
|
root: resolved.frame === this ? scope : undefined
|
|
@@ -1719,21 +1722,23 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1719
1722
|
return (0, _utils.asLocator)(this._page.attribution.playwright.options.sdkLanguage, selector);
|
|
1720
1723
|
}
|
|
1721
1724
|
async _getFrameMainFrameContextId(client) {
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
if (globalDocument && globalDocument.nodeId) {
|
|
1726
|
-
var descibedNode = await client._sendMayFail("DOM.describeNode", {
|
|
1727
|
-
backendNodeId: globalDocument.backendNodeId
|
|
1725
|
+
try {
|
|
1726
|
+
var globalDocument = await client._sendMayFail("DOM.getFrameOwner", {
|
|
1727
|
+
frameId: this._id
|
|
1728
1728
|
});
|
|
1729
|
-
if (
|
|
1730
|
-
var
|
|
1731
|
-
|
|
1729
|
+
if (globalDocument && globalDocument.nodeId) {
|
|
1730
|
+
var describedNode = await client._sendMayFail("DOM.describeNode", {
|
|
1731
|
+
backendNodeId: globalDocument.backendNodeId
|
|
1732
1732
|
});
|
|
1733
|
-
|
|
1734
|
-
|
|
1733
|
+
if (describedNode) {
|
|
1734
|
+
var resolvedNode = await client._sendMayFail("DOM.resolveNode", {
|
|
1735
|
+
nodeId: describedNode.node.contentDocument.nodeId
|
|
1736
|
+
});
|
|
1737
|
+
var _executionContextId = parseInt(resolvedNode.object.objectId.split(".")[1], 10);
|
|
1738
|
+
return _executionContextId;
|
|
1739
|
+
}
|
|
1735
1740
|
}
|
|
1736
|
-
}
|
|
1741
|
+
} catch (e) {}
|
|
1737
1742
|
return 0;
|
|
1738
1743
|
}
|
|
1739
1744
|
}
|
|
@@ -1782,16 +1787,6 @@ function verifyLifecycle(name, waitUntil) {
|
|
|
1782
1787
|
return waitUntil;
|
|
1783
1788
|
}
|
|
1784
1789
|
function renderUnexpectedValue(expression, received) {
|
|
1785
|
-
if (expression === 'to.be.checked') return received ? 'checked' : 'unchecked';
|
|
1786
|
-
if (expression === 'to.be.unchecked') return received ? 'unchecked' : 'checked';
|
|
1787
|
-
if (expression === 'to.be.visible') return received ? 'visible' : 'hidden';
|
|
1788
|
-
if (expression === 'to.be.hidden') return received ? 'hidden' : 'visible';
|
|
1789
|
-
if (expression === 'to.be.enabled') return received ? 'enabled' : 'disabled';
|
|
1790
|
-
if (expression === 'to.be.disabled') return received ? 'disabled' : 'enabled';
|
|
1791
|
-
if (expression === 'to.be.editable') return received ? 'editable' : 'readonly';
|
|
1792
|
-
if (expression === 'to.be.readonly') return received ? 'readonly' : 'editable';
|
|
1793
|
-
if (expression === 'to.be.empty') return received ? 'empty' : 'not empty';
|
|
1794
|
-
if (expression === 'to.be.focused') return received ? 'focused' : 'not focused';
|
|
1795
1790
|
if (expression === 'to.match.aria') return received ? received.raw : received;
|
|
1796
1791
|
return received;
|
|
1797
1792
|
}
|
|
@@ -196,7 +196,7 @@ class HarTracer {
|
|
|
196
196
|
if (!this._shouldIncludeEntryWithUrl(request.url())) return;
|
|
197
197
|
const page = (_request$frame = request.frame()) === null || _request$frame === void 0 ? void 0 : _request$frame._page;
|
|
198
198
|
if (this._page && page !== this._page) return;
|
|
199
|
-
const url = network.
|
|
199
|
+
const url = network.parseURL(request.url());
|
|
200
200
|
if (!url) return;
|
|
201
201
|
const pageEntry = this._createPageEntryIfNeeded(page);
|
|
202
202
|
const harEntry = createHarEntry(request.method(), url, (_request$frame2 = request.frame()) === null || _request$frame2 === void 0 ? void 0 : _request$frame2.guid, this._options);
|
package/lib/server/input.js
CHANGED
|
@@ -40,8 +40,7 @@ class Keyboard {
|
|
|
40
40
|
const autoRepeat = this._pressedKeys.has(description.code);
|
|
41
41
|
this._pressedKeys.add(description.code);
|
|
42
42
|
if (kModifiers.includes(description.key)) this._pressedModifiers.add(description.key);
|
|
43
|
-
|
|
44
|
-
await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location, autoRepeat, text);
|
|
43
|
+
await this._raw.keydown(this._pressedModifiers, key, description, autoRepeat);
|
|
45
44
|
}
|
|
46
45
|
_keyDescriptionForString(str) {
|
|
47
46
|
const keyString = resolveSmartModifierString(str);
|
|
@@ -61,7 +60,7 @@ class Keyboard {
|
|
|
61
60
|
const description = this._keyDescriptionForString(key);
|
|
62
61
|
if (kModifiers.includes(description.key)) this._pressedModifiers.delete(description.key);
|
|
63
62
|
this._pressedKeys.delete(description.code);
|
|
64
|
-
await this._raw.keyup(this._pressedModifiers,
|
|
63
|
+
await this._raw.keyup(this._pressedModifiers, key, description);
|
|
65
64
|
}
|
|
66
65
|
async insertText(text) {
|
|
67
66
|
await this._raw.sendText(text);
|
package/lib/server/network.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.WebSocket = exports.Route = exports.Response = exports.Request = void 0;
|
|
|
7
7
|
exports.filterCookies = filterCookies;
|
|
8
8
|
exports.kMaxCookieExpiresDateInSeconds = void 0;
|
|
9
9
|
exports.mergeHeaders = mergeHeaders;
|
|
10
|
-
exports.
|
|
10
|
+
exports.parseURL = parseURL;
|
|
11
11
|
exports.rewriteCookies = rewriteCookies;
|
|
12
12
|
exports.singleHeader = singleHeader;
|
|
13
13
|
exports.statusText = statusText;
|
|
@@ -75,7 +75,7 @@ function rewriteCookies(cookies) {
|
|
|
75
75
|
return copy;
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
-
function
|
|
78
|
+
function parseURL(url) {
|
|
79
79
|
try {
|
|
80
80
|
return new URL(url);
|
|
81
81
|
} catch (e) {
|
package/lib/server/page.js
CHANGED
|
@@ -47,7 +47,8 @@ class Page extends _instrumentation.SdkObject {
|
|
|
47
47
|
super(browserContext, 'page');
|
|
48
48
|
this._closedState = 'open';
|
|
49
49
|
this._closedPromise = new _manualPromise.ManualPromise();
|
|
50
|
-
this._initialized =
|
|
50
|
+
this._initialized = void 0;
|
|
51
|
+
this._initializedPromise = new _manualPromise.ManualPromise();
|
|
51
52
|
this._eventsToEmitAfterInitialized = [];
|
|
52
53
|
this._crashed = false;
|
|
53
54
|
this.openScope = new _utils.LongStandingScope();
|
|
@@ -72,7 +73,6 @@ class Page extends _instrumentation.SdkObject {
|
|
|
72
73
|
this._clientRequestInterceptor = void 0;
|
|
73
74
|
this._serverRequestInterceptor = void 0;
|
|
74
75
|
this._ownedContext = void 0;
|
|
75
|
-
this._pageIsError = void 0;
|
|
76
76
|
this._video = null;
|
|
77
77
|
this._opener = void 0;
|
|
78
78
|
this._isServerSideOnly = false;
|
|
@@ -96,19 +96,21 @@ class Page extends _instrumentation.SdkObject {
|
|
|
96
96
|
if (delegate.pdf) this.pdf = delegate.pdf.bind(delegate);
|
|
97
97
|
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
|
98
98
|
}
|
|
99
|
-
async
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
async reportAsNew(opener, error = undefined, contextEvent = _browserContext.BrowserContext.Events.Page) {
|
|
100
|
+
if (opener) {
|
|
101
|
+
const openerPageOrError = await opener.waitForInitializedOrError();
|
|
102
|
+
if (openerPageOrError instanceof Page && !openerPageOrError.isClosed()) this._opener = openerPageOrError;
|
|
103
|
+
}
|
|
104
|
+
this._markInitialized(error, contextEvent);
|
|
103
105
|
}
|
|
104
|
-
|
|
106
|
+
_markInitialized(error = undefined, contextEvent = _browserContext.BrowserContext.Events.Page) {
|
|
105
107
|
if (error) {
|
|
106
108
|
// Initialization error could have happened because of
|
|
107
109
|
// context/browser closure. Just ignore the page.
|
|
108
110
|
if (this._browserContext.isClosingOrClosed()) return;
|
|
109
|
-
this.
|
|
111
|
+
this._frameManager.createDummyMainFrameIfNeeded();
|
|
110
112
|
}
|
|
111
|
-
this._initialized =
|
|
113
|
+
this._initialized = error || this;
|
|
112
114
|
this.emitOnContext(contextEvent, this);
|
|
113
115
|
for (const {
|
|
114
116
|
event,
|
|
@@ -120,10 +122,17 @@ class Page extends _instrumentation.SdkObject {
|
|
|
120
122
|
// in that case we fire another Close event to ensure that each reported Page will have
|
|
121
123
|
// corresponding Close event after it is reported on the context.
|
|
122
124
|
if (this.isClosed()) this.emit(Page.Events.Close);else this.instrumentation.onPageOpen(this);
|
|
125
|
+
|
|
126
|
+
// Note: it is important to resolve _initializedPromise at the end,
|
|
127
|
+
// so that anyone who awaits waitForInitializedOrError got a ready and reported page.
|
|
128
|
+
this._initializedPromise.resolve(this._initialized);
|
|
123
129
|
}
|
|
124
130
|
initializedOrUndefined() {
|
|
125
131
|
return this._initialized ? this : undefined;
|
|
126
132
|
}
|
|
133
|
+
waitForInitializedOrError() {
|
|
134
|
+
return this._initializedPromise;
|
|
135
|
+
}
|
|
127
136
|
emitOnContext(event, ...args) {
|
|
128
137
|
if (this._isServerSideOnly) return;
|
|
129
138
|
this._browserContext.emit(event, ...args);
|
|
@@ -407,8 +416,8 @@ class Page extends _instrumentation.SdkObject {
|
|
|
407
416
|
async bringToFront() {
|
|
408
417
|
await this._delegate.bringToFront();
|
|
409
418
|
}
|
|
410
|
-
async addInitScript(source) {
|
|
411
|
-
const initScript = new InitScript(source);
|
|
419
|
+
async addInitScript(source, name) {
|
|
420
|
+
const initScript = new InitScript(source, false /* internal */, name);
|
|
412
421
|
this.initScripts.push(initScript);
|
|
413
422
|
await this._delegate.addInitScript(initScript);
|
|
414
423
|
}
|
|
@@ -532,10 +541,6 @@ class Page extends _instrumentation.SdkObject {
|
|
|
532
541
|
if (!runBeforeUnload) await this._closedPromise;
|
|
533
542
|
if (this._ownedContext) await this._ownedContext.close(options);
|
|
534
543
|
}
|
|
535
|
-
_setIsError(error) {
|
|
536
|
-
this._pageIsError = error;
|
|
537
|
-
this._frameManager.createDummyMainFrameIfNeeded();
|
|
538
|
-
}
|
|
539
544
|
isClosed() {
|
|
540
545
|
return this._closedState === 'closed';
|
|
541
546
|
}
|
|
@@ -778,12 +783,14 @@ function addPageBinding(bindingName, needsHandle, utilityScriptSerializers) {
|
|
|
778
783
|
};
|
|
779
784
|
}
|
|
780
785
|
class InitScript {
|
|
781
|
-
constructor(source, internal) {
|
|
786
|
+
constructor(source, internal, name) {
|
|
782
787
|
this.source = void 0;
|
|
783
788
|
this.internal = void 0;
|
|
789
|
+
this.name = void 0;
|
|
784
790
|
const guid = (0, _utils.createGuid)();
|
|
785
791
|
this.source = `(() => { ${source} })();`;
|
|
786
792
|
this.internal = !!internal;
|
|
793
|
+
this.name = name;
|
|
787
794
|
}
|
|
788
795
|
}
|
|
789
796
|
exports.InitScript = InitScript;
|