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
|
@@ -0,0 +1,335 @@
|
|
|
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 actionRunner_exports = {};
|
|
20
|
+
__export(actionRunner_exports, {
|
|
21
|
+
runAction: () => runAction,
|
|
22
|
+
traceParamsForAction: () => traceParamsForAction
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(actionRunner_exports);
|
|
25
|
+
var import_expectUtils = require("../utils/expectUtils");
|
|
26
|
+
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
|
27
|
+
var import_stringUtils = require("../../utils/isomorphic/stringUtils");
|
|
28
|
+
var import_time = require("../../utils/isomorphic/time");
|
|
29
|
+
var import_crypto = require("../utils/crypto");
|
|
30
|
+
var import_ariaSnapshot = require("../../utils/isomorphic/ariaSnapshot");
|
|
31
|
+
var import_locatorGenerators = require("../../utils/isomorphic/locatorGenerators");
|
|
32
|
+
var import_utilsBundle = require("../../utilsBundle");
|
|
33
|
+
var import_errors = require("../errors");
|
|
34
|
+
async function runAction(progress, mode, page, action, secrets) {
|
|
35
|
+
const parentMetadata = progress.metadata;
|
|
36
|
+
const frame = page.mainFrame();
|
|
37
|
+
const callMetadata = callMetadataForAction(progress, frame, action, mode);
|
|
38
|
+
callMetadata.log = parentMetadata.log;
|
|
39
|
+
progress.metadata = callMetadata;
|
|
40
|
+
await frame.instrumentation.onBeforeCall(frame, callMetadata, parentMetadata.id);
|
|
41
|
+
let error;
|
|
42
|
+
const result = await innerRunAction(progress, mode, page, action, secrets).catch((e) => error = e);
|
|
43
|
+
callMetadata.endTime = (0, import_time.monotonicTime)();
|
|
44
|
+
callMetadata.error = error ? (0, import_errors.serializeError)(error) : void 0;
|
|
45
|
+
callMetadata.result = error ? void 0 : result;
|
|
46
|
+
await frame.instrumentation.onAfterCall(frame, callMetadata);
|
|
47
|
+
if (error)
|
|
48
|
+
throw error;
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
async function innerRunAction(progress, mode, page, action, secrets) {
|
|
52
|
+
const frame = page.mainFrame();
|
|
53
|
+
const commonOptions = { strict: true, noAutoWaiting: mode === "generate" };
|
|
54
|
+
switch (action.method) {
|
|
55
|
+
case "navigate":
|
|
56
|
+
await frame.goto(progress, action.url);
|
|
57
|
+
break;
|
|
58
|
+
case "click":
|
|
59
|
+
await frame.click(progress, action.selector, {
|
|
60
|
+
button: action.button,
|
|
61
|
+
clickCount: action.clickCount,
|
|
62
|
+
modifiers: action.modifiers,
|
|
63
|
+
...commonOptions
|
|
64
|
+
});
|
|
65
|
+
break;
|
|
66
|
+
case "drag":
|
|
67
|
+
await frame.dragAndDrop(progress, action.sourceSelector, action.targetSelector, { ...commonOptions });
|
|
68
|
+
break;
|
|
69
|
+
case "hover":
|
|
70
|
+
await frame.hover(progress, action.selector, {
|
|
71
|
+
modifiers: action.modifiers,
|
|
72
|
+
...commonOptions
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
case "selectOption":
|
|
76
|
+
await frame.selectOption(progress, action.selector, [], action.labels.map((a) => ({ label: a })), { ...commonOptions });
|
|
77
|
+
break;
|
|
78
|
+
case "pressKey":
|
|
79
|
+
await page.keyboard.press(progress, action.key);
|
|
80
|
+
break;
|
|
81
|
+
case "pressSequentially": {
|
|
82
|
+
const secret = secrets?.find((s) => s.name === action.text)?.value ?? action.text;
|
|
83
|
+
await frame.type(progress, action.selector, secret, { ...commonOptions });
|
|
84
|
+
if (action.submit)
|
|
85
|
+
await page.keyboard.press(progress, "Enter");
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "fill": {
|
|
89
|
+
const secret = secrets?.find((s) => s.name === action.text)?.value ?? action.text;
|
|
90
|
+
await frame.fill(progress, action.selector, secret, { ...commonOptions });
|
|
91
|
+
if (action.submit)
|
|
92
|
+
await page.keyboard.press(progress, "Enter");
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "setChecked":
|
|
96
|
+
if (action.checked)
|
|
97
|
+
await frame.check(progress, action.selector, { ...commonOptions });
|
|
98
|
+
else
|
|
99
|
+
await frame.uncheck(progress, action.selector, { ...commonOptions });
|
|
100
|
+
break;
|
|
101
|
+
case "expectVisible": {
|
|
102
|
+
await runExpect(frame, progress, mode, action.selector, { expression: "to.be.visible", isNot: !!action.isNot }, "visible", "toBeVisible", "");
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case "expectValue": {
|
|
106
|
+
if (action.type === "textbox" || action.type === "combobox" || action.type === "slider") {
|
|
107
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([action.value]);
|
|
108
|
+
await runExpect(frame, progress, mode, action.selector, { expression: "to.have.value", expectedText, isNot: !!action.isNot }, action.value, "toHaveValue", "expected");
|
|
109
|
+
} else if (action.type === "checkbox" || action.type === "radio") {
|
|
110
|
+
const expectedValue = { checked: action.value === "true" };
|
|
111
|
+
await runExpect(frame, progress, mode, action.selector, { selector: action.selector, expression: "to.be.checked", expectedValue, isNot: !!action.isNot }, action.value ? "checked" : "unchecked", "toBeChecked", "");
|
|
112
|
+
} else {
|
|
113
|
+
throw new Error(`Unsupported element type: ${action.type}`);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case "expectAria": {
|
|
118
|
+
const expectedValue = (0, import_ariaSnapshot.parseAriaSnapshotUnsafe)(import_utilsBundle.yaml, action.template);
|
|
119
|
+
await runExpect(frame, progress, mode, "body", { expression: "to.match.aria", expectedValue, isNot: !!action.isNot }, "\n" + action.template, "toMatchAriaSnapshot", "expected");
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case "expectURL": {
|
|
123
|
+
if (!action.regex && !action.value)
|
|
124
|
+
throw new Error("Either url or regex must be provided");
|
|
125
|
+
if (action.regex && action.value)
|
|
126
|
+
throw new Error("Only one of url or regex can be provided");
|
|
127
|
+
const expected = action.regex ? (0, import_stringUtils.parseRegex)(action.regex) : (0, import_urlMatch.constructURLBasedOnBaseURL)(page.browserContext._options.baseURL, action.value);
|
|
128
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([expected]);
|
|
129
|
+
await runExpect(frame, progress, mode, void 0, { expression: "to.have.url", expectedText, isNot: !!action.isNot }, expected, "toHaveURL", "expected");
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "expectTitle": {
|
|
133
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([action.value], { normalizeWhiteSpace: true });
|
|
134
|
+
await runExpect(frame, progress, mode, void 0, { expression: "to.have.title", expectedText, isNot: !!action.isNot }, action.value, "toHaveTitle", "expected");
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function runExpect(frame, progress, mode, selector, options, expected, matcherName, expectation) {
|
|
140
|
+
const result = await frame.expect(progress, selector, {
|
|
141
|
+
...options,
|
|
142
|
+
// When generating, we want the expect to pass or fail immediately and give feedback to the model.
|
|
143
|
+
noAutoWaiting: mode === "generate",
|
|
144
|
+
timeoutForLogs: mode === "generate" ? void 0 : progress.timeout
|
|
145
|
+
});
|
|
146
|
+
if (!result.matches === !options.isNot) {
|
|
147
|
+
const received = matcherName === "toMatchAriaSnapshot" ? "\n" + result.received.raw : result.received;
|
|
148
|
+
const expectedSuffix = typeof expected === "string" ? "" : " pattern";
|
|
149
|
+
const expectedDisplay = typeof expected === "string" ? expected : expected.toString();
|
|
150
|
+
throw new Error((0, import_expectUtils.formatMatcherMessage)(import_expectUtils.simpleMatcherUtils, {
|
|
151
|
+
isNot: options.isNot,
|
|
152
|
+
matcherName,
|
|
153
|
+
expectation,
|
|
154
|
+
locator: selector ? (0, import_locatorGenerators.asLocatorDescription)("javascript", selector) : void 0,
|
|
155
|
+
timedOut: result.timedOut,
|
|
156
|
+
timeout: mode === "generate" ? void 0 : progress.timeout,
|
|
157
|
+
printedExpected: options.isNot ? `Expected${expectedSuffix}: not ${expectedDisplay}` : `Expected${expectedSuffix}: ${expectedDisplay}`,
|
|
158
|
+
printedReceived: result.errorMessage ? "" : `Received: ${received}`,
|
|
159
|
+
errorMessage: result.errorMessage
|
|
160
|
+
// Note: we are not passing call log, because it will be automatically appended on the client side,
|
|
161
|
+
// as a part of the agent.{perform,expect} call.
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function traceParamsForAction(progress, action, mode) {
|
|
166
|
+
const timeout = progress.timeout;
|
|
167
|
+
switch (action.method) {
|
|
168
|
+
case "navigate": {
|
|
169
|
+
const params = {
|
|
170
|
+
url: action.url,
|
|
171
|
+
timeout
|
|
172
|
+
};
|
|
173
|
+
return { type: "Frame", method: "goto", params };
|
|
174
|
+
}
|
|
175
|
+
case "click": {
|
|
176
|
+
const params = {
|
|
177
|
+
selector: action.selector,
|
|
178
|
+
strict: true,
|
|
179
|
+
modifiers: action.modifiers,
|
|
180
|
+
button: action.button,
|
|
181
|
+
clickCount: action.clickCount,
|
|
182
|
+
timeout
|
|
183
|
+
};
|
|
184
|
+
return { type: "Frame", method: "click", params };
|
|
185
|
+
}
|
|
186
|
+
case "drag": {
|
|
187
|
+
const params = {
|
|
188
|
+
source: action.sourceSelector,
|
|
189
|
+
target: action.targetSelector,
|
|
190
|
+
timeout
|
|
191
|
+
};
|
|
192
|
+
return { type: "Frame", method: "dragAndDrop", params };
|
|
193
|
+
}
|
|
194
|
+
case "hover": {
|
|
195
|
+
const params = {
|
|
196
|
+
selector: action.selector,
|
|
197
|
+
modifiers: action.modifiers,
|
|
198
|
+
timeout
|
|
199
|
+
};
|
|
200
|
+
return { type: "Frame", method: "hover", params };
|
|
201
|
+
}
|
|
202
|
+
case "pressKey": {
|
|
203
|
+
const params = {
|
|
204
|
+
key: action.key
|
|
205
|
+
};
|
|
206
|
+
return { type: "Page", method: "keyboardPress", params };
|
|
207
|
+
}
|
|
208
|
+
case "pressSequentially": {
|
|
209
|
+
const params = {
|
|
210
|
+
selector: action.selector,
|
|
211
|
+
text: action.text,
|
|
212
|
+
timeout
|
|
213
|
+
};
|
|
214
|
+
return { type: "Frame", method: "type", params };
|
|
215
|
+
}
|
|
216
|
+
case "fill": {
|
|
217
|
+
const params = {
|
|
218
|
+
selector: action.selector,
|
|
219
|
+
strict: true,
|
|
220
|
+
value: action.text,
|
|
221
|
+
timeout
|
|
222
|
+
};
|
|
223
|
+
return { type: "Frame", method: "fill", params };
|
|
224
|
+
}
|
|
225
|
+
case "setChecked": {
|
|
226
|
+
if (action.checked) {
|
|
227
|
+
const params = {
|
|
228
|
+
selector: action.selector,
|
|
229
|
+
strict: true,
|
|
230
|
+
timeout
|
|
231
|
+
};
|
|
232
|
+
return { type: "Frame", method: "check", params };
|
|
233
|
+
} else {
|
|
234
|
+
const params = {
|
|
235
|
+
selector: action.selector,
|
|
236
|
+
strict: true,
|
|
237
|
+
timeout
|
|
238
|
+
};
|
|
239
|
+
return { type: "Frame", method: "uncheck", params };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
case "selectOption": {
|
|
243
|
+
const params = {
|
|
244
|
+
selector: action.selector,
|
|
245
|
+
strict: true,
|
|
246
|
+
options: action.labels.map((label) => ({ label })),
|
|
247
|
+
timeout
|
|
248
|
+
};
|
|
249
|
+
return { type: "Frame", method: "selectOption", params };
|
|
250
|
+
}
|
|
251
|
+
case "expectValue": {
|
|
252
|
+
if (action.type === "textbox" || action.type === "combobox" || action.type === "slider") {
|
|
253
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([action.value]);
|
|
254
|
+
const params = {
|
|
255
|
+
selector: action.selector,
|
|
256
|
+
expression: "to.have.value",
|
|
257
|
+
expectedText,
|
|
258
|
+
isNot: !!action.isNot,
|
|
259
|
+
timeout
|
|
260
|
+
};
|
|
261
|
+
return { type: "Frame", method: "expect", title: "Expect Value", params };
|
|
262
|
+
} else if (action.type === "checkbox" || action.type === "radio") {
|
|
263
|
+
const params = {
|
|
264
|
+
selector: action.selector,
|
|
265
|
+
expression: "to.be.checked",
|
|
266
|
+
isNot: !!action.isNot,
|
|
267
|
+
timeout
|
|
268
|
+
};
|
|
269
|
+
return { type: "Frame", method: "expect", title: "Expect Checked", params };
|
|
270
|
+
} else {
|
|
271
|
+
throw new Error(`Unsupported element type: ${action.type}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
case "expectVisible": {
|
|
275
|
+
const params = {
|
|
276
|
+
selector: action.selector,
|
|
277
|
+
expression: "to.be.visible",
|
|
278
|
+
isNot: !!action.isNot,
|
|
279
|
+
timeout
|
|
280
|
+
};
|
|
281
|
+
return { type: "Frame", method: "expect", title: "Expect Visible", params };
|
|
282
|
+
}
|
|
283
|
+
case "expectAria": {
|
|
284
|
+
const params = {
|
|
285
|
+
selector: "body",
|
|
286
|
+
expression: "to.match.snapshot",
|
|
287
|
+
expectedText: [],
|
|
288
|
+
isNot: !!action.isNot,
|
|
289
|
+
timeout
|
|
290
|
+
};
|
|
291
|
+
return { type: "Frame", method: "expect", title: "Expect Aria Snapshot", params };
|
|
292
|
+
}
|
|
293
|
+
case "expectURL": {
|
|
294
|
+
const expected = action.regex ? (0, import_stringUtils.parseRegex)(action.regex) : action.value;
|
|
295
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([expected]);
|
|
296
|
+
const params = {
|
|
297
|
+
selector: void 0,
|
|
298
|
+
expression: "to.have.url",
|
|
299
|
+
expectedText,
|
|
300
|
+
isNot: !!action.isNot,
|
|
301
|
+
timeout
|
|
302
|
+
};
|
|
303
|
+
return { type: "Frame", method: "expect", title: "Expect URL", params };
|
|
304
|
+
}
|
|
305
|
+
case "expectTitle": {
|
|
306
|
+
const expectedText = (0, import_expectUtils.serializeExpectedTextValues)([action.value], { normalizeWhiteSpace: true });
|
|
307
|
+
const params = {
|
|
308
|
+
selector: void 0,
|
|
309
|
+
expression: "to.have.title",
|
|
310
|
+
expectedText,
|
|
311
|
+
isNot: !!action.isNot,
|
|
312
|
+
timeout
|
|
313
|
+
};
|
|
314
|
+
return { type: "Frame", method: "expect", title: "Expect Title", params };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function callMetadataForAction(progress, frame, action, mode) {
|
|
319
|
+
const callMetadata = {
|
|
320
|
+
id: `call@${(0, import_crypto.createGuid)()}`,
|
|
321
|
+
objectId: frame.guid,
|
|
322
|
+
pageId: frame._page.guid,
|
|
323
|
+
frameId: frame.guid,
|
|
324
|
+
startTime: (0, import_time.monotonicTime)(),
|
|
325
|
+
endTime: 0,
|
|
326
|
+
log: [],
|
|
327
|
+
...traceParamsForAction(progress, action, mode)
|
|
328
|
+
};
|
|
329
|
+
return callMetadata;
|
|
330
|
+
}
|
|
331
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
332
|
+
0 && (module.exports = {
|
|
333
|
+
runAction,
|
|
334
|
+
traceParamsForAction
|
|
335
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
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 actions_exports = {};
|
|
20
|
+
__export(actions_exports, {
|
|
21
|
+
cachedActionsSchema: () => cachedActionsSchema
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(actions_exports);
|
|
24
|
+
var import_mcpBundle = require("../../mcpBundle");
|
|
25
|
+
const modifiersSchema = import_mcpBundle.z.array(
|
|
26
|
+
import_mcpBundle.z.enum(["Alt", "Control", "ControlOrMeta", "Meta", "Shift"])
|
|
27
|
+
);
|
|
28
|
+
const navigateActionSchema = import_mcpBundle.z.object({
|
|
29
|
+
method: import_mcpBundle.z.literal("navigate"),
|
|
30
|
+
url: import_mcpBundle.z.string()
|
|
31
|
+
});
|
|
32
|
+
const clickActionSchema = import_mcpBundle.z.object({
|
|
33
|
+
method: import_mcpBundle.z.literal("click"),
|
|
34
|
+
selector: import_mcpBundle.z.string(),
|
|
35
|
+
button: import_mcpBundle.z.enum(["left", "right", "middle"]).optional(),
|
|
36
|
+
clickCount: import_mcpBundle.z.number().optional(),
|
|
37
|
+
modifiers: modifiersSchema.optional()
|
|
38
|
+
});
|
|
39
|
+
const dragActionSchema = import_mcpBundle.z.object({
|
|
40
|
+
method: import_mcpBundle.z.literal("drag"),
|
|
41
|
+
sourceSelector: import_mcpBundle.z.string(),
|
|
42
|
+
targetSelector: import_mcpBundle.z.string()
|
|
43
|
+
});
|
|
44
|
+
const hoverActionSchema = import_mcpBundle.z.object({
|
|
45
|
+
method: import_mcpBundle.z.literal("hover"),
|
|
46
|
+
selector: import_mcpBundle.z.string(),
|
|
47
|
+
modifiers: modifiersSchema.optional()
|
|
48
|
+
});
|
|
49
|
+
const selectOptionActionSchema = import_mcpBundle.z.object({
|
|
50
|
+
method: import_mcpBundle.z.literal("selectOption"),
|
|
51
|
+
selector: import_mcpBundle.z.string(),
|
|
52
|
+
labels: import_mcpBundle.z.array(import_mcpBundle.z.string())
|
|
53
|
+
});
|
|
54
|
+
const pressActionSchema = import_mcpBundle.z.object({
|
|
55
|
+
method: import_mcpBundle.z.literal("pressKey"),
|
|
56
|
+
key: import_mcpBundle.z.string()
|
|
57
|
+
});
|
|
58
|
+
const pressSequentiallyActionSchema = import_mcpBundle.z.object({
|
|
59
|
+
method: import_mcpBundle.z.literal("pressSequentially"),
|
|
60
|
+
selector: import_mcpBundle.z.string(),
|
|
61
|
+
text: import_mcpBundle.z.string(),
|
|
62
|
+
submit: import_mcpBundle.z.boolean().optional()
|
|
63
|
+
});
|
|
64
|
+
const fillActionSchema = import_mcpBundle.z.object({
|
|
65
|
+
method: import_mcpBundle.z.literal("fill"),
|
|
66
|
+
selector: import_mcpBundle.z.string(),
|
|
67
|
+
text: import_mcpBundle.z.string(),
|
|
68
|
+
submit: import_mcpBundle.z.boolean().optional()
|
|
69
|
+
});
|
|
70
|
+
const setCheckedSchema = import_mcpBundle.z.object({
|
|
71
|
+
method: import_mcpBundle.z.literal("setChecked"),
|
|
72
|
+
selector: import_mcpBundle.z.string(),
|
|
73
|
+
checked: import_mcpBundle.z.boolean()
|
|
74
|
+
});
|
|
75
|
+
const expectVisibleSchema = import_mcpBundle.z.object({
|
|
76
|
+
method: import_mcpBundle.z.literal("expectVisible"),
|
|
77
|
+
selector: import_mcpBundle.z.string(),
|
|
78
|
+
isNot: import_mcpBundle.z.boolean().optional()
|
|
79
|
+
});
|
|
80
|
+
const expectValueSchema = import_mcpBundle.z.object({
|
|
81
|
+
method: import_mcpBundle.z.literal("expectValue"),
|
|
82
|
+
selector: import_mcpBundle.z.string(),
|
|
83
|
+
type: import_mcpBundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]),
|
|
84
|
+
value: import_mcpBundle.z.string(),
|
|
85
|
+
isNot: import_mcpBundle.z.boolean().optional()
|
|
86
|
+
});
|
|
87
|
+
const expectAriaSchema = import_mcpBundle.z.object({
|
|
88
|
+
method: import_mcpBundle.z.literal("expectAria"),
|
|
89
|
+
template: import_mcpBundle.z.string(),
|
|
90
|
+
isNot: import_mcpBundle.z.boolean().optional()
|
|
91
|
+
});
|
|
92
|
+
const expectURLSchema = import_mcpBundle.z.object({
|
|
93
|
+
method: import_mcpBundle.z.literal("expectURL"),
|
|
94
|
+
value: import_mcpBundle.z.string().optional(),
|
|
95
|
+
regex: import_mcpBundle.z.string().optional(),
|
|
96
|
+
isNot: import_mcpBundle.z.boolean().optional()
|
|
97
|
+
});
|
|
98
|
+
const expectTitleSchema = import_mcpBundle.z.object({
|
|
99
|
+
method: import_mcpBundle.z.literal("expectTitle"),
|
|
100
|
+
value: import_mcpBundle.z.string(),
|
|
101
|
+
isNot: import_mcpBundle.z.boolean().optional()
|
|
102
|
+
});
|
|
103
|
+
const actionSchema = import_mcpBundle.z.discriminatedUnion("method", [
|
|
104
|
+
navigateActionSchema,
|
|
105
|
+
clickActionSchema,
|
|
106
|
+
dragActionSchema,
|
|
107
|
+
hoverActionSchema,
|
|
108
|
+
selectOptionActionSchema,
|
|
109
|
+
pressActionSchema,
|
|
110
|
+
pressSequentiallyActionSchema,
|
|
111
|
+
fillActionSchema,
|
|
112
|
+
setCheckedSchema,
|
|
113
|
+
expectVisibleSchema,
|
|
114
|
+
expectValueSchema,
|
|
115
|
+
expectAriaSchema,
|
|
116
|
+
expectURLSchema,
|
|
117
|
+
expectTitleSchema
|
|
118
|
+
]);
|
|
119
|
+
const actionWithCodeSchema = actionSchema.and(import_mcpBundle.z.object({
|
|
120
|
+
code: import_mcpBundle.z.string()
|
|
121
|
+
}));
|
|
122
|
+
const cachedActionsSchema = import_mcpBundle.z.record(import_mcpBundle.z.string(), import_mcpBundle.z.object({
|
|
123
|
+
actions: import_mcpBundle.z.array(actionWithCodeSchema)
|
|
124
|
+
}));
|
|
125
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
126
|
+
0 && (module.exports = {
|
|
127
|
+
cachedActionsSchema
|
|
128
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
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 codegen_exports = {};
|
|
20
|
+
__export(codegen_exports, {
|
|
21
|
+
generateCode: () => generateCode
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(codegen_exports);
|
|
24
|
+
var import_locatorGenerators = require("../../utils/isomorphic/locatorGenerators");
|
|
25
|
+
var import_stringUtils = require("../../utils/isomorphic/stringUtils");
|
|
26
|
+
async function generateCode(sdkLanguage, action) {
|
|
27
|
+
switch (action.method) {
|
|
28
|
+
case "navigate": {
|
|
29
|
+
return `await page.goto(${(0, import_stringUtils.escapeWithQuotes)(action.url)});`;
|
|
30
|
+
}
|
|
31
|
+
case "click": {
|
|
32
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
33
|
+
return `await page.${locator}.click(${(0, import_stringUtils.formatObjectOrVoid)({
|
|
34
|
+
button: action.button,
|
|
35
|
+
clickCount: action.clickCount,
|
|
36
|
+
modifiers: action.modifiers
|
|
37
|
+
})});`;
|
|
38
|
+
}
|
|
39
|
+
case "drag": {
|
|
40
|
+
const sourceLocator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.sourceSelector);
|
|
41
|
+
const targetLocator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.targetSelector);
|
|
42
|
+
return `await page.${sourceLocator}.dragAndDrop(${targetLocator});`;
|
|
43
|
+
}
|
|
44
|
+
case "hover": {
|
|
45
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
46
|
+
return `await page.${locator}.hover(${(0, import_stringUtils.formatObjectOrVoid)({
|
|
47
|
+
modifiers: action.modifiers
|
|
48
|
+
})});`;
|
|
49
|
+
}
|
|
50
|
+
case "pressKey": {
|
|
51
|
+
return `await page.keyboard.press(${(0, import_stringUtils.escapeWithQuotes)(action.key, "'")});`;
|
|
52
|
+
}
|
|
53
|
+
case "selectOption": {
|
|
54
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
55
|
+
return `await page.${locator}.selectOption(${action.labels.length === 1 ? (0, import_stringUtils.escapeWithQuotes)(action.labels[0]) : "[" + action.labels.map((label) => (0, import_stringUtils.escapeWithQuotes)(label)).join(", ") + "]"});`;
|
|
56
|
+
}
|
|
57
|
+
case "pressSequentially": {
|
|
58
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
59
|
+
const code = [`await page.${locator}.pressSequentially(${(0, import_stringUtils.escapeWithQuotes)(action.text)});`];
|
|
60
|
+
if (action.submit)
|
|
61
|
+
code.push(`await page.keyboard.press('Enter');`);
|
|
62
|
+
return code.join("\n");
|
|
63
|
+
}
|
|
64
|
+
case "fill": {
|
|
65
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
66
|
+
const code = [`await page.${locator}.fill(${(0, import_stringUtils.escapeWithQuotes)(action.text)});`];
|
|
67
|
+
if (action.submit)
|
|
68
|
+
code.push(`await page.keyboard.press('Enter');`);
|
|
69
|
+
return code.join("\n");
|
|
70
|
+
}
|
|
71
|
+
case "setChecked": {
|
|
72
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
73
|
+
if (action.checked)
|
|
74
|
+
return `await page.${locator}.check();`;
|
|
75
|
+
else
|
|
76
|
+
return `await page.${locator}.uncheck();`;
|
|
77
|
+
}
|
|
78
|
+
case "expectVisible": {
|
|
79
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
80
|
+
const notInfix = action.isNot ? "not." : "";
|
|
81
|
+
return `await expect(page.${locator}).${notInfix}toBeVisible();`;
|
|
82
|
+
}
|
|
83
|
+
case "expectValue": {
|
|
84
|
+
const notInfix = action.isNot ? "not." : "";
|
|
85
|
+
const locator = (0, import_locatorGenerators.asLocator)(sdkLanguage, action.selector);
|
|
86
|
+
if (action.type === "checkbox" || action.type === "radio")
|
|
87
|
+
return `await expect(page.${locator}).${notInfix}toBeChecked({ checked: ${action.value === "true"} });`;
|
|
88
|
+
return `await expect(page.${locator}).${notInfix}toHaveValue(${(0, import_stringUtils.escapeWithQuotes)(action.value)});`;
|
|
89
|
+
}
|
|
90
|
+
case "expectAria": {
|
|
91
|
+
const notInfix = action.isNot ? "not." : "";
|
|
92
|
+
return `await expect(page.locator('body')).${notInfix}toMatchAria(\`
|
|
93
|
+
${(0, import_stringUtils.escapeTemplateString)(action.template)}
|
|
94
|
+
\`);`;
|
|
95
|
+
}
|
|
96
|
+
case "expectURL": {
|
|
97
|
+
const arg = action.regex ? (0, import_stringUtils.parseRegex)(action.regex).toString() : (0, import_stringUtils.escapeWithQuotes)(action.value);
|
|
98
|
+
const notInfix = action.isNot ? "not." : "";
|
|
99
|
+
return `await expect(page).${notInfix}toHaveURL(${arg});`;
|
|
100
|
+
}
|
|
101
|
+
case "expectTitle": {
|
|
102
|
+
const notInfix = action.isNot ? "not." : "";
|
|
103
|
+
return `await expect(page).${notInfix}toHaveTitle(${(0, import_stringUtils.escapeWithQuotes)(action.value)});`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
throw new Error("Unknown action " + action.method);
|
|
107
|
+
}
|
|
108
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
109
|
+
0 && (module.exports = {
|
|
110
|
+
generateCode
|
|
111
|
+
});
|