@smoothdeploy/playwright 1.57.1 → 1.58.1-beta-1770383926000
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.
Potentially problematic release.
This version of @smoothdeploy/playwright might be problematic. Click here for more details.
- package/ThirdPartyNotices.txt +1188 -65
- package/lib/agents/agentParser.js +89 -0
- package/lib/agents/generateAgents.js +27 -74
- package/lib/agents/generateAgents.js.map +7 -0
- package/lib/agents/playwright-test-planner.agent.md +1 -0
- package/lib/common/config.js +6 -4
- package/lib/common/config.js.map +7 -0
- package/lib/common/configLoader.js.map +7 -0
- package/lib/common/esmLoaderHost.js +2 -0
- package/lib/common/esmLoaderHost.js.map +7 -0
- package/lib/common/expectBundle.js +2 -17
- package/lib/common/expectBundle.js.map +7 -0
- package/lib/common/expectBundleImpl.js +132 -132
- package/lib/common/expectBundleImpl.js.map +7 -0
- package/lib/common/fixtures.js.map +7 -0
- package/lib/common/globals.js.map +7 -0
- package/lib/common/ipc.js.map +7 -0
- package/lib/common/poolBuilder.js.map +7 -0
- package/lib/common/process.js +28 -0
- package/lib/common/process.js.map +7 -0
- package/lib/common/suiteUtils.js.map +7 -0
- package/lib/common/test.js.map +7 -0
- package/lib/common/testLoader.js.map +7 -0
- package/lib/common/testType.js.map +7 -0
- package/lib/common/validators.js +10 -10
- package/lib/common/validators.js.map +7 -0
- package/lib/fsWatcher.js.map +7 -0
- package/lib/index.js +205 -12
- package/lib/index.js.map +7 -0
- package/lib/internalsForTest.js.map +7 -0
- package/lib/isomorphic/events.js.map +7 -0
- package/lib/isomorphic/folders.js.map +7 -0
- package/lib/isomorphic/stringInternPool.js.map +7 -0
- package/lib/isomorphic/teleReceiver.js +15 -2
- package/lib/isomorphic/teleReceiver.js.map +7 -0
- package/lib/isomorphic/teleSuiteUpdater.js +24 -4
- package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
- package/lib/isomorphic/testServerConnection.js.map +7 -0
- package/lib/isomorphic/testServerInterface.js.map +7 -0
- package/lib/isomorphic/testTree.js +13 -18
- package/lib/isomorphic/testTree.js.map +7 -0
- package/lib/isomorphic/types.d.js.map +7 -0
- package/lib/loader/loaderMain.js.map +7 -0
- package/lib/matchers/expect.js +2 -15
- package/lib/matchers/expect.js.map +7 -0
- package/lib/matchers/matcherHint.js +1 -44
- package/lib/matchers/matcherHint.js.map +7 -0
- package/lib/matchers/matchers.js +3 -2
- package/lib/matchers/matchers.js.map +7 -0
- package/lib/matchers/toBeTruthy.js +5 -3
- package/lib/matchers/toBeTruthy.js.map +7 -0
- package/lib/matchers/toEqual.js +4 -3
- package/lib/matchers/toEqual.js.map +7 -0
- package/lib/matchers/toHaveURL.js +5 -6
- package/lib/matchers/toHaveURL.js.map +7 -0
- package/lib/matchers/toMatchAriaSnapshot.js +5 -5
- package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
- package/lib/matchers/toMatchSnapshot.js +9 -8
- package/lib/matchers/toMatchSnapshot.js.map +7 -0
- package/lib/matchers/toMatchText.js +9 -9
- package/lib/matchers/toMatchText.js.map +7 -0
- package/lib/mcp/browser/actions.d.js.map +7 -0
- package/lib/mcp/browser/browserContextFactory.js +62 -29
- package/lib/mcp/browser/browserContextFactory.js.map +7 -0
- package/lib/mcp/browser/browserServerBackend.js +17 -9
- package/lib/mcp/browser/browserServerBackend.js.map +7 -0
- package/lib/mcp/browser/codegen.js.map +7 -0
- package/lib/mcp/browser/config.js +65 -12
- package/lib/mcp/browser/config.js.map +7 -0
- package/lib/mcp/browser/context.js +71 -94
- package/lib/mcp/browser/context.js.map +7 -0
- package/lib/mcp/browser/response.js +172 -131
- package/lib/mcp/browser/response.js.map +7 -0
- package/lib/mcp/browser/sessionLog.js +19 -104
- package/lib/mcp/browser/sessionLog.js.map +7 -0
- package/lib/mcp/browser/tab.js +92 -41
- package/lib/mcp/browser/tab.js.map +7 -0
- package/lib/mcp/browser/tools/common.js +8 -6
- package/lib/mcp/browser/tools/common.js.map +7 -0
- package/lib/mcp/browser/tools/console.js +7 -5
- package/lib/mcp/browser/tools/console.js.map +7 -0
- package/lib/mcp/browser/tools/dialogs.js +4 -4
- package/lib/mcp/browser/tools/dialogs.js.map +7 -0
- package/lib/mcp/browser/tools/evaluate.js +11 -19
- package/lib/mcp/browser/tools/evaluate.js.map +7 -0
- package/lib/mcp/browser/tools/files.js +3 -3
- package/lib/mcp/browser/tools/files.js.map +7 -0
- package/lib/mcp/browser/tools/form.js +9 -19
- package/lib/mcp/browser/tools/form.js.map +7 -0
- package/lib/mcp/browser/tools/install.js +6 -3
- package/lib/mcp/browser/tools/install.js.map +7 -0
- package/lib/mcp/browser/tools/keyboard.js +34 -11
- package/lib/mcp/browser/tools/keyboard.js.map +7 -0
- package/lib/mcp/browser/tools/mouse.js +11 -11
- package/lib/mcp/browser/tools/mouse.js.map +7 -0
- package/lib/mcp/browser/tools/navigate.js +14 -5
- package/lib/mcp/browser/tools/navigate.js.map +7 -0
- package/lib/mcp/browser/tools/network.js +20 -11
- package/lib/mcp/browser/tools/network.js.map +7 -0
- package/lib/mcp/browser/tools/open.js +57 -0
- package/lib/mcp/browser/tools/pdf.js +9 -19
- package/lib/mcp/browser/tools/pdf.js.map +7 -0
- package/lib/mcp/browser/tools/runCode.js +11 -8
- package/lib/mcp/browser/tools/runCode.js.map +7 -0
- package/lib/mcp/browser/tools/screenshot.js +16 -29
- package/lib/mcp/browser/tools/screenshot.js.map +7 -0
- package/lib/mcp/browser/tools/snapshot.js +21 -29
- package/lib/mcp/browser/tools/snapshot.js.map +7 -0
- package/lib/mcp/browser/tools/tabs.js +12 -12
- package/lib/mcp/browser/tools/tabs.js.map +7 -0
- package/lib/mcp/browser/tools/tool.js +2 -4
- package/lib/mcp/browser/tools/tool.js.map +7 -0
- package/lib/mcp/browser/tools/tracing.js +6 -6
- package/lib/mcp/browser/tools/tracing.js.map +7 -0
- package/lib/mcp/browser/tools/utils.js +49 -44
- package/lib/mcp/browser/tools/utils.js.map +7 -0
- package/lib/mcp/browser/tools/verify.js +24 -34
- package/lib/mcp/browser/tools/verify.js.map +7 -0
- package/lib/mcp/browser/tools/wait.js +6 -6
- package/lib/mcp/browser/tools/wait.js.map +7 -0
- package/lib/mcp/browser/tools.js +3 -1
- package/lib/mcp/browser/tools.js.map +7 -0
- package/lib/mcp/browser/watchdog.js.map +7 -0
- package/lib/mcp/config.d.js.map +7 -0
- package/lib/mcp/extension/cdpRelay.js +1 -1
- package/lib/mcp/extension/cdpRelay.js.map +7 -0
- package/lib/mcp/extension/extensionContextFactory.js +6 -5
- package/lib/mcp/extension/extensionContextFactory.js.map +7 -0
- package/lib/mcp/extension/protocol.js.map +7 -0
- package/lib/mcp/index.js.map +7 -0
- package/lib/mcp/log.js.map +7 -0
- package/lib/mcp/program.js +15 -20
- package/lib/mcp/program.js.map +7 -0
- package/lib/mcp/sdk/bundle.js.map +7 -0
- package/lib/mcp/sdk/exports.js +0 -2
- package/lib/mcp/sdk/exports.js.map +7 -0
- package/lib/mcp/sdk/http.js +20 -55
- package/lib/mcp/sdk/http.js.map +7 -0
- package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
- package/lib/mcp/sdk/proxyBackend.js.map +7 -0
- package/lib/mcp/sdk/server.js +29 -4
- package/lib/mcp/sdk/server.js.map +7 -0
- package/lib/mcp/sdk/tool.js +2 -2
- package/lib/mcp/sdk/tool.js.map +7 -0
- package/lib/mcp/terminal/cli.js +296 -0
- package/lib/mcp/terminal/command.js +56 -0
- package/lib/mcp/terminal/commands.js +333 -0
- package/lib/mcp/terminal/daemon.js +129 -0
- package/lib/mcp/terminal/help.json +32 -0
- package/lib/mcp/terminal/helpGenerator.js +88 -0
- package/lib/mcp/terminal/socketConnection.js +80 -0
- package/lib/mcp/test/browserBackend.js +3 -13
- package/lib/mcp/test/browserBackend.js.map +7 -0
- package/lib/mcp/test/generatorTools.js +9 -9
- package/lib/mcp/test/generatorTools.js.map +7 -0
- package/lib/mcp/test/plannerTools.js +23 -22
- package/lib/mcp/test/plannerTools.js.map +7 -0
- package/lib/mcp/test/seed.js.map +7 -0
- package/lib/mcp/test/streams.js.map +7 -0
- package/lib/mcp/test/testBackend.js +6 -6
- package/lib/mcp/test/testBackend.js.map +7 -0
- package/lib/mcp/test/testContext.js +9 -3
- package/lib/mcp/test/testContext.js.map +7 -0
- package/lib/mcp/test/testTool.js.map +7 -0
- package/lib/mcp/test/testTools.js +12 -10
- package/lib/mcp/test/testTools.js.map +7 -0
- package/lib/mcpBundleImpl.js.map +7 -0
- package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
- package/lib/plugins/index.js.map +7 -0
- package/lib/plugins/webServerPlugin.js.map +7 -0
- package/lib/program.js +18 -4
- package/lib/program.js.map +7 -0
- package/lib/reporters/base.js +29 -4
- package/lib/reporters/base.js.map +7 -0
- package/lib/reporters/blob.js +3 -0
- package/lib/reporters/blob.js.map +7 -0
- package/lib/reporters/dot.js +17 -0
- package/lib/reporters/dot.js.map +7 -0
- package/lib/reporters/empty.js.map +7 -0
- package/lib/reporters/github.js.map +7 -0
- package/lib/reporters/html.js +13 -3
- package/lib/reporters/html.js.map +7 -0
- package/lib/reporters/internalReporter.js +6 -0
- package/lib/reporters/internalReporter.js.map +7 -0
- package/lib/reporters/json.js.map +7 -0
- package/lib/reporters/junit.js.map +7 -0
- package/lib/reporters/line.js +18 -0
- package/lib/reporters/line.js.map +7 -0
- package/lib/reporters/list.js +22 -0
- package/lib/reporters/list.js.map +7 -0
- package/lib/reporters/listModeReporter.js.map +7 -0
- package/lib/reporters/markdown.js.map +7 -0
- package/lib/reporters/merge.js +25 -8
- package/lib/reporters/merge.js.map +7 -0
- package/lib/reporters/multiplexer.js +8 -0
- package/lib/reporters/multiplexer.js.map +7 -0
- package/lib/reporters/reporterV2.js.map +7 -0
- package/lib/reporters/smoothdeploy.js +191 -0
- package/lib/reporters/teleEmitter.js +22 -4
- package/lib/reporters/teleEmitter.js.map +7 -0
- package/lib/reporters/versions/blobV1.js.map +7 -0
- package/lib/runner/dispatcher.js +20 -4
- package/lib/runner/dispatcher.js.map +7 -0
- package/lib/runner/failureTracker.js.map +7 -0
- package/lib/runner/lastRun.js.map +7 -0
- package/lib/runner/loadUtils.js +2 -2
- package/lib/runner/loadUtils.js.map +7 -0
- package/lib/runner/loaderHost.js.map +7 -0
- package/lib/runner/processHost.js +19 -0
- package/lib/runner/processHost.js.map +7 -0
- package/lib/runner/projectUtils.js +1 -1
- package/lib/runner/projectUtils.js.map +7 -0
- package/lib/runner/rebase.js.map +7 -0
- package/lib/runner/reporters.js +3 -1
- package/lib/runner/reporters.js.map +7 -0
- package/lib/runner/sigIntWatcher.js.map +7 -0
- package/lib/runner/storage.js +91 -0
- package/lib/runner/taskRunner.js.map +7 -0
- package/lib/runner/tasks.js.map +7 -0
- package/lib/runner/testGroups.js +14 -6
- package/lib/runner/testGroups.js.map +7 -0
- package/lib/runner/testRunner.js +13 -4
- package/lib/runner/testRunner.js.map +7 -0
- package/lib/runner/testServer.js +2 -2
- package/lib/runner/testServer.js.map +7 -0
- package/lib/runner/uiModeReporter.js.map +7 -0
- package/lib/runner/vcs.js.map +7 -0
- package/lib/runner/watchMode.js +2 -1
- package/lib/runner/watchMode.js.map +7 -0
- package/lib/runner/workerHost.js +6 -0
- package/lib/runner/workerHost.js.map +7 -0
- package/lib/third_party/pirates.js.map +7 -0
- package/lib/third_party/tsconfig-loader.js.map +7 -0
- package/lib/transform/babelBundle.js +3 -0
- package/lib/transform/babelBundle.js.map +7 -0
- package/lib/transform/babelBundleImpl.js +134 -134
- package/lib/transform/babelBundleImpl.js.map +7 -0
- package/lib/transform/compilationCache.js +2 -0
- package/lib/transform/compilationCache.js.map +7 -0
- package/lib/transform/esmLoader.js +10 -11
- package/lib/transform/esmLoader.js.map +7 -0
- package/lib/transform/md.js +221 -0
- package/lib/transform/portTransport.js.map +7 -0
- package/lib/transform/transform.js +18 -8
- package/lib/transform/transform.js.map +7 -0
- package/lib/util.js +3 -6
- package/lib/util.js.map +7 -0
- package/lib/utilsBundle.js +7 -0
- package/lib/utilsBundle.js.map +7 -0
- package/lib/utilsBundleImpl.js +51 -48
- package/lib/utilsBundleImpl.js.map +7 -0
- package/lib/worker/fixtureRunner.js +6 -2
- package/lib/worker/fixtureRunner.js.map +7 -0
- package/lib/worker/testInfo.js +39 -19
- package/lib/worker/testInfo.js.map +7 -0
- package/lib/worker/testTracing.js.map +7 -0
- package/lib/worker/timeoutManager.js.map +7 -0
- package/lib/worker/util.js.map +7 -0
- package/lib/worker/workerMain.js +17 -16
- package/lib/worker/workerMain.js.map +7 -0
- package/package.json +2 -2
- package/test.mjs +1 -0
- package/types/test.d.ts +26 -6
- package/types/testReporter.d.ts +1 -0
package/lib/mcp/browser/tab.js
CHANGED
|
@@ -20,7 +20,8 @@ var tab_exports = {};
|
|
|
20
20
|
__export(tab_exports, {
|
|
21
21
|
Tab: () => Tab,
|
|
22
22
|
TabEvents: () => TabEvents,
|
|
23
|
-
renderModalStates: () => renderModalStates
|
|
23
|
+
renderModalStates: () => renderModalStates,
|
|
24
|
+
shouldIncludeMessage: () => shouldIncludeMessage
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(tab_exports);
|
|
26
27
|
var import_events = require("events");
|
|
@@ -36,19 +37,20 @@ const TabEvents = {
|
|
|
36
37
|
class Tab extends import_events.EventEmitter {
|
|
37
38
|
constructor(context, page, onPageClose) {
|
|
38
39
|
super();
|
|
39
|
-
this.
|
|
40
|
+
this._lastHeader = { title: "about:blank", url: "about:blank", current: false };
|
|
40
41
|
this._consoleMessages = [];
|
|
41
|
-
this.
|
|
42
|
+
this._downloads = [];
|
|
42
43
|
this._requests = /* @__PURE__ */ new Set();
|
|
43
44
|
this._modalStates = [];
|
|
44
|
-
this._downloads = [];
|
|
45
45
|
this._needsFullSnapshot = false;
|
|
46
|
+
this._eventEntries = [];
|
|
47
|
+
this._recentEventEntries = [];
|
|
46
48
|
this.context = context;
|
|
47
49
|
this.page = page;
|
|
48
50
|
this._onPageClose = onPageClose;
|
|
49
51
|
page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
|
|
50
52
|
page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
|
|
51
|
-
page.on("request", (request) => this.
|
|
53
|
+
page.on("request", (request) => this._handleRequest(request));
|
|
52
54
|
page.on("close", () => this._onClose());
|
|
53
55
|
page.on("filechooser", (chooser) => {
|
|
54
56
|
this.setModalState({
|
|
@@ -65,7 +67,7 @@ class Tab extends import_events.EventEmitter {
|
|
|
65
67
|
page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
|
|
66
68
|
page.setDefaultTimeout(this.context.config.timeouts.action);
|
|
67
69
|
page[tabSymbol] = this;
|
|
68
|
-
this.
|
|
70
|
+
this._initializedPromise = this._initialize();
|
|
69
71
|
}
|
|
70
72
|
static forPage(page) {
|
|
71
73
|
return page[tabSymbol];
|
|
@@ -105,9 +107,6 @@ class Tab extends import_events.EventEmitter {
|
|
|
105
107
|
clearModalState(modalState) {
|
|
106
108
|
this._modalStates = this._modalStates.filter((state) => state !== modalState);
|
|
107
109
|
}
|
|
108
|
-
modalStatesMarkdown() {
|
|
109
|
-
return renderModalStates(this.context, this.modalStates());
|
|
110
|
-
}
|
|
111
110
|
_dialogShown(dialog) {
|
|
112
111
|
this.setModalState({
|
|
113
112
|
type: "dialog",
|
|
@@ -120,53 +119,68 @@ class Tab extends import_events.EventEmitter {
|
|
|
120
119
|
const entry = {
|
|
121
120
|
download,
|
|
122
121
|
finished: false,
|
|
123
|
-
outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web",
|
|
122
|
+
outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", title: "Saving download" })
|
|
124
123
|
};
|
|
125
124
|
this._downloads.push(entry);
|
|
125
|
+
this._addLogEntry({ type: "download-start", wallTime: Date.now(), download: entry });
|
|
126
126
|
await download.saveAs(entry.outputFile);
|
|
127
127
|
entry.finished = true;
|
|
128
|
+
this._addLogEntry({ type: "download-finish", wallTime: Date.now(), download: entry });
|
|
128
129
|
}
|
|
129
130
|
_clearCollectedArtifacts() {
|
|
130
131
|
this._consoleMessages.length = 0;
|
|
131
|
-
this.
|
|
132
|
+
this._downloads.length = 0;
|
|
132
133
|
this._requests.clear();
|
|
134
|
+
this._eventEntries.length = 0;
|
|
135
|
+
this._recentEventEntries.length = 0;
|
|
136
|
+
}
|
|
137
|
+
_handleRequest(request) {
|
|
138
|
+
this._requests.add(request);
|
|
139
|
+
this._addLogEntry({ type: "request", wallTime: Date.now(), request });
|
|
133
140
|
}
|
|
134
141
|
_handleConsoleMessage(message) {
|
|
135
142
|
this._consoleMessages.push(message);
|
|
136
|
-
this.
|
|
143
|
+
this._addLogEntry({ type: "console", wallTime: Date.now(), message });
|
|
144
|
+
}
|
|
145
|
+
_addLogEntry(entry) {
|
|
146
|
+
this._eventEntries.push(entry);
|
|
147
|
+
this._recentEventEntries.push(entry);
|
|
137
148
|
}
|
|
138
149
|
_onClose() {
|
|
139
150
|
this._clearCollectedArtifacts();
|
|
140
151
|
this._onPageClose(this);
|
|
141
152
|
}
|
|
142
|
-
async
|
|
153
|
+
async headerSnapshot() {
|
|
154
|
+
let title;
|
|
143
155
|
await this._raceAgainstModalStates(async () => {
|
|
144
|
-
|
|
156
|
+
title = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
|
|
145
157
|
});
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
158
|
+
if (this._lastHeader.title !== title || this._lastHeader.url !== this.page.url() || this._lastHeader.current !== this.isCurrentTab()) {
|
|
159
|
+
this._lastHeader = { title: title ?? "", url: this.page.url(), current: this.isCurrentTab() };
|
|
160
|
+
return { ...this._lastHeader, changed: true };
|
|
161
|
+
}
|
|
162
|
+
return { ...this._lastHeader, changed: false };
|
|
149
163
|
}
|
|
150
164
|
isCurrentTab() {
|
|
151
165
|
return this === this.context.currentTab();
|
|
152
166
|
}
|
|
153
167
|
async waitForLoadState(state, options) {
|
|
168
|
+
await this._initializedPromise;
|
|
154
169
|
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForLoadState(state, options).catch(import_log.logUnhandledError));
|
|
155
170
|
}
|
|
156
171
|
async navigate(url) {
|
|
172
|
+
await this._initializedPromise;
|
|
157
173
|
this._clearCollectedArtifacts();
|
|
158
|
-
const downloadEvent = (0, import_utils2.
|
|
174
|
+
const { promise: downloadEvent, abort: abortDownloadEvent } = (0, import_utils2.eventWaiter)(this.page, "download", 3e3);
|
|
159
175
|
try {
|
|
160
176
|
await this.page.goto(url, { waitUntil: "domcontentloaded" });
|
|
177
|
+
abortDownloadEvent();
|
|
161
178
|
} catch (_e) {
|
|
162
179
|
const e = _e;
|
|
163
180
|
const mightBeDownload = e.message.includes("net::ERR_ABORTED") || e.message.includes("Download is starting");
|
|
164
181
|
if (!mightBeDownload)
|
|
165
182
|
throw e;
|
|
166
|
-
const download = await
|
|
167
|
-
downloadEvent,
|
|
168
|
-
new Promise((resolve) => setTimeout(resolve, 3e3))
|
|
169
|
-
]);
|
|
183
|
+
const download = await downloadEvent;
|
|
170
184
|
if (!download)
|
|
171
185
|
throw e;
|
|
172
186
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
@@ -174,40 +188,36 @@ class Tab extends import_events.EventEmitter {
|
|
|
174
188
|
}
|
|
175
189
|
await this.waitForLoadState("load", { timeout: 5e3 });
|
|
176
190
|
}
|
|
177
|
-
async consoleMessages(
|
|
178
|
-
await this.
|
|
179
|
-
return this._consoleMessages.filter((message) =>
|
|
191
|
+
async consoleMessages(level) {
|
|
192
|
+
await this._initializedPromise;
|
|
193
|
+
return this._consoleMessages.filter((message) => shouldIncludeMessage(level, message.type));
|
|
180
194
|
}
|
|
181
195
|
async requests() {
|
|
182
|
-
await this.
|
|
196
|
+
await this._initializedPromise;
|
|
183
197
|
return this._requests;
|
|
184
198
|
}
|
|
185
199
|
async captureSnapshot() {
|
|
200
|
+
await this._initializedPromise;
|
|
186
201
|
let tabSnapshot;
|
|
187
202
|
const modalStates = await this._raceAgainstModalStates(async () => {
|
|
188
203
|
const snapshot = await this.page._snapshotForAI({ track: "response" });
|
|
189
204
|
tabSnapshot = {
|
|
190
|
-
url: this.page.url(),
|
|
191
|
-
title: await this.page.title(),
|
|
192
205
|
ariaSnapshot: snapshot.full,
|
|
193
206
|
ariaSnapshotDiff: this._needsFullSnapshot ? void 0 : snapshot.incremental,
|
|
194
207
|
modalStates: [],
|
|
195
|
-
|
|
196
|
-
downloads: this._downloads
|
|
208
|
+
events: []
|
|
197
209
|
};
|
|
198
210
|
});
|
|
199
211
|
if (tabSnapshot) {
|
|
200
|
-
tabSnapshot.
|
|
201
|
-
this.
|
|
212
|
+
tabSnapshot.events = this._recentEventEntries;
|
|
213
|
+
this._recentEventEntries = [];
|
|
202
214
|
}
|
|
203
215
|
this._needsFullSnapshot = !tabSnapshot;
|
|
204
216
|
return tabSnapshot ?? {
|
|
205
|
-
url: this.page.url(),
|
|
206
|
-
title: "",
|
|
207
217
|
ariaSnapshot: "",
|
|
218
|
+
ariaSnapshotDiff: "",
|
|
208
219
|
modalStates,
|
|
209
|
-
|
|
210
|
-
downloads: []
|
|
220
|
+
events: []
|
|
211
221
|
};
|
|
212
222
|
}
|
|
213
223
|
_javaScriptBlocked() {
|
|
@@ -228,15 +238,20 @@ class Tab extends import_events.EventEmitter {
|
|
|
228
238
|
]);
|
|
229
239
|
}
|
|
230
240
|
async waitForCompletion(callback) {
|
|
241
|
+
await this._initializedPromise;
|
|
231
242
|
await this._raceAgainstModalStates(() => (0, import_utils2.waitForCompletion)(this, callback));
|
|
232
243
|
}
|
|
233
244
|
async refLocator(params) {
|
|
245
|
+
await this._initializedPromise;
|
|
234
246
|
return (await this.refLocators([params]))[0];
|
|
235
247
|
}
|
|
236
248
|
async refLocators(params) {
|
|
249
|
+
await this._initializedPromise;
|
|
237
250
|
return Promise.all(params.map(async (param) => {
|
|
238
251
|
try {
|
|
239
|
-
|
|
252
|
+
let locator = this.page.locator(`aria-ref=${param.ref}`);
|
|
253
|
+
if (param.element)
|
|
254
|
+
locator = locator.describe(param.element);
|
|
240
255
|
const { resolvedSelector } = await locator._resolveSelector();
|
|
241
256
|
return { locator, resolved: (0, import_utils.asLocator)("javascript", resolvedSelector) };
|
|
242
257
|
} catch (e) {
|
|
@@ -250,7 +265,8 @@ class Tab extends import_events.EventEmitter {
|
|
|
250
265
|
return;
|
|
251
266
|
}
|
|
252
267
|
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => {
|
|
253
|
-
return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3)))
|
|
268
|
+
return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3))).catch(() => {
|
|
269
|
+
});
|
|
254
270
|
});
|
|
255
271
|
}
|
|
256
272
|
}
|
|
@@ -275,18 +291,53 @@ function pageErrorToConsoleMessage(errorOrValue) {
|
|
|
275
291
|
toString: () => String(errorOrValue)
|
|
276
292
|
};
|
|
277
293
|
}
|
|
278
|
-
function renderModalStates(
|
|
279
|
-
const result = [
|
|
294
|
+
function renderModalStates(modalStates) {
|
|
295
|
+
const result = [];
|
|
280
296
|
if (modalStates.length === 0)
|
|
281
297
|
result.push("- There is no modal state present");
|
|
282
298
|
for (const state of modalStates)
|
|
283
299
|
result.push(`- [${state.description}]: can be handled by the "${state.clearedBy}" tool`);
|
|
284
300
|
return result;
|
|
285
301
|
}
|
|
302
|
+
const consoleMessageLevels = ["error", "warning", "info", "debug"];
|
|
303
|
+
function shouldIncludeMessage(thresholdLevel, type) {
|
|
304
|
+
const messageLevel = consoleLevelForMessageType(type);
|
|
305
|
+
return consoleMessageLevels.indexOf(messageLevel) <= consoleMessageLevels.indexOf(thresholdLevel);
|
|
306
|
+
}
|
|
307
|
+
function consoleLevelForMessageType(type) {
|
|
308
|
+
switch (type) {
|
|
309
|
+
case "assert":
|
|
310
|
+
case "error":
|
|
311
|
+
return "error";
|
|
312
|
+
case "warning":
|
|
313
|
+
return "warning";
|
|
314
|
+
case "count":
|
|
315
|
+
case "dir":
|
|
316
|
+
case "dirxml":
|
|
317
|
+
case "info":
|
|
318
|
+
case "log":
|
|
319
|
+
case "table":
|
|
320
|
+
case "time":
|
|
321
|
+
case "timeEnd":
|
|
322
|
+
return "info";
|
|
323
|
+
case "clear":
|
|
324
|
+
case "debug":
|
|
325
|
+
case "endGroup":
|
|
326
|
+
case "profile":
|
|
327
|
+
case "profileEnd":
|
|
328
|
+
case "startGroup":
|
|
329
|
+
case "startGroupCollapsed":
|
|
330
|
+
case "trace":
|
|
331
|
+
return "debug";
|
|
332
|
+
default:
|
|
333
|
+
return "info";
|
|
334
|
+
}
|
|
335
|
+
}
|
|
286
336
|
const tabSymbol = Symbol("tabSymbol");
|
|
287
337
|
// Annotate the CommonJS export names for ESM import in node:
|
|
288
338
|
0 && (module.exports = {
|
|
289
339
|
Tab,
|
|
290
340
|
TabEvents,
|
|
291
|
-
renderModalStates
|
|
341
|
+
renderModalStates,
|
|
342
|
+
shouldIncludeMessage
|
|
292
343
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/browser/tab.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EventEmitter } from 'events';\nimport * as playwright from 'playwright-core';\nimport { asLocator, ManualPromise } from 'playwright-core/lib/utils';\n\nimport { callOnPageNoTrace, waitForCompletion } from './tools/utils';\nimport { logUnhandledError } from '../log';\nimport { ModalState } from './tools/tool';\nimport { handleDialog } from './tools/dialogs';\nimport { uploadFile } from './tools/files';\nimport { requireOrImport } from '../../transform/transform';\n\nimport type { Context } from './context';\nimport type { Page } from '../../../../playwright-core/src/client/page';\nimport type { Locator } from '../../../../playwright-core/src/client/locator';\n\nexport const TabEvents = {\n modalState: 'modalState'\n};\n\nexport type TabEventsInterface = {\n [TabEvents.modalState]: [modalState: ModalState];\n};\n\nexport type TabSnapshot = {\n url: string;\n title: string;\n ariaSnapshot: string;\n ariaSnapshotDiff?: string;\n modalStates: ModalState[];\n consoleMessages: ConsoleMessage[];\n downloads: { download: playwright.Download, finished: boolean, outputFile: string }[];\n};\n\nexport class Tab extends EventEmitter<TabEventsInterface> {\n readonly context: Context;\n readonly page: Page;\n private _lastTitle = 'about:blank';\n private _consoleMessages: ConsoleMessage[] = [];\n private _recentConsoleMessages: ConsoleMessage[] = [];\n private _requests: Set<playwright.Request> = new Set();\n private _onPageClose: (tab: Tab) => void;\n private _modalStates: ModalState[] = [];\n private _downloads: { download: playwright.Download, finished: boolean, outputFile: string }[] = [];\n readonly initializedPromise: Promise<void>;\n private _needsFullSnapshot = false;\n\n constructor(context: Context, page: playwright.Page, onPageClose: (tab: Tab) => void) {\n super();\n this.context = context;\n this.page = page as Page;\n this._onPageClose = onPageClose;\n page.on('console', event => this._handleConsoleMessage(messageToConsoleMessage(event)));\n page.on('pageerror', error => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));\n page.on('request', request => this._requests.add(request));\n page.on('close', () => this._onClose());\n page.on('filechooser', chooser => {\n this.setModalState({\n type: 'fileChooser',\n description: 'File chooser',\n fileChooser: chooser,\n clearedBy: uploadFile.schema.name,\n });\n });\n page.on('dialog', dialog => this._dialogShown(dialog));\n page.on('download', download => {\n void this._downloadStarted(download);\n });\n page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);\n page.setDefaultTimeout(this.context.config.timeouts.action);\n (page as any)[tabSymbol] = this;\n this.initializedPromise = this._initialize();\n }\n\n static forPage(page: playwright.Page): Tab | undefined {\n return (page as any)[tabSymbol];\n }\n\n static async collectConsoleMessages(page: playwright.Page): Promise<ConsoleMessage[]> {\n const result: ConsoleMessage[] = [];\n const messages = await page.consoleMessages().catch(() => []);\n for (const message of messages)\n result.push(messageToConsoleMessage(message));\n const errors = await page.pageErrors().catch(() => []);\n for (const error of errors)\n result.push(pageErrorToConsoleMessage(error));\n return result;\n }\n\n private async _initialize() {\n for (const message of await Tab.collectConsoleMessages(this.page))\n this._handleConsoleMessage(message);\n const requests = await this.page.requests().catch(() => []);\n for (const request of requests)\n this._requests.add(request);\n for (const initPage of this.context.config.browser.initPage || []) {\n try {\n const { default: func } = await requireOrImport(initPage);\n await func({ page: this.page });\n } catch (e) {\n logUnhandledError(e);\n }\n }\n }\n\n modalStates(): ModalState[] {\n return this._modalStates;\n }\n\n setModalState(modalState: ModalState) {\n this._modalStates.push(modalState);\n this.emit(TabEvents.modalState, modalState);\n }\n\n clearModalState(modalState: ModalState) {\n this._modalStates = this._modalStates.filter(state => state !== modalState);\n }\n\n modalStatesMarkdown(): string[] {\n return renderModalStates(this.context, this.modalStates());\n }\n\n private _dialogShown(dialog: playwright.Dialog) {\n this.setModalState({\n type: 'dialog',\n description: `\"${dialog.type()}\" dialog with message \"${dialog.message()}\"`,\n dialog,\n clearedBy: handleDialog.schema.name\n });\n }\n\n private async _downloadStarted(download: playwright.Download) {\n const entry = {\n download,\n finished: false,\n outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: 'web', reason: 'Saving download' })\n };\n this._downloads.push(entry);\n await download.saveAs(entry.outputFile);\n entry.finished = true;\n }\n\n private _clearCollectedArtifacts() {\n this._consoleMessages.length = 0;\n this._recentConsoleMessages.length = 0;\n this._requests.clear();\n }\n\n private _handleConsoleMessage(message: ConsoleMessage) {\n this._consoleMessages.push(message);\n this._recentConsoleMessages.push(message);\n }\n\n private _onClose() {\n this._clearCollectedArtifacts();\n this._onPageClose(this);\n }\n\n async updateTitle() {\n await this._raceAgainstModalStates(async () => {\n this._lastTitle = await callOnPageNoTrace(this.page, page => page.title());\n });\n }\n\n lastTitle(): string {\n return this._lastTitle;\n }\n\n isCurrentTab(): boolean {\n return this === this.context.currentTab();\n }\n\n async waitForLoadState(state: 'load', options?: { timeout?: number }): Promise<void> {\n await callOnPageNoTrace(this.page, page => page.waitForLoadState(state, options).catch(logUnhandledError));\n }\n\n async navigate(url: string) {\n this._clearCollectedArtifacts();\n\n const downloadEvent = callOnPageNoTrace(this.page, page => page.waitForEvent('download').catch(logUnhandledError));\n try {\n await this.page.goto(url, { waitUntil: 'domcontentloaded' });\n } catch (_e: unknown) {\n const e = _e as Error;\n const mightBeDownload =\n e.message.includes('net::ERR_ABORTED') // chromium\n || e.message.includes('Download is starting'); // firefox + webkit\n if (!mightBeDownload)\n throw e;\n // on chromium, the download event is fired *after* page.goto rejects, so we wait a lil bit\n const download = await Promise.race([\n downloadEvent,\n new Promise(resolve => setTimeout(resolve, 3000)),\n ]);\n if (!download)\n throw e;\n // Make sure other \"download\" listeners are notified first.\n await new Promise(resolve => setTimeout(resolve, 500));\n return;\n }\n\n // Cap load event to 5 seconds, the page is operational at this point.\n await this.waitForLoadState('load', { timeout: 5000 });\n }\n\n async consoleMessages(type?: 'error'): Promise<ConsoleMessage[]> {\n await this.initializedPromise;\n return this._consoleMessages.filter(message => type ? message.type === type : true);\n }\n\n async requests(): Promise<Set<playwright.Request>> {\n await this.initializedPromise;\n return this._requests;\n }\n\n async captureSnapshot(): Promise<TabSnapshot> {\n let tabSnapshot: TabSnapshot | undefined;\n const modalStates = await this._raceAgainstModalStates(async () => {\n const snapshot = await this.page._snapshotForAI({ track: 'response' });\n tabSnapshot = {\n url: this.page.url(),\n title: await this.page.title(),\n ariaSnapshot: snapshot.full,\n ariaSnapshotDiff: this._needsFullSnapshot ? undefined : snapshot.incremental,\n modalStates: [],\n consoleMessages: [],\n downloads: this._downloads,\n };\n });\n if (tabSnapshot) {\n // Assign console message late so that we did not lose any to modal state.\n tabSnapshot.consoleMessages = this._recentConsoleMessages;\n this._recentConsoleMessages = [];\n }\n // If we failed to capture a snapshot this time, make sure we do a full one next time,\n // to avoid reporting deltas against un-reported snapshot.\n this._needsFullSnapshot = !tabSnapshot;\n return tabSnapshot ?? {\n url: this.page.url(),\n title: '',\n ariaSnapshot: '',\n modalStates,\n consoleMessages: [],\n downloads: [],\n };\n }\n\n private _javaScriptBlocked(): boolean {\n return this._modalStates.some(state => state.type === 'dialog');\n }\n\n private async _raceAgainstModalStates(action: () => Promise<void>): Promise<ModalState[]> {\n if (this.modalStates().length)\n return this.modalStates();\n\n const promise = new ManualPromise<ModalState[]>();\n const listener = (modalState: ModalState) => promise.resolve([modalState]);\n this.once(TabEvents.modalState, listener);\n\n return await Promise.race([\n action().then(() => {\n this.off(TabEvents.modalState, listener);\n return [];\n }),\n promise,\n ]);\n }\n\n async waitForCompletion(callback: () => Promise<void>) {\n await this._raceAgainstModalStates(() => waitForCompletion(this, callback));\n }\n\n async refLocator(params: { element: string, ref: string }): Promise<{ locator: Locator, resolved: string }> {\n return (await this.refLocators([params]))[0];\n }\n\n async refLocators(params: { element: string, ref: string }[]): Promise<{ locator: Locator, resolved: string }[]> {\n return Promise.all(params.map(async param => {\n try {\n const locator = this.page.locator(`aria-ref=${param.ref}`).describe(param.element) as Locator;\n const { resolvedSelector } = await locator._resolveSelector();\n return { locator, resolved: asLocator('javascript', resolvedSelector) };\n } catch (e) {\n throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);\n }\n }));\n }\n\n async waitForTimeout(time: number) {\n if (this._javaScriptBlocked()) {\n await new Promise(f => setTimeout(f, time));\n return;\n }\n\n await callOnPageNoTrace(this.page, page => {\n return page.evaluate(() => new Promise(f => setTimeout(f, 1000)));\n });\n }\n}\n\nexport type ConsoleMessage = {\n type: ReturnType<playwright.ConsoleMessage['type']> | undefined;\n text: string;\n toString(): string;\n};\n\nfunction messageToConsoleMessage(message: playwright.ConsoleMessage): ConsoleMessage {\n return {\n type: message.type(),\n text: message.text(),\n toString: () => `[${message.type().toUpperCase()}] ${message.text()} @ ${message.location().url}:${message.location().lineNumber}`,\n };\n}\n\nfunction pageErrorToConsoleMessage(errorOrValue: Error | any): ConsoleMessage {\n if (errorOrValue instanceof Error) {\n return {\n type: 'error',\n text: errorOrValue.message,\n toString: () => errorOrValue.stack || errorOrValue.message,\n };\n }\n return {\n type: 'error',\n text: String(errorOrValue),\n toString: () => String(errorOrValue),\n };\n}\n\nexport function renderModalStates(context: Context, modalStates: ModalState[]): string[] {\n const result: string[] = ['### Modal state'];\n if (modalStates.length === 0)\n result.push('- There is no modal state present');\n for (const state of modalStates)\n result.push(`- [${state.description}]: can be handled by the \"${state.clearedBy}\" tool`);\n return result;\n}\n\nconst tabSymbol = Symbol('tabSymbol');\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_utils"]
|
|
7
|
+
}
|
|
@@ -21,20 +21,22 @@ __export(common_exports, {
|
|
|
21
21
|
default: () => common_default
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(common_exports);
|
|
24
|
-
var
|
|
24
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
25
25
|
var import_tool = require("./tool");
|
|
26
|
+
var import_response = require("../response");
|
|
26
27
|
const close = (0, import_tool.defineTool)({
|
|
27
28
|
capability: "core",
|
|
28
29
|
schema: {
|
|
29
30
|
name: "browser_close",
|
|
30
31
|
title: "Close browser",
|
|
31
32
|
description: "Close the page",
|
|
32
|
-
inputSchema:
|
|
33
|
+
inputSchema: import_mcpBundle.z.object({}),
|
|
33
34
|
type: "action"
|
|
34
35
|
},
|
|
35
36
|
handle: async (context, params, response) => {
|
|
36
37
|
await context.closeBrowserContext();
|
|
37
|
-
|
|
38
|
+
const result = (0, import_response.renderTabsMarkdown)([]);
|
|
39
|
+
response.addTextResult(result.join("\n"));
|
|
38
40
|
response.addCode(`await page.close()`);
|
|
39
41
|
}
|
|
40
42
|
});
|
|
@@ -44,9 +46,9 @@ const resize = (0, import_tool.defineTabTool)({
|
|
|
44
46
|
name: "browser_resize",
|
|
45
47
|
title: "Resize browser window",
|
|
46
48
|
description: "Resize the browser window",
|
|
47
|
-
inputSchema:
|
|
48
|
-
width:
|
|
49
|
-
height:
|
|
49
|
+
inputSchema: import_mcpBundle.z.object({
|
|
50
|
+
width: import_mcpBundle.z.number().describe("Width of the browser window"),
|
|
51
|
+
height: import_mcpBundle.z.number().describe("Height of the browser window")
|
|
50
52
|
}),
|
|
51
53
|
type: "action"
|
|
52
54
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/mcp/browser/tools/common.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool, defineTool } from './tool';\n\nconst close = defineTool({\n capability: 'core',\n\n schema: {\n name: 'browser_close',\n title: 'Close browser',\n description: 'Close the page',\n inputSchema: z.object({}),\n type: 'action',\n },\n\n handle: async (context, params, response) => {\n await context.closeBrowserContext();\n response.setIncludeTabs();\n response.addCode(`await page.close()`);\n },\n});\n\nconst resize = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_resize',\n title: 'Resize browser window',\n description: 'Resize the browser window',\n inputSchema: z.object({\n width: z.number().describe('Width of the browser window'),\n height: z.number().describe('Height of the browser window'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.setViewportSize({ width: params.width, height: params.height });\n });\n },\n});\n\nexport default [\n close,\n resize\n];\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA0C;AAE1C,MAAM,YAAQ,wBAAW;AAAA,EACvB,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,UAAM,QAAQ,oBAAoB;AAClC,aAAS,eAAe;AACxB,aAAS,QAAQ,oBAAoB;AAAA,EACvC;AACF,CAAC;AAED,MAAM,aAAS,2BAAc;AAAA,EAC3B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,OAAO,gBAAE,OAAO,EAAE,SAAS,6BAA6B;AAAA,MACxD,QAAQ,gBAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,IAC5D,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,QAAQ,uCAAuC,OAAO,KAAK,aAAa,OAAO,MAAM,MAAM;AAEpG,UAAM,IAAI,kBAAkB,YAAY;AACtC,YAAM,IAAI,KAAK,gBAAgB,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC;AAAA,IAC/E,CAAC;AAAA,EACH;AACF,CAAC;AAED,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -21,7 +21,7 @@ __export(console_exports, {
|
|
|
21
21
|
default: () => console_default
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(console_exports);
|
|
24
|
-
var
|
|
24
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
25
25
|
var import_tool = require("./tool");
|
|
26
26
|
const console = (0, import_tool.defineTabTool)({
|
|
27
27
|
capability: "core",
|
|
@@ -29,14 +29,16 @@ const console = (0, import_tool.defineTabTool)({
|
|
|
29
29
|
name: "browser_console_messages",
|
|
30
30
|
title: "Get console messages",
|
|
31
31
|
description: "Returns all console messages",
|
|
32
|
-
inputSchema:
|
|
33
|
-
|
|
32
|
+
inputSchema: import_mcpBundle.z.object({
|
|
33
|
+
level: import_mcpBundle.z.enum(["error", "warning", "info", "debug"]).default("info").describe('Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info".'),
|
|
34
|
+
filename: import_mcpBundle.z.string().optional().describe("Filename to save the console messages to. If not provided, messages are returned as text.")
|
|
34
35
|
}),
|
|
35
36
|
type: "readOnly"
|
|
36
37
|
},
|
|
37
38
|
handle: async (tab, params, response) => {
|
|
38
|
-
const messages = await tab.consoleMessages(params.
|
|
39
|
-
messages.map((message) =>
|
|
39
|
+
const messages = await tab.consoleMessages(params.level);
|
|
40
|
+
const text = messages.map((message) => message.toString()).join("\n");
|
|
41
|
+
await response.addResult({ text, suggestedFilename: params.filename });
|
|
40
42
|
}
|
|
41
43
|
});
|
|
42
44
|
var console_default = [
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/mcp/browser/tools/console.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nconst console = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_console_messages',\n title: 'Get console messages',\n description: 'Returns all console messages',\n inputSchema: z.object({\n onlyErrors: z.boolean().optional().describe('Only return error messages'),\n }),\n type: 'readOnly',\n },\n handle: async (tab, params, response) => {\n const messages = await tab.consoleMessages(params.onlyErrors ? 'error' : undefined);\n messages.map(message => response.addResult(message.toString()));\n },\n});\n\nexport default [\n console,\n];\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAE9B,MAAM,cAAU,2BAAc;AAAA,EAC5B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,YAAY,gBAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,IAC1E,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EACA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAM,WAAW,MAAM,IAAI,gBAAgB,OAAO,aAAa,UAAU,MAAS;AAClF,aAAS,IAAI,aAAW,SAAS,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,EAChE;AACF,CAAC;AAED,IAAO,kBAAQ;AAAA,EACb;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -22,7 +22,7 @@ __export(dialogs_exports, {
|
|
|
22
22
|
handleDialog: () => handleDialog
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(dialogs_exports);
|
|
25
|
-
var
|
|
25
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
26
26
|
var import_tool = require("./tool");
|
|
27
27
|
const handleDialog = (0, import_tool.defineTabTool)({
|
|
28
28
|
capability: "core",
|
|
@@ -30,9 +30,9 @@ const handleDialog = (0, import_tool.defineTabTool)({
|
|
|
30
30
|
name: "browser_handle_dialog",
|
|
31
31
|
title: "Handle a dialog",
|
|
32
32
|
description: "Handle a dialog",
|
|
33
|
-
inputSchema:
|
|
34
|
-
accept:
|
|
35
|
-
promptText:
|
|
33
|
+
inputSchema: import_mcpBundle.z.object({
|
|
34
|
+
accept: import_mcpBundle.z.boolean().describe("Whether to accept the dialog."),
|
|
35
|
+
promptText: import_mcpBundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
|
|
36
36
|
}),
|
|
37
37
|
type: "action"
|
|
38
38
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/mcp/browser/tools/dialogs.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nexport const handleDialog = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_handle_dialog',\n title: 'Handle a dialog',\n description: 'Handle a dialog',\n inputSchema: z.object({\n accept: z.boolean().describe('Whether to accept the dialog.'),\n promptText: z.string().optional().describe('The text of the prompt in case of a prompt dialog.'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const dialogState = tab.modalStates().find(state => state.type === 'dialog');\n if (!dialogState)\n throw new Error('No dialog visible');\n\n tab.clearModalState(dialogState);\n await tab.waitForCompletion(async () => {\n if (params.accept)\n await dialogState.dialog.accept(params.promptText);\n else\n await dialogState.dialog.dismiss();\n });\n },\n\n clearsModalState: 'dialog',\n});\n\nexport default [\n handleDialog,\n];\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAEvB,MAAM,mBAAe,2BAAc;AAAA,EACxC,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,QAAQ,gBAAE,QAAQ,EAAE,SAAS,+BAA+B;AAAA,MAC5D,YAAY,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IACjG,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,UAAM,cAAc,IAAI,YAAY,EAAE,KAAK,WAAS,MAAM,SAAS,QAAQ;AAC3E,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,mBAAmB;AAErC,QAAI,gBAAgB,WAAW;AAC/B,UAAM,IAAI,kBAAkB,YAAY;AACtC,UAAI,OAAO;AACT,cAAM,YAAY,OAAO,OAAO,OAAO,UAAU;AAAA;AAEjD,cAAM,YAAY,OAAO,QAAQ;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AACpB,CAAC;AAED,IAAO,kBAAQ;AAAA,EACb;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,27 +15,20 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var evaluate_exports = {};
|
|
30
20
|
__export(evaluate_exports, {
|
|
31
21
|
default: () => evaluate_default
|
|
32
22
|
});
|
|
33
23
|
module.exports = __toCommonJS(evaluate_exports);
|
|
34
|
-
var
|
|
24
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
25
|
+
var import_utils = require("playwright-core/lib/utils");
|
|
35
26
|
var import_tool = require("./tool");
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
const evaluateSchema = import_mcpBundle.z.object({
|
|
28
|
+
function: import_mcpBundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
|
|
29
|
+
element: import_mcpBundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
|
|
30
|
+
ref: import_mcpBundle.z.string().optional().describe("Exact target element reference from the page snapshot"),
|
|
31
|
+
filename: import_mcpBundle.z.string().optional().describe("Filename to save the result to. If not provided, result is returned as JSON string.")
|
|
41
32
|
});
|
|
42
33
|
const evaluate = (0, import_tool.defineTabTool)({
|
|
43
34
|
capability: "core",
|
|
@@ -53,14 +44,15 @@ const evaluate = (0, import_tool.defineTabTool)({
|
|
|
53
44
|
let locator;
|
|
54
45
|
if (params.ref && params.element) {
|
|
55
46
|
locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
56
|
-
response.addCode(`await page.${locator.resolved}.evaluate(${
|
|
47
|
+
response.addCode(`await page.${locator.resolved}.evaluate(${(0, import_utils.escapeWithQuotes)(params.function)});`);
|
|
57
48
|
} else {
|
|
58
|
-
response.addCode(`await page.evaluate(${
|
|
49
|
+
response.addCode(`await page.evaluate(${(0, import_utils.escapeWithQuotes)(params.function)});`);
|
|
59
50
|
}
|
|
60
51
|
await tab.waitForCompletion(async () => {
|
|
61
52
|
const receiver = locator?.locator ?? tab.page;
|
|
62
53
|
const result = await receiver._evaluateFunction(params.function);
|
|
63
|
-
|
|
54
|
+
const text = JSON.stringify(result, null, 2) || "undefined";
|
|
55
|
+
await response.addResult({ text, suggestedFilename: params.filename });
|
|
64
56
|
});
|
|
65
57
|
}
|
|
66
58
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/mcp/browser/tools/evaluate.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport * as javascript from '../codegen';\n\nimport type { Tab } from '../tab';\n\nconst evaluateSchema = z.object({\n function: z.string().describe('() => { /* code */ } or (element) => { /* code */ } when element is provided'),\n element: z.string().optional().describe('Human-readable element description used to obtain permission to interact with the element'),\n ref: z.string().optional().describe('Exact target element reference from the page snapshot'),\n});\n\nconst evaluate = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_evaluate',\n title: 'Evaluate JavaScript',\n description: 'Evaluate JavaScript expression on page or element',\n inputSchema: evaluateSchema,\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n let locator: Awaited<ReturnType<Tab['refLocator']>> | undefined;\n if (params.ref && params.element) {\n locator = await tab.refLocator({ ref: params.ref, element: params.element });\n response.addCode(`await page.${locator.resolved}.evaluate(${javascript.quote(params.function)});`);\n } else {\n response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);\n }\n\n await tab.waitForCompletion(async () => {\n const receiver = locator?.locator ?? tab.page;\n const result = await receiver._evaluateFunction(params.function);\n response.addResult(JSON.stringify(result, null, 2) || 'undefined');\n });\n },\n});\n\nexport default [\n evaluate,\n];\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAC9B,iBAA4B;AAI5B,MAAM,iBAAiB,gBAAE,OAAO;AAAA,EAC9B,UAAU,gBAAE,OAAO,EAAE,SAAS,8EAA8E;AAAA,EAC5G,SAAS,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2FAA2F;AAAA,EACnI,KAAK,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAC7F,CAAC;AAED,MAAM,eAAW,2BAAc;AAAA,EAC7B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,QAAI;AACJ,QAAI,OAAO,OAAO,OAAO,SAAS;AAChC,gBAAU,MAAM,IAAI,WAAW,EAAE,KAAK,OAAO,KAAK,SAAS,OAAO,QAAQ,CAAC;AAC3E,eAAS,QAAQ,cAAc,QAAQ,QAAQ,aAAa,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI;AAAA,IACnG,OAAO;AACL,eAAS,QAAQ,uBAAuB,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI;AAAA,IAC/E;AAEA,UAAM,IAAI,kBAAkB,YAAY;AACtC,YAAM,WAAW,SAAS,WAAW,IAAI;AACzC,YAAM,SAAS,MAAM,SAAS,kBAAkB,OAAO,QAAQ;AAC/D,eAAS,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,KAAK,WAAW;AAAA,IACnE,CAAC;AAAA,EACH;AACF,CAAC;AAED,IAAO,mBAAQ;AAAA,EACb;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -22,7 +22,7 @@ __export(files_exports, {
|
|
|
22
22
|
uploadFile: () => uploadFile
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(files_exports);
|
|
25
|
-
var
|
|
25
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
26
26
|
var import_tool = require("./tool");
|
|
27
27
|
const uploadFile = (0, import_tool.defineTabTool)({
|
|
28
28
|
capability: "core",
|
|
@@ -30,8 +30,8 @@ const uploadFile = (0, import_tool.defineTabTool)({
|
|
|
30
30
|
name: "browser_file_upload",
|
|
31
31
|
title: "Upload files",
|
|
32
32
|
description: "Upload one or multiple files",
|
|
33
|
-
inputSchema:
|
|
34
|
-
paths:
|
|
33
|
+
inputSchema: import_mcpBundle.z.object({
|
|
34
|
+
paths: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
|
|
35
35
|
}),
|
|
36
36
|
type: "action"
|
|
37
37
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/mcp/browser/tools/files.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nexport const uploadFile = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_file_upload',\n title: 'Upload files',\n description: 'Upload one or multiple files',\n inputSchema: z.object({\n paths: z.array(z.string()).optional().describe('The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const modalState = tab.modalStates().find(state => state.type === 'fileChooser');\n if (!modalState)\n throw new Error('No file chooser visible');\n\n response.addCode(`await fileChooser.setFiles(${JSON.stringify(params.paths)})`);\n\n tab.clearModalState(modalState);\n await tab.waitForCompletion(async () => {\n if (params.paths)\n await modalState.fileChooser.setFiles(params.paths);\n });\n },\n\n clearsModalState: 'fileChooser',\n});\n\nexport default [\n uploadFile,\n];\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAEvB,MAAM,iBAAa,2BAAc;AAAA,EACtC,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,OAAO,gBAAE,MAAM,gBAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yHAAyH;AAAA,IAC1K,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,UAAM,aAAa,IAAI,YAAY,EAAE,KAAK,WAAS,MAAM,SAAS,aAAa;AAC/E,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,yBAAyB;AAE3C,aAAS,QAAQ,8BAA8B,KAAK,UAAU,OAAO,KAAK,CAAC,GAAG;AAE9E,QAAI,gBAAgB,UAAU;AAC9B,UAAM,IAAI,kBAAkB,YAAY;AACtC,UAAI,OAAO;AACT,cAAM,WAAW,YAAY,SAAS,OAAO,KAAK;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AACpB,CAAC;AAED,IAAO,gBAAQ;AAAA,EACb;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,35 +15,27 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var form_exports = {};
|
|
30
20
|
__export(form_exports, {
|
|
31
21
|
default: () => form_default
|
|
32
22
|
});
|
|
33
23
|
module.exports = __toCommonJS(form_exports);
|
|
34
|
-
var
|
|
24
|
+
var import_mcpBundle = require("playwright-core/lib/mcpBundle");
|
|
25
|
+
var import_utils = require("playwright-core/lib/utils");
|
|
35
26
|
var import_tool = require("./tool");
|
|
36
|
-
var codegen = __toESM(require("../codegen"));
|
|
37
27
|
const fillForm = (0, import_tool.defineTabTool)({
|
|
38
28
|
capability: "core",
|
|
39
29
|
schema: {
|
|
40
30
|
name: "browser_fill_form",
|
|
41
31
|
title: "Fill form",
|
|
42
32
|
description: "Fill multiple form fields",
|
|
43
|
-
inputSchema:
|
|
44
|
-
fields:
|
|
45
|
-
name:
|
|
46
|
-
type:
|
|
47
|
-
ref:
|
|
48
|
-
value:
|
|
33
|
+
inputSchema: import_mcpBundle.z.object({
|
|
34
|
+
fields: import_mcpBundle.z.array(import_mcpBundle.z.object({
|
|
35
|
+
name: import_mcpBundle.z.string().describe("Human-readable field name"),
|
|
36
|
+
type: import_mcpBundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
|
|
37
|
+
ref: import_mcpBundle.z.string().describe("Exact target field reference from the page snapshot"),
|
|
38
|
+
value: import_mcpBundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
|
|
49
39
|
})).describe("Fields to fill in")
|
|
50
40
|
}),
|
|
51
41
|
type: "input"
|
|
@@ -63,7 +53,7 @@ const fillForm = (0, import_tool.defineTabTool)({
|
|
|
63
53
|
response.addCode(`${locatorSource}.setChecked(${field.value});`);
|
|
64
54
|
} else if (field.type === "combobox") {
|
|
65
55
|
await locator.selectOption({ label: field.value });
|
|
66
|
-
response.addCode(`${locatorSource}.selectOption(${
|
|
56
|
+
response.addCode(`${locatorSource}.selectOption(${(0, import_utils.escapeWithQuotes)(field.value)});`);
|
|
67
57
|
}
|
|
68
58
|
}
|
|
69
59
|
}
|