Midscene.js 实战指南:4 个场景跑通 AI 视觉 UI 自动化
2026/9/11 16:54:25 网站建设 项目流程

Midscene.js 实战指南:4 个场景跑通 AI 视觉 UI 自动化

【免费下载链接】midsceneGUI Agent for E2E Testing项目地址: https://gitcode.com/GitHub_Trending/mid/midscene

Midscene.js 是一套 AI 视觉 UI 自动化框架,用 VLM 读截图直接驱动 Web、Android、iOS 和桌面端,不依赖 DOM 定位器。先说个真实痛点:一次 A/B 实验把弹窗的 class 前缀改了,整条基于 CSS 选择器的回归流水线红了一半,而弹窗本身没有任何行为变化。视觉路线的价值就在这——它看的是"屏幕上有什么",不是"源码里叫什么名字"。

五分钟:跑通你的第一次视觉自动化

装 CLI、配模型环境变量、写一个 8 行的 YAML,一条命令就能跑起来。CLI 要求 Node 20.19+ / 22.12+ / 24+。

npm i -g @midscene/cli
MIDSCENE_MODEL_BASE_URL="https://你的模型服务地址/v1" MIDSCENE_MODEL_API_KEY="你的API_KEY" MIDSCENE_MODEL_NAME="模型名称" MIDSCENE_MODEL_FAMILY="模型系列"
page: url: https://example.com tasks: - name: 冒烟 flow: - ai: 点击页面上的"登录"入口 - sleep: 2000 - aiAssert: 页面出现了用户名输入框
midscene ./smoke.yaml

跑完终端输出进度,./midscene_run/output下会生成一份 HTML 报告,每个步骤带截图和模型决策过程,后面"调试"一节会细讲。

它到底怎么"看懂"屏幕的?——从截图到操作的内部链路

每一步视觉任务的执行链路固定为四步,没有第五步:

  1. 截屏:按当前平台适配器抓一帧当前画面,归一化尺寸后作为输入;
  2. 模型理解:把"任务指令 + 截图"发给 VLM(视觉语言模型),返回目标元素坐标或结构化数据,复杂指令会先规划成多步子任务;
  3. 执行动作:坐标交给平台驱动层——Web 走 CDP 注入点击、移动端走input tap、桌面走系统输入事件;
  4. 验证回环aiAssert/ 下一步的截屏对比确认状态变化,不满足就按错误类型回退重试。

这条链路的核心实现在 packages/core/src/agent/,各平台只是替换了"截图"和"执行动作"两个端点,中间的理解层完全复用。所以同一句自然语言指令,在 Web 和 Android 上能触发几乎相同的决策。

能力边界:多端适配架构一览

同一套 Agent API,五个平台各自有独立适配器,底层驱动技术不同,选型时先确认你的端在这里面:

平台适配器包底层技术
Web(Puppeteer / Playwright)packages/web-integration/CDP 注入点击输入,另支持 Chrome 扩展 Bridge 模式接管你正在用的桌面浏览器
Androidpackages/android/adb + scrcpy 屏幕流
iOSpackages/ios/WebDriverAgent + MJPEG 画面
HarmonyOSpackages/harmony/hdc 设备桥
桌面(Win / macOS / Linux)packages/computer/原生输入驱动,RDP 可接管远程 Windows 桌面

注意两点:各端能力不是完全对齐的(比如 XPath 定位缓存目前只在 Web 生效);移动端要先把设备接好——Android 走 USB 调试,iOS 要先起 WebDriverAgent,这部分前置成本比 Web 高不少。

三个生产级场景

场景一:CI 流水线中的跨端冒烟验证

YAML 天然适合当 CI 的"契约文件":一份脚本同时描述 Web 和 App 的关键路径,每次合入都跑。

page: url: https://staging.example.com tasks: - name: 登录主链路 flow: - ai: 打开登录页,使用测试账号完成登录 - aiAssert: 顶部出现用户头像 - name: 核心页可达 flow: - ai: 进入"订单"页面 - aiAssert: 订单列表区域可见,没有报错弹窗
midscene ./ci-smoke.yaml # 产出 ./midscene_run/output 报告

适用条件:主链路步骤少而关键(登录、下单、核心页可达),容忍单步 2~5 秒的模型耗时;不适合用来替代细粒度的断言密集型用例集。

场景二:竞品页面定时巡检与数据抽取

把"看页面"变成结构化数据源,cron 定时跑,抽取结果落盘供对比。

import { PuppeteerPageAgent } from '@midscene/web'; const browser = await import('puppeteer').then(m => m.default.launch({ headless: true })); const page = await (await browser.newPage()).goto('https://competitor.example.com/hot'); const agent = new PuppeteerPageAgent(page); const rows = await agent.aiQuery( '抓取前 10 个商品,返回 JSON: {name: string, price: number, tag: string}[]' ); await page.screenshot({ path: `patrol-${Date.now()}.png` }); await browser.close(); console.log(JSON.stringify(rows, null, 2));

适用条件:页面结构多变、写选择器维护成本高于直接抽数据;数据量小(一次几个字段)、对成本不敏感。大规模高频抓取请先算模型账单,或只对"疑似有变化"的页面触发抽取。

场景三:与 Playwright 混合驱动的存量测试迁移

不用推倒重来:Playwright 负责它擅长的确定步骤,Midscene 负责定位器容易碎的动态部分。

