mobile-automation — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited mobile-automation (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Mobile MCP + 飞书 MCP 双协作自动化测试专家。
核心能力:
触发关键词:手机自动化、移动端测试、App 测试、mobile_mcp、点击手机、操作手机、执行飞书用例、批量执行、多维表格
┌─────────────────────────────────────────────────────────────┐
│ AI(Windsurf) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 飞书 MCP │ │ Mobile MCP │ │
│ │ │ │ │ │
│ │ • 读取用例 │ │ • 启动App │ │
│ │ • 写入结果 │ │ • 点击元素 │ │
│ │ • 更新状态 │ │ • 输入文本 │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 飞书多维表格 │ │ 手机设备 │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘永远优先使用 `list_elements`,而不是截图!
| 方式 | Token 消耗 | 使用场景 |
|---|---|---|
list_elements | ~500 | ✅ 确认页面状态、查找元素 |
take_screenshot | ~2000 | ❌ 只在需要视觉分析时使用 |
❌ 错误流程:截图 → 分析 → 点击 → 截图确认
✅ 正确流程:list_elements → 点击 → list_elements 确认点击元素时,按以下优先级选择工具:
1️⃣ click_by_text(最稳定,跨设备兼容)
↓ 找不到文本?
2️⃣ click_by_id(需要 resource-id)
↓ 没有 id?
3️⃣ click_by_percent(百分比坐标,跨分辨率)
↓ 复杂场景?
4️⃣ click_at_coords(兜底,需要截图获取坐标)使用 verify 参数减少额外调用:
# ❌ 低效(3次调用)
list_elements()
click_by_text("登录")
list_elements() # 确认
# ✅ 高效(2次调用)
list_elements()
click_by_text("登录", verify="首页") # 自动验证"首页"出现# 标准流程
1. launch_app("com.example.app")
2. wait(2) # 等待启动
3. close_popup() # 自动检测并关闭弹窗(无需先截图)
4. list_elements() # 确认主页面注意:close_popup 会自动检测是否有弹窗,如果没有会直接返回"无弹窗",不会误操作。
# 推荐流程
1. list_elements() # 获取输入框 ID
2. input_text_by_id("username_input", "test123")
3. input_text_by_id("password_input", "password")
4. hide_keyboard() # ⭐ 必须!收起键盘,确保协议复选框可点击
5. click_by_text("我已阅读并同意") # 勾选用户协议
6. click_by_text("登录", verify="首页") # 点击并验证跳转⚠️ 重要:输入密码后键盘可能遮挡协议复选框,必须先调用 hide_keyboard() 收起键盘!
# 元素可能在屏幕外时
max_scrolls = 5
for i in range(max_scrolls):
elements = list_elements()
if "目标文本" in str(elements):
click_by_text("目标文本")
break
swipe("up") # 向上滑动
wait(0.5)
else:
# 滚动到底还没找到
return "未找到目标元素"当页面有多个相同文本的元素时,使用 position 参数:
# 点击上方的"更多"
click_by_text("更多", position="top")
# 点击下方的"确定"
click_by_text("确定", position="bottom")
# 支持的位置:top/bottom/left/right/center# 1. 开始录制
clear_operation_history()
# 2. 执行测试步骤(正常操作)
launch_app("com.example.app")
click_by_text("登录")
input_text_by_id("username", "test")
click_by_text("提交")
# 3. 生成脚本
generate_test_script(
test_name="登录测试",
package_name="com.example.app",
filename="login_test"
)生成的脚本会自动:
| 场景 | 推荐工具 |
|---|---|
| 通用弹窗(权限、广告) | close_popup |
| 广告弹窗 | close_ad |
| 已知模板的 X 按钮 | template_close |
| 需要先确认位置 | find_close_button |
# 如果 close_popup 失败
1. find_close_button() # 获取推荐的点击方式
2. 按返回的 click_command 执行
# 如果还是失败
1. screenshot_with_som() # SoM 标注截图
2. click_by_som(编号) # 点击 X 号对应的编号
# 学习新的 X 按钮模板
template_add(template_name="app_x_button", x_percent=95, y_percent=8, size=60)# 可能原因及解决
1. 文本不完全匹配 → 用 list_elements 确认完整文本
2. 元素在屏幕外 → swipe 滚动后重试
3. 页面未加载完 → wait(1-2秒) 后重试
4. 被弹窗遮挡 → close_popup 后重试# 检查连接
check_connection()
# 如果断开,提示用户:
# Android: adb devices / adb kill-server && adb start-server
# iOS: tidevice list / 重启 WebDriverAgent# 可能是元素 clickable=false,尝试:
1. 点击父元素
2. 使用坐标点击
3. 长按后操作# 正确流程(必须先监听)
1. start_toast_watch() # 开始监听
2. click_by_text("提交") # 触发 Toast 的操作
3. assert_toast("提交成功") # 验证 Toast 内容
# ❌ 错误:操作后才监听,会错过 Toast执行操作前,确认:
list_elements 而不是截图确认页面click_by_text,其次 click_by_idverify 参数减少确认调用close_popup 处理弹窗start_toast_watchclear_operation_historylist_elements - 📋 列出元素(首选)take_screenshot - 📸 截图(token 高)screenshot_with_som - 📸 SoM 标注截图get_screen_size - 📐 屏幕尺寸click_by_text - 👆 文本点击(推荐)click_by_id - 👆 ID 点击click_by_percent - 👆 百分比点击click_by_som - 👆 SoM 编号点击click_at_coords - 👆 坐标点击(兜底)long_press_by_text - 👆 文本长按long_press_by_id - 👆 ID 长按long_press_by_percent - 👆 百分比长按long_press_at_coords - 👆 坐标长按input_text_by_id - ⌨️ ID 输入input_at_coords - ⌨️ 坐标输入swipe - 👆 滑动(up/down/left/right)press_key - ⌨️ 按键(home/back/enter)hide_keyboard - ⌨️ 收起键盘(⭐ 登录场景必备)wait - ⏰ 等待launch_app - 🚀 启动应用terminate_app - ⏹️ 终止应用list_apps - 📦 列出应用close_popup - 🚫 智能关闭弹窗close_ad - 🚫 关闭广告find_close_button - 🔍 查找关闭按钮template_close - 🎯 模板匹配关闭assert_text - ✅ 断言文本存在assert_toast - ✅ 断言 Toast 内容clear_operation_history - 🗑️ 清空历史get_operation_history - 📜 获取历史generate_test_script - 📝 生成 pytest 脚本当用户说"执行 xxx.yaml"时,按以下规则执行:
config:
app_package: com.example.app # App 包名
cases:
- name: 用例名称
setup: launch_app # 可选:启动方式
steps:
- 等待2秒
- 点击登录
verify: 首页 # 可选:验证页面包含该文本| setup 值 | 执行动作 |
|---|---|
launch_app | 先 terminate_app 杀掉App,再 launch_app 启动(确保干净状态) |
none 或不填 | 不做任何启动操作,继续当前页面 |
| 自然语言步骤 | 对应工具调用 |
|---|---|
| 等待N秒 | wait(N) |
| 关闭弹窗 | 检测后 close_popup() |
| 点击XXX | click_by_text("XXX") |
| 在XXX输入YYY | input_text_by_id("XXX", "YYY") |
| 向上/下滑动 | swipe("up/down") |
| 按返回键 | press_key("back") |
| 收起键盘 | hide_keyboard() |
| 勾选协议/勾选用户协议 | hide_keyboard() + click_by_text("协议文本") |
| 开始监听Toast | start_toast_watch() |
| 验证Toast包含XXX | assert_toast("XXX") |
当 MCP 工具返回 fallback=vision 时:
screenshot_with_som 获取 SoM 截图click_by_som(编号) 点击close_popup 后重试当用户说"执行飞书用例"或"继续执行飞书用例"时,按以下规则执行:
| 工具 | 用途 | 示例 |
|---|---|---|
bitable_v1_appTableRecord_search | 查询用例 | 读取待执行的用例 |
bitable_v1_appTableRecord_update | 更新记录 | 回写执行结果 |
bitable_v1_appTableRecord_create | 创建记录 | 新增用例 |
bitable_v1_appTableField_list | 列出字段 | 获取表格结构 |
| 字段 | 类型 | 说明 |
|---|---|---|
| 用例编号 | 数字 | 唯一标识 |
| 用例名称 | 文本 | 用例名称 |
| 预置条件 | 多行文本 | 前置依赖条件(AI理解自然语言) |
| 测试步骤 | 文本 | 自然语言描述的步骤 |
| 预期结果 | 文本 | 期望的最终状态 |
| 验证点 | 多选 | 最终验证内容(可选) |
| 执行结果 | 文本 | PASS / FAIL |
| 失败原因 | 单选/文本 | 失败时的原因 |
尝试1: click_by_text("登录")
↓ 失败
尝试2: list_elements → 找相似文本 → click_by_text
↓ 失败
尝试3: screenshot_with_som → click_by_som(编号)
↓ 失败
尝试4: close_popup() → 重试 click_by_text
↓ 失败
尝试5: take_screenshot → AI分析坐标 → click_at_coords
↓ 失败
━━━ 放弃!标记FAIL,继续下一条用例 ━━━⚠️ 禁止行为:
| 失败场景 | 失败原因 |
|---|---|
| 元素找不到 | 元素未找到: {文本} |
| 视觉识别失败 | SoM识别失败 |
| 验证不通过 | 验证失败: 未找到"{验证点}" |
| 超时 | 操作超时 |
| 设备断开 | 设备连接失败 |
执行用例前必须先获取表格Token:
https://xxx.feishu.cn/base/{app_token}?table={table_id}禁止使用占位符,Token缺失时必须询问用户。
如果执行中断:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.