AI测试-02-Midscene.js在真实UI自动化里到底能解决哪些问题

Midscene.js 这类 AI UI 自动化工具最近很容易被讨论成两种极端:

  • 要么被说成“以后都不用写定位了”
  • 要么被说成“只是套了一层视觉识别,稳定不了”

这两种说法都不准确。

放到真实 UI 自动化里看,Midscene.js 真正有价值的地方,不是替代现有自动化体系,而是补掉传统脚本长期处理不好的那一段:页面结构复杂、业务组件嵌套深、定位语义不稳定、人工巡检成本高、失败现场难还原

如果把它当成“AI 版 Selenium”,很快就会失望。
如果把它当成“专门处理弱结构页面和高语义操作的增强层”,落地价值会清晰很多。

这篇文章只讨论一件事:Midscene.js 在真实 UI 自动化里到底能解决哪些问题,解决到什么程度,边界又在哪里。

一、先把问题拆开:传统 UI 自动化最脆的不是点击,而是“页面理解”

传统 UI 自动化最成熟的部分,其实从来不是“能不能点按钮”,而是:

  • 能不能稳定找到那个按钮
  • 能不能确认当前页面状态是不是预期状态
  • 能不能在复杂页面里准确描述“下一步该操作哪个区域”
  • 能不能在失败时还原现场,而不是只留下一个超时异常

所以真实项目里,UI 自动化最脆的位置通常集中在 5 层:

1. 定位层

  • DOM 结构频繁变化
  • 组件层级过深
  • class 名和属性名带动态后缀
  • 同文案元素重复出现

2. 语义层

  • 页面上有多个“确定”“提交”“保存”
  • 同一个动作在不同页面区域含义不同
  • 视觉上明显是一个卡片区域,DOM 上却分散在多个节点

3. 状态层

  • 页面已经渲染,但业务数据还没完成
  • 浮层、抽屉、懒加载区域遮挡真实目标
  • 页面上“看起来成功”,实际仍在处理中

4. 证据层

  • 脚本失败后只有一个超时日志
  • 没有明确失败时页面长什么样
  • 无法快速判断是定位错、等待错,还是页面逻辑错

5. 维护层

  • 小改版导致大量选择器一起失效
  • 巡检脚本可读性越来越差
  • 新增用例速度远慢于页面变更速度

Midscene.js 的价值,主要集中在这 5 层里的前 4 层,尤其是定位层、语义层和证据层

二、Midscene.js 真正能补的,不是“所有操作”,而是 4 类高成本场景

如果要判断它值不值得接入,不需要先问“它能不能替代 Playwright”,而应该先问:当前 UI 自动化最贵、最脆、最费人工的环节是什么。

从真实项目角度看,Midscene.js 比较值得投入的通常是下面 4 类场景。

三、第一类价值:处理“人能看懂,但脚本很难稳定描述”的页面

这类页面通常有几个共同点:

  • 布局复杂
  • 业务语义强
  • DOM 结构不规整
  • 视觉区域明显,但程序语义不明显

例如:

  • 运营后台里的统计看板
  • 包含卡片、图表、筛选器、浮层的复杂页面
  • 低代码页面
  • 多 tab、多抽屉、多面板混排页面

传统脚本在这种场景里会出现两个问题:

  1. 选择器能写出来,但表达不了“页面中间那块订单趋势卡片右上角的下载按钮”这种语义。
  2. 即使勉强写出来,也会因为组件重构、层级调整、节点包装变化很快失效。

Midscene.js 的优势就在这里:

  • 它更接近“按视觉语义找目标”
  • 可以把操作描述成业务语言,而不是一串脆弱的节点路径
  • 更适合表达区域、相对位置、文本语义和页面上下文

这并不意味着可以完全放弃结构化定位。
更合适的做法是:

  • 稳定控件继续用结构化定位
  • 复杂区域、弱结构区域、视觉语义区域交给 Midscene.js

这样接入后,脚本层会更像“双轨制”:

  • 结构化动作走 Playwright 原生能力
  • 语义型动作走 Midscene.js

这也是它在真实项目里最稳的落地方式。