// @playwright/test 用例内 import { PlaywrightAiFixture } from '@midscene/web'; test('登录流程', async ({ page, ai, aiQuery }) => { await page.goto('https://app.example.com/login'); await ai('在账号框输入 test@example.com,密码框输入正确密码,点击登录'); const banner = await aiQuery('当前页面顶部 banner 的文案', { schema: { type: 'object', properties: { text: { type: 'string' } } }, }); expect(banner.text).toMatch(/欢迎|Hello/); });

适用条件:存量 Playwright 用例中"动态 UI 步骤"占比 20%~50%——全是静态元素就别引入,全在频繁变的组件上收益最大。迁移节奏建议按页面逐个替换,别一次性全切。

别急着上生产:让脚本真正可靠的 5 个工程实践

  1. 重试前先做幂等检查——按钮可能已经点掉了,别对着旧截图盲重试。
async function tapIfPresent(agent, desc) { if (!(await agent.aiBoolean(`${desc} 按钮可见`))) return false; await agent.aiTap(desc); return true; }
  1. 生产用只读缓存,别边跑边写——官方文档给的效果示例:同一脚本缓存命中后从 51 秒降到 28 秒,写入时机要自己控制。

const agent = new PuppeteerPageAgent(page, { cache: { strategy: 'read-only', id: 'smoke-login' }, }); // 本地验证通过后,再手动 agent.flushCache() 写回缓存
  1. 模型按任务复杂度分级——简单断言走便宜快的模型,复杂规划走更强的;不同任务创建 Agent 时传入不同模型配置即可。
const fast = new PuppeteerPageAgent(page, { model: { name: '小模型', family: '对应系列' } }); const smart = new PuppeteerPageAgent(page, { model: { name: '大模型', family: '对应系列' } }); await fast.aiAssert('出现登录成功提示'); // 判断类:小模型 await smart.ai('完成整个注册流程'); // 规划类:大模型
  1. 并发要限流,跑完必回收——多设备并行时限制同时发起的模型请求数,结束时关浏览器和缓存的 agent 实例。
const sem = new Semaphore(4); // 最多 4 个并发模型任务 await Promise.all(targets.map(t => sem.run(() => runCase(t)))); await Promise.allSettled(agents.map(a => a.destroy?.())); await browser.close();
  1. 失败告警与报告归档要挂在流水线钩子上——CLI 跑完自动在./midscene_run/output生成 HTML 报告,把它归档成 artifact、失败时推送链接,比截一堆图发到群里有用得多。
midscene: script: midscene ./ci-smoke.yaml artifacts: when: always paths: [midscene_run/output]

调试不止于看截图:报告系统与 Playground

报告是执行过程自动落盘的,不用额外调接口:report-generator会把每步的截图、prompt、模型返回坐标和耗时写进单文件 HTML。两个关键用法:

  • 本地调试:直接浏览器打开报告,时间轴上能逐步回放"模型看到了什么、点了哪里",配合 Playground 的实时指令面板快速验证措辞;
  • CI 归档:把midscene_run/output作为 artifact 上传,报告文件名按任务名生成,失败时告警里带上 artifact 链接,点开就是完整现场。
artifacts: paths: [midscene_run/output] when: always expire_in: 7 days

报告体积主要由截图数量决定,长任务建议控制sleep时长减少无效帧,而不是删步骤——删了步骤现场就丢了。

生态拼图:MCP 工具暴露与框架集成

先给结论:MCP server 在 v1.10 已下线,官方推荐用Skills + 各平台 CLI让 AI 编程助手直接驱动 Midscene(旧项目可固定 1.9.8 继续用 MCP)。也就是说"让 AI 助手操作你的界面"这件事,现在走 CLI 入口,而不是自建 MCP 服务。v1.9.8 时代的典型工具定义长这样,可以作为你理解暴露面粒度的参照:

{ "name": "tap", "description": "点击描述匹配的界面元素", "inputSchema": { "type": "object", "properties": { "desc": { "type": "string", "description": "元素的自然语言描述" }, "deepLocate": { "type": "boolean", "description": "启用深度定位" } }, "required": ["desc"] } }

和测试框架的集成则以 Playwright fixture 形式内置在 packages/web-integration/src/playwright/,8 行接入:

import { test, expect } from '@playwright/test'; import { PlaywrightAiFixture } from '@midscene/web'; test('混合驱动', async ({ page, ai, aiBoolean }) => { await page.goto('https://app.example.com'); await ai('点击"登录",输入测试账号并登录'); expect(await aiBoolean('已处于登录态')).toBe(true); });

选型决策:什么时候该用 / 什么时候别用

✅ 适合⚠️ 谨慎
动态 UI / Canvas / 频繁改版,定位器维护成本高高并发批量回归(千级用例),模型时延和费用压不住
Web + App + 桌面多端一致性验证,想共用一套语义化用例强确定性、毫秒级时延敏感的关键路径自动化
存量 Playwright/Appium 用例中定位器碎片化严重,想渐进迁移纯静态内部系统,写一次选择器十年不变——直接用传统方案更省
竞品/多站点页面巡检与结构化数据抽取数据抓取规模大、频率高,成本核算没跑通

一句话收束:Midscene.js 解决的是"定位器写不动"的那部分问题,把它当作传统自动化之上的补偿层,而不是全量替换,是目前最稳的姿势。先从一条 CI 冒烟脚本和一份 artifact 报告开始,跑两周再谈规模化。

【免费下载链接】midsceneGUI Agent for E2E Testing项目地址: https://gitcode.com/GitHub_Trending/mid/midscene

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询