@wdio/mcp 3.3.0 → 3.4.0
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/README.md +1 -0
- package/lib/server.js +52 -19
- package/lib/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -426,6 +426,7 @@ All session types support `reporting` labels that appear in the BrowserStack Aut
|
|
|
426
426
|
| `scroll` | Scroll in a direction (up/down) by specified pixels. Browser-only. |
|
|
427
427
|
| `execute_script` | Execute arbitrary JavaScript in the browser, or Appium mobile commands on devices |
|
|
428
428
|
| `switch_tab` | Switch to a different browser tab by handle or 0-based index. Browser-only. |
|
|
429
|
+
| `switch_frame` | Switch into an iframe by CSS/XPath selector, or back to the top-level frame if no selector is given. Browser-only. |
|
|
429
430
|
|
|
430
431
|
### Element Interaction (Web & Mobile)
|
|
431
432
|
|
package/lib/server.js
CHANGED
|
@@ -46,7 +46,7 @@ var package_default = {
|
|
|
46
46
|
type: "git",
|
|
47
47
|
url: "git://github.com/webdriverio/mcp.git"
|
|
48
48
|
},
|
|
49
|
-
version: "3.
|
|
49
|
+
version: "3.3.0",
|
|
50
50
|
description: "MCP server with WebdriverIO for browser and mobile app automation (iOS/Android via Appium)",
|
|
51
51
|
main: "./lib/server.js",
|
|
52
52
|
module: "./lib/server.js",
|
|
@@ -3152,7 +3152,8 @@ function getAppiumServerConfig(overrides) {
|
|
|
3152
3152
|
return {
|
|
3153
3153
|
hostname: overrides?.hostname || process.env.APPIUM_URL || "127.0.0.1",
|
|
3154
3154
|
port: overrides?.port || Number(process.env.APPIUM_URL_PORT) || 4723,
|
|
3155
|
-
path: overrides?.path || process.env.APPIUM_PATH || "/"
|
|
3155
|
+
path: overrides?.path || process.env.APPIUM_PATH || "/",
|
|
3156
|
+
protocol: overrides?.protocol || process.env.APPIUM_PROTOCOL || "http"
|
|
3156
3157
|
};
|
|
3157
3158
|
}
|
|
3158
3159
|
function buildIOSCapabilities(appPath, options) {
|
|
@@ -3235,12 +3236,12 @@ var LocalAppiumProvider = class {
|
|
|
3235
3236
|
name = "local-appium";
|
|
3236
3237
|
getConnectionConfig(options) {
|
|
3237
3238
|
const appiumConfig = options.appiumConfig;
|
|
3238
|
-
|
|
3239
|
+
return getAppiumServerConfig({
|
|
3239
3240
|
hostname: appiumConfig?.host,
|
|
3240
3241
|
port: appiumConfig?.port,
|
|
3241
|
-
path: appiumConfig?.path
|
|
3242
|
+
path: appiumConfig?.path,
|
|
3243
|
+
protocol: appiumConfig?.protocol
|
|
3242
3244
|
});
|
|
3243
|
-
return { protocol: "http", ...config };
|
|
3244
3245
|
}
|
|
3245
3246
|
buildCapabilities(options) {
|
|
3246
3247
|
const platform2 = options.platform;
|
|
@@ -3538,7 +3539,8 @@ var startSessionToolDefinition = {
|
|
|
3538
3539
|
appiumConfig: z14.object({
|
|
3539
3540
|
host: z14.string().optional(),
|
|
3540
3541
|
port: z14.number().optional(),
|
|
3541
|
-
path: z14.string().optional()
|
|
3542
|
+
path: z14.string().optional(),
|
|
3543
|
+
protocol: z14.string().optional()
|
|
3542
3544
|
}).optional().describe("Appium server connection (local provider only)"),
|
|
3543
3545
|
browserstackLocal: z14.union([coerceBoolean, z14.literal("external")]).optional().default(false).describe('Enable BrowserStack Local tunnel routing (BrowserStack only, default: false). true = auto-start tunnel before session and stop on close. "external" = tunnel already running externally, set local: true in capabilities only.'),
|
|
3544
3546
|
navigationUrl: z14.string().optional().describe("URL to navigate to after starting"),
|
|
@@ -3823,9 +3825,39 @@ var switchTabTool = async ({ handle, index }) => {
|
|
|
3823
3825
|
}
|
|
3824
3826
|
};
|
|
3825
3827
|
|
|
3828
|
+
// src/tools/switch-frame.tool.ts
|
|
3829
|
+
init_state();
|
|
3830
|
+
import { z as z16 } from "zod";
|
|
3831
|
+
var switchFrameToolDefinition = {
|
|
3832
|
+
name: "switch_frame",
|
|
3833
|
+
description: "Switches into an iframe by CSS or XPath selector, or back to the top-level frame if no selector is given. Required before interacting with elements inside iframes \u2014 click, set_value, and get_elements only see the current frame context. Browser-only.",
|
|
3834
|
+
inputSchema: {
|
|
3835
|
+
selector: z16.string().optional().describe(
|
|
3836
|
+
"CSS/XPath selector for the iframe element. Omit to switch back to the top-level frame."
|
|
3837
|
+
)
|
|
3838
|
+
}
|
|
3839
|
+
};
|
|
3840
|
+
var switchFrameTool = async ({
|
|
3841
|
+
selector
|
|
3842
|
+
}) => {
|
|
3843
|
+
try {
|
|
3844
|
+
const browser = getBrowser();
|
|
3845
|
+
if (!selector) {
|
|
3846
|
+
await browser.switchFrame(null);
|
|
3847
|
+
return { content: [{ type: "text", text: "Switched back to top-level frame" }] };
|
|
3848
|
+
}
|
|
3849
|
+
const iframe = await browser.$(selector);
|
|
3850
|
+
await iframe.waitForExist({ timeout: 5e3 });
|
|
3851
|
+
await browser.switchFrame(iframe);
|
|
3852
|
+
return { content: [{ type: "text", text: `Switched to iframe: ${selector}` }] };
|
|
3853
|
+
} catch (e) {
|
|
3854
|
+
return { isError: true, content: [{ type: "text", text: `Error switching frame: ${e}` }] };
|
|
3855
|
+
}
|
|
3856
|
+
};
|
|
3857
|
+
|
|
3826
3858
|
// src/tools/browserstack.tool.ts
|
|
3827
3859
|
import { existsSync as existsSync2, createReadStream } from "fs";
|
|
3828
|
-
import { z as
|
|
3860
|
+
import { z as z17 } from "zod";
|
|
3829
3861
|
var BS_API = "https://api-cloud.browserstack.com";
|
|
3830
3862
|
function getAuth() {
|
|
3831
3863
|
const user = process.env.BROWSERSTACK_USERNAME;
|
|
@@ -3844,9 +3876,9 @@ var listAppsToolDefinition = {
|
|
|
3844
3876
|
name: "list_apps",
|
|
3845
3877
|
description: "List apps uploaded to BrowserStack App Automate. Reads BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY from environment.",
|
|
3846
3878
|
inputSchema: {
|
|
3847
|
-
sortBy:
|
|
3879
|
+
sortBy: z17.enum(["app_name", "uploaded_at"]).optional().default("uploaded_at").describe("Sort order for results"),
|
|
3848
3880
|
organizationWide: coerceBoolean.optional().default(false).describe("List apps uploaded by all users in the organization (uses recent_group_apps endpoint). Defaults to false (own uploads only)."),
|
|
3849
|
-
limit:
|
|
3881
|
+
limit: z17.number().int().min(1).optional().default(20).describe("Maximum number of apps to return (only applies when organizationWide is true, default 20)")
|
|
3850
3882
|
}
|
|
3851
3883
|
};
|
|
3852
3884
|
var listAppsTool = async ({ sortBy = "uploaded_at", organizationWide = false, limit = 20 }) => {
|
|
@@ -3876,8 +3908,8 @@ var uploadAppToolDefinition = {
|
|
|
3876
3908
|
name: "upload_app",
|
|
3877
3909
|
description: "Upload a local .apk or .ipa to BrowserStack App Automate. Returns a bs:// URL for use in start_session.",
|
|
3878
3910
|
inputSchema: {
|
|
3879
|
-
path:
|
|
3880
|
-
customId:
|
|
3911
|
+
path: z17.string().describe("Absolute path to the .apk or .ipa file"),
|
|
3912
|
+
customId: z17.string().optional().describe("Optional custom ID for the app (used to reference it later)")
|
|
3881
3913
|
}
|
|
3882
3914
|
};
|
|
3883
3915
|
var uploadAppTool = async ({ path, customId }) => {
|
|
@@ -3930,14 +3962,14 @@ var screenshotTool = async () => {
|
|
|
3930
3962
|
};
|
|
3931
3963
|
|
|
3932
3964
|
// src/tools/accessibility.tool.ts
|
|
3933
|
-
import { z as
|
|
3965
|
+
import { z as z18 } from "zod";
|
|
3934
3966
|
var accessibilityToolDefinition = {
|
|
3935
3967
|
name: "get_accessibility_tree",
|
|
3936
3968
|
description: "Returns the page accessibility tree with roles, names, and selectors. Browser-only. Supports filtering by ARIA roles and pagination via limit/offset.",
|
|
3937
3969
|
inputSchema: {
|
|
3938
|
-
limit:
|
|
3939
|
-
offset:
|
|
3940
|
-
roles:
|
|
3970
|
+
limit: z18.number().optional().default(0).describe("Maximum number of nodes to return (0 = no limit)"),
|
|
3971
|
+
offset: z18.number().optional().default(0).describe("Number of nodes to skip for pagination"),
|
|
3972
|
+
roles: z18.array(z18.string()).optional().describe('Filter by ARIA roles, e.g. ["button", "link", "heading"]')
|
|
3941
3973
|
}
|
|
3942
3974
|
};
|
|
3943
3975
|
var accessibilityTool = async ({ limit = 0, offset = 0, roles }) => {
|
|
@@ -3984,12 +4016,12 @@ var getContextsTool = async () => {
|
|
|
3984
4016
|
};
|
|
3985
4017
|
|
|
3986
4018
|
// src/tools/app-state.tool.ts
|
|
3987
|
-
import { z as
|
|
4019
|
+
import { z as z19 } from "zod";
|
|
3988
4020
|
var appStateToolDefinition = {
|
|
3989
4021
|
name: "get_app_state",
|
|
3990
4022
|
description: "Returns the current state of a mobile app: not installed, not running, background, or foreground. Mobile-only.",
|
|
3991
4023
|
inputSchema: {
|
|
3992
|
-
bundleId:
|
|
4024
|
+
bundleId: z19.string().describe('App bundle ID (iOS) or package name (Android), e.g. "com.example.app"')
|
|
3993
4025
|
}
|
|
3994
4026
|
};
|
|
3995
4027
|
var appStateTool = async ({ bundleId }) => {
|
|
@@ -4001,12 +4033,12 @@ var appStateTool = async ({ bundleId }) => {
|
|
|
4001
4033
|
};
|
|
4002
4034
|
|
|
4003
4035
|
// src/tools/get-cookies.tool.ts
|
|
4004
|
-
import { z as
|
|
4036
|
+
import { z as z20 } from "zod";
|
|
4005
4037
|
var getCookiesToolDefinition = {
|
|
4006
4038
|
name: "get_cookies",
|
|
4007
4039
|
description: "Returns all cookies for the current session, or a single cookie by name. Use to verify auth state, session tokens, or feature flags after login flows.",
|
|
4008
4040
|
inputSchema: {
|
|
4009
|
-
name:
|
|
4041
|
+
name: z20.string().optional().describe("Cookie name to retrieve a specific cookie. If omitted, returns all cookies.")
|
|
4010
4042
|
}
|
|
4011
4043
|
};
|
|
4012
4044
|
var getCookiesTool = async ({ name }) => {
|
|
@@ -4063,6 +4095,7 @@ function createServer() {
|
|
|
4063
4095
|
registerTool(emulateDeviceToolDefinition, emulateDeviceTool);
|
|
4064
4096
|
registerTool(navigateToolDefinition, withRecording("navigate", navigateTool));
|
|
4065
4097
|
registerTool(switchTabToolDefinition, switchTabTool);
|
|
4098
|
+
registerTool(switchFrameToolDefinition, switchFrameTool);
|
|
4066
4099
|
registerTool(scrollToolDefinition, withRecording("scroll", scrollTool));
|
|
4067
4100
|
registerTool(clickToolDefinition, withRecording("click_element", clickTool));
|
|
4068
4101
|
registerTool(setValueToolDefinition, withRecording("set_value", setValueTool));
|