四、第二类价值:减少“页面小改版导致整批脚本一起失效”的维护成本

很多 UI 自动化问题,本质上不是脚本写不出来,而是维护成本长期高于收益

典型表现是:

  • 前端把按钮包到新组件里,定位全失效
  • 页面只是调了布局顺序,脚本就找不到目标
  • 样式类名换了一批 hash,脚本全部重录

Midscene.js 对这类问题的缓解点在于:

  • 它更关注“页面上是什么”,而不是“节点树长什么样”
  • 对视觉层变动的容忍度,通常高于纯 DOM 选择器
  • 对相对稳定的业务文本和区域关系更友好

这类收益尤其适合:

  • 巡检类用例
  • 高频冒烟用例
  • 需要快速补覆盖的新页面
  • 不值得长期精细维护定位器的后台系统

但这里有一个边界必须说清楚:

它减少的是一部分维护成本,不是全部维护成本。

如果页面文案本身经常变、区域布局经常重构、视觉层命名也不稳定,那么 AI 语义描述同样会漂。
所以真正稳定的前提仍然是:

  • 页面语义相对清晰
  • 页面视觉结构不是每天重画
  • 用例目标明确,不是模糊操作

五、第三类价值:提高巡检、回归、问题复现这类“高语义操作”的脚本可读性

很多 UI 自动化脚本写到后面会变成这样:

1
2
3
await page.locator('.panel > div:nth-child(2) .toolbar .btn-primary').click();
await page.locator('[data-id=\"tab-order\"]').click();
await page.locator('.drawer-container .footer button:nth-of-type(1)').click();

脚本确实能跑,但两个问题会马上出现:

  • 新接手的人根本看不出这几步到底在做什么
  • 出问题时排查成本很高,必须重新打开页面对照结构

如果其中一部分动作改成高语义表达,脚本可读性会明显改善,例如:

  • 点击订单趋势卡片右上角的导出按钮
  • 打开订单详情抽屉并确认当前是退款记录 tab
  • 在提交前确认弹窗里点击确认

这种变化的价值不只是“更好读”,更重要的是:

  • 用例步骤更接近业务语言
  • 失败日志更容易和测试报告对应
  • 更适合后续接测试平台、报告系统、AI 辅助分析

也就是说,Midscene.js 不是只影响执行层,它还会影响:

  • 步骤描述层
  • 报告证据层
  • 失败归因层

这一点在后续平台化时很重要。

六、第四类价值:补强失败现场还原和证据生成

真实项目里,UI 自动化最大的问题往往不是“失败了”,而是失败后不知道为什么失败

传统失败现场通常只有这些内容:

  • 一个超时异常
  • 一张截图
  • 一段控制台日志

如果目标页面复杂,这些证据通常不够。
因为排查仍然要回答这些问题:

  • 目标元素到底有没有出现
  • 出现了,但是不是被遮挡了
  • 页面是不是切错区域了
  • 当前看到的是不是预期卡片、预期弹窗、预期 tab

Midscene.js 的一个现实价值,是可以把“页面语义理解”也带进证据链:

  • 当前页面主要区域是什么
  • 识别到的操作目标是什么
  • 失败时系统以为自己在找哪个对象
  • 目标对象和真实页面的偏差在哪里

如果这部分证据和:

  • 截图
  • 视频
  • Playwright trace
  • 控制台日志
  • 网络请求

一起保存,失败排查效率会高很多。

换句话说,Midscene.js 的价值不只在“让脚本点到东西”,还在于让脚本失败得更可解释

七、适用边界:哪些场景接入更值,哪些场景先别上

讨论 AI UI 工具时,最容易出的问题是直接问“好不好用”。
更有效的问题是:在哪些场景下用,收益大于复杂度。

更适合优先接入的场景

  • 视觉语义强、DOM 结构弱的页面
  • 后台管理系统、运营系统、看板系统
  • 巡检类、冒烟类、高层业务验证类脚本
  • 页面变化较快,但业务语义相对稳定的模块
  • 失败后需要快速定位“页面现场”的场景

