patchright-core 1.48.2 → 1.49.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/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/crPage.js +4 -1
- 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 +43 -27
- 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-DUzBrnvO.js +24 -0
- package/lib/vite/recorder/assets/index-CqeZmzx8.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-KatbITLF.js +24 -0
- package/lib/vite/traceViewer/assets/inspectorTab-DdpLd2bb.js +68 -0
- package/lib/vite/traceViewer/assets/workbench-CdYbzWFD.js +9 -0
- package/lib/vite/traceViewer/{embedded.BlHoW5LY.js → embedded.6m3UZh7r.js} +1 -1
- package/lib/vite/traceViewer/embedded.html +5 -5
- package/lib/vite/traceViewer/{index.DaWVfou1.js → index.WUV-8boJ.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.OT2tVHgn.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.BZBTyvGn.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,
|
|
@@ -729,12 +734,12 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
729
734
|
return await this.waitForSelectorInternal(progress, selector, true, options, scope);
|
|
730
735
|
}, this._page._timeoutSettings.timeout(options));
|
|
731
736
|
}
|
|
732
|
-
async waitForSelectorInternal(progress, selector,
|
|
737
|
+
async waitForSelectorInternal(progress, selector, performActionPreChecks, options, scope) {
|
|
733
738
|
const {
|
|
734
739
|
state = 'visible'
|
|
735
740
|
} = options;
|
|
736
741
|
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
737
|
-
if (
|
|
742
|
+
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
738
743
|
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
|
|
739
744
|
progress.throwIfAborted();
|
|
740
745
|
if (!resolved) {
|
|
@@ -745,6 +750,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
745
750
|
info,
|
|
746
751
|
root
|
|
747
752
|
}) => {
|
|
753
|
+
if (root && !root.isConnected) throw injected.createStacklessError('Element is not attached to the DOM');
|
|
748
754
|
const elements = injected.querySelectorAll(info.parsed, root || document);
|
|
749
755
|
const element = elements[0];
|
|
750
756
|
const visible = element ? injected.utils.isElementVisible(element) : false;
|
|
@@ -1058,19 +1064,21 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1058
1064
|
// Retry upon all other errors.
|
|
1059
1065
|
return false;
|
|
1060
1066
|
}
|
|
1061
|
-
async _retryWithProgressIfNotConnected(progress, selector, strict,
|
|
1067
|
+
async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action) {
|
|
1062
1068
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1063
1069
|
return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
1064
|
-
if (
|
|
1070
|
+
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
1065
1071
|
const resolved = await this.selectors.resolveInjectedForSelector(selector, {
|
|
1066
1072
|
strict
|
|
1067
1073
|
});
|
|
1068
1074
|
progress.throwIfAborted();
|
|
1069
1075
|
if (!resolved) return continuePolling;
|
|
1070
1076
|
const result = await resolved.injected.evaluateHandle((injected, {
|
|
1071
|
-
info
|
|
1077
|
+
info,
|
|
1078
|
+
callId
|
|
1072
1079
|
}) => {
|
|
1073
1080
|
const elements = injected.querySelectorAll(info.parsed, document);
|
|
1081
|
+
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1074
1082
|
const element = elements[0];
|
|
1075
1083
|
let log = '';
|
|
1076
1084
|
if (elements.length > 1) {
|
|
@@ -1085,7 +1093,8 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1085
1093
|
element
|
|
1086
1094
|
};
|
|
1087
1095
|
}, {
|
|
1088
|
-
info: resolved.info
|
|
1096
|
+
info: resolved.info,
|
|
1097
|
+
callId: progress.metadata.id
|
|
1089
1098
|
});
|
|
1090
1099
|
const {
|
|
1091
1100
|
log,
|
|
@@ -1114,7 +1123,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1114
1123
|
});
|
|
1115
1124
|
}
|
|
1116
1125
|
async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
|
|
1117
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /*
|
|
1126
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, async handle => {
|
|
1118
1127
|
await handle._frame.rafrafTimeout(timeout);
|
|
1119
1128
|
return await this._page._screenshotter.screenshotElement(progress, handle, options);
|
|
1120
1129
|
});
|
|
@@ -1122,7 +1131,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1122
1131
|
async click(metadata, selector, options) {
|
|
1123
1132
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1124
1133
|
return controller.run(async progress => {
|
|
1125
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1134
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._click(progress, {
|
|
1126
1135
|
...options,
|
|
1127
1136
|
waitAfter: !options.noWaitAfter
|
|
1128
1137
|
})));
|
|
@@ -1131,13 +1140,13 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1131
1140
|
async dblclick(metadata, selector, options = {}) {
|
|
1132
1141
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1133
1142
|
return controller.run(async progress => {
|
|
1134
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1143
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._dblclick(progress, options)));
|
|
1135
1144
|
}, this._page._timeoutSettings.timeout(options));
|
|
1136
1145
|
}
|
|
1137
1146
|
async dragAndDrop(metadata, source, target, options = {}) {
|
|
1138
1147
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1139
1148
|
await controller.run(async progress => {
|
|
1140
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force /*
|
|
1149
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force /* performActionPreChecks */, async handle => {
|
|
1141
1150
|
return handle._retryPointerAction(progress, 'move and down', false, async point => {
|
|
1142
1151
|
await this._page.mouse.move(point.x, point.y);
|
|
1143
1152
|
await this._page.mouse.down();
|
|
@@ -1149,7 +1158,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1149
1158
|
});
|
|
1150
1159
|
}));
|
|
1151
1160
|
// 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 /*
|
|
1161
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false /* performActionPreChecks */, async handle => {
|
|
1153
1162
|
return handle._retryPointerAction(progress, 'move and up', false, async point => {
|
|
1154
1163
|
await this._page.mouse.move(point.x, point.y);
|
|
1155
1164
|
await this._page.mouse.up();
|
|
@@ -1166,25 +1175,25 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1166
1175
|
if (!this._page._browserContext._options.hasTouch) throw new Error('The page does not support tap. Use hasTouch context option to enable touch support.');
|
|
1167
1176
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1168
1177
|
return controller.run(async progress => {
|
|
1169
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1178
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._tap(progress, options)));
|
|
1170
1179
|
}, this._page._timeoutSettings.timeout(options));
|
|
1171
1180
|
}
|
|
1172
1181
|
async fill(metadata, selector, value, options) {
|
|
1173
1182
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1174
1183
|
return controller.run(async progress => {
|
|
1175
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1184
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._fill(progress, value, options)));
|
|
1176
1185
|
}, this._page._timeoutSettings.timeout(options));
|
|
1177
1186
|
}
|
|
1178
1187
|
async focus(metadata, selector, options = {}) {
|
|
1179
1188
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1180
1189
|
await controller.run(async progress => {
|
|
1181
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1190
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._focus(progress)));
|
|
1182
1191
|
}, this._page._timeoutSettings.timeout(options));
|
|
1183
1192
|
}
|
|
1184
1193
|
async blur(metadata, selector, options = {}) {
|
|
1185
1194
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1186
1195
|
await controller.run(async progress => {
|
|
1187
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1196
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._blur(progress)));
|
|
1188
1197
|
}, this._page._timeoutSettings.timeout(options));
|
|
1189
1198
|
}
|
|
1190
1199
|
async textContent(metadata, selector, options = {}, scope) {
|
|
@@ -1284,44 +1293,44 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1284
1293
|
async hover(metadata, selector, options = {}) {
|
|
1285
1294
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1286
1295
|
return controller.run(async progress => {
|
|
1287
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1296
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._hover(progress, options)));
|
|
1288
1297
|
}, this._page._timeoutSettings.timeout(options));
|
|
1289
1298
|
}
|
|
1290
1299
|
async selectOption(metadata, selector, elements, values, options = {}) {
|
|
1291
1300
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1292
1301
|
return controller.run(async progress => {
|
|
1293
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1302
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._selectOption(progress, elements, values, options));
|
|
1294
1303
|
}, this._page._timeoutSettings.timeout(options));
|
|
1295
1304
|
}
|
|
1296
1305
|
async setInputFiles(metadata, selector, params) {
|
|
1297
1306
|
const inputFileItems = await (0, _fileUploadUtils.prepareFilesForUpload)(this, params);
|
|
1298
1307
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1299
1308
|
return controller.run(async progress => {
|
|
1300
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /*
|
|
1309
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /* performActionPreChecks */, handle => handle._setInputFiles(progress, inputFileItems)));
|
|
1301
1310
|
}, this._page._timeoutSettings.timeout(params));
|
|
1302
1311
|
}
|
|
1303
1312
|
async type(metadata, selector, text, options = {}) {
|
|
1304
1313
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1305
1314
|
return controller.run(async progress => {
|
|
1306
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1315
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._type(progress, text, options)));
|
|
1307
1316
|
}, this._page._timeoutSettings.timeout(options));
|
|
1308
1317
|
}
|
|
1309
1318
|
async press(metadata, selector, key, options = {}) {
|
|
1310
1319
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1311
1320
|
return controller.run(async progress => {
|
|
1312
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /*
|
|
1321
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._press(progress, key, options)));
|
|
1313
1322
|
}, this._page._timeoutSettings.timeout(options));
|
|
1314
1323
|
}
|
|
1315
1324
|
async check(metadata, selector, options = {}) {
|
|
1316
1325
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1317
1326
|
return controller.run(async progress => {
|
|
1318
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1327
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, true, options)));
|
|
1319
1328
|
}, this._page._timeoutSettings.timeout(options));
|
|
1320
1329
|
}
|
|
1321
1330
|
async uncheck(metadata, selector, options = {}) {
|
|
1322
1331
|
const controller = new _progress.ProgressController(metadata, this);
|
|
1323
1332
|
return controller.run(async progress => {
|
|
1324
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /*
|
|
1333
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, false, options)));
|
|
1325
1334
|
}, this._page._timeoutSettings.timeout(options));
|
|
1326
1335
|
}
|
|
1327
1336
|
async waitForTimeout(metadata, timeout) {
|
|
@@ -1330,6 +1339,12 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1330
1339
|
await new Promise(resolve => setTimeout(resolve, timeout));
|
|
1331
1340
|
});
|
|
1332
1341
|
}
|
|
1342
|
+
async ariaSnapshot(metadata, selector, options = {}) {
|
|
1343
|
+
const controller = new _progress.ProgressController(metadata, this);
|
|
1344
|
+
return controller.run(async progress => {
|
|
1345
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, handle => handle.ariaSnapshot());
|
|
1346
|
+
}, this._page._timeoutSettings.timeout(options));
|
|
1347
|
+
}
|
|
1333
1348
|
async expect(metadata, selector, options) {
|
|
1334
1349
|
const result = await this._expectImpl(metadata, selector, options);
|
|
1335
1350
|
// Library mode special case for the expect errors which are return values, not exceptions.
|
|
@@ -1353,7 +1368,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1353
1368
|
await new _progress.ProgressController(metadata, this).run(async progress => {
|
|
1354
1369
|
progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`);
|
|
1355
1370
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1356
|
-
await this._page.
|
|
1371
|
+
await this._page.performActionPreChecks(progress);
|
|
1357
1372
|
}, timeout);
|
|
1358
1373
|
|
|
1359
1374
|
// Step 2: perform one-shot expect check without a timeout.
|
|
@@ -1374,7 +1389,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1374
1389
|
}
|
|
1375
1390
|
if (timeout < 0) return {
|
|
1376
1391
|
matches: options.isNot,
|
|
1377
|
-
log: metadata.log,
|
|
1392
|
+
log: (0, _utils.compressCallLog)(metadata.log),
|
|
1378
1393
|
timedOut: true,
|
|
1379
1394
|
received: lastIntermediateResult.received
|
|
1380
1395
|
};
|
|
@@ -1382,7 +1397,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1382
1397
|
// Step 3: auto-retry expect with increasing timeouts. Bounded by the total remaining time.
|
|
1383
1398
|
return await new _progress.ProgressController(metadata, this).run(async progress => {
|
|
1384
1399
|
return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1000], async continuePolling => {
|
|
1385
|
-
await this._page.
|
|
1400
|
+
await this._page.performActionPreChecks(progress);
|
|
1386
1401
|
const {
|
|
1387
1402
|
matches,
|
|
1388
1403
|
received
|
|
@@ -1405,7 +1420,7 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1405
1420
|
if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;
|
|
1406
1421
|
const result = {
|
|
1407
1422
|
matches: options.isNot,
|
|
1408
|
-
log: metadata.log
|
|
1423
|
+
log: (0, _utils.compressCallLog)(metadata.log)
|
|
1409
1424
|
};
|
|
1410
1425
|
if (lastIntermediateResult.isSet) result.received = lastIntermediateResult.received;
|
|
1411
1426
|
if (e instanceof _errors.TimeoutError) result.timedOut = true;
|
|
@@ -1440,10 +1455,10 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1440
1455
|
callId
|
|
1441
1456
|
}) => {
|
|
1442
1457
|
const elements = info ? injected.querySelectorAll(info.parsed, document) : [];
|
|
1458
|
+
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1443
1459
|
const isArray = options.expression === 'to.have.count' || options.expression.endsWith('.array');
|
|
1444
1460
|
let log = '';
|
|
1445
1461
|
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
1462
|
return {
|
|
1448
1463
|
log,
|
|
1449
1464
|
...(await injected.expect(elements[0], options, elements))
|
|
@@ -1804,5 +1819,6 @@ function renderUnexpectedValue(expression, received) {
|
|
|
1804
1819
|
if (expression === 'to.be.readonly') return received ? 'readonly' : 'editable';
|
|
1805
1820
|
if (expression === 'to.be.empty') return received ? 'empty' : 'not empty';
|
|
1806
1821
|
if (expression === 'to.be.focused') return received ? 'focused' : 'not focused';
|
|
1822
|
+
if (expression === 'to.match.aria') return received ? received.raw : received;
|
|
1807
1823
|
return received;
|
|
1808
1824
|
}
|
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,
|