@checkly/playwright-core 1.41.26 → 1.42.11
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 +3 -3
- package/bin/reinstall_chrome_beta_win.ps1 +2 -1
- package/bin/reinstall_chrome_stable_win.ps1 +2 -1
- package/bin/reinstall_msedge_beta_win.ps1 +2 -1
- package/bin/reinstall_msedge_dev_win.ps1 +2 -1
- package/bin/reinstall_msedge_stable_win.ps1 +2 -1
- package/browsers.json +14 -15
- package/cli.js +2 -1
- package/lib/checkly/fetch.js +28 -1
- package/lib/cli/cli.js +2 -1
- package/lib/cli/driver.js +9 -1
- package/lib/cli/program.js +12 -4
- package/lib/client/browserContext.js +1 -1
- package/lib/client/channelOwner.js +1 -1
- package/lib/client/clientHelper.js +5 -1
- package/lib/client/connection.js +1 -1
- package/lib/client/consoleMessage.js +1 -1
- package/lib/client/electron.js +3 -0
- package/lib/client/events.js +1 -0
- package/lib/client/frame.js +2 -1
- package/lib/client/harRouter.js +7 -1
- package/lib/client/page.js +25 -6
- package/lib/common/debugLogger.js +3 -1
- package/lib/common/socksProxy.js +1 -1
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/recorderSource.js +1 -1
- package/lib/outofprocess.js +1 -1
- package/lib/protocol/validator.js +60 -30
- package/lib/remote/playwrightConnection.js +1 -1
- package/lib/remote/playwrightServer.js +72 -166
- package/lib/server/android/android.js +1 -1
- package/lib/server/browserType.js +2 -2
- package/lib/server/chromium/chromium.js +5 -4
- package/lib/server/chromium/crConnection.js +1 -1
- package/lib/server/chromium/crNetworkManager.js +1 -3
- package/lib/server/chromium/crPage.js +45 -2
- package/lib/server/chromium/crPdf.js +8 -2
- package/lib/server/console.js +1 -3
- package/lib/server/debugController.js +0 -3
- package/lib/server/deviceDescriptorsSource.json +50 -50
- package/lib/server/dispatchers/browserContextDispatcher.js +3 -2
- package/lib/server/dispatchers/dispatcher.js +9 -10
- package/lib/server/dispatchers/electronDispatcher.js +13 -0
- package/lib/server/dispatchers/frameDispatcher.js +0 -6
- package/lib/server/dispatchers/networkDispatchers.js +1 -0
- package/lib/server/dispatchers/pageDispatcher.js +14 -10
- package/lib/server/dom.js +130 -167
- package/lib/server/electron/electron.js +38 -12
- package/lib/server/electron/loader.js +4 -2
- package/lib/server/fetch.js +1 -0
- package/lib/server/firefox/ffAccessibility.js +2 -1
- package/lib/server/firefox/ffConnection.js +1 -1
- package/lib/server/firefox/ffPage.js +1 -1
- package/lib/server/frames.js +39 -20
- package/lib/server/helper.js +1 -1
- package/lib/server/page.js +49 -5
- package/lib/server/pipeTransport.js +1 -1
- package/lib/server/playwright.js +1 -1
- package/lib/server/progress.js +3 -11
- package/lib/server/recorder/csharp.js +1 -1
- package/lib/server/recorder/java.js +36 -4
- package/lib/server/recorder.js +2 -2
- package/lib/server/registry/browserFetcher.js +1 -1
- package/lib/server/registry/dependencies.js +5 -4
- package/lib/server/registry/index.js +48 -30
- package/lib/server/registry/nativeDeps.js +0 -94
- package/lib/server/trace/recorder/snapshotter.js +1 -1
- package/lib/server/trace/recorder/tracing.js +5 -2
- package/lib/server/trace/viewer/traceViewer.js +1 -1
- package/lib/server/transport.js +4 -2
- package/lib/server/webkit/wkConnection.js +1 -1
- package/lib/server/webkit/wkPage.js +2 -2
- package/lib/utils/comparators.js +4 -4
- package/lib/utils/fileUtils.js +4 -0
- package/lib/utils/hostPlatform.js +1 -1
- package/lib/utils/index.js +33 -0
- package/lib/utils/isomorphic/locatorParser.js +6 -4
- package/lib/utils/isomorphic/stringUtils.js +5 -0
- package/lib/utils/network.js +32 -0
- package/lib/utils/processLauncher.js +7 -0
- package/lib/utils/rtti.js +7 -4
- package/lib/utils/wsServer.js +5 -3
- package/lib/utilsBundleImpl/index.js +4 -4
- package/lib/vite/htmlReport/index.html +11 -11
- package/lib/vite/{traceViewer/assets/codeMirrorModule-GJA8DRmd.js → recorder/assets/codeMirrorModule-W69B4LBB.js} +1 -1
- package/lib/vite/recorder/assets/{index-yg8ypzl6.js → index-Ly3PcVUb.js} +2 -2
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-2ImvVqMb.js → codeMirrorModule-BK3t1EEu.js} +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-cc2329e4.js +15593 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-d725feea.js +15586 -0
- package/lib/vite/traceViewer/assets/{codeMirrorModule-fqJB1XDu.js → codeMirrorModule-e5a15eec.js} +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-kT-uS7F4.js +15592 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-rcsC5no8.js +15592 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-yboVpgC0.js +15592 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-ytMY1awF.js +15585 -0
- package/lib/vite/traceViewer/assets/wsPort-54626118.js +18361 -0
- package/lib/vite/traceViewer/assets/{wsPort-uVqol1LI.js → wsPort-964mA9MZ.js} +18 -18
- package/lib/vite/traceViewer/assets/wsPort-CAXygIGt.js +18540 -0
- package/lib/vite/traceViewer/assets/wsPort-a88a6a12.js +18361 -0
- package/lib/vite/traceViewer/assets/{wsPort-722747dc.js → wsPort-cb764cde.js} +1 -1
- package/lib/vite/traceViewer/assets/wsPort-lTlmZhJd.js +18564 -0
- package/lib/vite/traceViewer/assets/wsPort-xpIMLVfx.js +18540 -0
- package/lib/vite/traceViewer/assets/wsPort-yM58htfg.js +18360 -0
- package/lib/vite/traceViewer/assets/xtermModule-60687b6b.js +6410 -0
- package/lib/vite/traceViewer/assets/xtermModule-_6TC5FYT.js +6529 -0
- package/lib/vite/traceViewer/codeMirrorModule.eb494ea9.css +344 -0
- package/lib/vite/traceViewer/codeMirrorModule.svF_VrcJ.css +344 -0
- package/lib/vite/traceViewer/{index.0d08c336.js → index.4a8ee36e.js} +1 -1
- package/lib/vite/traceViewer/index.55e65778.js +181 -0
- package/lib/vite/traceViewer/index.5mge2rY_.css +124 -0
- package/lib/vite/traceViewer/index.5nqVcfiC.js +180 -0
- package/lib/vite/traceViewer/index.742fd3e5.js +181 -0
- package/lib/vite/traceViewer/index.76e9f312.css +124 -0
- package/lib/vite/traceViewer/{index.LR1HufLs.js → index.cbtHmFgM.js} +1 -1
- package/lib/vite/traceViewer/index.html +3 -3
- package/lib/vite/traceViewer/index.ici1bqta.js +180 -0
- package/lib/vite/traceViewer/index.mxOcKqpu.js +180 -0
- package/lib/vite/traceViewer/index.zXVxM5ps.js +180 -0
- package/lib/vite/traceViewer/sw.bundle.js +4 -4
- package/lib/vite/traceViewer/uiMode.216233d5.js +1484 -0
- package/lib/vite/traceViewer/uiMode.2c31018f.css +1324 -0
- package/lib/vite/traceViewer/{uiMode.c1ebfc43.js → uiMode.468b0309.js} +1 -1
- package/lib/vite/traceViewer/uiMode.67C8Ij-c.js +1490 -0
- package/lib/vite/traceViewer/uiMode.F_k6a2aC.js +1488 -0
- package/lib/vite/traceViewer/uiMode.NjZAwD_B.js +1485 -0
- package/lib/vite/traceViewer/uiMode.YQRCZjm8.js +1485 -0
- package/lib/vite/traceViewer/uiMode.b2068d00.js +1484 -0
- package/lib/vite/traceViewer/uiMode.e-PLonGl.js +1490 -0
- package/lib/vite/traceViewer/{uiMode.PlLkrJDI.js → uiMode.fcU_T5Nf.js} +1 -1
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/lib/vite/traceViewer/uiMode.xvJHbkzl.css +1324 -0
- package/lib/vite/traceViewer/uiMode.ybQP_6Xr.js +10 -0
- package/lib/vite/traceViewer/wsPort.997c92cf.css +3513 -0
- package/lib/vite/traceViewer/wsPort.Oa05jfrO.css +3513 -0
- package/lib/vite/traceViewer/wsPort.p5jUwABW.css +3450 -0
- package/lib/vite/traceViewer/xtermModule.125f4259.css +191 -0
- package/lib/vite/traceViewer/xtermModule.OKEVRlkP.css +209 -0
- package/package.json +6 -5
- package/types/protocol.d.ts +367 -53
- package/types/types.d.ts +220 -50
- package/LICENSE +0 -202
- package/NOTICE +0 -5
- package/lib/vite/recorder/assets/codeMirrorModule-I9ks4y7D.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-2mdjgmqe.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-56536a77.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-A2_PGeGB.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-GluP1cQ1.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-aUzO-LID.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-b361a51f.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-f333a775.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-y3M3aAqy.js +0 -24
- package/lib/vite/traceViewer/assets/wsPort-762c6840.js +0 -64
- package/lib/vite/traceViewer/assets/wsPort-93o0i57c.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-L8WBvZfK.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-Rvwd4WC-.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-db501ca9.js +0 -64
- package/lib/vite/traceViewer/assets/wsPort-dlD7vDkY.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-qI0zJPR7.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-qOE2NWrO.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-sh0wpjYp.js +0 -69
- package/lib/vite/traceViewer/index.4X7zDysg.js +0 -2
- package/lib/vite/traceViewer/index.4xhUWj1f.js +0 -2
- package/lib/vite/traceViewer/index.HkJgzlGy.js +0 -2
- package/lib/vite/traceViewer/index.Ox-CymYJ.js +0 -2
- package/lib/vite/traceViewer/index.d05939c9.js +0 -2
- package/lib/vite/traceViewer/index.ed9a3c58.js +0 -2
- package/lib/vite/traceViewer/index.kRjx5sAJ.js +0 -2
- package/lib/vite/traceViewer/index.krETyIB_.js +0 -2
- package/lib/vite/traceViewer/index.o6j3Cv4u.js +0 -2
- package/lib/vite/traceViewer/uiMode.1Wcp_Kto.js +0 -10
- package/lib/vite/traceViewer/uiMode.3ff70f7d.js +0 -4
- package/lib/vite/traceViewer/uiMode.8e0454c4.js +0 -4
- package/lib/vite/traceViewer/uiMode.GTNzARcV.js +0 -10
- package/lib/vite/traceViewer/uiMode.Rcwfn0db.js +0 -10
- package/lib/vite/traceViewer/uiMode.YGPXSUMv.js +0 -10
- package/lib/vite/traceViewer/uiMode.YYFJGvtV.js +0 -10
- package/lib/vite/traceViewer/uiMode.qpn6w4df.js +0 -10
- package/lib/vite/traceViewer/uiMode.zV-7Lf9v.js +0 -10
- package/lib/vite/traceViewer/wsPort.kSgQKQ0y.css +0 -1
package/lib/server/dom.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.NonRecoverableDOMError = exports.
|
|
6
|
+
exports.NonRecoverableDOMError = exports.FrameExecutionContext = exports.ElementHandle = void 0;
|
|
7
7
|
exports.assertDone = assertDone;
|
|
8
8
|
exports.isNonRecoverableDOMError = isNonRecoverableDOMError;
|
|
9
9
|
exports.kUnableToAdoptErrorMessage = void 0;
|
|
@@ -136,17 +136,6 @@ class ElementHandle extends js.JSHandle {
|
|
|
136
136
|
return 'error:notconnected';
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
async evaluatePoll(progress, pageFunction, arg) {
|
|
140
|
-
try {
|
|
141
|
-
const utility = await this._frame._utilityContext();
|
|
142
|
-
const poll = await utility.evaluateHandle(pageFunction, [await utility.injectedScript(), this, arg]);
|
|
143
|
-
const pollHandler = new InjectedScriptPollHandler(progress, poll);
|
|
144
|
-
return await pollHandler.finish();
|
|
145
|
-
} catch (e) {
|
|
146
|
-
if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) throw e;
|
|
147
|
-
return 'error:notconnected';
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
139
|
async ownerFrame() {
|
|
151
140
|
const frameId = await this._page._delegate.getOwnerFrame(this);
|
|
152
141
|
if (!frameId) return null;
|
|
@@ -188,25 +177,19 @@ class ElementHandle extends js.JSHandle {
|
|
|
188
177
|
return await this._page._delegate.scrollRectIntoViewIfNeeded(this, rect);
|
|
189
178
|
}
|
|
190
179
|
async _waitAndScrollIntoViewIfNeeded(progress, waitForVisible) {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
assertDone(result);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
180
|
+
const result = await this._retryAction(progress, 'scroll into view', async () => {
|
|
181
|
+
progress.log(` waiting for element to be stable`);
|
|
182
|
+
const waitResult = await this.evaluateInUtility(async ([injected, node, {
|
|
183
|
+
waitForVisible
|
|
184
|
+
}]) => {
|
|
185
|
+
return await injected.checkElementStates(node, waitForVisible ? ['visible', 'stable'] : ['stable']);
|
|
186
|
+
}, {
|
|
187
|
+
waitForVisible
|
|
188
|
+
});
|
|
189
|
+
if (waitResult) return waitResult;
|
|
190
|
+
return await this._scrollRectIntoViewIfNeeded();
|
|
191
|
+
}, {});
|
|
192
|
+
assertDone(throwRetargetableDOMError(result));
|
|
210
193
|
}
|
|
211
194
|
async scrollIntoViewIfNeeded(metadata, options = {}) {
|
|
212
195
|
const controller = new _progress.ProgressController(metadata, this);
|
|
@@ -261,25 +244,10 @@ class ElementHandle extends js.JSHandle {
|
|
|
261
244
|
y: box.y + border.top + offset.y
|
|
262
245
|
};
|
|
263
246
|
}
|
|
264
|
-
async
|
|
247
|
+
async _retryAction(progress, actionName, action, options) {
|
|
265
248
|
let retry = 0;
|
|
266
249
|
// We progressively wait longer between retries, up to 500ms.
|
|
267
250
|
const waitTime = [0, 20, 100, 100, 500];
|
|
268
|
-
|
|
269
|
-
// By default, we scroll with protocol method to reveal the action point.
|
|
270
|
-
// However, that might not work to scroll from under position:sticky elements
|
|
271
|
-
// that overlay the target element. To fight this, we cycle through different
|
|
272
|
-
// scroll alignments. This works in most scenarios.
|
|
273
|
-
const scrollOptions = [undefined, {
|
|
274
|
-
block: 'end',
|
|
275
|
-
inline: 'end'
|
|
276
|
-
}, {
|
|
277
|
-
block: 'center',
|
|
278
|
-
inline: 'center'
|
|
279
|
-
}, {
|
|
280
|
-
block: 'start',
|
|
281
|
-
inline: 'start'
|
|
282
|
-
}];
|
|
283
251
|
while (progress.isRunning()) {
|
|
284
252
|
if (retry) {
|
|
285
253
|
progress.log(`retrying ${actionName} action${options.trial ? ' (trial run)' : ''}, attempt #${retry}`);
|
|
@@ -292,8 +260,8 @@ class ElementHandle extends js.JSHandle {
|
|
|
292
260
|
} else {
|
|
293
261
|
progress.log(`attempting ${actionName} action${options.trial ? ' (trial run)' : ''}`);
|
|
294
262
|
}
|
|
295
|
-
|
|
296
|
-
const result = await
|
|
263
|
+
if (!options.skipLocatorHandlersCheckpoint && !options.force) await this._frame._page.performLocatorHandlersCheckpoint(progress);
|
|
264
|
+
const result = await action(retry);
|
|
297
265
|
++retry;
|
|
298
266
|
if (result === 'error:notvisible') {
|
|
299
267
|
if (options.force) throw new NonRecoverableDOMError('Element is not visible');
|
|
@@ -305,14 +273,47 @@ class ElementHandle extends js.JSHandle {
|
|
|
305
273
|
progress.log(' element is outside of the viewport');
|
|
306
274
|
continue;
|
|
307
275
|
}
|
|
276
|
+
if (result === 'error:optionsnotfound') {
|
|
277
|
+
progress.log(' did not find some options');
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
308
280
|
if (typeof result === 'object' && 'hitTargetDescription' in result) {
|
|
309
281
|
progress.log(` ${result.hitTargetDescription} intercepts pointer events`);
|
|
310
282
|
continue;
|
|
311
283
|
}
|
|
284
|
+
if (typeof result === 'object' && 'missingState' in result) {
|
|
285
|
+
progress.log(` element is not ${result.missingState}`);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
312
288
|
return result;
|
|
313
289
|
}
|
|
314
290
|
return 'done';
|
|
315
291
|
}
|
|
292
|
+
async _retryPointerAction(progress, actionName, waitForEnabled, action, options) {
|
|
293
|
+
// Note: do not perform locator handlers checkpoint to avoid moving the mouse in the middle of a drag operation.
|
|
294
|
+
const skipLocatorHandlersCheckpoint = actionName === 'move and up';
|
|
295
|
+
return await this._retryAction(progress, actionName, async retry => {
|
|
296
|
+
// By default, we scroll with protocol method to reveal the action point.
|
|
297
|
+
// However, that might not work to scroll from under position:sticky elements
|
|
298
|
+
// that overlay the target element. To fight this, we cycle through different
|
|
299
|
+
// scroll alignments. This works in most scenarios.
|
|
300
|
+
const scrollOptions = [undefined, {
|
|
301
|
+
block: 'end',
|
|
302
|
+
inline: 'end'
|
|
303
|
+
}, {
|
|
304
|
+
block: 'center',
|
|
305
|
+
inline: 'center'
|
|
306
|
+
}, {
|
|
307
|
+
block: 'start',
|
|
308
|
+
inline: 'start'
|
|
309
|
+
}];
|
|
310
|
+
const forceScrollOptions = scrollOptions[retry % scrollOptions.length];
|
|
311
|
+
return await this._performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options);
|
|
312
|
+
}, {
|
|
313
|
+
...options,
|
|
314
|
+
skipLocatorHandlersCheckpoint
|
|
315
|
+
});
|
|
316
|
+
}
|
|
316
317
|
async _performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options) {
|
|
317
318
|
const {
|
|
318
319
|
force = false,
|
|
@@ -340,8 +341,19 @@ class ElementHandle extends js.JSHandle {
|
|
|
340
341
|
await doScrollIntoView().catch(() => {});
|
|
341
342
|
}
|
|
342
343
|
if (options.__testHookBeforeStable) await options.__testHookBeforeStable();
|
|
343
|
-
|
|
344
|
-
|
|
344
|
+
if (!force) {
|
|
345
|
+
const elementStates = waitForEnabled ? ['visible', 'enabled', 'stable'] : ['visible', 'stable'];
|
|
346
|
+
progress.log(` waiting for element to be ${waitForEnabled ? 'visible, enabled and stable' : 'visible and stable'}`);
|
|
347
|
+
const result = await this.evaluateInUtility(async ([injected, node, {
|
|
348
|
+
elementStates
|
|
349
|
+
}]) => {
|
|
350
|
+
return await injected.checkElementStates(node, elementStates);
|
|
351
|
+
}, {
|
|
352
|
+
elementStates
|
|
353
|
+
});
|
|
354
|
+
if (result) return result;
|
|
355
|
+
progress.log(` element is ${waitForEnabled ? 'visible, enabled and stable' : 'visible and stable'}`);
|
|
356
|
+
}
|
|
345
357
|
if (options.__testHookAfterStable) await options.__testHookAfterStable();
|
|
346
358
|
progress.log(' scrolling into view if needed');
|
|
347
359
|
progress.throwIfAborted(); // Avoid action that has side-effects.
|
|
@@ -354,7 +366,9 @@ class ElementHandle extends js.JSHandle {
|
|
|
354
366
|
progress.metadata.point = point;
|
|
355
367
|
await progress.beforeInputAction(this);
|
|
356
368
|
let hitTargetInterceptionHandle;
|
|
357
|
-
if (
|
|
369
|
+
if (force) {
|
|
370
|
+
progress.log(` forcing action`);
|
|
371
|
+
} else {
|
|
358
372
|
if (options.__testHookBeforeHitTarget) await options.__testHookBeforeHitTarget();
|
|
359
373
|
const frameCheckResult = await this._checkFrameIsHitTarget(point);
|
|
360
374
|
if (frameCheckResult === 'error:notconnected' || 'hitTargetDescription' in frameCheckResult) return frameCheckResult;
|
|
@@ -462,22 +476,32 @@ class ElementHandle extends js.JSHandle {
|
|
|
462
476
|
}, this._page._timeoutSettings.timeout(options));
|
|
463
477
|
}
|
|
464
478
|
async _selectOption(progress, elements, values, options) {
|
|
465
|
-
|
|
466
|
-
await
|
|
467
|
-
|
|
468
|
-
progress.
|
|
469
|
-
|
|
470
|
-
const result = await this.
|
|
479
|
+
let resultingOptions = [];
|
|
480
|
+
await this._retryAction(progress, 'select option', async () => {
|
|
481
|
+
await progress.beforeInputAction(this);
|
|
482
|
+
if (!options.force) progress.log(` waiting for element to be visible and enabled`);
|
|
483
|
+
const optionsToSelect = [...elements, ...values];
|
|
484
|
+
const result = await this.evaluateInUtility(async ([injected, node, {
|
|
471
485
|
optionsToSelect,
|
|
472
486
|
force
|
|
473
487
|
}]) => {
|
|
474
|
-
|
|
488
|
+
if (!force) {
|
|
489
|
+
const checkResult = await injected.checkElementStates(node, ['visible', 'enabled']);
|
|
490
|
+
if (checkResult) return checkResult;
|
|
491
|
+
}
|
|
492
|
+
return injected.selectOptions(node, optionsToSelect);
|
|
475
493
|
}, {
|
|
476
494
|
optionsToSelect,
|
|
477
495
|
force: options.force
|
|
478
496
|
});
|
|
497
|
+
if (Array.isArray(result)) {
|
|
498
|
+
progress.log(' selected specified option(s)');
|
|
499
|
+
resultingOptions = result;
|
|
500
|
+
return 'done';
|
|
501
|
+
}
|
|
479
502
|
return result;
|
|
480
|
-
});
|
|
503
|
+
}, options);
|
|
504
|
+
return resultingOptions;
|
|
481
505
|
}
|
|
482
506
|
async fill(metadata, value, options = {}) {
|
|
483
507
|
const controller = new _progress.ProgressController(metadata, this);
|
|
@@ -487,38 +511,51 @@ class ElementHandle extends js.JSHandle {
|
|
|
487
511
|
}, this._page._timeoutSettings.timeout(options));
|
|
488
512
|
}
|
|
489
513
|
async _fill(progress, value, options) {
|
|
490
|
-
progress.log(`
|
|
491
|
-
await
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
514
|
+
progress.log(` fill("${value}")`);
|
|
515
|
+
return await this._retryAction(progress, 'fill', async () => {
|
|
516
|
+
await progress.beforeInputAction(this);
|
|
517
|
+
return this._page._frameManager.waitForSignalsCreatedBy(progress, options.noWaitAfter, async () => {
|
|
518
|
+
if (!options.force) progress.log(' waiting for element to be visible, enabled and editable');
|
|
519
|
+
const result = await this.evaluateInUtility(async ([injected, node, {
|
|
520
|
+
value,
|
|
521
|
+
force
|
|
522
|
+
}]) => {
|
|
523
|
+
if (!force) {
|
|
524
|
+
const checkResult = await injected.checkElementStates(node, ['visible', 'enabled', 'editable']);
|
|
525
|
+
if (checkResult) return checkResult;
|
|
526
|
+
}
|
|
527
|
+
return injected.fill(node, value);
|
|
528
|
+
}, {
|
|
529
|
+
value,
|
|
530
|
+
force: options.force
|
|
531
|
+
});
|
|
507
532
|
progress.throwIfAborted(); // Avoid action that has side-effects.
|
|
508
|
-
if (
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
533
|
+
if (result === 'needsinput') {
|
|
534
|
+
if (value) await this._page.keyboard.insertText(value);else await this._page.keyboard.press('Delete');
|
|
535
|
+
return 'done';
|
|
536
|
+
} else {
|
|
537
|
+
return result;
|
|
538
|
+
}
|
|
539
|
+
}, 'input');
|
|
540
|
+
}, options);
|
|
514
541
|
}
|
|
515
542
|
async selectText(metadata, options = {}) {
|
|
516
543
|
const controller = new _progress.ProgressController(metadata, this);
|
|
517
544
|
return controller.run(async progress => {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
return
|
|
521
|
-
|
|
545
|
+
const result = await this._retryAction(progress, 'selectText', async () => {
|
|
546
|
+
if (!options.force) progress.log(' waiting for element to be visible');
|
|
547
|
+
return await this.evaluateInUtility(async ([injected, node, {
|
|
548
|
+
force
|
|
549
|
+
}]) => {
|
|
550
|
+
if (!force) {
|
|
551
|
+
const checkResult = await injected.checkElementStates(node, ['visible']);
|
|
552
|
+
if (checkResult) return checkResult;
|
|
553
|
+
}
|
|
554
|
+
return injected.selectText(node);
|
|
555
|
+
}, {
|
|
556
|
+
force: options.force
|
|
557
|
+
});
|
|
558
|
+
}, options);
|
|
522
559
|
assertDone(throwRetargetableDOMError(result));
|
|
523
560
|
}, this._page._timeoutSettings.timeout(options));
|
|
524
561
|
}
|
|
@@ -669,10 +706,12 @@ class ElementHandle extends js.JSHandle {
|
|
|
669
706
|
async waitForElementState(metadata, state, options = {}) {
|
|
670
707
|
const controller = new _progress.ProgressController(metadata, this);
|
|
671
708
|
return controller.run(async progress => {
|
|
672
|
-
|
|
673
|
-
const result = await this.
|
|
674
|
-
return
|
|
675
|
-
|
|
709
|
+
const actionName = `wait for ${state}`;
|
|
710
|
+
const result = await this._retryAction(progress, actionName, async () => {
|
|
711
|
+
return await this.evaluateInUtility(async ([injected, node, state]) => {
|
|
712
|
+
return (await injected.checkElementStates(node, [state])) || 'done';
|
|
713
|
+
}, state);
|
|
714
|
+
}, {});
|
|
676
715
|
assertDone(throwRetargetableDOMError(result));
|
|
677
716
|
}, this._page._timeoutSettings.timeout(options));
|
|
678
717
|
}
|
|
@@ -687,22 +726,6 @@ class ElementHandle extends js.JSHandle {
|
|
|
687
726
|
}
|
|
688
727
|
return this;
|
|
689
728
|
}
|
|
690
|
-
async _waitForElementStates(progress, states, force) {
|
|
691
|
-
const title = joinWithAnd(states);
|
|
692
|
-
progress.log(` waiting for element to be ${title}`);
|
|
693
|
-
const result = await this.evaluatePoll(progress, ([injected, node, {
|
|
694
|
-
states,
|
|
695
|
-
force
|
|
696
|
-
}]) => {
|
|
697
|
-
return injected.waitForElementStatesAndPerformAction(node, states, force, () => 'done');
|
|
698
|
-
}, {
|
|
699
|
-
states,
|
|
700
|
-
force
|
|
701
|
-
});
|
|
702
|
-
if (result === 'error:notconnected') return result;
|
|
703
|
-
progress.log(` element is ${title}`);
|
|
704
|
-
return result;
|
|
705
|
-
}
|
|
706
729
|
async _checkFrameIsHitTarget(point) {
|
|
707
730
|
let frame = this._frame;
|
|
708
731
|
const data = [];
|
|
@@ -751,63 +774,7 @@ class ElementHandle extends js.JSHandle {
|
|
|
751
774
|
};
|
|
752
775
|
}
|
|
753
776
|
}
|
|
754
|
-
|
|
755
|
-
// Handles an InjectedScriptPoll running in injected script:
|
|
756
|
-
// - streams logs into progress;
|
|
757
|
-
// - cancels the poll when progress cancels.
|
|
758
777
|
exports.ElementHandle = ElementHandle;
|
|
759
|
-
class InjectedScriptPollHandler {
|
|
760
|
-
constructor(progress, poll) {
|
|
761
|
-
this._progress = void 0;
|
|
762
|
-
this._poll = void 0;
|
|
763
|
-
this._progress = progress;
|
|
764
|
-
this._poll = poll;
|
|
765
|
-
// Ensure we cancel the poll before progress aborts and returns:
|
|
766
|
-
// - no unnecessary work in the page;
|
|
767
|
-
// - no possible side effects after progress promise rejects.
|
|
768
|
-
this._progress.cleanupWhenAborted(() => this.cancel());
|
|
769
|
-
this._streamLogs();
|
|
770
|
-
}
|
|
771
|
-
async _streamLogs() {
|
|
772
|
-
while (this._poll && this._progress.isRunning()) {
|
|
773
|
-
const log = await this._poll.evaluate(poll => poll.takeNextLogs()).catch(e => []);
|
|
774
|
-
if (!this._poll || !this._progress.isRunning()) return;
|
|
775
|
-
for (const entry of log) this._progress.logEntry(entry);
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
async finishHandle() {
|
|
779
|
-
try {
|
|
780
|
-
const result = await this._poll.evaluateHandle(poll => poll.run());
|
|
781
|
-
await this._finishInternal();
|
|
782
|
-
return result;
|
|
783
|
-
} finally {
|
|
784
|
-
await this.cancel();
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
async finish() {
|
|
788
|
-
try {
|
|
789
|
-
const result = await this._poll.evaluate(poll => poll.run());
|
|
790
|
-
await this._finishInternal();
|
|
791
|
-
return result;
|
|
792
|
-
} finally {
|
|
793
|
-
await this.cancel();
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
async _finishInternal() {
|
|
797
|
-
if (!this._poll) return;
|
|
798
|
-
// Retrieve all the logs before continuing.
|
|
799
|
-
const log = await this._poll.evaluate(poll => poll.takeLastLogs()).catch(e => []);
|
|
800
|
-
for (const entry of log) this._progress.logEntry(entry);
|
|
801
|
-
}
|
|
802
|
-
async cancel() {
|
|
803
|
-
if (!this._poll) return;
|
|
804
|
-
const copy = this._poll;
|
|
805
|
-
this._poll = null;
|
|
806
|
-
await copy.evaluate(p => p.cancel()).catch(e => {});
|
|
807
|
-
copy.dispose();
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
exports.InjectedScriptPollHandler = InjectedScriptPollHandler;
|
|
811
778
|
function throwRetargetableDOMError(result) {
|
|
812
779
|
if (result === 'error:notconnected') throw new Error('Element is not attached to the DOM');
|
|
813
780
|
return result;
|
|
@@ -838,8 +805,4 @@ function compensateHalfIntegerRoundingError(point) {
|
|
|
838
805
|
const remainderY = point.y - Math.floor(point.y);
|
|
839
806
|
if (remainderY > 0.49 && remainderY < 0.51) point.y -= 0.02;
|
|
840
807
|
}
|
|
841
|
-
function joinWithAnd(strings) {
|
|
842
|
-
if (strings.length <= 1) return strings.join('');
|
|
843
|
-
return strings.slice(0, strings.length - 1).join(', ') + ' and ' + strings[strings.length - 1];
|
|
844
|
-
}
|
|
845
808
|
const kUnableToAdoptErrorMessage = exports.kUnableToAdoptErrorMessage = 'Unable to adopt element handle from a different document';
|
|
@@ -20,8 +20,10 @@ var _progress = require("../progress");
|
|
|
20
20
|
var _helper = require("../helper");
|
|
21
21
|
var _eventsHelper = require("../../utils/eventsHelper");
|
|
22
22
|
var readline = _interopRequireWildcard(require("readline"));
|
|
23
|
-
var _debugLogger = require("../../
|
|
23
|
+
var _debugLogger = require("../../utils/debugLogger");
|
|
24
24
|
var _instrumentation = require("../instrumentation");
|
|
25
|
+
var _crProtocolHelper = require("../chromium/crProtocolHelper");
|
|
26
|
+
var _console = require("../console");
|
|
25
27
|
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
28
|
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
29
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -54,10 +56,6 @@ class ElectronApplication extends _instrumentation.SdkObject {
|
|
|
54
56
|
this._process = void 0;
|
|
55
57
|
this._process = process;
|
|
56
58
|
this._browserContext = browser._defaultContext;
|
|
57
|
-
this._browserContext.on(_browserContext.BrowserContext.Events.Close, () => {
|
|
58
|
-
// Emit application closed after context closed.
|
|
59
|
-
Promise.resolve().then(() => this.emit(ElectronApplication.Events.Close));
|
|
60
|
-
});
|
|
61
59
|
this._nodeConnection = nodeConnection;
|
|
62
60
|
this._nodeSession = nodeConnection.rootSession;
|
|
63
61
|
this._nodeSession.on('Runtime.executionContextCreated', async event => {
|
|
@@ -74,14 +72,40 @@ class ElectronApplication extends _instrumentation.SdkObject {
|
|
|
74
72
|
});
|
|
75
73
|
this._nodeElectronHandlePromise.resolve(new js.JSHandle(this._nodeExecutionContext, 'object', 'ElectronModule', remoteObject.objectId));
|
|
76
74
|
});
|
|
75
|
+
this._nodeSession.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
|
76
|
+
const appClosePromise = new Promise(f => this.once(ElectronApplication.Events.Close, f));
|
|
77
77
|
this._browserContext.setCustomCloseHandler(async () => {
|
|
78
78
|
await this._browserContext.stopVideoRecording();
|
|
79
79
|
const electronHandle = await this._nodeElectronHandlePromise;
|
|
80
80
|
await electronHandle.evaluate(({
|
|
81
81
|
app
|
|
82
82
|
}) => app.quit()).catch(() => {});
|
|
83
|
+
this._nodeConnection.close();
|
|
84
|
+
await appClosePromise;
|
|
83
85
|
});
|
|
84
86
|
}
|
|
87
|
+
async _onConsoleAPI(event) {
|
|
88
|
+
if (event.executionContextId === 0) {
|
|
89
|
+
// DevTools protocol stores the last 1000 console messages. These
|
|
90
|
+
// messages are always reported even for removed execution contexts. In
|
|
91
|
+
// this case, they are marked with executionContextId = 0 and are
|
|
92
|
+
// reported upon enabling Runtime agent.
|
|
93
|
+
//
|
|
94
|
+
// Ignore these messages since:
|
|
95
|
+
// - there's no execution context we can use to operate with message
|
|
96
|
+
// arguments
|
|
97
|
+
// - these messages are reported before Playwright clients can subscribe
|
|
98
|
+
// to the 'console'
|
|
99
|
+
// page event.
|
|
100
|
+
//
|
|
101
|
+
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!this._nodeExecutionContext) return;
|
|
105
|
+
const args = event.args.map(arg => this._nodeExecutionContext.createHandle(arg));
|
|
106
|
+
const message = new _console.ConsoleMessage(null, event.type, undefined, args, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
107
|
+
this.emit(ElectronApplication.Events.Console, message);
|
|
108
|
+
}
|
|
85
109
|
async initialize() {
|
|
86
110
|
await this._nodeSession.send('Runtime.enable', {});
|
|
87
111
|
// Delay loading the app until browser is started and the browser targets are configured to auto-attach.
|
|
@@ -96,13 +120,10 @@ class ElectronApplication extends _instrumentation.SdkObject {
|
|
|
96
120
|
return this._browserContext;
|
|
97
121
|
}
|
|
98
122
|
async close() {
|
|
99
|
-
|
|
100
|
-
const closed = progressController.run(progress => _helper.helper.waitForEvent(progress, this, ElectronApplication.Events.Close).promise);
|
|
123
|
+
// This will call BrowserContext.setCustomCloseHandler.
|
|
101
124
|
await this._browserContext.close({
|
|
102
125
|
reason: 'Application exited'
|
|
103
126
|
});
|
|
104
|
-
this._nodeConnection.close();
|
|
105
|
-
await closed;
|
|
106
127
|
}
|
|
107
128
|
async browserWindow(page) {
|
|
108
129
|
// Assume CRPage as Electron is always Chromium.
|
|
@@ -119,7 +140,8 @@ class ElectronApplication extends _instrumentation.SdkObject {
|
|
|
119
140
|
}
|
|
120
141
|
exports.ElectronApplication = ElectronApplication;
|
|
121
142
|
ElectronApplication.Events = {
|
|
122
|
-
Close: 'close'
|
|
143
|
+
Close: 'close',
|
|
144
|
+
Console: 'console'
|
|
123
145
|
};
|
|
124
146
|
class Electron extends _instrumentation.SdkObject {
|
|
125
147
|
constructor(playwright) {
|
|
@@ -133,10 +155,11 @@ class Electron extends _instrumentation.SdkObject {
|
|
|
133
155
|
controller.setLogName('browser');
|
|
134
156
|
return controller.run(async progress => {
|
|
135
157
|
let app = undefined;
|
|
158
|
+
// --remote-debugging-port=0 must be the last playwright's argument, loader.ts relies on it.
|
|
136
159
|
const electronArguments = ['--inspect=0', '--remote-debugging-port=0', ...args];
|
|
137
160
|
if (_os.default.platform() === 'linux') {
|
|
138
161
|
const runningAsRoot = process.geteuid && process.geteuid() === 0;
|
|
139
|
-
if (runningAsRoot && electronArguments.indexOf('--no-sandbox') === -1) electronArguments.
|
|
162
|
+
if (runningAsRoot && electronArguments.indexOf('--no-sandbox') === -1) electronArguments.unshift('--no-sandbox');
|
|
140
163
|
}
|
|
141
164
|
const artifactsDir = await _fs.default.promises.mkdtemp(ARTIFACTS_FOLDER);
|
|
142
165
|
const browserLogsCollector = new _debugLogger.RecentLogsCollector();
|
|
@@ -183,7 +206,10 @@ class Electron extends _instrumentation.SdkObject {
|
|
|
183
206
|
handleSIGINT: true,
|
|
184
207
|
handleSIGTERM: true,
|
|
185
208
|
handleSIGHUP: true,
|
|
186
|
-
onExit: () => {
|
|
209
|
+
onExit: () => {
|
|
210
|
+
var _app;
|
|
211
|
+
return (_app = app) === null || _app === void 0 ? void 0 : _app.emit(ElectronApplication.Events.Close);
|
|
212
|
+
}
|
|
187
213
|
});
|
|
188
214
|
const waitForXserverError = new Promise(async (resolve, reject) => {
|
|
189
215
|
waitForLine(progress, launchedProcess, /Unable to open X display/).then(() => reject(new Error(['Unable to open X display!', `================================`, 'Most likely this is because there is no X server available.', "Use 'xvfb-run' on Linux to launch your tests with an emulated display server.", "For example: 'xvfb-run npm run test:e2e'", `================================`, progress.metadata.log].join('\n')))).catch(() => {});
|
|
@@ -23,8 +23,10 @@ const {
|
|
|
23
23
|
chromiumSwitches
|
|
24
24
|
} = require('../chromium/chromiumSwitches');
|
|
25
25
|
|
|
26
|
-
//
|
|
27
|
-
|
|
26
|
+
// Always pass user arguments first, see https://github.com/microsoft/playwright/issues/16614 and
|
|
27
|
+
// https://github.com/microsoft/playwright/issues/29198.
|
|
28
|
+
// [Electron, -r, loader.js[, --no-sandbox>], --inspect=0, --remote-debugging-port=0, ...args]
|
|
29
|
+
process.argv.splice(1, process.argv.indexOf('--remote-debugging-port=0'));
|
|
28
30
|
for (const arg of chromiumSwitches) {
|
|
29
31
|
const match = arg.match(/--([^=]*)=?(.*)/);
|
|
30
32
|
app.commandLine.appendSwitch(match[1], match[2]);
|
package/lib/server/fetch.js
CHANGED
|
@@ -149,6 +149,7 @@ class APIRequestContext extends _instrumentation.SdkObject {
|
|
|
149
149
|
queryParams: (0, _fetch.parseQueryParameters)(fetchResponse.url),
|
|
150
150
|
url: params.tokenizedURL || fetchResponse.url,
|
|
151
151
|
timings: (0, _fetch.getTimings)(fetchResponse.timings),
|
|
152
|
+
requestBody: (0, _fetch.getRequestBody)(postData, params.multipartData, options),
|
|
152
153
|
body: (0, _fetch.getBody)(fetchResponse.body),
|
|
153
154
|
method: options.method
|
|
154
155
|
};
|
|
@@ -200,7 +200,7 @@ class FFAXNode {
|
|
|
200
200
|
if (!(numericalProperty in this._payload)) continue;
|
|
201
201
|
node[numericalProperty] = this._payload[numericalProperty];
|
|
202
202
|
}
|
|
203
|
-
const tokenProperties = ['autocomplete', 'haspopup', '
|
|
203
|
+
const tokenProperties = ['autocomplete', 'haspopup', 'orientation'];
|
|
204
204
|
for (const tokenProperty of tokenProperties) {
|
|
205
205
|
const value = this._payload[tokenProperty];
|
|
206
206
|
if (!value || value === 'false') continue;
|
|
@@ -210,6 +210,7 @@ class FFAXNode {
|
|
|
210
210
|
axNode.valueString = this._payload.value;
|
|
211
211
|
if ('checked' in this._payload) axNode.checked = this._payload.checked === true ? 'checked' : this._payload.checked === 'mixed' ? 'mixed' : 'unchecked';
|
|
212
212
|
if ('pressed' in this._payload) axNode.pressed = this._payload.pressed === true ? 'pressed' : 'released';
|
|
213
|
+
if ('invalid' in this._payload) axNode.invalid = this._payload.invalid === true ? 'true' : 'false';
|
|
213
214
|
return axNode;
|
|
214
215
|
}
|
|
215
216
|
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.kBrowserCloseMessageId = exports.FFSession = exports.FFConnection = exports.ConnectionEvents = void 0;
|
|
7
7
|
var _events = require("events");
|
|
8
|
-
var _debugLogger = require("../../
|
|
8
|
+
var _debugLogger = require("../../utils/debugLogger");
|
|
9
9
|
var _helper = require("../helper");
|
|
10
10
|
var _protocolError = require("../protocolError");
|
|
11
11
|
/**
|
|
@@ -14,7 +14,7 @@ var _ffExecutionContext = require("./ffExecutionContext");
|
|
|
14
14
|
var _ffInput = require("./ffInput");
|
|
15
15
|
var _ffNetworkManager = require("./ffNetworkManager");
|
|
16
16
|
var _stackTrace = require("../../utils/stackTrace");
|
|
17
|
-
var _debugLogger = require("../../
|
|
17
|
+
var _debugLogger = require("../../utils/debugLogger");
|
|
18
18
|
var _manualPromise = require("../../utils/manualPromise");
|
|
19
19
|
var _browserContext = require("../browserContext");
|
|
20
20
|
var _errors = require("../errors");
|