不适合优先接入的场景

  • 对精确坐标、精确像素要求极高的场景
  • 纯表单、纯接口驱动、原生结构很稳定的页面
  • 高频低延迟执行、对速度要求极高的批量回归
  • 对操作确定性要求极高的资金、风控、核心交易动作
  • 文案变化频繁、主题皮肤变化极大、页面语义不稳定的区域

这部分边界很关键。
如果把 Midscene.js 用在本来就适合原生 Playwright 的地方,结果通常不会更好,只会更慢、更贵、变量更多。

八、落地方式:不要直接全量替换,先接成“增强层”

真实落地时,最不推荐的做法就是:

  • 全量改造所有 UI 自动化脚本
  • 所有点击和断言都改成 AI 语义描述
  • 指望一套工具统一解决稳定性和维护性问题

这条路基本都会失败。

更稳的落地方式,是把 Midscene.js 接成现有 UI 自动化体系的一层增强能力。

一个更可落地的分层方式如下:

1. 基础驱动层

  • 浏览器启动
  • 登录态注入
  • 网络监听
  • 截图、trace、录屏
  • 原生 Playwright 操作

2. 结构化动作层

  • 稳定元素定位
  • 表单输入
  • 接口联动校验
  • 显式等待和结果断言

3. AI 语义动作层

  • 复杂区域识别
  • 视觉语义点击
  • 区域级确认
  • 页面对象语义提取

4. 证据与归因层

  • 失败截图
  • 页面语义快照
  • 操作步骤日志
  • trace / video / network 归档

这样接入后,Midscene.js 的定位非常清楚:

  • 不是主框架
  • 不是唯一定位方式
  • 是结构化自动化的增强层

这也是最接近真实工程治理的方案。

九、最小执行骨架:第一版不要追求大而全

如果准备把它接到真实项目里,第一版只需要把 4 件事收稳。

1. 先选页面,不先选工具能力

优先挑这两类页面试点:

  • 传统脚本维护成本已经明显过高的页面
  • 人工巡检成本高、但业务动作相对清晰的页面

不要一上来就挑:

  • 核心交易链路
  • 动态文案极多页面
  • 复杂动画和拖拽页面

2. 先做“单步增强”,不做“全流程接管”

第一版可以只让 Midscene.js 做一件事:

  • 找复杂按钮
  • 确认页面区域
  • 辅助判断弹窗内容

而不是从登录到提交全部交给它。

3. 给每一步保留原始证据

至少保留:

  • 操作前截图
  • 操作后截图
  • 页面语义描述
  • Playwright trace
  • 失败时网络和控制台日志

如果没有这套证据,后面很难治理误判。

4. 建一张最小记录表

第一轮接入时,至少记录这些字段:

字段 含义
页面/模块 接入的是哪个页面
场景目标 这一步想验证什么
AI 动作类型 点击、识别、确认、提取
执行结果 成功、失败、误判
失败类型 找错目标、没找到、页面未稳定、遮挡、超时
证据链接 截图、trace、日志
是否保留 这一步最后是否值得继续用 AI 方案

这张表的作用不是管理文档,而是帮助判断:哪些动作适合继续保留在 AI 层,哪些动作应该退回结构化定位。

十、常见坑:真实落地里最容易踩错的不是“模型能力”,而是接入方式

Midscene.js 这类工具在 PoC 阶段通常很容易让人产生错觉:演示效果很好,实际批量跑起来却不稳。
问题往往不在工具本身,而在接入方式。

1. 把它当成万能定位器

结果通常是:

  • 脚本速度变慢
  • 稳定性没有提升
  • 误判面更宽

AI 语义定位应该只接在“原生定位明显不划算”的地方。

2. 页面还没稳定就开始识别

这类误判特别常见。
页面刚渲染出骨架时,视觉上已经像是目标页面,但:

  • 数据还没回填
  • 抽屉还没展开到位
  • 浮层还没消失
  • 关键卡片还没加载完成

如果此时开始语义识别,很容易找错区域。

3. 没有给 AI 动作做降级路径

真实工程里,任何增强能力都应该有兜底:

  • AI 动作失败后是否重试
  • 重试前是否重新截图
  • 是否允许退回原生定位
  • 是否直接终止并留证

如果没有降级路径,失败会直接扩散到整条链路。

