迅速介绍

midScene.js是“视觉模型驱动,支持全平台的 UI 自动化 SDK” 官方文档:https://midscenejs.com/zh/introduction.html

简单点说就是,你随便说点啥,他就能自己截屏自己去执行你文本描述的自动化步骤

使用 AI 模型驱动 UI 自动化的有两个关键点:规划合理的操作路径,以及准确找到需要交互的元素。其中“元素定位”能力的强弱,会直接影响到自动化任务的成功率。

为了完成元素定位工作,UI 自动化框架一般有两种技术路线:

  • 基于 DOM + 截图标注:提前提取页面的 DOM 结构,结合截图做好标注,请模型“挑选”其中的内容。
  • 纯视觉:利用模型的视觉定位能力,基于截图完成所有分析工作,即模型收到的只有图片没有 DOM也没有标注信息。那也就是说,该框架是完完全全和传统selenium是不同的,使用此框架必须得放弃传统的DOM自动化的思路,不管是从封装还是设计模式上

优缺点

吧啦半天,直接说优缺点

优点:

1.前端改动不用再去维护Xpath,Css这种传统路径的DOM自动化,基于纯视觉更省事儿

2.书写非常方便,配置也非常简单,只需要视觉大模型+yaml就能写,不需要写啥代码

3.可以通过插件驱动自己的浏览器,免登录,用selenium写过驱动自己的浏览器的朋友应该知道,配置有多麻烦

缺点:费钱,视觉大模型要比纯文本大模型花的token更多,什么时候图像识别也能便宜点就好了

案例展示

大模型环境配置文件.env

提前准备好视觉大模型,官网推荐豆包Doubao-Seed-1.6-Vision、qwen3-vl-plus、GLM-4.6V,我综合使用下来,qwen3-vl-plus是最不墨迹的,详情可以看midScene官网评测

所以准备好qwen3-vl-plus的配置(由于写本篇文章,qwen3.5还没有出来,现在更推荐qwen3.5)

https://midscenejs.com/zh/model-common-config.html#qwen35

MIDSCENE_MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MIDSCENE_MODEL_API_KEY="sk-a4f203cd7手动打码ba5291d846"  为什么打码,因为我充钱了
MIDSCENE_MODEL_NAME="qwen3-vl-plus"
MIDSCENE_MODEL_FAMILY="qwen3-vl"

新建.env文件,把上面配置存进去

配置文件config.yaml

环境文件同级目录新建config.yaml,写入

# Example batch execution index YAML file
# This demonstrates how to use the multi-YAML file batch execution feature

# Concurrency settings (default: 1 for sequential execution)
concurrent: 1

# Continue execution even if one file fails (default: false)
continueOnError: false

# Summary output file
summary: "./midscene_run/output/custom-summary.json"

# Global web environment configuration (applied to all files)
web:
  # All individual YAML files will inherit these settings
  # viewportWidth: 1280
  # viewportHeight: 720
  # bridgeMode: "newTabWithUrl"
  # Output directory for individual files (will be combined with file-specific paths)

# Execution order using glob patterns
files:
  - "yamlTest.yaml"

Yaml测试用例文件

然后就是书写步骤的环节了,这里我拿一个实际的应用场景:

1.输入xcid,然后搜索,

2.搜索完后筛选记录。

3.打开记录,找到调用日志

4.然后点击调用日志跳转,检查跳转后的页面是否正常

这里面的步骤涉及到:输入、搜索、滚动、筛选、页面跳转、文本校验(视觉校验)基本涵盖UI自动化的大部分步骤

最后新建yamlTest.yaml,输入下面内容,并把三个文件放在同级目录即可,下面是第一版本的yaml测试用例

web:
  url: http://implusreport.site.fat46.qa.nt.ctripcorp.com/managesite/index/callDetailQuery?tab=CTRIP&selBUId=-1&selLanguageList=&selCallSkillGroupType=0&selSkillGroupList=&selPhoneType=-1
  bridgeMode: newTabWithUrl
  closeNewTabsAfterDisconnect: true

agent:
  cache:
    id: "my-cache-test"
    strategy: "read-write"

tasks:
  # - name: 登陆
  #   flow:
  #     - aiAct: 点击账号登录
  #     - aiAct: 在域账户名输入框里面输入"shuai_w"
  #     - aiAct: 在密码输入框里面输入"Phaseless1"
  #     - aiAct: 点击登录按钮
  #     - sleep: 10000

  - name: 搜索xcid并校验样式和查询结果
    flow:
      - aiAct: 在电话标识搜索框输入 "0bb9bb91f17706371174EXCIDEND",然后点击右边的搜索(放大镜样式)按钮
      - aiAct: 点击"筛选"文字右边的漏斗按钮,弹窗出现后通话方向单选项选择呼入,通话状态单选项选择接通,点击查询
      - aiAssert: 检查前端页面筛选按钮右边出现"通话方向:呼入、接通状态:接通的文字"样式
      - aiAct: 点击107608861452641263085,等弹窗出现后,然后点击服务详情,服务详情内容区域滚动到最底部,点击IVR流程调用右边的"调用日志"按钮
      - sleep: 10000
      - aiAssert: 检查新弹出的页面左上角是否有"basebiz-aigateway-api-topic.ck"文字

