Midscene.js:基于AI视觉的零代码自动化测试与RPA实践指南

📅 2026/7/3 23:03:16 👁️ 阅读次数 📝 编程学习
Midscene.js:基于AI视觉的零代码自动化测试与RPA实践指南

1. 项目概述:当AI视觉遇见零代码自动化

最近在折腾自动化测试和RPA(机器人流程自动化)时,我发现了一个挺有意思的开源项目——Midscene.js。简单来说,它想解决一个自动化领域的老大难问题:我们写的那些基于DOM元素选择器(比如XPath、CSS Selector)的脚本,为什么总是那么脆弱?页面结构稍微一改,比如开发把某个按钮的classbtn-primary改成了btn-submit,或者把div换成了button,我们的自动化脚本就立刻“瞎了”,报错找不到元素。维护成本高得吓人,测试同学和开发同学经常为此“友好交流”。

Midscene.js提出了一条截然不同的思路:既然人是通过眼睛看屏幕来操作电脑和手机的,那为什么不让AI也“看”着屏幕来操作呢?它本质上是一个视觉驱动的UI自动化SDK。你不用再写繁琐的选择器去定位一个按钮,你只需要像告诉一个新手同事那样,用自然语言描述你想做什么,比如“点击那个蓝色的登录按钮”,或者“在搜索框里输入‘测试数据’并回车”。Midscene.js会利用多模态大模型(就是既能理解文字又能看懂图片的AI)去“看”当前屏幕的截图,理解你的指令,然后模拟鼠标或触摸事件去执行操作。

更吸引人的是,它打出了“零代码”和“跨平台”两张牌。这意味着,哪怕你完全不懂编程,理论上也能通过类似录制回放或填写YAML配置文件的方式,创建自动化流程。而且,它宣称能覆盖Web浏览器、Android、iOS、HarmonyOS乃至Windows/macOS桌面应用,野心不小。这让我这个被各种平台专用API和框架折磨过的老手,产生了强烈的好奇心。它到底是怎么做到的?实际用起来是“神器”还是“玩具”?这篇指南,我就结合自己的实操和踩坑经验,带你彻底拆解Midscene.js。

2. 核心原理深度拆解:视觉驱动如何颠覆传统自动化

要理解Midscene.js的价值,得先看看我们过去是怎么做自动化的。传统UI自动化,无论是Selenium、Playwright还是Appium,核心逻辑都是基于UI元素的结构化信息

2.1 传统自动化:与“代码结构”绑定的脆弱链条

以Web自动化为例,我们通常这样定位一个元素:

// 使用Playwright await page.click('button#submit'); // 或使用XPath await page.click('//button[contains(text(), "登录")]');

这种方式高度依赖前端代码生成的DOM树。它的优势是精准、快速。但缺点同样致命:

  1. 极度脆弱:前端任何微小的重构(ID变更、类名修改、标签替换、组件库升级)都可能导致选择器失效。
  2. 覆盖不全:对于<canvas>绘制的游戏界面、复杂图表,或者没有无障碍标签的纯图标按钮,DOM里根本没有可定位的节点。
  3. 跨域隔离:浏览器出于安全考虑,禁止主页面脚本直接访问<iframe>(尤其是跨域iframe)内部的DOM,这让自动化操作iframe内容变得异常困难。
  4. 原生应用适配:虽然Appium等工具提供了访问Android/iOS原生控件树的能力,但不同应用、不同版本的控件结构千差万别,脚本通用性差。

注意:这里说的“脆弱”是工程上的概念。一次成功的产品迭代可能涉及几十上百个页面的改动,对应的自动化测试脚本维护起来就像一场永无止境的“打地鼠”游戏。

2.2 Midscene.js的视觉驱动:模拟人类“所见即所得”

Midscene.js跳出了这个框框。它的工作流程可以概括为:截图 -> AI分析 -> 坐标计算 -> 模拟操作

  1. 截图:首先,Midscene.js会获取目标界面(浏览器窗口、手机屏幕、应用窗口)的当前画面,生成一张截图。
  2. AI分析(核心):将这张截图和你用自然语言描述的指令(例如:“点击登录按钮”)一起,发送给一个多模态大模型。这个模型经过海量图文数据训练,能够像人一样理解图片内容,并找出图中与“登录按钮”语义最匹配的视觉区域。
  3. 坐标计算:模型会返回一个或多个目标区域的边界框坐标。Midscene.js拿到坐标后,会计算出该区域的中心点。
  4. 模拟操作:最后,它通过底层驱动(如Playwright、Appium、或系统级的输入模拟库)在这个坐标点上执行点击、输入等操作。

这个过程完全不依赖应用内部的任何代码结构,只依赖于屏幕上的像素信息。只要这个按钮在屏幕上看起来像个按钮,并且人能认出来,AI大概率也能认出来。

2.3 技术栈与模型选型:引擎盖下有什么

Midscene.js不是一个“AI模型”,而是一个编排框架。它负责截图、调用模型API、解析结果、执行操作这一整套流水线。其核心能力来源于集成的多模态大模型。

根据其官方文档,它支持多种模型,主要分为两类:

  • 云端大模型API:如Google的Gemini系列、DeepSeek-V2等。这些模型能力强大,识别准确率高,但需要网络调用,可能产生费用,且涉及数据出海的隐私考量。
  • 可本地部署的开源模型:如Qwen-VL、GLM-4V、UI-TARS等。这是Midscene.js的一大亮点,你可以在自己的服务器或甚至本地电脑上部署这些模型,实现完全离线的、数据私有的自动化。这对于企业内网环境或对数据安全要求高的场景至关重要。

实操心得:模型的选择是平衡成本、速度和精度的艺术。对于快速原型验证,可以用免费的Gemini API配额;对于稳定生产环境,尤其是涉及敏感数据的操作,自建开源模型服务是更稳妥的选择。UI-TARS是专门为UI理解任务训练的模型,在按钮、图标、文本输入框等元素的识别上表现往往比通用模型更精准。

3. 环境搭建与快速入门:从零到第一个自动化脚本

理论讲再多不如动手试一下。我们以最常见的Web浏览器自动化为例,走通一个完整的“Hello World”流程。

3.1 基础环境准备

Midscene.js是一个Node.js库,所以首先确保你的系统已经安装了Node.js(建议版本18或以上)和npm/yarn/pnpm等包管理器。

  1. 创建项目并初始化

    mkdir midscene-demo && cd midscene-demo npm init -y
  2. 安装核心依赖

    npm install midscene

    这里安装的是Midscene.js的核心SDK。它本身不包含浏览器驱动,我们需要额外安装Playwright(Midscene官方推荐并深度集成)来操控浏览器。

    npx playwright install chromium npm install @playwright/test

    Playwright会下载一个无头Chromium浏览器,用于后续的自动化操作。

3.2 配置AI模型(关键一步)

这是与传统自动化工具最大的不同点。你需要一个“眼睛”来看图。我们以使用通义千问(Qwen)的开放API为例,因为它对中文指令的理解通常更好。

  1. 获取API Key:前往阿里云灵积平台,开通并获取Qwen系列模型(如qwen-plusqwen-vl-plus)的API Key。
  2. 在项目中配置环境变量:创建一个.env文件在项目根目录(注意不要提交到Git)。
    # .env MIDSCENE_MODEL_PROVIDER=qwen QWEN_API_KEY=你的实际API密钥 # 指定使用视觉模型 MIDSCENE_MODEL_NAME=qwen-vl-plus
    你也可以在代码中直接配置,但环境变量更安全、灵活。

3.3 编写第一个视觉自动化脚本

现在,我们来写一个脚本,让AI自动打开百度,在搜索框输入“Midscene.js”,并点击搜索按钮。

// demo.js import { chromium } from 'playwright'; import { MidsceneWeb } from 'midscene'; async function runDemo() { // 1. 启动一个真实的浏览器 const browser = await chromium.launch({ headless: false // 设置为true则无头运行,不显示界面 }); const context = await browser.newContext(); const page = await context.newPage(); // 2. 创建Midscene代理,并关联到当前页面 const agent = new MidsceneWeb({ page }); // 如果你的模型配置不在环境变量里,可以在这里传入 // const agent = new MidsceneWeb({ page, modelConfig: { provider: 'qwen', apiKey: 'xxx' } }); try { // 3. 导航到目标页面 await page.goto('https://www.baidu.com'); // 等待页面基本加载完成 await page.waitForLoadState('networkidle'); // 4. 使用自然语言指令驱动AI操作 console.log('正在让AI识别搜索框并输入...'); // aiAct: 让AI自主规划并执行一个动作 await agent.aiAct('在页面的搜索框里输入文字“Midscene.js”'); console.log('正在让AI识别“百度一下”按钮并点击...'); await agent.aiAct('点击“百度一下”按钮'); // 5. 等待搜索结果加载 await page.waitForTimeout(3000); // 简单等待,生产环境应用更智能的等待逻辑 console.log('自动化操作完成!当前页面标题:', await page.title()); } catch (error) { console.error('自动化过程出错:', error); } finally { // 6. 关闭浏览器,释放资源 await browser.close(); } } runDemo();