4. 只看成功率,不看误判成本

有些 PoC 看起来成功率不低,但误判一次的排查成本极高。
这种情况下,表面成功率并不能说明问题。

更应该看的是:

  • 平均排查成本
  • 单次失败的可解释性
  • 新增脚本速度
  • 小改版后的维护成本

5. 忽略页面主题、分辨率、缩放比差异

视觉语义工具很容易受到这些因素影响:

  • 浏览器缩放
  • 字体渲染差异
  • 暗黑主题 / 浅色主题
  • 屏幕尺寸和分辨率

如果环境没有标准化,稳定性评估会被严重放大或缩小。

十一、真实案例型段落:一次“按钮明明在页面上,但脚本始终点错”的排查

1. 场景

某运营后台有一个订单趋势看板页面,右上角有“导出数据”按钮。
页面结构复杂,右上区域同时存在:

  • 页面级导出按钮
  • 单卡片导出按钮
  • 筛选器重置按钮

传统 Playwright 脚本原本用一串组合选择器定位单卡片导出按钮。前端改版后,卡片结构重包了一层,旧定位大面积失效。于是这一段被改成 Midscene.js 语义动作,目标是“点击订单趋势卡片右上角的导出按钮”。

2. 执行

  • 进入看板页面
  • 等待主接口返回成功
  • 调用 Midscene.js 识别订单趋势卡片区域并点击右上角导出按钮
  • 校验是否出现“导出成功”提示

3. 现象

脚本在部分环境执行成功,在部分环境持续失败。
失败时没有报“找不到按钮”,而是实际点到了页面级导出按钮,导致下载了错误报表。

4. 排查

排查顺序按下面几步收敛:

  1. 先看截图,确认失败时页面上确实同时存在两个“导出”。
  2. 再看页面语义截图和动作日志,发现识别结果把页面级工具栏误判成了目标卡片顶部区域。
  3. 再对比成功环境与失败环境,发现失败环境浏览器宽度更小,卡片区域被压缩,页面级工具栏与卡片头部在视觉上距离更近。
  4. 再看等待链路,发现脚本只等了接口成功,没有等筛选器动画和布局稳定完成。

5. 修复

最终没有继续强化一条更长的自然语言描述,而是做了 3 个修正:

  • 在 AI 动作前增加布局稳定等待,确认卡片区域高度和关键文本已经稳定
  • 先让 Midscene.js 只负责识别“订单趋势卡片”区域,再在该区域内部执行更窄的动作
  • 对导出结果增加业务校验,确认导出的报表标题与卡片名称一致

修完之后,误点问题明显下降。
这次问题也说明了一点:AI 动作最怕的不是页面复杂,而是目标边界没有先收窄。

十二、怎么判断值不值得长期用

判断 Midscene.js 是否值得长期留在 UI 自动化体系里,不要只看 demo 成功率。
更应该看下面 5 个指标:

  • 复杂页面动作的新增脚本速度是否提升
  • 小改版后的维护工时是否下降
  • 失败时的可解释性是否提升
  • 巡检类脚本的阅读和接手成本是否下降
  • 是否真的减少了“因为定位脆弱导致的无效失败”

如果这 5 项没有明显改善,即使单步动作看起来很智能,也不一定值得保留。

十三、结论:它不是替代层,而是增强层

回到最开始的问题,Midscene.js 在真实 UI 自动化里到底能解决哪些问题。

更准确的答案是:

  • 能解决一部分复杂页面的高语义定位问题
  • 能缓解一部分因 DOM 结构变化带来的维护成本
  • 能提升巡检和回归脚本的可读性
  • 能补强失败现场的证据和解释能力

但同时也要承认:

  • 它不能替代所有结构化定位
  • 不能跳过等待设计和状态治理
  • 不能绕开环境标准化
  • 不能代替业务结果校验

所以更合适的落地姿势不是“用 AI 重写 UI 自动化”,而是:

Midscene.js 放到现有自动化体系里,专门处理那些传统脚本长期做得很痛苦、但业务上又确实值得自动化的部分。

用对位置,它会是增益。
用错位置,它只会变成新的不稳定来源。