patchright-core 1.48.2 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/ThirdPartyNotices.txt +70 -384
- package/bin/reinstall_chrome_beta_linux.sh +10 -8
- package/bin/reinstall_chrome_stable_linux.sh +10 -8
- package/bin/reinstall_msedge_beta_linux.sh +11 -9
- package/bin/reinstall_msedge_dev_linux.sh +11 -9
- package/bin/reinstall_msedge_stable_linux.sh +11 -9
- package/browsers.json +19 -11
- package/lib/cli/program.js +23 -5
- package/lib/client/channelOwner.js +2 -2
- package/lib/client/locator.js +7 -0
- package/lib/client/network.js +5 -0
- package/lib/client/page.js +4 -2
- package/lib/client/tracing.js +13 -0
- package/lib/client/waiter.js +15 -11
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/generated/webSocketMockSource.js +1 -1
- package/lib/protocol/validator.js +23 -3
- package/lib/server/ariaSnapshot.js +33 -0
- package/lib/server/bidi/bidiChromium.js +1 -1
- package/lib/server/bidi/bidiConnection.js +0 -2
- package/lib/server/bidi/bidiExecutionContext.js +0 -3
- package/lib/server/browserType.js +4 -1
- package/lib/server/chromium/chromium.js +6 -2
- package/lib/server/chromium/crExecutionContext.js +0 -13
- package/lib/server/chromium/crNetworkManager.js +1 -1
- package/lib/server/chromium/crPage.js +4 -5
- package/lib/server/codegen/csharp.js +11 -16
- package/lib/server/codegen/java.js +4 -7
- package/lib/server/codegen/javascript.js +28 -6
- package/lib/server/codegen/python.js +12 -16
- package/lib/server/debugController.js +8 -5
- package/lib/server/deviceDescriptorsSource.json +127 -127
- package/lib/server/dispatchers/androidDispatcher.js +13 -2
- package/lib/server/dispatchers/debugControllerDispatcher.js +1 -1
- package/lib/server/dispatchers/dispatcher.js +1 -1
- package/lib/server/dispatchers/frameDispatcher.js +8 -1
- package/lib/server/dispatchers/tracingDispatcher.js +10 -0
- package/lib/server/dom.js +79 -36
- package/lib/server/fetch.js +30 -17
- package/lib/server/firefox/ffExecutionContext.js +0 -12
- package/lib/server/firefox/ffNetworkManager.js +1 -1
- package/lib/server/frames.js +55 -62
- package/lib/server/index.js +0 -6
- package/lib/server/javascript.js +0 -6
- package/lib/server/page.js +32 -5
- package/lib/server/progress.js +0 -3
- package/lib/server/recorder/recorderApp.js +6 -15
- package/lib/server/recorder/recorderInTraceViewer.js +3 -3
- package/lib/server/recorder/recorderUtils.js +2 -1
- package/lib/server/recorder.js +66 -31
- package/lib/server/registry/index.js +70 -23
- package/lib/server/registry/nativeDeps.js +6 -3
- package/lib/server/socksClientCertificatesInterceptor.js +1 -1
- package/lib/server/trace/recorder/snapshotter.js +1 -12
- package/lib/server/trace/recorder/snapshotterInjected.js +19 -1
- package/lib/server/trace/recorder/tracing.js +69 -15
- package/lib/server/trace/test/inMemorySnapshotter.js +3 -3
- package/lib/server/trace/viewer/traceViewer.js +2 -1
- package/lib/server/webkit/wkBrowser.js +2 -2
- package/lib/server/webkit/wkExecutionContext.js +0 -13
- package/lib/server/webkit/wkPage.js +4 -0
- package/lib/utils/comparators.js +12 -30
- package/lib/utils/crypto.js +1 -4
- package/lib/utils/hostPlatform.js +6 -0
- package/lib/utils/isomorphic/ariaSnapshot.js +267 -0
- package/lib/utils/isomorphic/locatorGenerators.js +23 -5
- package/lib/utils/isomorphic/recorderUtils.js +36 -4
- package/lib/utils/isomorphic/stringUtils.js +30 -0
- package/lib/utils/isomorphic/urlMatch.js +5 -1
- package/lib/utils/network.js +1 -1
- package/lib/utils/sequence.js +64 -0
- package/lib/utils/stackTrace.js +16 -3
- package/lib/utils/zones.js +32 -23
- package/lib/utilsBundle.js +4 -5
- package/lib/utilsBundleImpl/index.js +190 -33
- package/lib/vite/htmlReport/index.html +19 -16
- package/lib/vite/recorder/assets/codeMirrorModule-AFvV6hAs.js +24 -0
- package/lib/vite/recorder/assets/index-_cTWgVuJ.js +184 -0
- package/lib/vite/recorder/assets/{index-BW-aOBcL.css → index-iA1aAGZg.css} +1 -1
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BWCrdKft.js +24 -0
- package/lib/vite/traceViewer/assets/inspectorTab-C_9qyxv5.js +68 -0
- package/lib/vite/traceViewer/assets/workbench-DsQEOQud.js +9 -0
- package/lib/vite/traceViewer/{embedded.BlHoW5LY.js → embedded.D4x_-tXl.js} +1 -1
- package/lib/vite/traceViewer/embedded.html +5 -5
- package/lib/vite/traceViewer/{index.DaWVfou1.js → index.BskMikzx.js} +1 -1
- package/lib/vite/traceViewer/index.html +24 -7
- package/lib/vite/traceViewer/{inspectorTab.DLjBDrQR.css → inspectorTab.DEOUW62d.css} +1 -1
- package/lib/vite/traceViewer/recorder.Dsk1wX5k.js +2 -0
- package/lib/vite/traceViewer/recorder.html +3 -3
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.CzKr-TMc.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +6 -6
- package/lib/vite/traceViewer/{uiMode.CAYqod-m.css → uiMode.voC1ZiOQ.css} +1 -1
- package/lib/vite/traceViewer/workbench.C-zR9ysA.css +1 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +58 -10
- package/types/types.d.ts +116 -20
- package/lib/third_party/diff_match_patch.js +0 -2222
- package/lib/vite/recorder/assets/codeMirrorModule-baozm8ur.js +0 -24
- package/lib/vite/recorder/assets/index-2ElAIWFB.js +0 -42
- package/lib/vite/traceViewer/assets/codeMirrorModule-Bh1rfd2w.js +0 -24
- package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +0 -64
- package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +0 -9
- package/lib/vite/traceViewer/recorder.C4zxcvd2.js +0 -2
- package/lib/vite/traceViewer/uiMode.mTXWniJb.js +0 -5
- package/lib/vite/traceViewer/workbench.D3JVcA9K.css +0 -1
package/lib/server/frames.js
CHANGED
|
@@ -201,6 +201,11 @@ class FrameManager {
|
|
|
201
201
|
frameCommittedSameDocumentNavigation(frameId, url) {
|
|
202
202
|
const frame = this._frames.get(frameId);
|
|
203
203
|
if (!frame) return;
|
|
204
|
+
const pending = frame.pendingDocument();
|
|
205
|
+
if (pending && pending.documentId === undefined && pending.request === undefined) {
|
|
206
|
+
// WebKit has notified about the same-document navigation being requested, so clear it.
|
|
207
|
+
frame.setPendingDocument(undefined);
|
|
208
|
+
}
|
|
204
209
|
frame._url = url;
|
|
205
210
|
const navigationEvent = {
|
|
206
211
|
url,
|
|
@@ -603,7 +608,8 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
603
608
|
nodeId: globalDoc.nodeId
|
|
604
609
|
});
|
|
605
610
|
}
|
|
606
|
-
|
|
611
|
+
|
|
612
|
+
// if (this.isDetached()) throw new Error('Frame was detached');
|
|
607
613
|
try {
|
|
608
614
|
var client = this._page._delegate._sessionForFrame(this)._client;
|
|
609
615
|
} catch (e) {
|
|
@@ -664,6 +670,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
664
670
|
worldName: world
|
|
665
671
|
});
|
|
666
672
|
if (!result) {
|
|
673
|
+
// if (this.isDetached()) throw new Error("Frame was detached");
|
|
667
674
|
return;
|
|
668
675
|
}
|
|
669
676
|
var executionContextId = result.executionContextId;
|
|
@@ -729,12 +736,12 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
729
736
|
return await this.waitForSelectorInternal(progress, selector, true, options, scope);
|
|
730
737
|
}, this._page._timeoutSettings.timeout(options));
|
|
731
738
|
}
|
|
732
|
-
async waitForSelectorInternal(progress, selector,
|
|
739
|
+
async waitForSelectorInternal(progress, selector, performActionPreChecks, options, scope) {
|
|
733
740
|
const {
|
|
734
741
|
state = 'visible'
|
|
735
742
|
} = options;
|
|
736
743
|
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
737
|
-
if (
|
|
744
|
+
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
738
745
|
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
|
|
739
746
|
progress.throwIfAborted();
|
|
740
747
|
if (!resolved) {
|
|
@@ -745,6 +752,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
745
752
|
info,
|
|
746
753
|
root
|
|
747
754
|
}) => {
|
|
755
|
+
if (root && !root.isConnected) throw injected.createStacklessError('Element is not attached to the DOM');
|
|
748
756
|
const elements = injected.querySelectorAll(info.parsed, root || document);
|
|
749
757
|
const element = elements[0];
|
|
750
758
|
const visible = element ? injected.utils.isElementVisible(element) : false;
|
|
@@ -1058,19 +1066,21 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1058
1066
|
// Retry upon all other errors.
|
|
1059
1067
|
return false;
|
|
1060
1068
|
}
|
|
1061
|
-
async _retryWithProgressIfNotConnected(progress, selector, strict,
|
|
1069
|
+
async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action) {
|
|
1062
1070
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1063
1071
|
return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
1064
|
-
if (
|
|
1072
|
+
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
1065
1073
|
const resolved = await this.selectors.resolveInjectedForSelector(selector, {
|
|
1066
1074
|
strict
|
|
1067
1075
|
});
|
|
1068
1076
|
progress.throwIfAborted();
|
|
1069
1077
|
if (!resolved) return continuePolling;
|
|
1070
1078
|
const result = await resolved.injected.evaluateHandle((injected, {
|
|
1071
|
-
info
|
|
1079
|
+
info,
|
|
1080
|
+
callId
|
|
1072
1081
|
}) => {
|
|
1073
1082
|
const elements = injected.querySelectorAll(info.parsed, document);
|
|
1083
|
+
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1074
1084
|
const element = elements[0];
|
|
1075
1085
|
let log = '';
|
|
1076
1086
|
if (elements.length > 1) {
|
|
@@ -1085,7 +1095,8 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1085
1095
|
element
|
|
1086
1096
|
};
|
|
1087
1097
|
}, {
|
|
1088
|
-
info: resolved.info
|
|
1098
|
+
info: resolved.info,
|
|
1099
|
+
callId: progress.metadata.id
|
|
1089
1100
|
});
|
|
1090
1101
|
const {
|
|
1091
1102
|
log,
|
|
@@ -1114,7 +1125,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1114
1125
|
});
|
|
1115
1126
|
}
|
|
1116
1127
|
async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
|
|
1117
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /*
|
|
1128
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, async handle => {
|
|
1118
1129
|
await handle._frame.rafrafTimeout(timeout);
|
|
1119
1130
|
return await this._page._screenshotter.screenshotElement(progress, handle, options);
|
|
1120
1131
|
});
|
|
@@ -1122,7 +1133,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1122
1133
|
async click(metadata, selector, options) {
|
|
1123
1134
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1124
1135
|
return controller.run(async progress => {
|
|
1125
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1136
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._click(progress, {
|
|
1126
1137
|
...options,
|
|
1127
1138
|
waitAfter: !options.noWaitAfter
|
|
1128
1139
|
})));
|
|
@@ -1131,13 +1142,13 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1131
1142
|
async dblclick(metadata, selector, options = {}) {
|
|
1132
1143
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1133
1144
|
return controller.run(async progress => {
|
|
1134
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1145
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._dblclick(progress, options)));
|
|
1135
1146
|
}, this._page._timeoutSettings.timeout(options));
|
|
1136
1147
|
}
|
|
1137
1148
|
async dragAndDrop(metadata, source, target, options = {}) {
|
|
1138
1149
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1139
1150
|
await controller.run(async progress => {
|
|
1140
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force /*
|
|
1151
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force /* performActionPreChecks */, async handle => {
|
|
1141
1152
|
return handle._retryPointerAction(progress, 'move and down', false, async point => {
|
|
1142
1153
|
await this._page.mouse.move(point.x, point.y);
|
|
1143
1154
|
await this._page.mouse.down();
|
|
@@ -1149,7 +1160,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1149
1160
|
});
|
|
1150
1161
|
}));
|
|
1151
1162
|
// Note: do not perform locator handlers checkpoint to avoid moving the mouse in the middle of a drag operation.
|
|
1152
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false /*
|
|
1163
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false /* performActionPreChecks */, async handle => {
|
|
1153
1164
|
return handle._retryPointerAction(progress, 'move and up', false, async point => {
|
|
1154
1165
|
await this._page.mouse.move(point.x, point.y);
|
|
1155
1166
|
await this._page.mouse.up();
|
|
@@ -1166,25 +1177,25 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1166
1177
|
if (!this._page._browserContext._options.hasTouch) throw new Error('The page does not support tap. Use hasTouch context option to enable touch support.');
|
|
1167
1178
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1168
1179
|
return controller.run(async progress => {
|
|
1169
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1180
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._tap(progress, options)));
|
|
1170
1181
|
}, this._page._timeoutSettings.timeout(options));
|
|
1171
1182
|
}
|
|
1172
1183
|
async fill(metadata, selector, value, options) {
|
|
1173
1184
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1174
1185
|
return controller.run(async progress => {
|
|
1175
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1186
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._fill(progress, value, options)));
|
|
1176
1187
|
}, this._page._timeoutSettings.timeout(options));
|
|
1177
1188
|
}
|
|
1178
1189
|
async focus(metadata, selector, options = {}) {
|
|
1179
1190
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1180
1191
|
await controller.run(async progress => {
|
|
1181
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1192
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._focus(progress)));
|
|
1182
1193
|
}, this._page._timeoutSettings.timeout(options));
|
|
1183
1194
|
}
|
|
1184
1195
|
async blur(metadata, selector, options = {}) {
|
|
1185
1196
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1186
1197
|
await controller.run(async progress => {
|
|
1187
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1198
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._blur(progress)));
|
|
1188
1199
|
}, this._page._timeoutSettings.timeout(options));
|
|
1189
1200
|
}
|
|
1190
1201
|
async textContent(metadata, selector, options = {}, scope) {
|
|
@@ -1284,44 +1295,44 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1284
1295
|
async hover(metadata, selector, options = {}) {
|
|
1285
1296
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1286
1297
|
return controller.run(async progress => {
|
|
1287
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1298
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._hover(progress, options)));
|
|
1288
1299
|
}, this._page._timeoutSettings.timeout(options));
|
|
1289
1300
|
}
|
|
1290
1301
|
async selectOption(metadata, selector, elements, values, options = {}) {
|
|
1291
1302
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1292
1303
|
return controller.run(async progress => {
|
|
1293
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1304
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._selectOption(progress, elements, values, options));
|
|
1294
1305
|
}, this._page._timeoutSettings.timeout(options));
|
|
1295
1306
|
}
|
|
1296
1307
|
async setInputFiles(metadata, selector, params) {
|
|
1297
1308
|
const inputFileItems = await (0, _fileUploadUtils.prepareFilesForUpload)(this, params);
|
|
1298
1309
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1299
1310
|
return controller.run(async progress => {
|
|
1300
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /*
|
|
1311
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /* performActionPreChecks */, handle => handle._setInputFiles(progress, inputFileItems)));
|
|
1301
1312
|
}, this._page._timeoutSettings.timeout(params));
|
|
1302
1313
|
}
|
|
1303
1314
|
async type(metadata, selector, text, options = {}) {
|
|
1304
1315
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1305
1316
|
return controller.run(async progress => {
|
|
1306
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1317
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._type(progress, text, options)));
|
|
1307
1318
|
}, this._page._timeoutSettings.timeout(options));
|
|
1308
1319
|
}
|
|
1309
1320
|
async press(metadata, selector, key, options = {}) {
|
|
1310
1321
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1311
1322
|
return controller.run(async progress => {
|
|
1312
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1323
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._press(progress, key, options)));
|
|
1313
1324
|
}, this._page._timeoutSettings.timeout(options));
|
|
1314
1325
|
}
|
|
1315
1326
|
async check(metadata, selector, options = {}) {
|
|
1316
1327
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1317
1328
|
return controller.run(async progress => {
|
|
1318
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1329
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, true, options)));
|
|
1319
1330
|
}, this._page._timeoutSettings.timeout(options));
|
|
1320
1331
|
}
|
|
1321
1332
|
async uncheck(metadata, selector, options = {}) {
|
|
1322
1333
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1323
1334
|
return controller.run(async progress => {
|
|
1324
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1335
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, false, options)));
|
|
1325
1336
|
}, this._page._timeoutSettings.timeout(options));
|
|
1326
1337
|
}
|
|
1327
1338
|
async waitForTimeout(metadata, timeout) {
|
|
@@ -1330,6 +1341,12 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1330
1341
|
await new Promise(resolve => setTimeout(resolve, timeout));
|
|
1331
1342
|
});
|
|
1332
1343
|
}
|
|
1344
|
+
async ariaSnapshot(metadata, selector, options = {}) {
|
|
1345
|
+
const controller = new _progress.ProgressController(metadata, this);
|
|
1346
|
+
return controller.run(async progress => {
|
|
1347
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, handle => handle.ariaSnapshot());
|
|
1348
|
+
}, this._page._timeoutSettings.timeout(options));
|
|
1349
|
+
}
|
|
1333
1350
|
async expect(metadata, selector, options) {
|
|
1334
1351
|
const result = await this._expectImpl(metadata, selector, options);
|
|
1335
1352
|
// Library mode special case for the expect errors which are return values, not exceptions.
|
|
@@ -1353,7 +1370,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1353
1370
|
await new _progress.ProgressController(metadata, this).run(async progress => {
|
|
1354
1371
|
progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`);
|
|
1355
1372
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1356
|
-
await this._page.
|
|
1373
|
+
await this._page.performActionPreChecks(progress);
|
|
1357
1374
|
}, timeout);
|
|
1358
1375
|
|
|
1359
1376
|
// Step 2: perform one-shot expect check without a timeout.
|
|
@@ -1374,7 +1391,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1374
1391
|
}
|
|
1375
1392
|
if (timeout < 0) return {
|
|
1376
1393
|
matches: options.isNot,
|
|
1377
|
-
log: metadata.log,
|
|
1394
|
+
log: (0, _utils.compressCallLog)(metadata.log),
|
|
1378
1395
|
timedOut: true,
|
|
1379
1396
|
received: lastIntermediateResult.received
|
|
1380
1397
|
};
|
|
@@ -1382,7 +1399,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1382
1399
|
// Step 3: auto-retry expect with increasing timeouts. Bounded by the total remaining time.
|
|
1383
1400
|
return await new _progress.ProgressController(metadata, this).run(async progress => {
|
|
1384
1401
|
return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1000], async continuePolling => {
|
|
1385
|
-
await this._page.
|
|
1402
|
+
await this._page.performActionPreChecks(progress);
|
|
1386
1403
|
const {
|
|
1387
1404
|
matches,
|
|
1388
1405
|
received
|
|
@@ -1405,7 +1422,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1405
1422
|
if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;
|
|
1406
1423
|
const result = {
|
|
1407
1424
|
matches: options.isNot,
|
|
1408
|
-
log: metadata.log
|
|
1425
|
+
log: (0, _utils.compressCallLog)(metadata.log)
|
|
1409
1426
|
};
|
|
1410
1427
|
if (lastIntermediateResult.isSet) result.received = lastIntermediateResult.received;
|
|
1411
1428
|
if (e instanceof _errors.TimeoutError) result.timedOut = true;
|
|
@@ -1440,10 +1457,10 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1440
1457
|
callId
|
|
1441
1458
|
}) => {
|
|
1442
1459
|
const elements = info ? injected.querySelectorAll(info.parsed, document) : [];
|
|
1460
|
+
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1443
1461
|
const isArray = options.expression === 'to.have.count' || options.expression.endsWith('.array');
|
|
1444
1462
|
let log = '';
|
|
1445
1463
|
if (isArray) log = ` locator resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`;else if (elements.length > 1) throw injected.strictModeViolationError(info.parsed, elements);else if (elements.length) log = ` locator resolved to ${injected.previewNode(elements[0])}`;
|
|
1446
|
-
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1447
1464
|
return {
|
|
1448
1465
|
log,
|
|
1449
1466
|
...(await injected.expect(elements[0], options, elements))
|
|
@@ -1706,44 +1723,19 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1706
1723
|
return (0, _utils.asLocator)(this._page.attribution.playwright.options.sdkLanguage, selector);
|
|
1707
1724
|
}
|
|
1708
1725
|
async _getFrameMainFrameContextId(client) {
|
|
1709
|
-
var globalDocument = await client._sendMayFail(
|
|
1726
|
+
var globalDocument = await client._sendMayFail("DOM.getFrameOwner", {
|
|
1710
1727
|
frameId: this._id
|
|
1711
1728
|
});
|
|
1712
1729
|
if (globalDocument && globalDocument.nodeId) {
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1730
|
+
var descibedNode = await client._sendMayFail("DOM.describeNode", {
|
|
1731
|
+
backendNodeId: globalDocument.backendNodeId
|
|
1732
|
+
});
|
|
1733
|
+
if (descibedNode) {
|
|
1734
|
+
var resolvedNode = await client._sendMayFail("DOM.resolveNode", {
|
|
1735
|
+
nodeId: descibedNode.node.contentDocument.nodeId
|
|
1716
1736
|
});
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
expression: "document",
|
|
1720
|
-
serializationOptions: {
|
|
1721
|
-
serialization: "idOnly"
|
|
1722
|
-
},
|
|
1723
|
-
contextId: executionContextId
|
|
1724
|
-
});
|
|
1725
|
-
if (globalThis) {
|
|
1726
|
-
var globalThisObjId = globalThis["result"]['objectId'];
|
|
1727
|
-
var requestedNode = await client.send("DOM.requestNode", {
|
|
1728
|
-
objectId: globalThisObjId
|
|
1729
|
-
});
|
|
1730
|
-
var node = await client._sendMayFail("DOM.describeNode", {
|
|
1731
|
-
nodeId: requestedNode.nodeId,
|
|
1732
|
-
pierce: true,
|
|
1733
|
-
depth: 10
|
|
1734
|
-
});
|
|
1735
|
-
if (node && node.node.documentURL == this._url) {
|
|
1736
|
-
var node0 = await client._sendMayFail("DOM.resolveNode", {
|
|
1737
|
-
nodeId: requestedNode.nodeId
|
|
1738
|
-
});
|
|
1739
|
-
if (node0 && node.node.nodeId - 1 == globalDocument.nodeId) {
|
|
1740
|
-
// && (node.node.backendNodeId + 1 == globalDocument.backendNodeId)
|
|
1741
|
-
var _executionContextId = parseInt(node0.object.objectId.split('.')[1], 10);
|
|
1742
|
-
return _executionContextId;
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1737
|
+
var _executionContextId = parseInt(resolvedNode.object.objectId.split(".")[1], 10);
|
|
1738
|
+
return _executionContextId;
|
|
1747
1739
|
}
|
|
1748
1740
|
}
|
|
1749
1741
|
return 0;
|
|
@@ -1804,5 +1796,6 @@ function renderUnexpectedValue(expression, received) {
|
|
|
1804
1796
|
if (expression === 'to.be.readonly') return received ? 'readonly' : 'editable';
|
|
1805
1797
|
if (expression === 'to.be.empty') return received ? 'empty' : 'not empty';
|
|
1806
1798
|
if (expression === 'to.be.focused') return received ? 'focused' : 'not focused';
|
|
1799
|
+
if (expression === 'to.match.aria') return received ? received.raw : received;
|
|
1807
1800
|
return received;
|
|
1808
1801
|
}
|
package/lib/server/index.js
CHANGED
|
@@ -45,12 +45,6 @@ Object.defineProperty(exports, "installBrowsersForNpmInstall", {
|
|
|
45
45
|
return _registry.installBrowsersForNpmInstall;
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
|
-
Object.defineProperty(exports, "installDefaultBrowsersForNpmInstall", {
|
|
49
|
-
enumerable: true,
|
|
50
|
-
get: function () {
|
|
51
|
-
return _registry.installDefaultBrowsersForNpmInstall;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
48
|
Object.defineProperty(exports, "installRootRedirect", {
|
|
55
49
|
enumerable: true,
|
|
56
50
|
get: function () {
|
package/lib/server/javascript.js
CHANGED
|
@@ -55,9 +55,6 @@ class ExecutionContext extends _instrumentation.SdkObject {
|
|
|
55
55
|
rawEvaluateHandle(expression) {
|
|
56
56
|
return this._raceAgainstContextDestroyed(this._delegate.rawEvaluateHandle(expression));
|
|
57
57
|
}
|
|
58
|
-
rawCallFunctionNoReply(func, ...args) {
|
|
59
|
-
this._delegate.rawCallFunctionNoReply(func, ...args);
|
|
60
|
-
}
|
|
61
58
|
evaluateWithArguments(expression, returnByValue, utilityScript, values, objectIds) {
|
|
62
59
|
return this._raceAgainstContextDestroyed(this._delegate.evaluateWithArguments(expression, returnByValue, utilityScript, values, objectIds));
|
|
63
60
|
}
|
|
@@ -108,9 +105,6 @@ class JSHandle extends _instrumentation.SdkObject {
|
|
|
108
105
|
this._preview = this._objectId ? preview || `JSHandle@${this._objectType}` : String(value);
|
|
109
106
|
if (this._objectId && globalThis.leakedJSHandles) globalThis.leakedJSHandles.set(this, new Error('Leaked JSHandle'));
|
|
110
107
|
}
|
|
111
|
-
callFunctionNoReply(func, arg) {
|
|
112
|
-
this._context.rawCallFunctionNoReply(func, this, arg);
|
|
113
|
-
}
|
|
114
108
|
async evaluate(pageFunction, arg) {
|
|
115
109
|
return evaluate(this._context, true /* returnByValue */, pageFunction, this, arg);
|
|
116
110
|
}
|
package/lib/server/page.js
CHANGED
|
@@ -22,6 +22,7 @@ var _instrumentation = require("./instrumentation");
|
|
|
22
22
|
var _selectorParser = require("../utils/isomorphic/selectorParser");
|
|
23
23
|
var _utilityScriptSerializers = require("./isomorphic/utilityScriptSerializers");
|
|
24
24
|
var _errors = require("./errors");
|
|
25
|
+
var _helper = require("./helper");
|
|
25
26
|
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); }
|
|
26
27
|
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; }
|
|
27
28
|
/**
|
|
@@ -308,7 +309,29 @@ class Page extends _instrumentation.SdkObject {
|
|
|
308
309
|
unregisterLocatorHandler(uid) {
|
|
309
310
|
this._locatorHandlers.delete(uid);
|
|
310
311
|
}
|
|
311
|
-
async
|
|
312
|
+
async performActionPreChecks(progress) {
|
|
313
|
+
await this._performWaitForNavigationCheck(progress);
|
|
314
|
+
progress.throwIfAborted();
|
|
315
|
+
await this._performLocatorHandlersCheckpoint(progress);
|
|
316
|
+
progress.throwIfAborted();
|
|
317
|
+
// Wait once again, just in case a locator handler caused a navigation.
|
|
318
|
+
await this._performWaitForNavigationCheck(progress);
|
|
319
|
+
}
|
|
320
|
+
async _performWaitForNavigationCheck(progress) {
|
|
321
|
+
var _mainFrame$pendingDoc;
|
|
322
|
+
if (process.env.PLAYWRIGHT_SKIP_NAVIGATION_CHECK) return;
|
|
323
|
+
const mainFrame = this._frameManager.mainFrame();
|
|
324
|
+
if (!mainFrame || !mainFrame.pendingDocument()) return;
|
|
325
|
+
const url = (_mainFrame$pendingDoc = mainFrame.pendingDocument()) === null || _mainFrame$pendingDoc === void 0 || (_mainFrame$pendingDoc = _mainFrame$pendingDoc.request) === null || _mainFrame$pendingDoc === void 0 ? void 0 : _mainFrame$pendingDoc.url();
|
|
326
|
+
const toUrl = url ? `" ${(0, _utils.trimStringWithEllipsis)(url, 200)}"` : '';
|
|
327
|
+
progress.log(` waiting for${toUrl} navigation to finish...`);
|
|
328
|
+
await _helper.helper.waitForEvent(progress, mainFrame, frames.Frame.Events.InternalNavigation, e => {
|
|
329
|
+
if (!e.isPublic) return false;
|
|
330
|
+
if (!e.error) progress.log(` navigated to "${(0, _utils.trimStringWithEllipsis)(mainFrame.url(), 200)}"`);
|
|
331
|
+
return true;
|
|
332
|
+
}).promise;
|
|
333
|
+
}
|
|
334
|
+
async _performLocatorHandlersCheckpoint(progress) {
|
|
312
335
|
// Do not run locator handlers from inside locator handler callbacks to avoid deadlocks.
|
|
313
336
|
if (this._locatorHandlerRunningCounter) return;
|
|
314
337
|
for (const [uid, handler] of this._locatorHandlers) {
|
|
@@ -409,7 +432,7 @@ class Page extends _instrumentation.SdkObject {
|
|
|
409
432
|
const rafrafScreenshot = locator ? async (progress, timeout) => {
|
|
410
433
|
return await locator.frame.rafrafTimeoutScreenshotElementWithProgress(progress, locator.selector, timeout, options || {});
|
|
411
434
|
} : async (progress, timeout) => {
|
|
412
|
-
await this.
|
|
435
|
+
await this.performActionPreChecks(progress);
|
|
413
436
|
await this.mainFrame().rafrafTimeout(timeout);
|
|
414
437
|
return await this._screenshotter.screenshotPage(progress, options || {});
|
|
415
438
|
};
|
|
@@ -472,19 +495,23 @@ class Page extends _instrumentation.SdkObject {
|
|
|
472
495
|
progress.log(`screenshot matched expectation`);
|
|
473
496
|
return {};
|
|
474
497
|
}
|
|
475
|
-
if (areEqualScreenshots(actual, options.expected,
|
|
498
|
+
if (areEqualScreenshots(actual, options.expected, undefined)) {
|
|
476
499
|
progress.log(`screenshot matched expectation`);
|
|
477
500
|
return {};
|
|
478
501
|
}
|
|
479
502
|
throw new Error(intermediateResult.errorMessage);
|
|
480
503
|
}, callTimeout).catch(e => {
|
|
504
|
+
var _intermediateResult;
|
|
481
505
|
// Q: Why not throw upon isSessionClosedError(e) as in other places?
|
|
482
506
|
// A: We want user to receive a friendly diff between actual and expected/previous.
|
|
483
507
|
if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;
|
|
508
|
+
let errorMessage = e.message;
|
|
509
|
+
if (e instanceof _errors.TimeoutError && (_intermediateResult = intermediateResult) !== null && _intermediateResult !== void 0 && _intermediateResult.previous) errorMessage = `Failed to take two consecutive stable screenshots.`;
|
|
484
510
|
return {
|
|
485
|
-
log: e.message ? [...metadata.log, e.message] : metadata.log,
|
|
511
|
+
log: (0, _utils.compressCallLog)(e.message ? [...metadata.log, e.message] : metadata.log),
|
|
486
512
|
...intermediateResult,
|
|
487
|
-
errorMessage
|
|
513
|
+
errorMessage,
|
|
514
|
+
timedOut: e instanceof _errors.TimeoutError
|
|
488
515
|
};
|
|
489
516
|
});
|
|
490
517
|
}
|
package/lib/server/progress.js
CHANGED
|
@@ -70,9 +70,6 @@ class ProgressController {
|
|
|
70
70
|
throwIfAborted: () => {
|
|
71
71
|
if (this._state === 'aborted') throw new AbortedError();
|
|
72
72
|
},
|
|
73
|
-
beforeInputAction: async element => {
|
|
74
|
-
await this.instrumentation.onBeforeInputAction(this.sdkObject, this.metadata, element);
|
|
75
|
-
},
|
|
76
73
|
metadata: this.metadata
|
|
77
74
|
};
|
|
78
75
|
const timeoutError = new _errors.TimeoutError(`Timeout ${this._timeout}ms exceeded.`);
|
|
@@ -38,7 +38,7 @@ class EmptyRecorderApp extends _events.EventEmitter {
|
|
|
38
38
|
async setPaused(paused) {}
|
|
39
39
|
async setMode(mode) {}
|
|
40
40
|
async setRunningFile(file) {}
|
|
41
|
-
async
|
|
41
|
+
async elementPicked(elementInfo, userGesture) {}
|
|
42
42
|
async updateCallLogs(callLogs) {}
|
|
43
43
|
async setSources(sources) {}
|
|
44
44
|
async setActions(actions, sources) {}
|
|
@@ -165,23 +165,14 @@ class RecorderApp extends _events.EventEmitter {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
async setActions(actions, sources) {}
|
|
168
|
-
async
|
|
169
|
-
if (userGesture)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this._recorder.setMode('standby');
|
|
173
|
-
this._page.bringToFront();
|
|
174
|
-
} else {
|
|
175
|
-
var _this$_recorder2;
|
|
176
|
-
(_this$_recorder2 = this._recorder) === null || _this$_recorder2 === void 0 || _this$_recorder2.setMode('recording');
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
await this._page.mainFrame().evaluateExpression((data => {
|
|
180
|
-
window.playwrightSetSelector(data.selector, data.userGesture);
|
|
168
|
+
async elementPicked(elementInfo, userGesture) {
|
|
169
|
+
if (userGesture) this._page.bringToFront();
|
|
170
|
+
await this._page.mainFrame().evaluateExpression((param => {
|
|
171
|
+
window.playwrightElementPicked(param.elementInfo, param.userGesture);
|
|
181
172
|
}).toString(), {
|
|
182
173
|
isFunction: true
|
|
183
174
|
}, {
|
|
184
|
-
|
|
175
|
+
elementInfo,
|
|
185
176
|
userGesture
|
|
186
177
|
}).catch(() => {});
|
|
187
178
|
}
|
|
@@ -77,9 +77,9 @@ class RecorderInTraceViewer extends _events.EventEmitter {
|
|
|
77
77
|
file
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
-
async
|
|
81
|
-
this._transport.deliverEvent('
|
|
82
|
-
|
|
80
|
+
async elementPicked(elementInfo, userGesture) {
|
|
81
|
+
this._transport.deliverEvent('elementPicked', {
|
|
82
|
+
elementInfo,
|
|
83
83
|
userGesture
|
|
84
84
|
});
|
|
85
85
|
}
|
|
@@ -73,11 +73,12 @@ function callMetadataForAction(pageAliases, actionInContext) {
|
|
|
73
73
|
const mainFrame = mainFrameForAction(pageAliases, actionInContext);
|
|
74
74
|
const {
|
|
75
75
|
method,
|
|
76
|
+
apiName,
|
|
76
77
|
params
|
|
77
78
|
} = (0, _recorderUtils.traceParamsForAction)(actionInContext);
|
|
78
79
|
const callMetadata = {
|
|
79
80
|
id: `call@${(0, _utils.createGuid)()}`,
|
|
80
|
-
apiName
|
|
81
|
+
apiName,
|
|
81
82
|
objectId: mainFrame.guid,
|
|
82
83
|
pageId: mainFrame._page.guid,
|
|
83
84
|
frameId: mainFrame.guid,
|