patchright-core 1.56.1 → 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 +3134 -560
- package/bin/install_webkit_wsl.ps1 +1 -3
- package/browsers.json +21 -22
- package/lib/cli/program.js +16 -60
- package/lib/client/api.js +3 -3
- package/lib/client/browser.js +3 -5
- package/lib/client/browserContext.js +62 -8
- package/lib/client/browserType.js +4 -3
- package/lib/client/connection.js +4 -0
- package/lib/client/consoleMessage.js +5 -1
- package/lib/client/electron.js +1 -1
- package/lib/client/elementHandle.js +3 -0
- package/lib/client/events.js +5 -1
- package/lib/client/fetch.js +3 -4
- package/lib/client/frame.js +10 -1
- package/lib/client/locator.js +12 -1
- package/lib/client/network.js +5 -1
- package/lib/client/page.js +31 -6
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +3 -0
- package/lib/client/playwright.js +1 -5
- package/lib/client/tracing.js +7 -5
- package/lib/client/worker.js +22 -0
- package/lib/generated/clockSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/inProcessFactory.js +0 -2
- 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 +112 -50
- 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/android/android.js +1 -1
- package/lib/server/artifact.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +81 -22
- package/lib/server/bidi/bidiChromium.js +9 -13
- 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 +7 -9
- package/lib/server/bidi/bidiNetworkManager.js +1 -1
- package/lib/server/bidi/bidiPage.js +61 -30
- package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
- package/lib/server/browserContext.js +43 -36
- package/lib/server/browserType.js +12 -4
- package/lib/server/chromium/chromium.js +26 -21
- package/lib/server/chromium/chromiumSwitches.js +12 -3
- package/lib/server/chromium/crBrowser.js +30 -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 +107 -18
- package/lib/server/chromium/crPage.js +68 -124
- package/lib/server/chromium/crServiceWorker.js +14 -1
- package/lib/server/codegen/javascript.js +6 -29
- package/lib/server/console.js +5 -1
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
- 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 +14 -22
- package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
- package/lib/server/dom.js +12 -3
- package/lib/server/electron/electron.js +6 -3
- 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 +18 -24
- package/lib/server/firefox/firefox.js +18 -9
- package/lib/server/frameSelectors.js +18 -8
- package/lib/server/frames.js +257 -87
- package/lib/server/input.js +7 -3
- package/lib/server/instrumentation.js +3 -0
- package/lib/server/javascript.js +8 -4
- package/lib/server/launchApp.js +2 -1
- package/lib/server/localUtils.js +4 -8
- package/lib/server/network.js +50 -12
- package/lib/server/page.js +112 -126
- package/lib/server/playwright.js +2 -4
- package/lib/server/progress.js +26 -6
- package/lib/server/recorder/recorderApp.js +80 -101
- package/lib/server/recorder.js +3 -2
- package/lib/server/registry/browserFetcher.js +6 -4
- package/lib/server/registry/index.js +278 -189
- package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
- package/lib/server/screencast.js +190 -0
- package/lib/server/screenshotter.js +6 -0
- package/lib/server/socksClientCertificatesInterceptor.js +1 -1
- 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 +31 -21
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +45 -40
- package/lib/server/utils/comparators.js +3 -25
- package/lib/server/utils/expectUtils.js +87 -2
- package/lib/server/utils/hostPlatform.js +30 -3
- package/lib/server/utils/httpServer.js +5 -20
- package/lib/server/utils/imageUtils.js +141 -0
- package/lib/server/utils/network.js +55 -40
- package/lib/server/utils/nodePlatform.js +6 -0
- package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
- package/lib/server/webkit/webkit.js +5 -16
- 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 +76 -51
- package/lib/server/webkit/wkWorkers.js +2 -1
- package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
- package/lib/utils/isomorphic/locatorGenerators.js +24 -8
- package/lib/utils/isomorphic/lruCache.js +51 -0
- package/lib/utils/isomorphic/mimeType.js +1 -1
- package/lib/utils/isomorphic/protocolFormatter.js +3 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
- 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/urlMatch.js +19 -5
- package/lib/utils/isomorphic/yaml.js +84 -0
- package/lib/utils.js +4 -0
- package/lib/utilsBundle.js +1 -1
- package/lib/utilsBundleImpl/index.js +124 -124
- package/lib/vite/htmlReport/index.html +21 -21
- package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
- package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → 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/traceViewer/{codeMirrorModule.C3UTv-Ge.css → 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 +6 -6
- package/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/lib/vite/traceViewer/snapshot.html +3 -3
- 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 +939 -245
- package/types/types.d.ts +143 -153
- package/lib/client/accessibility.js +0 -49
- package/lib/server/accessibility.js +0 -69
- package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
- package/lib/server/chromium/crAccessibility.js +0 -263
- package/lib/server/firefox/ffAccessibility.js +0 -238
- package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
- package/lib/server/webkit/wkAccessibility.js +0 -237
- package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
- package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
- package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
- package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
- package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
- package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
- package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
- package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
- package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
- package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
|
@@ -39,11 +39,11 @@ class JSHandleDispatcher extends import_dispatcher.Dispatcher {
|
|
|
39
39
|
return scope.connection.existingDispatcher(handle) || new JSHandleDispatcher(scope, handle);
|
|
40
40
|
}
|
|
41
41
|
async evaluateExpression(params, progress) {
|
|
42
|
-
const jsHandle = await progress.race(this._object.evaluateExpression(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)));
|
|
42
|
+
const jsHandle = await progress.race(this._object.evaluateExpression(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg), params.isolatedContext));
|
|
43
43
|
return { value: serializeResult(jsHandle) };
|
|
44
44
|
}
|
|
45
45
|
async evaluateExpressionHandle(params, progress) {
|
|
46
|
-
const jsHandle = await progress.race(this._object.evaluateExpressionHandle(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)));
|
|
46
|
+
const jsHandle = await progress.race(this._object.evaluateExpressionHandle(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg), params.isolatedContext));
|
|
47
47
|
return { handle: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this.parentScope(), jsHandle) };
|
|
48
48
|
}
|
|
49
49
|
async getProperty(params, progress) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var pageAgentDispatcher_exports = {};
|
|
20
|
+
__export(pageAgentDispatcher_exports, {
|
|
21
|
+
PageAgentDispatcher: () => PageAgentDispatcher
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(pageAgentDispatcher_exports);
|
|
24
|
+
var import_dispatcher = require("./dispatcher");
|
|
25
|
+
var import_pageAgent = require("../agent/pageAgent");
|
|
26
|
+
var import_instrumentation = require("../instrumentation");
|
|
27
|
+
var import_context = require("../agent/context");
|
|
28
|
+
class PageAgentDispatcher extends import_dispatcher.Dispatcher {
|
|
29
|
+
constructor(scope, options) {
|
|
30
|
+
super(scope, new import_instrumentation.SdkObject(scope._object, "pageAgent"), "PageAgent", { page: scope });
|
|
31
|
+
this._type_PageAgent = true;
|
|
32
|
+
this._type_EventTarget = true;
|
|
33
|
+
this._usage = { turns: 0, inputTokens: 0, outputTokens: 0 };
|
|
34
|
+
this._page = scope._object;
|
|
35
|
+
this._context = new import_context.Context(this._page, options, this._eventSupport());
|
|
36
|
+
}
|
|
37
|
+
async perform(params, progress) {
|
|
38
|
+
try {
|
|
39
|
+
await (0, import_pageAgent.pageAgentPerform)(progress, this._context, params.task, params);
|
|
40
|
+
} finally {
|
|
41
|
+
this._context.pushHistory({ type: "perform", description: params.task });
|
|
42
|
+
}
|
|
43
|
+
return { usage: this._usage };
|
|
44
|
+
}
|
|
45
|
+
async expect(params, progress) {
|
|
46
|
+
try {
|
|
47
|
+
await (0, import_pageAgent.pageAgentExpect)(progress, this._context, params.expectation, params);
|
|
48
|
+
} finally {
|
|
49
|
+
this._context.pushHistory({ type: "expect", description: params.expectation });
|
|
50
|
+
}
|
|
51
|
+
return { usage: this._usage };
|
|
52
|
+
}
|
|
53
|
+
async extract(params, progress) {
|
|
54
|
+
const result = await (0, import_pageAgent.pageAgentExtract)(progress, this._context, params.query, params.schema, params);
|
|
55
|
+
return { result, usage: this._usage };
|
|
56
|
+
}
|
|
57
|
+
async usage(params, progress) {
|
|
58
|
+
return { usage: this._usage };
|
|
59
|
+
}
|
|
60
|
+
async dispose(params, progress) {
|
|
61
|
+
progress.metadata.potentiallyClosesScope = true;
|
|
62
|
+
void this.stopPendingOperations(new Error("The agent is disposed"));
|
|
63
|
+
this._dispose();
|
|
64
|
+
}
|
|
65
|
+
_eventSupport() {
|
|
66
|
+
const self = this;
|
|
67
|
+
return {
|
|
68
|
+
onBeforeTurn(params) {
|
|
69
|
+
const userMessage = params.conversation.messages.find((m) => m.role === "user");
|
|
70
|
+
self._dispatchEvent("turn", { role: "user", message: userMessage?.content ?? "" });
|
|
71
|
+
},
|
|
72
|
+
onAfterTurn(params) {
|
|
73
|
+
const usage = { inputTokens: params.totalUsage.input, outputTokens: params.totalUsage.output };
|
|
74
|
+
const intent = params.assistantMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
75
|
+
self._dispatchEvent("turn", { role: "assistant", message: intent, usage });
|
|
76
|
+
if (!params.assistantMessage.content.filter((c) => c.type === "tool_call").length)
|
|
77
|
+
self._dispatchEvent("turn", { role: "assistant", message: `no tool calls`, usage });
|
|
78
|
+
self._usage = { turns: self._usage.turns + 1, inputTokens: self._usage.inputTokens + usage.inputTokens, outputTokens: self._usage.outputTokens + usage.outputTokens };
|
|
79
|
+
},
|
|
80
|
+
onBeforeToolCall(params) {
|
|
81
|
+
self._dispatchEvent("turn", { role: "assistant", message: `call tool "${params.toolCall.name}"` });
|
|
82
|
+
},
|
|
83
|
+
onAfterToolCall(params) {
|
|
84
|
+
const suffix = params.toolCall.result?.isError ? "failed" : "succeeded";
|
|
85
|
+
self._dispatchEvent("turn", { role: "user", message: `tool "${params.toolCall.name}" ${suffix}` });
|
|
86
|
+
},
|
|
87
|
+
onToolCallError(params) {
|
|
88
|
+
self._dispatchEvent("turn", { role: "user", message: `tool "${params.toolCall.name}" failed: ${params.error.message}` });
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
94
|
+
0 && (module.exports = {
|
|
95
|
+
PageAgentDispatcher
|
|
96
|
+
});
|
|
@@ -36,6 +36,7 @@ var import_networkDispatchers3 = require("./networkDispatchers");
|
|
|
36
36
|
var import_webSocketRouteDispatcher = require("./webSocketRouteDispatcher");
|
|
37
37
|
var import_instrumentation = require("../instrumentation");
|
|
38
38
|
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
|
39
|
+
var import_pageAgentDispatcher = require("./pageAgentDispatcher");
|
|
39
40
|
class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
40
41
|
constructor(parentScope, page) {
|
|
41
42
|
const mainFrame = import_frameDispatcher.FrameDispatcher.from(parentScope, page.mainFrame());
|
|
@@ -103,19 +104,6 @@ class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
|
103
104
|
page() {
|
|
104
105
|
return this._page;
|
|
105
106
|
}
|
|
106
|
-
serializeConsoleMessage(message) {
|
|
107
|
-
return {
|
|
108
|
-
type: message.type(),
|
|
109
|
-
text: message.text(),
|
|
110
|
-
args: message.args().map((a) => {
|
|
111
|
-
const elementHandle = a.asElement();
|
|
112
|
-
if (elementHandle)
|
|
113
|
-
return import_elementHandlerDispatcher.ElementHandleDispatcher.from(import_frameDispatcher.FrameDispatcher.from(this.parentScope(), elementHandle._frame), elementHandle);
|
|
114
|
-
return import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, a);
|
|
115
|
-
}),
|
|
116
|
-
location: message.location()
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
107
|
async exposeBinding(params, progress) {
|
|
120
108
|
const binding = await this._page.exposeBinding(progress, params.name, !!params.needsHandle, (source, ...args) => {
|
|
121
109
|
if (this._disposed)
|
|
@@ -237,7 +225,7 @@ class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
|
237
225
|
}
|
|
238
226
|
async consoleMessages(params, progress) {
|
|
239
227
|
this._subscriptions.add("console");
|
|
240
|
-
return { messages: this._page.consoleMessages().map((message) => this.serializeConsoleMessage(message)) };
|
|
228
|
+
return { messages: this._page.consoleMessages().map((message) => this.parentScope().serializeConsoleMessage(message, this)) };
|
|
241
229
|
}
|
|
242
230
|
async pageErrors(params, progress) {
|
|
243
231
|
return { errors: this._page.pageErrors().map((error) => (0, import_errors.serializeError)(error)) };
|
|
@@ -265,13 +253,6 @@ class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
|
265
253
|
progress.metadata.point = { x: params.x, y: params.y };
|
|
266
254
|
await this._page.touchscreen.tap(progress, params.x, params.y);
|
|
267
255
|
}
|
|
268
|
-
async accessibilitySnapshot(params, progress) {
|
|
269
|
-
const rootAXNode = await progress.race(this._page.accessibility.snapshot({
|
|
270
|
-
interestingOnly: params.interestingOnly,
|
|
271
|
-
root: params.root ? params.root._elementHandle : void 0
|
|
272
|
-
}));
|
|
273
|
-
return { rootAXNode: rootAXNode || void 0 };
|
|
274
|
-
}
|
|
275
256
|
async pdf(params, progress) {
|
|
276
257
|
if (!this._page.pdf)
|
|
277
258
|
throw new Error("PDF generation is only supported for Headless Chromium");
|
|
@@ -283,7 +264,7 @@ class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
|
283
264
|
return { requests: this._page.networkRequests().map((request) => import_networkDispatchers.RequestDispatcher.from(this.parentScope(), request)) };
|
|
284
265
|
}
|
|
285
266
|
async snapshotForAI(params, progress) {
|
|
286
|
-
return
|
|
267
|
+
return await this._page.snapshotForAI(progress, params);
|
|
287
268
|
}
|
|
288
269
|
async bringToFront(params, progress) {
|
|
289
270
|
await progress.race(this._page.bringToFront());
|
|
@@ -308,6 +289,9 @@ class PageDispatcher extends import_dispatcher.Dispatcher {
|
|
|
308
289
|
const coverage = this._page.coverage;
|
|
309
290
|
return await coverage.stopCSSCoverage();
|
|
310
291
|
}
|
|
292
|
+
async agent(params, progress) {
|
|
293
|
+
return { agent: new import_pageAgentDispatcher.PageAgentDispatcher(this, params) };
|
|
294
|
+
}
|
|
311
295
|
_onFrameAttached(frame) {
|
|
312
296
|
this._dispatchEvent("frameAttached", { frame: import_frameDispatcher.FrameDispatcher.from(this.parentScope(), frame) });
|
|
313
297
|
}
|
|
@@ -351,6 +335,8 @@ class WorkerDispatcher extends import_dispatcher.Dispatcher {
|
|
|
351
335
|
url: worker.url
|
|
352
336
|
});
|
|
353
337
|
this._type_Worker = true;
|
|
338
|
+
this._type_EventTarget = true;
|
|
339
|
+
this._subscriptions = /* @__PURE__ */ new Set();
|
|
354
340
|
this.addObjectListener(import_page.Worker.Events.Close, () => this._dispatchEvent("close"));
|
|
355
341
|
}
|
|
356
342
|
static fromNullable(scope, worker) {
|
|
@@ -365,6 +351,12 @@ class WorkerDispatcher extends import_dispatcher.Dispatcher {
|
|
|
365
351
|
async evaluateExpressionHandle(params, progress) {
|
|
366
352
|
return { handle: import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, await progress.race(this._object.evaluateExpressionHandle(params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
|
367
353
|
}
|
|
354
|
+
async updateSubscription(params, progress) {
|
|
355
|
+
if (params.enabled)
|
|
356
|
+
this._subscriptions.add(params.event);
|
|
357
|
+
else
|
|
358
|
+
this._subscriptions.delete(params.event);
|
|
359
|
+
}
|
|
368
360
|
}
|
|
369
361
|
class BindingCallDispatcher extends import_dispatcher.Dispatcher {
|
|
370
362
|
constructor(scope, name, needsHandle, source, args) {
|
|
@@ -39,15 +39,11 @@ class PlaywrightDispatcher extends import_dispatcher.Dispatcher {
|
|
|
39
39
|
const chromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium, denyLaunch);
|
|
40
40
|
const firefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox, denyLaunch);
|
|
41
41
|
const webkit = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit, denyLaunch);
|
|
42
|
-
const _bidiChromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright._bidiChromium, denyLaunch);
|
|
43
|
-
const _bidiFirefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright._bidiFirefox, denyLaunch);
|
|
44
42
|
const android = new import_androidDispatcher.AndroidDispatcher(scope, playwright.android);
|
|
45
43
|
const initializer = {
|
|
46
44
|
chromium,
|
|
47
45
|
firefox,
|
|
48
46
|
webkit,
|
|
49
|
-
_bidiChromium,
|
|
50
|
-
_bidiFirefox,
|
|
51
47
|
android,
|
|
52
48
|
electron: new import_electronDispatcher.ElectronDispatcher(scope, playwright.electron, denyLaunch),
|
|
53
49
|
utils: playwright.options.isServer ? void 0 : new import_localUtilsDispatcher.LocalUtilsDispatcher(scope, playwright),
|
package/lib/server/dom.js
CHANGED
|
@@ -255,6 +255,7 @@ class ElementHandle extends js.JSHandle {
|
|
|
255
255
|
async _retryAction(progress, actionName, action, options) {
|
|
256
256
|
let retry = 0;
|
|
257
257
|
const waitTime = [0, 20, 100, 100, 500];
|
|
258
|
+
const noAutoWaiting = options.__testHookNoAutoWaiting ?? options.noAutoWaiting;
|
|
258
259
|
while (true) {
|
|
259
260
|
if (retry) {
|
|
260
261
|
progress.log(`retrying ${actionName} action${options.trial ? " (trial run)" : ""}`);
|
|
@@ -268,35 +269,43 @@ class ElementHandle extends js.JSHandle {
|
|
|
268
269
|
} else {
|
|
269
270
|
progress.log(`attempting ${actionName} action${options.trial ? " (trial run)" : ""}`);
|
|
270
271
|
}
|
|
271
|
-
if (!options.skipActionPreChecks && !options.force)
|
|
272
|
+
if (!options.skipActionPreChecks && !options.force && !noAutoWaiting)
|
|
272
273
|
await this._frame._page.performActionPreChecks(progress);
|
|
273
274
|
const result = await action(retry);
|
|
274
275
|
++retry;
|
|
275
276
|
if (result === "error:notvisible") {
|
|
276
|
-
if (options.force)
|
|
277
|
+
if (options.force || noAutoWaiting)
|
|
277
278
|
throw new NonRecoverableDOMError("Element is not visible");
|
|
278
279
|
progress.log(" element is not visible");
|
|
279
280
|
continue;
|
|
280
281
|
}
|
|
281
282
|
if (result === "error:notinviewport") {
|
|
282
|
-
if (options.force)
|
|
283
|
+
if (options.force || noAutoWaiting)
|
|
283
284
|
throw new NonRecoverableDOMError("Element is outside of the viewport");
|
|
284
285
|
progress.log(" element is outside of the viewport");
|
|
285
286
|
continue;
|
|
286
287
|
}
|
|
287
288
|
if (result === "error:optionsnotfound") {
|
|
289
|
+
if (noAutoWaiting)
|
|
290
|
+
throw new NonRecoverableDOMError("Did not find some options");
|
|
288
291
|
progress.log(" did not find some options");
|
|
289
292
|
continue;
|
|
290
293
|
}
|
|
291
294
|
if (result === "error:optionnotenabled") {
|
|
295
|
+
if (noAutoWaiting)
|
|
296
|
+
throw new NonRecoverableDOMError("Option being selected is not enabled");
|
|
292
297
|
progress.log(" option being selected is not enabled");
|
|
293
298
|
continue;
|
|
294
299
|
}
|
|
295
300
|
if (typeof result === "object" && "hitTargetDescription" in result) {
|
|
301
|
+
if (noAutoWaiting)
|
|
302
|
+
throw new NonRecoverableDOMError(`${result.hitTargetDescription} intercepts pointer events`);
|
|
296
303
|
progress.log(` ${result.hitTargetDescription} intercepts pointer events`);
|
|
297
304
|
continue;
|
|
298
305
|
}
|
|
299
306
|
if (typeof result === "object" && "missingState" in result) {
|
|
307
|
+
if (noAutoWaiting)
|
|
308
|
+
throw new NonRecoverableDOMError(`Element is not ${result.missingState}`);
|
|
300
309
|
progress.log(` element is not ${result.missingState}`);
|
|
301
310
|
continue;
|
|
302
311
|
}
|
|
@@ -97,7 +97,7 @@ class ElectronApplication extends import_instrumentation.SdkObject {
|
|
|
97
97
|
if (!this._nodeExecutionContext)
|
|
98
98
|
return;
|
|
99
99
|
const args = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(this._nodeExecutionContext, arg));
|
|
100
|
-
const message = new import_console.ConsoleMessage(null, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
100
|
+
const message = new import_console.ConsoleMessage(null, null, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
101
101
|
this.emit(ElectronApplication.Events.Console, message);
|
|
102
102
|
}
|
|
103
103
|
async initialize() {
|
|
@@ -158,8 +158,8 @@ class Electron extends import_instrumentation.SdkObject {
|
|
|
158
158
|
let shell = false;
|
|
159
159
|
if (process.platform === "win32") {
|
|
160
160
|
shell = true;
|
|
161
|
-
command = `"${
|
|
162
|
-
electronArguments =
|
|
161
|
+
command = [command, ...electronArguments].map((arg) => `"${escapeDoubleQuotes(arg)}"`).join(" ");
|
|
162
|
+
electronArguments = [];
|
|
163
163
|
}
|
|
164
164
|
delete env.NODE_OPTIONS;
|
|
165
165
|
const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
|
|
@@ -263,6 +263,9 @@ async function waitForLine(progress, process2, regex) {
|
|
|
263
263
|
import_eventsHelper.eventsHelper.removeEventListeners(listeners);
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
+
function escapeDoubleQuotes(str) {
|
|
267
|
+
return str.replace(/"/g, '\\"');
|
|
268
|
+
}
|
|
266
269
|
// Annotate the CommonJS export names for ESM import in node:
|
|
267
270
|
0 && (module.exports = {
|
|
268
271
|
Electron,
|
|
@@ -54,7 +54,6 @@ class FFBrowser extends import_browser.Browser {
|
|
|
54
54
|
this.session.on("Browser.detachedFromTarget", this._onDetachedFromTarget.bind(this));
|
|
55
55
|
this.session.on("Browser.downloadCreated", this._onDownloadCreated.bind(this));
|
|
56
56
|
this.session.on("Browser.downloadFinished", this._onDownloadFinished.bind(this));
|
|
57
|
-
this.session.on("Browser.videoRecordingFinished", this._onVideoRecordingFinished.bind(this));
|
|
58
57
|
}
|
|
59
58
|
static async connect(parent, transport, options) {
|
|
60
59
|
const connection = new import_ffConnection.FFConnection(transport, options.protocolLogger, options.browserLogsCollector);
|
|
@@ -141,12 +140,9 @@ class FFBrowser extends import_browser.Browser {
|
|
|
141
140
|
const error = payload.canceled ? "canceled" : payload.error;
|
|
142
141
|
this._downloadFinished(payload.uuid, error);
|
|
143
142
|
}
|
|
144
|
-
_onVideoRecordingFinished(payload) {
|
|
145
|
-
this._takeVideo(payload.screencastId)?.reportFinished();
|
|
146
|
-
}
|
|
147
143
|
_onDisconnect() {
|
|
148
144
|
for (const video of this._idToVideo.values())
|
|
149
|
-
video.artifact.reportFinished(new import_errors.TargetClosedError());
|
|
145
|
+
video.artifact.reportFinished(new import_errors.TargetClosedError(this.closeReason()));
|
|
150
146
|
this._idToVideo.clear();
|
|
151
147
|
for (const ffPage of this._ffPages.values())
|
|
152
148
|
ffPage.didClose();
|
|
@@ -199,15 +195,13 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
199
195
|
promises.push(this.doUpdateOffline());
|
|
200
196
|
promises.push(this.doUpdateDefaultEmulatedMedia());
|
|
201
197
|
if (this._options.recordVideo) {
|
|
202
|
-
promises.push(this.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
browserContextId: this._browserContextId
|
|
210
|
-
});
|
|
198
|
+
promises.push(this._browser.session.send("Browser.setScreencastOptions", {
|
|
199
|
+
// validateBrowserContextOptions ensures correct video size.
|
|
200
|
+
options: {
|
|
201
|
+
...this._options.recordVideo.size,
|
|
202
|
+
quality: 90
|
|
203
|
+
},
|
|
204
|
+
browserContextId: this._browserContextId
|
|
211
205
|
}));
|
|
212
206
|
}
|
|
213
207
|
const proxy = this._options.proxyOverride || this._options.proxy;
|
|
@@ -379,12 +373,8 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
379
373
|
}
|
|
380
374
|
async doClose(reason) {
|
|
381
375
|
if (!this._browserContextId) {
|
|
382
|
-
if (this._options.recordVideo)
|
|
383
|
-
await this.
|
|
384
|
-
options: void 0,
|
|
385
|
-
browserContextId: this._browserContextId
|
|
386
|
-
});
|
|
387
|
-
}
|
|
376
|
+
if (this._options.recordVideo)
|
|
377
|
+
await Promise.all(this._ffPages().map((ffPage) => ffPage._page.screencast.stopVideoRecording()));
|
|
388
378
|
await this._browser.close({ reason });
|
|
389
379
|
} else {
|
|
390
380
|
await this._browser.session.send("Browser.removeBrowserContext", { browserContextId: this._browserContextId });
|
|
@@ -90,11 +90,6 @@ class FFSession extends import_events.EventEmitter {
|
|
|
90
90
|
this._connection = connection;
|
|
91
91
|
this._sessionId = sessionId;
|
|
92
92
|
this._rawSend = rawSend;
|
|
93
|
-
this.on = super.on;
|
|
94
|
-
this.addListener = super.addListener;
|
|
95
|
-
this.off = super.removeListener;
|
|
96
|
-
this.removeListener = super.removeListener;
|
|
97
|
-
this.once = super.once;
|
|
98
93
|
}
|
|
99
94
|
markAsCrashed() {
|
|
100
95
|
this._crashed = true;
|
|
@@ -170,9 +170,9 @@ const causeToResourceType = {
|
|
|
170
170
|
TYPE_FONT: "font",
|
|
171
171
|
TYPE_MEDIA: "media",
|
|
172
172
|
TYPE_WEBSOCKET: "websocket",
|
|
173
|
-
TYPE_CSP_REPORT: "
|
|
173
|
+
TYPE_CSP_REPORT: "cspreport",
|
|
174
174
|
TYPE_XSLT: "other",
|
|
175
|
-
TYPE_BEACON: "
|
|
175
|
+
TYPE_BEACON: "beacon",
|
|
176
176
|
TYPE_FETCH: "fetch",
|
|
177
177
|
TYPE_IMAGESET: "image",
|
|
178
178
|
TYPE_WEB_MANIFEST: "manifest"
|
|
@@ -37,14 +37,13 @@ var dialog = __toESM(require("../dialog"));
|
|
|
37
37
|
var dom = __toESM(require("../dom"));
|
|
38
38
|
var import_page = require("../page");
|
|
39
39
|
var import_page2 = require("../page");
|
|
40
|
-
var import_ffAccessibility = require("./ffAccessibility");
|
|
41
40
|
var import_ffConnection = require("./ffConnection");
|
|
42
41
|
var import_ffExecutionContext = require("./ffExecutionContext");
|
|
43
42
|
var import_ffInput = require("./ffInput");
|
|
44
43
|
var import_ffNetworkManager = require("./ffNetworkManager");
|
|
45
|
-
var import_debugLogger = require("../utils/debugLogger");
|
|
46
44
|
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
|
47
45
|
var import_errors = require("../errors");
|
|
46
|
+
var import_debugLogger = require("../utils/debugLogger");
|
|
48
47
|
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
|
49
48
|
class FFPage {
|
|
50
49
|
constructor(session, browserContext, opener) {
|
|
@@ -84,13 +83,16 @@ class FFPage {
|
|
|
84
83
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.workerDestroyed", this._onWorkerDestroyed.bind(this)),
|
|
85
84
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.dispatchMessageFromWorker", this._onDispatchMessageFromWorker.bind(this)),
|
|
86
85
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.crashed", this._onCrashed.bind(this)),
|
|
87
|
-
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.videoRecordingStarted", this._onVideoRecordingStarted.bind(this)),
|
|
88
86
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketCreated", this._onWebSocketCreated.bind(this)),
|
|
89
87
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketClosed", this._onWebSocketClosed.bind(this)),
|
|
90
88
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameReceived", this._onWebSocketFrameReceived.bind(this)),
|
|
91
89
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameSent", this._onWebSocketFrameSent.bind(this)),
|
|
92
90
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.screencastFrame", this._onScreencastFrame.bind(this))
|
|
93
91
|
];
|
|
92
|
+
const screencast = this._page.screencast;
|
|
93
|
+
const videoOptions = screencast.launchVideoRecorder();
|
|
94
|
+
if (videoOptions)
|
|
95
|
+
screencast.startVideoRecording(videoOptions).catch((e) => import_debugLogger.debugLogger.log("error", e));
|
|
94
96
|
this._session.once("Page.ready", () => {
|
|
95
97
|
if (this._reportedAsNew)
|
|
96
98
|
return;
|
|
@@ -201,7 +203,7 @@ class FFPage {
|
|
|
201
203
|
const context = this._contextIdToContext.get(executionContextId);
|
|
202
204
|
if (!context)
|
|
203
205
|
return;
|
|
204
|
-
this._page.addConsoleMessage(type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
|
206
|
+
this._page.addConsoleMessage(null, type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
|
205
207
|
}
|
|
206
208
|
_onDialogOpened(params) {
|
|
207
209
|
this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
|
|
@@ -246,11 +248,12 @@ class FFPage {
|
|
|
246
248
|
this._page.addWorker(workerId, worker);
|
|
247
249
|
workerSession.once("Runtime.executionContextCreated", (event2) => {
|
|
248
250
|
worker.createExecutionContext(new import_ffExecutionContext.FFExecutionContext(workerSession, event2.executionContextId));
|
|
251
|
+
worker.workerScriptLoaded();
|
|
249
252
|
});
|
|
250
253
|
workerSession.on("Runtime.console", (event2) => {
|
|
251
254
|
const { type, args, location } = event2;
|
|
252
255
|
const context = worker.existingExecutionContext;
|
|
253
|
-
this._page.addConsoleMessage(type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
|
256
|
+
this._page.addConsoleMessage(worker, type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
|
254
257
|
});
|
|
255
258
|
}
|
|
256
259
|
_onWorkerDestroyed(event) {
|
|
@@ -272,11 +275,8 @@ class FFPage {
|
|
|
272
275
|
this._session.markAsCrashed();
|
|
273
276
|
this._page._didCrash();
|
|
274
277
|
}
|
|
275
|
-
_onVideoRecordingStarted(event) {
|
|
276
|
-
this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this._page.waitForInitializedOrError());
|
|
277
|
-
}
|
|
278
278
|
didClose() {
|
|
279
|
-
this._markAsError(new import_errors.TargetClosedError());
|
|
279
|
+
this._markAsError(new import_errors.TargetClosedError(this._page.closeReason()));
|
|
280
280
|
this._session.dispose();
|
|
281
281
|
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
|
282
282
|
this._networkManager.dispose();
|
|
@@ -417,24 +417,21 @@ class FFPage {
|
|
|
417
417
|
throw e;
|
|
418
418
|
});
|
|
419
419
|
}
|
|
420
|
-
async
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
await this._session.send("Page.stopScreencast");
|
|
426
|
-
}
|
|
420
|
+
async startScreencast(options) {
|
|
421
|
+
await this._session.send("Page.startScreencast", options);
|
|
422
|
+
}
|
|
423
|
+
async stopScreencast() {
|
|
424
|
+
await this._session.sendMayFail("Page.stopScreencast");
|
|
427
425
|
}
|
|
428
426
|
_onScreencastFrame(event) {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const screencastId = this._screencastId;
|
|
432
|
-
this._page.throttleScreencastFrameAck(() => {
|
|
433
|
-
this._session.send("Page.screencastFrameAck", { screencastId }).catch((e) => import_debugLogger.debugLogger.log("error", e));
|
|
427
|
+
this._page.screencast.throttleFrameAck(() => {
|
|
428
|
+
this._session.sendMayFail("Page.screencastFrameAck");
|
|
434
429
|
});
|
|
435
430
|
const buffer = Buffer.from(event.data, "base64");
|
|
436
431
|
this._page.emit(import_page2.Page.Events.ScreencastFrame, {
|
|
437
432
|
buffer,
|
|
433
|
+
frameSwapWallTime: event.timestamp * 1e3,
|
|
434
|
+
// timestamp is in seconds, we need to convert to milliseconds.
|
|
438
435
|
width: event.deviceWidth,
|
|
439
436
|
height: event.deviceHeight
|
|
440
437
|
});
|
|
@@ -468,9 +465,6 @@ class FFPage {
|
|
|
468
465
|
throw new Error(dom.kUnableToAdoptErrorMessage);
|
|
469
466
|
return (0, import_ffExecutionContext.createHandle)(to, result.remoteObject);
|
|
470
467
|
}
|
|
471
|
-
async getAccessibilityTree(needle) {
|
|
472
|
-
return (0, import_ffAccessibility.getAccessibilityTree)(this._session, needle);
|
|
473
|
-
}
|
|
474
468
|
async inputActionEpilogue() {
|
|
475
469
|
}
|
|
476
470
|
async resetForReuse(progress) {
|
|
@@ -39,21 +39,30 @@ var import_ascii = require("../utils/ascii");
|
|
|
39
39
|
var import_browserType = require("../browserType");
|
|
40
40
|
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
|
41
41
|
class Firefox extends import_browserType.BrowserType {
|
|
42
|
-
constructor(parent) {
|
|
42
|
+
constructor(parent, bidiFirefox) {
|
|
43
43
|
super(parent, "firefox");
|
|
44
|
+
this._bidiFirefox = bidiFirefox;
|
|
45
|
+
}
|
|
46
|
+
launch(progress, options, protocolLogger) {
|
|
47
|
+
if (options.channel?.startsWith("moz-"))
|
|
48
|
+
return this._bidiFirefox.launch(progress, options, protocolLogger);
|
|
49
|
+
return super.launch(progress, options, protocolLogger);
|
|
50
|
+
}
|
|
51
|
+
async launchPersistentContext(progress, userDataDir, options) {
|
|
52
|
+
if (options.channel?.startsWith("moz-"))
|
|
53
|
+
return this._bidiFirefox.launchPersistentContext(progress, userDataDir, options);
|
|
54
|
+
return super.launchPersistentContext(progress, userDataDir, options);
|
|
44
55
|
}
|
|
45
56
|
connectToTransport(transport, options) {
|
|
46
57
|
return import_ffBrowser.FFBrowser.connect(this.attribution.playwright, transport, options);
|
|
47
58
|
}
|
|
48
|
-
doRewriteStartupLog(
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
if (error.logs.includes(`as root in a regular user's session is not supported.`))
|
|
52
|
-
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
|
59
|
+
doRewriteStartupLog(logs) {
|
|
60
|
+
if (logs.includes(`as root in a regular user's session is not supported.`))
|
|
61
|
+
logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
|
53
62
|
Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? " in your GitHub Actions workflow file" : ""} when running Playwright.`, 1);
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
return
|
|
63
|
+
if (logs.includes("no DISPLAY environment variable specified"))
|
|
64
|
+
logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
|
65
|
+
return logs;
|
|
57
66
|
}
|
|
58
67
|
amendEnvironment(env) {
|
|
59
68
|
if (!import_path.default.isAbsolute(import_os.default.homedir()))
|
|
@@ -51,7 +51,9 @@ class FrameSelectors {
|
|
|
51
51
|
if (!resolved)
|
|
52
52
|
throw new Error(`Failed to find frame for selector "${selector}"`);
|
|
53
53
|
return await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
|
|
54
|
-
|
|
54
|
+
const elements = injected.querySelectorAll(info.parsed, scope2 || document);
|
|
55
|
+
injected.checkDeprecatedSelectorUsage(info.parsed, elements);
|
|
56
|
+
return elements;
|
|
55
57
|
}, { info: resolved.info, scope: resolved.scope });
|
|
56
58
|
}
|
|
57
59
|
async queryCount(selector, options) {
|
|
@@ -60,7 +62,9 @@ class FrameSelectors {
|
|
|
60
62
|
throw new Error(`Failed to find frame for selector "${selector}"`);
|
|
61
63
|
await options.__testHookBeforeQuery?.();
|
|
62
64
|
return await resolved.injected.evaluate((injected, { info }) => {
|
|
63
|
-
|
|
65
|
+
const elements = injected.querySelectorAll(info.parsed, document);
|
|
66
|
+
injected.checkDeprecatedSelectorUsage(info.parsed, elements);
|
|
67
|
+
return elements.length;
|
|
64
68
|
}, { info: resolved.info });
|
|
65
69
|
}
|
|
66
70
|
async queryAll(selector, scope) {
|
|
@@ -68,7 +72,9 @@ class FrameSelectors {
|
|
|
68
72
|
if (!resolved)
|
|
69
73
|
return [];
|
|
70
74
|
const arrayHandle = await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
|
|
71
|
-
|
|
75
|
+
const elements = injected.querySelectorAll(info.parsed, scope2 || document);
|
|
76
|
+
injected.checkDeprecatedSelectorUsage(info.parsed, elements);
|
|
77
|
+
return elements;
|
|
72
78
|
}, { info: resolved.info, scope: resolved.scope });
|
|
73
79
|
const properties = await arrayHandle.getProperties();
|
|
74
80
|
arrayHandle.dispose();
|
|
@@ -90,10 +96,8 @@ class FrameSelectors {
|
|
|
90
96
|
const match = body.match(/^f(\d+)e\d+$/);
|
|
91
97
|
if (!match)
|
|
92
98
|
return frame;
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const frameId = page.lastSnapshotFrameIds[frameIndex - 1];
|
|
96
|
-
const jumptToFrame = frameId ? page.frameManager.frame(frameId) : null;
|
|
99
|
+
const frameSeq = +match[1];
|
|
100
|
+
const jumptToFrame = this.frame._page.frameManager.frames().find((frame2) => frame2.seq === frameSeq);
|
|
97
101
|
if (!jumptToFrame)
|
|
98
102
|
throw new import_selectorParser.InvalidSelectorError(`Invalid frame in aria-ref selector "${selector}"`);
|
|
99
103
|
return jumptToFrame;
|
|
@@ -160,6 +164,7 @@ class FrameSelectors {
|
|
|
160
164
|
if (!resolved)
|
|
161
165
|
return;
|
|
162
166
|
const context = await resolved.frame._context(options?.mainWorld ? "main" : resolved.info.world);
|
|
167
|
+
if (!context) throw new Error("Frame was detached");
|
|
163
168
|
const injected = await context.injectedScript();
|
|
164
169
|
return { injected, info: resolved.info, frame: resolved.frame, scope: resolved.scope };
|
|
165
170
|
}
|
|
@@ -289,7 +294,7 @@ class FrameSelectors {
|
|
|
289
294
|
}
|
|
290
295
|
for (const child of queryingElement.children || []) {
|
|
291
296
|
const childrenNodeIndex = queryingElement.children.indexOf(child);
|
|
292
|
-
const childIndex = this._findElementPositionInDomTree(element, child, documentScope, currentIndex + childrenNodeIndex.toString());
|
|
297
|
+
const childIndex = this._findElementPositionInDomTree(element, child, documentScope, currentIndex + "." + childrenNodeIndex.toString());
|
|
293
298
|
if (childIndex !== null) return childIndex;
|
|
294
299
|
}
|
|
295
300
|
if (queryingElement.shadowRoots && Array.isArray(queryingElement.shadowRoots)) {
|
|
@@ -299,6 +304,11 @@ class FrameSelectors {
|
|
|
299
304
|
const childIndex = this._findElementPositionInDomTree(element, shadowRootHandle, documentScope, currentIndex);
|
|
300
305
|
if (childIndex !== null) return childIndex;
|
|
301
306
|
}
|
|
307
|
+
for (const shadowChild of shadowRoot.children || []) {
|
|
308
|
+
const shadowChildIndex = (shadowRoot.children || []).indexOf(shadowChild);
|
|
309
|
+
const childIndex = this._findElementPositionInDomTree(element, shadowChild, documentScope, currentIndex + "." + shadowChildIndex.toString());
|
|
310
|
+
if (childIndex !== null) return childIndex;
|
|
311
|
+
}
|
|
302
312
|
}
|
|
303
313
|
}
|
|
304
314
|
return null;
|