patchright-core 1.57.0 → 1.58.2
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 +3223 -308
- package/browsers.json +21 -22
- package/lib/cli/program.js +4 -5
- package/lib/client/api.js +3 -0
- package/lib/client/browser.js +3 -5
- package/lib/client/browserContext.js +40 -4
- package/lib/client/browserType.js +4 -3
- package/lib/client/connection.js +4 -0
- package/lib/client/elementHandle.js +3 -0
- package/lib/client/events.js +3 -0
- package/lib/client/fetch.js +3 -4
- package/lib/client/frame.js +10 -1
- package/lib/client/locator.js +8 -0
- package/lib/client/network.js +5 -1
- package/lib/client/page.js +29 -1
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +3 -0
- package/lib/client/tracing.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/mcpBundle.js +84 -0
- package/lib/mcpBundleImpl/index.js +147 -0
- package/lib/protocol/serializers.js +5 -0
- package/lib/protocol/validator.js +88 -4
- package/lib/remote/playwrightServer.js +1 -2
- package/lib/server/agent/actionRunner.js +335 -0
- package/lib/server/agent/actions.js +128 -0
- package/lib/server/agent/codegen.js +111 -0
- package/lib/server/agent/context.js +150 -0
- package/lib/server/agent/expectTools.js +156 -0
- package/lib/server/agent/pageAgent.js +204 -0
- package/lib/server/agent/performTools.js +262 -0
- package/lib/server/agent/tool.js +109 -0
- package/lib/server/artifact.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +56 -12
- package/lib/server/bidi/bidiChromium.js +8 -12
- package/lib/server/bidi/bidiConnection.js +1 -0
- package/lib/server/bidi/bidiDeserializer.js +116 -0
- package/lib/server/bidi/bidiExecutionContext.js +75 -29
- package/lib/server/bidi/bidiFirefox.js +6 -8
- package/lib/server/bidi/bidiNetworkManager.js +1 -1
- package/lib/server/bidi/bidiPage.js +39 -28
- package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
- package/lib/server/browserContext.js +34 -26
- package/lib/server/browserType.js +12 -4
- package/lib/server/chromium/chromium.js +14 -20
- package/lib/server/chromium/chromiumSwitches.js +2 -2
- package/lib/server/chromium/crBrowser.js +22 -12
- package/lib/server/chromium/crConnection.js +0 -5
- package/lib/server/chromium/crCoverage.js +13 -1
- package/lib/server/chromium/crDevTools.js +0 -2
- package/lib/server/chromium/crNetworkManager.js +92 -12
- package/lib/server/chromium/crPage.js +62 -116
- package/lib/server/codegen/javascript.js +6 -29
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +3 -2
- package/lib/server/dispatchers/dispatcher.js +6 -13
- package/lib/server/dispatchers/frameDispatcher.js +1 -1
- package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
- package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
- package/lib/server/dispatchers/pageDispatcher.js +4 -0
- package/lib/server/dom.js +12 -3
- package/lib/server/electron/electron.js +5 -2
- package/lib/server/firefox/ffBrowser.js +10 -20
- package/lib/server/firefox/ffConnection.js +0 -5
- package/lib/server/firefox/ffNetworkManager.js +2 -2
- package/lib/server/firefox/ffPage.js +15 -18
- package/lib/server/firefox/firefox.js +6 -8
- package/lib/server/frameSelectors.js +16 -4
- package/lib/server/frames.js +251 -86
- package/lib/server/instrumentation.js +3 -0
- package/lib/server/javascript.js +8 -4
- package/lib/server/launchApp.js +2 -1
- package/lib/server/network.js +50 -12
- package/lib/server/page.js +61 -91
- package/lib/server/progress.js +26 -6
- package/lib/server/recorder/recorderApp.js +79 -100
- package/lib/server/registry/browserFetcher.js +6 -4
- package/lib/server/registry/index.js +172 -149
- package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
- package/lib/server/screencast.js +190 -0
- package/lib/server/screenshotter.js +6 -0
- package/lib/server/trace/recorder/snapshotter.js +17 -8
- package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
- package/lib/server/trace/recorder/tracing.js +29 -21
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +21 -17
- package/lib/server/utils/expectUtils.js +87 -2
- package/lib/server/utils/hostPlatform.js +15 -0
- package/lib/server/utils/httpServer.js +5 -20
- package/lib/server/utils/network.js +37 -28
- package/lib/server/utils/nodePlatform.js +6 -0
- package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +22 -13
- package/lib/server/webkit/webkit.js +4 -6
- package/lib/server/webkit/wkBrowser.js +2 -6
- package/lib/server/webkit/wkConnection.js +1 -6
- package/lib/server/webkit/wkInterceptableRequest.js +29 -1
- package/lib/server/webkit/wkPage.js +75 -46
- package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
- package/lib/utils/isomorphic/lruCache.js +51 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +9 -1
- package/lib/utils/isomorphic/stringUtils.js +49 -0
- package/lib/utils/isomorphic/trace/entries.js +16 -0
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
- package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
- package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
- package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
- package/lib/utils/isomorphic/trace/traceModel.js +365 -0
- package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
- package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
- package/lib/utils/isomorphic/yaml.js +84 -0
- package/lib/utils.js +2 -0
- package/lib/utilsBundle.js +2 -5
- package/lib/utilsBundleImpl/index.js +165 -165
- package/lib/vite/htmlReport/index.html +21 -21
- package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
- package/lib/vite/{traceViewer/codeMirrorModule.C3UTv-Ge.css → recorder/assets/codeMirrorModule-DYBRYzYX.css} +1 -1
- package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
- package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
- package/lib/vite/{recorder/assets/codeMirrorModule-C3UTv-Ge.css → traceViewer/codeMirrorModule.DYBRYzYX.css} +1 -1
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
- package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
- package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
- package/lib/vite/traceViewer/index.html +4 -4
- package/lib/vite/traceViewer/sw.bundle.js +5 -3
- package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/package.json +2 -1
- package/types/protocol.d.ts +738 -159
- package/types/types.d.ts +25 -38
- package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
- package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
- package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
- package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
- package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
- package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
- package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
- package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
- package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
- package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
|
@@ -32,9 +32,7 @@ __export(crPage_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(crPage_exports);
|
|
34
34
|
var import_crypto = __toESM(require("crypto"));
|
|
35
|
-
var import_path = __toESM(require("path"));
|
|
36
35
|
var import_assert = require("../../utils/isomorphic/assert");
|
|
37
|
-
var import_crypto2 = require("../utils/crypto");
|
|
38
36
|
var import_eventsHelper = require("../utils/eventsHelper");
|
|
39
37
|
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
|
40
38
|
var dialog = __toESM(require("../dialog"));
|
|
@@ -43,7 +41,6 @@ var frames = __toESM(require("../frames"));
|
|
|
43
41
|
var import_helper = require("../helper");
|
|
44
42
|
var network = __toESM(require("../network"));
|
|
45
43
|
var import_page = require("../page");
|
|
46
|
-
var import_registry = require("../registry");
|
|
47
44
|
var import_crCoverage = require("./crCoverage");
|
|
48
45
|
var import_crDragDrop = require("./crDragDrop");
|
|
49
46
|
var import_crExecutionContext = require("./crExecutionContext");
|
|
@@ -52,7 +49,6 @@ var import_crNetworkManager = require("./crNetworkManager");
|
|
|
52
49
|
var import_crPdf = require("./crPdf");
|
|
53
50
|
var import_crProtocolHelper = require("./crProtocolHelper");
|
|
54
51
|
var import_defaultFontFamilies = require("./defaultFontFamilies");
|
|
55
|
-
var import_videoRecorder = require("./videoRecorder");
|
|
56
52
|
var import_errors = require("../errors");
|
|
57
53
|
var import_protocolError = require("../protocolError");
|
|
58
54
|
class CRPage {
|
|
@@ -114,7 +110,7 @@ class CRPage {
|
|
|
114
110
|
while (!this._sessions.has(frame._id)) {
|
|
115
111
|
const parent = frame.parentFrame();
|
|
116
112
|
if (!parent)
|
|
117
|
-
throw new Error(`Frame
|
|
113
|
+
throw new Error(`Frame was detached`);
|
|
118
114
|
frame = parent;
|
|
119
115
|
}
|
|
120
116
|
return this._sessions.get(frame._id);
|
|
@@ -239,17 +235,16 @@ class CRPage {
|
|
|
239
235
|
async scrollRectIntoViewIfNeeded(handle, rect) {
|
|
240
236
|
return this._sessionForHandle(handle)._scrollRectIntoViewIfNeeded(handle, rect);
|
|
241
237
|
}
|
|
242
|
-
async
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
238
|
+
async startScreencast(options) {
|
|
239
|
+
await this._mainFrameSession._client.send("Page.startScreencast", {
|
|
240
|
+
format: "jpeg",
|
|
241
|
+
quality: options.quality,
|
|
242
|
+
maxWidth: options.width,
|
|
243
|
+
maxHeight: options.height
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
async stopScreencast() {
|
|
247
|
+
await this._mainFrameSession._client._sendMayFail("Page.stopScreencast");
|
|
253
248
|
}
|
|
254
249
|
rafCountForStablePosition() {
|
|
255
250
|
return 1;
|
|
@@ -322,9 +317,6 @@ class FrameSession {
|
|
|
322
317
|
// Marks the oopif session that remote -> local transition has happened in the parent.
|
|
323
318
|
// See Target.detachedFromTarget handler for details.
|
|
324
319
|
this._swappedIn = false;
|
|
325
|
-
this._videoRecorder = null;
|
|
326
|
-
this._screencastId = null;
|
|
327
|
-
this._screencastClients = /* @__PURE__ */ new Set();
|
|
328
320
|
this._workerSessions = /* @__PURE__ */ new Map();
|
|
329
321
|
this._initScriptIds = /* @__PURE__ */ new Map();
|
|
330
322
|
this._exposedBindingNames = [];
|
|
@@ -376,38 +368,32 @@ class FrameSession {
|
|
|
376
368
|
]);
|
|
377
369
|
}
|
|
378
370
|
async _initialize(hasUIWindow) {
|
|
371
|
+
const pageEnablePromise = this._client.send("Page.enable");
|
|
379
372
|
if (!this._page.isStorageStatePage && hasUIWindow && !this._crPage._browserContext._browser.isClank() && !this._crPage._browserContext._options.noDefaultViewport) {
|
|
380
373
|
const { windowId } = await this._client.send("Browser.getWindowForTarget");
|
|
381
374
|
this._windowId = windowId;
|
|
382
375
|
}
|
|
383
|
-
let
|
|
384
|
-
if (!this._page.isStorageStatePage && this._isMainFrame() &&
|
|
385
|
-
|
|
386
|
-
const outputFile = import_path.default.join(this._crPage._browserContext._options.recordVideo.dir, screencastId + ".webm");
|
|
387
|
-
screencastOptions = {
|
|
388
|
-
// validateBrowserContextOptions ensures correct video size.
|
|
389
|
-
...this._crPage._browserContext._options.recordVideo.size,
|
|
390
|
-
outputFile
|
|
391
|
-
};
|
|
392
|
-
await this._crPage._browserContext._ensureVideosPath();
|
|
393
|
-
await this._createVideoRecorder(screencastId, screencastOptions);
|
|
394
|
-
this._crPage._page.waitForInitializedOrError().then((p) => {
|
|
395
|
-
if (p instanceof Error)
|
|
396
|
-
this._stopVideoRecording().catch(() => {
|
|
397
|
-
});
|
|
398
|
-
});
|
|
399
|
-
}
|
|
376
|
+
let videoOptions;
|
|
377
|
+
if (!this._page.isStorageStatePage && this._isMainFrame() && hasUIWindow)
|
|
378
|
+
videoOptions = this._crPage._page.screencast.launchVideoRecorder();
|
|
400
379
|
let lifecycleEventsEnabled;
|
|
401
380
|
if (!this._isMainFrame())
|
|
402
381
|
this._addRendererListeners();
|
|
382
|
+
let bufferedDialogEvents = this._isMainFrame() ? [] : void 0;
|
|
383
|
+
if (bufferedDialogEvents)
|
|
384
|
+
this._eventListeners.push(import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.javascriptDialogOpening", (event) => bufferedDialogEvents ? bufferedDialogEvents.push(event) : void 0));
|
|
403
385
|
this._addBrowserListeners();
|
|
404
386
|
this._bufferedAttachedToTargetEvents = [];
|
|
405
387
|
const promises = [
|
|
406
|
-
|
|
388
|
+
pageEnablePromise,
|
|
407
389
|
this._client.send("Page.getFrameTree").then(({ frameTree }) => {
|
|
408
390
|
if (this._isMainFrame()) {
|
|
409
391
|
this._handleFrameTree(frameTree);
|
|
410
392
|
this._addRendererListeners();
|
|
393
|
+
const pendingDialogEvents = bufferedDialogEvents || [];
|
|
394
|
+
bufferedDialogEvents = void 0;
|
|
395
|
+
for (const event of pendingDialogEvents)
|
|
396
|
+
this._onDialog(event);
|
|
411
397
|
}
|
|
412
398
|
const attachedToTargetEvents = this._bufferedAttachedToTargetEvents || [];
|
|
413
399
|
this._bufferedAttachedToTargetEvents = void 0;
|
|
@@ -422,12 +408,16 @@ class FrameSession {
|
|
|
422
408
|
} else {
|
|
423
409
|
const localFrames = this._isMainFrame() ? this._page.frames() : [this._page.frameManager.frame(this._targetId)];
|
|
424
410
|
for (const frame of localFrames) {
|
|
425
|
-
this._page.frameManager.frame(frame._id)._context("utility")
|
|
411
|
+
this._page.frameManager.frame(frame._id)._context("utility").catch(() => {
|
|
412
|
+
});
|
|
426
413
|
for (const binding of this._crPage._browserContext._pageBindings.values())
|
|
427
414
|
frame.evaluateExpression(binding.source).catch((e) => {
|
|
428
415
|
});
|
|
429
416
|
for (const source of this._crPage._browserContext.initScripts)
|
|
430
|
-
frame.evaluateExpression(source).catch((e) => {
|
|
417
|
+
frame.evaluateExpression(source.source).catch((e) => {
|
|
418
|
+
});
|
|
419
|
+
for (const source of this._crPage._page.initScripts)
|
|
420
|
+
frame.evaluateExpression(source.source).catch((e) => {
|
|
431
421
|
});
|
|
432
422
|
}
|
|
433
423
|
this._firstNonInitialNavigationCommittedFulfill();
|
|
@@ -446,6 +436,8 @@ class FrameSession {
|
|
|
446
436
|
if (!this._page.isStorageStatePage) {
|
|
447
437
|
if (this._crPage._browserContext.needsPlaywrightBinding())
|
|
448
438
|
promises.push(this.exposePlaywrightBinding());
|
|
439
|
+
if (this._isMainFrame() && !this._crPage._browserContext._options.focusControl)
|
|
440
|
+
promises.push(this._client.send("Emulation.setFocusEmulationEnabled", { enabled: true }));
|
|
449
441
|
const options = this._crPage._browserContext._options;
|
|
450
442
|
if (options.bypassCSP)
|
|
451
443
|
promises.push(this._client.send("Page.setBypassCSP", { enabled: true }));
|
|
@@ -471,18 +463,15 @@ class FrameSession {
|
|
|
471
463
|
for (const binding of this._crPage._page.allBindings()) promises.push(this._initBinding(binding));
|
|
472
464
|
for (const initScript of this._crPage._browserContext.initScripts) promises.push(this._evaluateOnNewDocument(initScript, "main"));
|
|
473
465
|
for (const initScript of this._crPage._page.initScripts) promises.push(this._evaluateOnNewDocument(initScript, "main"));
|
|
474
|
-
if (
|
|
475
|
-
promises.push(this.
|
|
466
|
+
if (videoOptions)
|
|
467
|
+
promises.push(this._crPage._page.screencast.startVideoRecording(videoOptions));
|
|
476
468
|
}
|
|
477
|
-
|
|
478
|
-
promises.push(this._client.send("Runtime.runIfWaitingForDebugger"));
|
|
469
|
+
promises.push(this._client.send("Runtime.runIfWaitingForDebugger"));
|
|
479
470
|
promises.push(this._firstNonInitialNavigationCommittedPromise);
|
|
480
471
|
await Promise.all(promises);
|
|
481
|
-
if (this._crPage._page._pageBindings.size || this._crPage._browserContext._pageBindings.size)
|
|
482
|
-
await this._client.send("Runtime.runIfWaitingForDebugger");
|
|
483
472
|
}
|
|
484
473
|
dispose() {
|
|
485
|
-
this._firstNonInitialNavigationCommittedReject(new import_errors.TargetClosedError());
|
|
474
|
+
this._firstNonInitialNavigationCommittedReject(new import_errors.TargetClosedError(this._page.closeReason()));
|
|
486
475
|
for (const childSession of this._childSessions)
|
|
487
476
|
childSession.dispose();
|
|
488
477
|
if (this._parentSession)
|
|
@@ -507,6 +496,10 @@ class FrameSession {
|
|
|
507
496
|
this._page.frameManager.frameLifecycleEvent(event.frameId, "load");
|
|
508
497
|
else if (event.name === "DOMContentLoaded")
|
|
509
498
|
this._page.frameManager.frameLifecycleEvent(event.frameId, "domcontentloaded");
|
|
499
|
+
if (event.name !== "load") {
|
|
500
|
+
await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
510
503
|
await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
|
|
511
504
|
var document = await this._client._sendMayFail("DOM.getDocument");
|
|
512
505
|
if (!document) return;
|
|
@@ -559,6 +552,14 @@ class FrameSession {
|
|
|
559
552
|
if (!initial)
|
|
560
553
|
this._firstNonInitialNavigationCommittedFulfill();
|
|
561
554
|
await this._client._sendMayFail("Runtime.runIfWaitingForDebugger");
|
|
555
|
+
if (!initial) {
|
|
556
|
+
try {
|
|
557
|
+
await this._page.frameManager.frame(this._targetId)._context("utility");
|
|
558
|
+
} catch {
|
|
559
|
+
}
|
|
560
|
+
;
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
562
563
|
var document = await this._client._sendMayFail("DOM.getDocument");
|
|
563
564
|
if (!document) return;
|
|
564
565
|
var query = await this._client._sendMayFail("DOM.querySelectorAll", {
|
|
@@ -607,7 +608,7 @@ class FrameSession {
|
|
|
607
608
|
const delegate = new import_crExecutionContext.CRExecutionContext(this._client, contextPayload);
|
|
608
609
|
let worldName = contextPayload.name;
|
|
609
610
|
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
|
610
|
-
if (worldName)
|
|
611
|
+
if (worldName && (worldName === "main" || worldName === "utility"))
|
|
611
612
|
frame._contextCreated(worldName, context);
|
|
612
613
|
this._contextIdToContext.set(contextPayload.id, context);
|
|
613
614
|
for (const source of this._exposedBindingScripts) {
|
|
@@ -787,63 +788,17 @@ class FrameSession {
|
|
|
787
788
|
}
|
|
788
789
|
}
|
|
789
790
|
_onScreencastFrame(payload) {
|
|
790
|
-
this._page.
|
|
791
|
-
this._client.
|
|
792
|
-
});
|
|
791
|
+
this._page.screencast.throttleFrameAck(() => {
|
|
792
|
+
this._client._sendMayFail("Page.screencastFrameAck", { sessionId: payload.sessionId });
|
|
793
793
|
});
|
|
794
794
|
const buffer = Buffer.from(payload.data, "base64");
|
|
795
795
|
this._page.emit(import_page.Page.Events.ScreencastFrame, {
|
|
796
796
|
buffer,
|
|
797
|
-
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1e3 :
|
|
797
|
+
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1e3 : Date.now(),
|
|
798
798
|
width: payload.metadata.deviceWidth,
|
|
799
799
|
height: payload.metadata.deviceHeight
|
|
800
800
|
});
|
|
801
801
|
}
|
|
802
|
-
async _createVideoRecorder(screencastId, options) {
|
|
803
|
-
(0, import_assert.assert)(!this._screencastId);
|
|
804
|
-
const ffmpegPath = import_registry.registry.findExecutable("ffmpeg").executablePathOrDie(this._page.browserContext._browser.sdkLanguage());
|
|
805
|
-
this._videoRecorder = await import_videoRecorder.VideoRecorder.launch(this._crPage._page, ffmpegPath, options);
|
|
806
|
-
this._screencastId = screencastId;
|
|
807
|
-
}
|
|
808
|
-
async _startVideoRecording(options) {
|
|
809
|
-
const screencastId = this._screencastId;
|
|
810
|
-
(0, import_assert.assert)(screencastId);
|
|
811
|
-
this._page.once(import_page.Page.Events.Close, () => this._stopVideoRecording().catch(() => {
|
|
812
|
-
}));
|
|
813
|
-
const gotFirstFrame = new Promise((f) => this._client.once("Page.screencastFrame", f));
|
|
814
|
-
await this._startScreencast(this._videoRecorder, {
|
|
815
|
-
format: "jpeg",
|
|
816
|
-
quality: 90,
|
|
817
|
-
maxWidth: options.width,
|
|
818
|
-
maxHeight: options.height
|
|
819
|
-
});
|
|
820
|
-
gotFirstFrame.then(() => {
|
|
821
|
-
this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage._page.waitForInitializedOrError());
|
|
822
|
-
});
|
|
823
|
-
}
|
|
824
|
-
async _stopVideoRecording() {
|
|
825
|
-
if (!this._screencastId)
|
|
826
|
-
return;
|
|
827
|
-
const screencastId = this._screencastId;
|
|
828
|
-
this._screencastId = null;
|
|
829
|
-
const recorder = this._videoRecorder;
|
|
830
|
-
this._videoRecorder = null;
|
|
831
|
-
await this._stopScreencast(recorder);
|
|
832
|
-
await recorder.stop().catch(() => {
|
|
833
|
-
});
|
|
834
|
-
const video = this._crPage._browserContext._browser._takeVideo(screencastId);
|
|
835
|
-
video?.reportFinished();
|
|
836
|
-
}
|
|
837
|
-
async _startScreencast(client, options = {}) {
|
|
838
|
-
this._screencastClients.add(client);
|
|
839
|
-
if (this._screencastClients.size === 1)
|
|
840
|
-
await this._client.send("Page.startScreencast", options);
|
|
841
|
-
}
|
|
842
|
-
async _stopScreencast(client) {
|
|
843
|
-
this._screencastClients.delete(client);
|
|
844
|
-
if (!this._screencastClients.size)
|
|
845
|
-
await this._client._sendMayFail("Page.stopScreencast");
|
|
846
|
-
}
|
|
847
802
|
async _updateGeolocation(initial) {
|
|
848
803
|
const geolocation = this._crPage._browserContext._options.geolocation;
|
|
849
804
|
if (!initial || geolocation)
|
|
@@ -1047,29 +1002,20 @@ class FrameSession {
|
|
|
1047
1002
|
return (0, import_crExecutionContext.createHandle)(to, result.object).asElement();
|
|
1048
1003
|
}
|
|
1049
1004
|
async _initBinding(binding = import_page.PageBinding) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
worldName: "utility"
|
|
1054
|
-
});
|
|
1055
|
-
if (!result) return;
|
|
1056
|
-
var isolatedContextId = result.executionContextId;
|
|
1057
|
-
var globalThis = await this._client._sendMayFail("Runtime.evaluate", {
|
|
1058
|
-
expression: "globalThis",
|
|
1059
|
-
serializationOptions: { serialization: "idOnly" }
|
|
1060
|
-
});
|
|
1061
|
-
if (!globalThis) return;
|
|
1062
|
-
var globalThisObjId = globalThis["result"]["objectId"];
|
|
1063
|
-
var mainContextId = parseInt(globalThisObjId.split(".")[1], 10);
|
|
1005
|
+
this._exposedBindingNames.push(binding.name);
|
|
1006
|
+
this._exposedBindingScripts.push(binding.source);
|
|
1007
|
+
const contextIds = Array.from(this._contextIdToContext.keys());
|
|
1064
1008
|
await Promise.all([
|
|
1065
1009
|
this._client._sendMayFail("Runtime.addBinding", { name: binding.name }),
|
|
1066
|
-
this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId
|
|
1067
|
-
this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId: isolatedContextId })
|
|
1068
|
-
// this._client._sendMayFail("Runtime.evaluate", { expression: binding.source, contextId: mainContextId, awaitPromise: true })
|
|
1010
|
+
...contextIds.map((executionContextId) => this._client._sendMayFail("Runtime.addBinding", { name: binding.name, executionContextId }))
|
|
1069
1011
|
]);
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1012
|
+
for (const contextId of contextIds) {
|
|
1013
|
+
this._client._sendMayFail("Runtime.evaluate", {
|
|
1014
|
+
expression: binding.source,
|
|
1015
|
+
contextId,
|
|
1016
|
+
awaitPromise: true
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1073
1019
|
}
|
|
1074
1020
|
async _removeExposedBindings() {
|
|
1075
1021
|
const toRetain = [];
|
|
@@ -90,7 +90,7 @@ class JavaScriptLanguageGenerator {
|
|
|
90
90
|
case "fill":
|
|
91
91
|
return `await ${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)});`;
|
|
92
92
|
case "setInputFiles":
|
|
93
|
-
return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${formatObject(action.files.length === 1 ? action.files[0] : action.files)});`;
|
|
93
|
+
return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${(0, import_utils.formatObject)(action.files.length === 1 ? action.files[0] : action.files)});`;
|
|
94
94
|
case "press": {
|
|
95
95
|
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
|
96
96
|
const shortcut = [...modifiers, action.key].join("+");
|
|
@@ -99,7 +99,7 @@ class JavaScriptLanguageGenerator {
|
|
|
99
99
|
case "navigate":
|
|
100
100
|
return `await ${subject}.goto(${quote(action.url)});`;
|
|
101
101
|
case "select":
|
|
102
|
-
return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${formatObject(action.options.length === 1 ? action.options[0] : action.options)});`;
|
|
102
|
+
return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${(0, import_utils.formatObject)(action.options.length === 1 ? action.options[0] : action.options)});`;
|
|
103
103
|
case "assertText":
|
|
104
104
|
return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "toContainText" : "toHaveText"}(${quote(action.text)});`;
|
|
105
105
|
case "assertChecked":
|
|
@@ -151,7 +151,7 @@ ${useText ? "\ntest.use(" + useText + ");\n" : ""}
|
|
|
151
151
|
const { ${options.browserName}${options.deviceName ? ", devices" : ""} } = require('playwright');
|
|
152
152
|
|
|
153
153
|
(async () => {
|
|
154
|
-
const browser = await ${options.browserName}.launch(${formatObjectOrVoid(options.launchOptions)});
|
|
154
|
+
const browser = await ${options.browserName}.launch(${(0, import_utils.formatObjectOrVoid)(options.launchOptions)});
|
|
155
155
|
const context = await browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName, false)});`);
|
|
156
156
|
if (options.contextOptions.recordHar)
|
|
157
157
|
formatter.add(` await context.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
|
|
@@ -171,37 +171,14 @@ function formatOptions(value, hasArguments) {
|
|
|
171
171
|
const keys = Object.keys(value).filter((key) => value[key] !== void 0);
|
|
172
172
|
if (!keys.length)
|
|
173
173
|
return "";
|
|
174
|
-
return (hasArguments ? ", " : "") + formatObject(value);
|
|
175
|
-
}
|
|
176
|
-
function formatObject(value, indent = " ") {
|
|
177
|
-
if (typeof value === "string")
|
|
178
|
-
return quote(value);
|
|
179
|
-
if (Array.isArray(value))
|
|
180
|
-
return `[${value.map((o) => formatObject(o)).join(", ")}]`;
|
|
181
|
-
if (typeof value === "object") {
|
|
182
|
-
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
|
183
|
-
if (!keys.length)
|
|
184
|
-
return "{}";
|
|
185
|
-
const tokens = [];
|
|
186
|
-
for (const key of keys)
|
|
187
|
-
tokens.push(`${key}: ${formatObject(value[key])}`);
|
|
188
|
-
return `{
|
|
189
|
-
${indent}${tokens.join(`,
|
|
190
|
-
${indent}`)}
|
|
191
|
-
}`;
|
|
192
|
-
}
|
|
193
|
-
return String(value);
|
|
194
|
-
}
|
|
195
|
-
function formatObjectOrVoid(value, indent = " ") {
|
|
196
|
-
const result = formatObject(value, indent);
|
|
197
|
-
return result === "{}" ? "" : result;
|
|
174
|
+
return (hasArguments ? ", " : "") + (0, import_utils.formatObject)(value);
|
|
198
175
|
}
|
|
199
176
|
function formatContextOptions(options, deviceName, isTest) {
|
|
200
177
|
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
|
|
201
178
|
options = { ...options, recordHar: void 0 };
|
|
202
179
|
if (!device)
|
|
203
|
-
return formatObjectOrVoid(options);
|
|
204
|
-
let serializedObject = formatObjectOrVoid((0, import_language.sanitizeDeviceOptions)(device, options));
|
|
180
|
+
return (0, import_utils.formatObjectOrVoid)(options);
|
|
181
|
+
let serializedObject = (0, import_utils.formatObjectOrVoid)((0, import_language.sanitizeDeviceOptions)(device, options));
|
|
205
182
|
if (!serializedObject)
|
|
206
183
|
serializedObject = "{\n}";
|
|
207
184
|
const lines = serializedObject.split("\n");
|