@nbakka/mcp-appium 2.0.9 → 2.0.11

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.
Files changed (2) hide show
  1. package/lib/server.js +20 -59
  2. package/package.json +1 -1
package/lib/server.js CHANGED
@@ -214,73 +214,34 @@ await new Promise(resolve => setTimeout(resolve, 5000));
214
214
  return `Current device orientation is ${orientation}`;
215
215
  });
216
216
  tool(
217
- "tap_by_text",
218
- "tap an element by passing the text visible on screen",
219
- { text: z.string().describe("The exact text to search for in the UI element"), },
217
+ "mobile_tap_by_text",
218
+ "Tap an element on screen by its displayed text or accessibility label using ADB tap",
219
+ {
220
+ text: zod_1.z.string().describe("The exact text or label of the element to tap"),
221
+ },
220
222
  async ({ text }) => {
221
- const { execSync } = require("child_process");
222
- const { XMLParser } = require("fast-xml-parser");
223
-
224
223
  if (!text) throw new Error("Input text is required");
225
224
 
226
- // 1. Dump UI Automator XML to stdout
227
- let dump;
228
- try {
229
- dump = execSync("adb shell uiautomator dump /dev/tty", { maxBuffer: 10 * 1024 * 1024 }).toString();
230
- } catch (e) {
231
- throw new Error("Failed to dump UI Automator XML via adb");
232
- }
233
-
234
- // 2. Parse XML
235
- const parser = new XMLParser({
236
- ignoreAttributes: false,
237
- attributeNamePrefix: "",
238
- });
239
- const xmlObj = parser.parse(dump);
240
-
241
- // 3. Recursive traversal to find matching element by text/content-desc/hint
242
- function findElement(node) {
243
- if (!node) return null;
244
-
245
- const matchText = node.text || node["content-desc"] || node.hint || "";
246
- if (matchText === text) return node;
225
+ requireRobot(); // ensure robot instance available
226
+ const elements = await robot.getElementsOnScreen();
247
227
 
248
- if (node.node) {
249
- if (Array.isArray(node.node)) {
250
- for (const child of node.node) {
251
- const found = findElement(child);
252
- if (found) return found;
253
- }
254
- } else {
255
- return findElement(node.node);
256
- }
257
- }
258
-
259
- return null;
260
- }
261
-
262
- const element = findElement(xmlObj.hierarchy.node);
263
- if (!element) throw new Error(`Element with text "${text}" not found`);
228
+ // Find element by exact match on text or label
229
+ const element = elements.find(
230
+ el => el.text === text || el.label === text
231
+ );
264
232
 
265
- // 4. Parse bounds: format "[left,top][right,bottom]"
266
- const bounds = element.bounds;
267
- if (!bounds) throw new Error("Element bounds not found");
233
+ if (!element) throw new Error(`Element with text or label "${text}" not found`);
268
234
 
269
- const coords = bounds.match(/\d+/g).map(Number);
270
- if (coords.length !== 4) throw new Error("Invalid bounds format");
235
+ // Calculate center coordinates
236
+ const rect = element.rect;
237
+ const x = Math.floor(rect.x + rect.width / 2);
238
+ const y = Math.floor(rect.y + rect.height / 2);
271
239
 
272
- const [left, top, right, bottom] = coords;
273
- const x = Math.floor((left + right) / 2);
274
- const y = Math.floor((top + bottom) / 2);
275
-
276
- // 5. Tap via adb
277
- try {
278
- execSync(`adb shell input tap ${x} ${y}`);
279
- } catch (e) {
280
- throw new Error("Failed to perform tap via adb");
281
- }
240
+ // Execute adb tap
241
+ const { execSync } = require("child_process");
242
+ execSync(`adb shell input tap ${x} ${y}`);
282
243
 
283
- return `Tapped element with text "${text}" at (${x},${y})`;
244
+ return `Tapped element with text/label "${text}" at (${x},${y})`;
284
245
  }
285
246
  );
286
247
  // async check for latest agent version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "2.0.9",
3
+ "version": "2.0.11",
4
4
  "description": "Appium MCP",
5
5
  "engines": {
6
6
  "node": ">=18"