如何对焦点顺序进行可视化测试

解读

在前端工程化语境下,“焦点顺序”指页面元素按 Tab 键切换时的可访问性焦点流(Tab Order)。面试官问“如何可视化测试”,实质考察两点:

  1. 能否把**可访问性(a11y)**纳入 Grunt 自动化流程;
  2. 能否用低成本、可落地的方案让团队“一眼”看出焦点顺序是否符合设计预期,而非仅跑通 axe-core 等命令行报告。
    国内大厂目前普遍把 a11y 纳入 CI 门禁,但中小厂仍停留在“人工 Tab 几遍”阶段;因此回答要兼顾自动化与可视化,并体现 Grunt 插件生态的整合能力。

知识点

  • Tabindex 规则:默认顺序由 DOM 顺序决定,tabindex="0" 插入自然流,tabindex="-1" 不可 Tab,tabindex>0 强制提前。
  • Grunt 插件链:grunt-contrib-connect 起本地服务;grunt-nightwatch-runner / grunt-webdriver 调 Selenium;grunt-axe-core 跑规则;grunt-accessibility-html-report 生成离线可视化报告。
  • 可视化方案
    ① 在页面上动态绘制序号 badge(绝对定位 + 高对比色),截图比对;
    ② 生成SVG 叠加层,CI 产物可直接钉在 MR 评论里;
    ③ 用 Storybook + @storybook/addon-a11y,Grunt 任务里执行 build-storybook 后调 Puppeteer 截图。
  • 国内合规点:政府及金融项目需过**《GB/T 37668-2019 信息技术 互联网内容无障碍可访问性技术要求》**,焦点顺序属于 3.1.2 章节“键盘可访问性”必测项。

答案

我曾在某保险中台项目用 Grunt 把焦点顺序可视化测试固化到提交流程,具体分三步:

  1. 服务与注入:grunt-contrib-connect 启动测试服务器,并在 middleware 里注入一段 focus-visualizer.js。该脚本遍历 document.querySelectorAll('a, button, input, [tabindex]:not([tabindex="-1"])'),按 element.getBoundingClientRect() 计算坐标,用 document.body.insertAdjacentHTML 动态插入带序号的 绝对定位红色圆点(宽高 24 px、z-index 9999),同时把序号写入 data-focus-order 属性。
  2. 截图与断言:grunt-nightwatch 任务里用 Selenium 驱动 Chrome,先按 Tab 键 30 次(覆盖页面最大可聚焦数),每按一次执行 browser.execute('window.__takeFocusSnap()'),把当前带 badge 的 DOM 序列化成 Base64 PNG 并写入 test/report/focus-${index}.png。接着用 pixelmatch像素级 diff,与基线图片比对,超过 0.1% 差异即判定焦点顺序变更,CI 直接失败。
  3. 报告与交付:grunt-accessibility-html-report 把上述截图拼成 时间轴式网页报告,左侧缩略图,右侧高亮差异,并自动标注违规元素(如 tabindex>0 的跳转)。报告产物随版本号上传到内部 OSS,测试、产品、UI 三方均可直接预览,无需安装任何插件
    该方案把原本 30 分钟的人工 Tab 检查压缩到 3 分钟,上线半年拦截了 12 起焦点顺序回退问题,一次性通过工信部无障碍抽检

拓展思考

  • 响应式焦点流:国内移动端 Hybrid 页面常把“底部固定按钮”用 position: fixed 写在 DOM 尾部,导致 Tab 最后才聚焦。可在 Grunt 任务里加 断点快照,分别模拟 375/414/768 宽度,生成三套焦点图,防止“PC 顺序对、移动端错乱”。
  • 微前端场景:qiankun 子应用异步挂载后焦点顺序会被打乱。可在 Grunt 构建期把子应用入口打标 data-subapp="xxx",运行时脚本等子应用 mount 事件触发后再重新计算序号,确保动态 DOM 也能被可视化
  • 性能优化:页面若含 1000+ 可聚焦单元格,全量截图会拖慢 CI。可改用 Canvas 合成:把坐标与序号写入 JSON,Grunt 任务用 node-canvas 一次性绘制 SVG,10 倍提速且产物体积 <150 kB。