代码解读与注意事项

  • MidsceneWeb是专门用于Web浏览器的代理类,它封装了与Playwright页面的交互。
  • aiAct方法是核心,你只需要用一句人话告诉它做什么。AI会自己去截图、分析、定位、操作。
  • 脚本中headless: false让你能看到浏览器的操作过程,非常适合调试。在生产环境或CI/CD中,应设为true以提高性能。
  • page.waitForTimeout是简单的固定等待,在实际项目中,建议结合aiAssert(AI断言页面状态)或Playwright的等待选择器来确保操作稳定性。

运行这个脚本:

node demo.js

你会看到一个浏览器窗口自动打开,访问百度,输入文字,点击搜索。整个过程,你没有写一行关于#kw#su这样的选择器代码。

4. 核心API与高级用法:从“能用”到“好用”

掌握了基础操作后,我们来深入看看Midscene.js提供的核心API,它们能帮你构建更复杂、更健壮的自动化流程。

4.1 核心三剑客:aiAct, aiQuery, aiAssert

Midscene.js的API设计非常简洁,核心就是三个方法,覆盖了自动化操作的“执行、查询、断言”三大场景。

  1. aiAct(instruction: string):执行动作这是最常用的方法,用于执行一个操作。指令越清晰,成功率越高。

    // 好的指令:具体、包含关键标识 await agent.aiAct('点击顶部导航栏中红色的“发布文章”按钮'); await agent.aiAct('在用户名输入框里输入“test_user”'); await agent.aiAct('向下滚动直到看到“加载更多”按钮,然后点击它'); // 模糊的指令(尽量避免): // await agent.aiAct('点击那个按钮'); // 哪个按钮?
  2. aiQuery<T>(instruction: string): Promise<T>:查询信息当你需要从页面上提取信息时使用。你需要指定期望返回的类型。

    // 查询商品价格列表,返回数字数组 const prices: number[] = await agent.aiQuery('number[], 当前页面所有商品的价格'); console.log(prices); // 例如 [29.9, 45.5, 12.0] // 查询第一条新闻的标题,返回字符串 const firstNewsTitle: string = await agent.aiQuery('string, 列表第一条新闻的标题文字'); // 查询“登录”按钮是否存在且可见,返回布尔值 const isLoginButtonVisible: boolean = await agent.aiQuery('boolean, “登录”按钮是否在屏幕上可见');

    aiQuery非常强大,它让AI成为了你的“信息提取器”,可以处理那些用传统方法很难抓取的非结构化数据。

  3. aiAssert(condition: string): Promise<void>:视觉断言传统的断言检查DOM属性或文本内容。aiAssert进行的是视觉断言,检查的是“看起来”是否正确。

    // 断言登录成功后,页面出现了用户的头像 await agent.aiAssert('页面右上角显示了用户的头像图片'); // 断言错误提示信息以红色字体显示 await agent.aiAssert('“密码错误”的提示信息是红色的'); // 断言进度条已经走到了100% await agent.aiAssert('进度条已经充满,显示为100%完成状态');

    这对于验证UI样式、布局、动态效果是否符合预期特别有用,是传统自动化测试的盲区。

4.2 工作流风格:混合AI与逻辑控制

完全依赖AI一步规划(aiAct)虽然简单,但对于复杂、多分支的逻辑,可能不够稳定或成本高昂。Midscene.js鼓励工作流风格:用AI完成识别和定位,用传统编程逻辑控制流程。

// 示例:自动化清理一个TODO列表,只删除标记为“已完成”的项目 async function cleanupCompletedTodos(agent) { // 1. 让AI识别出所有TODO项的文本列表 const todoItems: string[] = await agent.aiQuery('string[], 列表中的所有待办事项文本'); for (const itemText of todoItems) { // 2. 针对每一项,让AI判断是否显示为“已完成”状态(例如,前面有勾选图标或文字被划掉) const isCompleted: boolean = await agent.aiBoolean(`布尔值,文本为“${itemText}”的条目是否显示为已完成状态(如有勾选图标或删除线)`); if (isCompleted) { // 3. 如果已完成,让AI找到该条目旁边的“删除”按钮或图标并点击 await agent.aiAct(`找到文本是“${itemText}”的那一行,点击它右边的删除图标(垃圾桶图标)`); // 4. 确认删除弹窗并点击确定 await page.waitForTimeout(500); // 等待弹窗动画 await agent.aiAct('点击弹窗中的“确定”或“删除”按钮'); } } }

这种模式结合了AI的灵活性和程序逻辑的精确性,是构建可靠生产级自动化脚本的推荐方式。

4.3 跨平台实战:不止于Web

Midscene.js的野心在于“一处编写,多处运行”。其架构通过不同的Agent类来适配不同平台。

  • Android/iOS:底层依赖scrcpy(屏幕镜像)和appium/WebDriverAgent(输入注入)来获取屏幕和控制设备。你需要先配置好相应的开发环境。
    import { MidsceneAndroid } from 'midscene'; // 连接设备后 const agent = new MidsceneAndroid({ deviceSerial: 'your_device_id' }); await agent.aiAct('打开微信应用'); await agent.aiAct('点击右下角的“我”选项卡');
  • 桌面应用(Windows/macOS):通过截取特定窗口的屏幕,并模拟全局鼠标键盘事件来实现。这需要对系统API有一定调用能力。
  • HarmonyOS:原理与移动端类似,提供了专门的集成方案。
  • 自定义界面:你可以实现一个简单的ScreenProviderInputProvider接口,将任何能截图和接收输入指令的系统接入Midscene.js,比如自动化操作一台工业触摸屏设备。

重要提示:跨平台功能虽然强大,但每个平台的配置复杂度不同。移动端需要开启开发者选项和USB调试,桌面端需要处理窗口权限。初次搭建环境可能会遇到一些挑战,建议从Web端开始,熟悉后再拓展到其他平台。

5. 零代码与YAML自动化:为非开发者打开大门

“零代码”是Midscene.js宣传的一大亮点。它主要通过两种方式实现:

5.1 Chrome浏览器插件(最快捷的体验)

Midscene提供了Chrome插件,安装后,你可以在任何网页上直接录制操作。插件会记录你的自然语言指令和对应的屏幕区域,并生成可回放的YAML脚本。这对于产品经理、测试人员快速创建演示或简单测试用例非常友好。你无需安装Node.js或任何IDE,在浏览器里就能完成自动化流程的搭建。

5.2 YAML脚本运行器

对于更复杂、需要版本控制和调度的自动化流程,Midscene.js支持用YAML文件来定义工作流。YAML格式对人类可读,易于编写和维护。

# search_and_save.yaml name: "百度搜索并截图保存" steps: - name: "打开百度首页" act: "打开浏览器,访问 https://www.baidu.com" # 这里可能需要一个特定的“打开浏览器”技能或前置步骤 - name: "输入搜索词" act: "在搜索框输入‘人工智能最新进展’" - name: "执行搜索" act: "点击‘百度一下’按钮" - name: "等待结果" wait: 2s # 等待2秒 - name: "断言结果" assert: "页面中出现了与‘人工智能’相关的搜索结果列表" - name: "保存截图" # 这是一个预定义的“技能”(Skill),Midscene或社区可能提供 skill: "page.screenshot" args: path: "./search_result.png"

然后,你可以使用Midscene CLI来运行这个YAML脚本:

npx midscene run ./search_and_save.yaml

YAML的方式将自动化逻辑和运行环境(JavaScript代码)解耦,使得业务人员也能参与编写自动化用例。

6. 常见问题、局限性与优化策略实录

在实际项目中使用Midscene.js几周后,我记录下了一些典型问题和应对策略。

6.1 识别准确率与稳定性问题

问题:AI模型毕竟不是人,有时会“看错”。比如把“登录”按钮识别成“注册”按钮,或者在元素密集区域点击位置偏移。对策

  1. 优化指令:指令要尽可能唯一、具体。用“点击第二行第三个蓝色的‘提交’按钮”代替“点击提交按钮”。利用页面上的其他视觉元素作为参照物。
  2. 区域限定aiActaiQuery方法可以传入一个region参数,指定只对屏幕的某一部分进行分析,减少干扰。
    await agent.aiAct('点击登录按钮', { region: { x: 100, y: 200, width: 400, height: 300 } // 只在这个矩形区域内查找 });
  3. 混合定位:对于极其重要且稳定的元素,可以回退到传统选择器进行辅助定位,或者先用AI找到大致区域,再用精确坐标微调。
  4. 重试与降级:在关键步骤后加入aiAssert进行验证,如果失败则加入指数退避的重试机制,或记录日志转人工处理。

6.2 执行速度与成本考量

问题:每次调用AI模型进行截图分析,相比直接操作DOM,延迟要高得多(从几百毫秒到几秒不等)。使用云端API还可能产生费用。对策

  1. 缓存策略:Midscene.js支持缓存AI的规划结果。对于静态或变化不大的界面,相同的指令可以复用之前的定位结果,大幅提升速度。
  2. 本地模型:对于速度敏感或长期运行的自动化任务,部署如Qwen-VL这样的开源模型到本地GPU服务器是终极方案。初期投入大,但长期成本低、延迟稳定。
  3. 减少不必要的调用:不要每一步都用aiAct。在已知页面结构稳定处,用传统方法快速跳转;只在需要视觉识别的关键节点调用AI。

6.3 动态内容与等待机制

问题:现代Web应用大量使用异步加载和动画。刚截图时按钮还没出现,AI自然找不到。对策

  1. 主动等待:在aiAct前,使用Playwright的等待机制确保元素加载。
    // 先等某个加载动画消失 await page.waitForSelector('.loading-spinner', { state: 'hidden' }); // 再让AI操作 await agent.aiAct('点击新出现的‘确认’按钮');
  2. 智能轮询:可以封装一个辅助函数,在超时时间内循环进行aiQueryaiAssert,直到条件满足。
    async function waitForAI(agent, condition, timeout = 10000) { const startTime = Date.now(); while (Date.now() - startTime < timeout) { try { await agent.aiAssert(condition); return; // 条件满足,退出 } catch (e) { await page.waitForTimeout(500); // 等待500ms再试 } } throw new Error(`等待条件"${condition}"超时`); } await waitForAI(agent, '“提交成功”的绿色提示框已经出现');

6.4 报告与调试

问题:自动化失败了,怎么知道AI“看”到了什么,又为什么做错了?对策:Midscene.js在每次运行后,默认会生成一份可视化的HTML报告。这份报告会包含每一步的屏幕截图、AI接收到的指令、AI返回的识别区域(通常用红框标出)、以及执行结果。这是调试视觉自动化脚本不可或缺的工具。务必在CI/CD流水线中保存并归档这些报告。

7. 适用场景与未来展望

经过一番深度体验,我认为Midscene.js在以下场景具有独特优势:

  1. 跨平台、跨技术栈的端到端测试:你的产品有Web、小程序、iOS/Android App、桌面客户端?用Midscene.js可以尝试用一套基于自然语言的用例描述,覆盖所有平台的核心流程测试。
  2. 对Canvas、游戏、三维应用进行自动化:这些领域传统自动化工具几乎无能为力,而视觉驱动是唯一的出路。
  3. 快速原型和演示制作:产品经理想演示一个尚未开发的功能流程?可以用Midscene.js快速“模拟”出来。
  4. 遗留系统或无法注入代码的系统的自动化:面对那些没有API、没有测试钩子、甚至代码都找不到的古老黑盒系统,视觉自动化可能是实现自动化的唯一途径。
  5. RPA(机器人流程自动化):处理需要人工判断屏幕内容的重复性办公任务,如从不同格式的邮件或报表中提取信息并填入系统。

当然,它并非银弹。对于追求极致执行速度、操作逻辑极其固定、界面元素高度结构化的场景,传统的基于选择器的自动化框架(如Playwright, Cypress)仍然是更成熟、更快速、更稳定的选择。

我个人在实际操作中的体会是,Midscene.js代表了UI自动化测试的一个新范式。它把测试脚本的维护负担,从“紧跟代码结构变化”部分转移到了“优化自然语言指令和AI模型调优”上。初期学习成本和调试成本可能更高,但长期来看,对于界面频繁迭代、或涉及复杂视觉验证的项目,它可能带来更高的投资回报率。它的成熟度还在快速演进中,开源社区和背后的团队正在积极开发。如果你正在为脆弱的UI自动化脚本而头疼,或者有一个用传统方法难以自动化的场景,花一个下午时间试试Midscene.js,它很可能会给你带来惊喜。至少,它让我重新思考了“自动化”的边界——原来,让机器“看见”并理解界面,已经是一件触手可及的事情。