由于可以通过桥接模式实现免登录操作,这里面我就把登陆部分注解掉了,如果想模拟新用户可以打开,并注释掉上面的桥接模式,运行完后,可以在report目录打开

完整过程请看VCR

没有缓存执行下来非常非常慢,虽然很精确没有出错啊,这个时候我们来看看花费了多少tokens

再来看下qwen3-vl-plus价格

https://bailian.console.aliyun.com/cn-beijing/?tab=model#/model-market/detail/qwen3-vl-plus

我们可以粗略估算一下这个 YAML 一次执行的费用

输入
84419 / 1000 × 0.001
= 0.084419 元
缓存
1536 / 1000 × 0.0002
= 0.0003072 元
输出
2486 / 1000 × 0.01
= 0.02486 元

总共加一起≈ 0.11 元

好家伙,我调一次一毛钱没了,比短信还贵啊,image-20260305202125761

这我还玩个毛,所以接下来我要对token下手了

由于第一次我们缓存了,所以第二次,我们走缓存再看看花费多少

缓存midScene官方配置:https://midscenejs.com/zh/caching.html

agent:
  cache:
    id: "my-cache-test"
    strategy: "read-write"

配置在yamlTest里面,在执行一次,请看VCR

走了缓存后可以发现,速度非常快,因为缓存部分没有调大模型,只有断言的部分调用了,当然也可以自定义缓存在哪一步需不需要调用

整体花费

输入
3933 / 1000 × 0.001
= 0.003933 元
输出
126 / 1000 × 0.01
= 0.00126 元
总计≈ 0.0052 元

一分钱都不到!!!
image-20260305202125761
OK呀别着急,还有更狠的,官方由于aiAct比较废token,所以出了更精确的API,我们是可以用API来试试的,API不带缓存,API写法可参考https://midscenejs.com/zh/api.html

那根据API写法优化后的yaml测试用例为

web:
  url: http://implusreport.site.fat46.qa.nt.ctripcorp.com/managesite/index/callDetailQuery?tab=CTRIP&selBUId=-1&selLanguageList=&selCallSkillGroupType=0&selSkillGroupList=&selPhoneType=-1
  bridgeMode: newTabWithUrl
  closeNewTabsAfterDisconnect: true

agent:
  cache:
    id: "my-cache-test-api"
    strategy: "read-write"

tasks:
  - name: 搜索 xcid 并校验样式和查询结果
    flow:

      # 1️⃣ 输入 xcid
      - aiInput: 右侧主区域 “电话标识”右边的“ 请输入内容”输入框
        value: "0bb9bb91f17706371174EXCIDEND"

      - aiTap: 搜索按钮

      # 2️⃣ 点击筛选
      - aiTap: “筛选”文字右边的漏斗按钮

      # 3️⃣ 选择筛选项
      - aiTap: 通话方向选择“呼入”单选项按钮
      - aiTap: 通话状态选择“接通”单选项按钮
      - aiTap: 查询按钮

      # 4️⃣ 断言筛选条件生效
      - aiAssert: 筛选按钮右边出现“通话方向:呼入”  “接通状态:接通”

      # 5️⃣ 点击记录
      - aiTap: 列表中 ID  107608861452641263085 的记录

      # 6️⃣ 打开服务详情
      - aiTap: 服务详情按钮

      # 7️⃣ 滚动到底部
      - aiScroll: 服务详情内容区域
        scrollType: scrollToBottom
        xpath: //*[@id="main-bodyNew"]/div/div[2]/div/div/section/div/div[1]/div/div[2]/div[3]/div[2]/div/div[2]

      # 8️⃣ 点击调用日志
      - aiTap: ”ivr流程调用“右边的“调用日志”按钮
        timeout: 10000

      # 🔟 最终断言
      - aiAssert: 页面出现“basebiz-aigateway-api-topic.ck”
      

依旧运行,midscene .\yamlTestAgent.yml

输入
29196 × 0.000001 = 0.029196
输出
601 × 0.00001 = 0.00601
总计≈ 0.035 元

3分钱!!!调教成功 image-20260305202125761
所以所以,我们可以在调试时候用midScene的api方式去调试(如果觉得上手困难,可以让AI去读midscene的api文章,然后把自己已经写好的用例润色为midScene的官方写法),并且把缓存打开,然后呢,只有断言、悬浮等待啊,或者切换页面的时候可以调一下视觉大模型,让这些复杂的操作更加精准,而对于比较常规的点击,输入,滚动等等我觉得都可以走缓存不调大模型,个人觉得对需要长期维护和小型测试项目非常有用

OK呀,又到了说再见的时候了,美好的时光总是如此短暂,马上走开,不要回来

下一篇见,即将更新Agent Skills项目实战