Skip to content

[observe] 嵌套 cursor:pointer 子按钮被去重吞掉,多 CTA 卡片/弹出菜单子项 observe→act 够不到 #42

Description

@benbergg

⚠️ 根因已订正:真根因是 observe.ts:1406 嵌套去重(非命名 isContainer),见 订正评论。下方原文保留作审计。

[observe] 嵌套 cursor:pointer 子按钮被去重吞掉,多 CTA 卡片/弹出菜单的子项 observe→act 够不到

Labels: bug, observe, P1
发现来源: N0062 vortex 生产能力评测 V3(班牛预发深度复测,2026-06-11,基线 047f3df

现象

当一个 cursor:pointer 容器内含多个功能不同cursor:pointer 子按钮时,vortex_observe 只暴露最外层一个合并 ref,内部子按钮全部丢失。点击合并 ref 命中容器几何中心,往往是插图/描述等非动作区 → 点击无效。agent 仅靠 observe → act 无法触达子按钮,必须 vortex_evaluate 兜底。

复现(班牛,跨环境 3 次稳定复现)

环境:https://newbeta.bytenew.com/app.html(预发,也在 testc.bytenew.com 复现)

实例 1 — 创建工作表卡片

  1. 进入空白 applet 首页,observe 中间「创建工作表」卡片
  2. observe 仅得一个 ref,名为整片拼接文本 创建工作表…创建空白工作表模板中心创建
  3. vortex_act click 该 ref → 命中卡片中心(插图),effect.domMutations≈8,无导航
  4. 但卡片内 创建空白工作表 / 模板中心 / 创建 是 3 个功能不同的子按钮,均未单独暴露

ground-truth 对照:对 创建空白工作表 span 直接 dispatch click(pointerdown/mousedown/.../click)→ location.hash#/applet/appNew/appEmptyNew/12261/0 跳到 #/workCreate/12261,导航成功。证明子按钮才是正确目标。

实例 2 — 弹出菜单:点 addcube(+) 弹出菜单「模板中心创建 / 新建空白小程序」两项被合并成单一 tooltip ref,无法分别 targeting。

DOM 结构

DIV.create-box-list-item.createBox        (cursor:pointer)  ← observe 暴露的合并 ref
 └ DIV.create-box-list-item-box.box1       (cursor:pointer)
    └ SPAN "创建空白工作表"                  (cursor:pointer)  ← 真实点击目标,未暴露
 └ (模板中心 / 创建 ...)                      (cursor:pointer)  ← 同样未暴露

根因(推断,待 bench 实证)

packages/extension/src/handlers/observe.ts 命名逻辑(约 717-730 行)的 isContainer 判定:

const isContainer =
  el.querySelector(
    "a[href],button,input,select,textarea,[tabindex],[contenteditable=true]",
  ) != null;
if (text && !isContainer) return text;   // 非容器 → 用整片 textContent 命名为单一 leaf
...
if (isContainer) return "";              // 容器 → 返空交噪声过滤丢弃,内部交互项另行收集

isContainer 只检查原生交互后代,不含 cursor:pointer 后代。因此"内部只含 cursor:pointer 子按钮"的卡片不被判为容器拆分,而被当作单一 leaf 用整片 textContent 命名,子按钮丢失。

期望

容器内含多个独立 click 行为的 cursor:pointer 子元素时,应分别暴露为可 targeting 的 ref(或将 cursor:pointer 后代纳入 isContainer 判定,让外层卡片被当容器、子按钮单独收集)。

修复注意

  • aria-cursor-dedup / 自主发现引擎(子项目 0022)同族,dedup 策略改动易引入噪声回归 → 必须配 bench fixture + 单测(建议新增"多 CTA 卡片"+"弹出菜单多项"两个 fixture)。
  • 仅当子 cursor:pointer 元素确有独立 click 行为/导向不同动作时才拆分,避免把"整卡可点"的纯展示卡片拆碎。

复合风险

若该缺陷出现在跨域 iframe 内(如班牛 VOC voc-testc.bytenew.com),vortex_evaluate 兜底不可用(跨域 evaluate 设计禁用),将彻底卡死该路径。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions