如何对焦点顺序进行可视化测试
解读
在前端工程化语境下,“焦点顺序”指页面元素按 Tab 键切换时的可访问性焦点流(Tab Order)。面试官问“如何可视化测试”,实质考察两点:
- 能否把**可访问性(a11y)**纳入 Grunt 自动化流程;
- 能否用低成本、可落地的方案让团队“一眼”看出焦点顺序是否符合设计预期,而非仅跑通 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 把焦点顺序可视化测试固化到提交流程,具体分三步:
- 服务与注入: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属性。 - 截图与断言:grunt-nightwatch 任务里用 Selenium 驱动 Chrome,先按 Tab 键 30 次(覆盖页面最大可聚焦数),每按一次执行
browser.execute('window.__takeFocusSnap()'),把当前带 badge 的 DOM 序列化成 Base64 PNG 并写入test/report/focus-${index}.png。接着用pixelmatch做像素级 diff,与基线图片比对,超过 0.1% 差异即判定焦点顺序变更,CI 直接失败。 - 报告与交付: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。