
使用 Storybook 自动进行可访问性测试
在开发过程中使用“Accessibility”插件运行检查,并使用测试运行程序捕获回归。

可访问性是指让所有人都能使用应用程序的做法。这意味着要确保您的应用程序与辅助技术兼容,支持键盘导航、高对比度模式、减少动画以及更多功能。
验证UI可访问性的最准确方法是在真实设备上手动进行测试。但手动测试需要大量精力,因此大多数团队都使用像Axe这样的自动化工具作为第一道防线。
本文将介绍如何使用Storybook运行自动化可访问性测试。您将学习如何配置Storybook测试运行器,在所有组件上运行Axe并为可访问性树进行快照。

编码时测试可访问性
在编码时修复可访问性问题比在应用程序部署后修复更容易。Axe等自动化工具通过审核渲染的DOM来工作。这使得开发人员在构建UI时能够发现和解决缺陷。
Axe根据WCAG规则和其他行业接受的最佳实践运行检查。使用Axe并不能自动使您的UI可访问,但它平均可以找到57%的WCAG问题。
Storybook的可访问性插件会在当前选定的故事上运行Axe,并在可访问性面板中可视化测试结果。它甚至可以描绘DOM节点,帮助您一目了然地找到违规之处。
在处理组件时,您可以循环浏览其故事,以验证其外观并发现可访问性问题。

有关使用和配置A11y插件的更多信息,请参阅设置指南。
自动捕获可访问性回归
组件的更改可能会无意中引入新的可访问性问题。为了捕获此类回归,您需要在打开拉取请求之前测试所有故事。
可访问性插件仅在您查看故事时运行检查。我们希望通过Storybook测试运行器一次性在所有故事上运行Axe。它是一个独立的实用程序(由Jest和Playwright提供支持),用于检查故事中的渲染错误。
现在,让我们来设置测试运行器并配置它来运行Axe。我们将首先安装测试运行器和相关包(请注意,这需要Storybook 6.4或更高版本)。
npm i -D jest @storybook/test-runner axe-playwright
并安装playwright依赖项
npx playwright install --with-deps然后,您可以使用Storybook测试运行器和axe-playwright将这些可访问性测试集成到您的测试自动化流水线中。
在Storybook目录内添加一个新的配置文件,其中包含以下内容:
// .storybook/test-runner.js
const { injectAxe, checkA11y } = require('axe-playwright');
module.exports = {
async preRender(page, context) {
await injectAxe(page);
},
async postRender(page, context) {
await checkA11y(page, '#root', {
detailedReport: true,
detailedReportOptions: {
html: true,
},
})
},
};preRender和postRender是方便的钩子,允许您配置测试运行器以执行其他任务。我们使用这些钩子将Axe注入故事,然后在渲染后运行可访问性测试。
您会注意到传递给checkA11y函数的一些选项。我们已将Axe设置为从故事的根元素开始,然后向下遍历DOM树以检查问题。它还将根据遇到的问题生成详细报告,并输出一个违反可访问性规则的HTML元素列表。
要运行测试,请在package.json中为测试运行器添加一个脚本。
{
"scripts": {
"test-storybook:ci": "yarn test-storybook --maxWorkers=2"
}
}然后在一个终端窗口中使用npm run storybook启动您的Storybook,在另一个终端窗口中使用npm run test-storybook启动测试运行器。

导出测试结果
默认情况下,结果通过CLI报告。要导出它们,请切换到getViolations函数,并使用Node的fsAPI将它们保存到JSON文件中。
// .storybook/test-runner.js
const { injectAxe, getViolations } = require('axe-playwright');
const fs = require('fs');
module.exports = {
setup() {
fs.mkdir(
process.cwd() + '/src/__accessibility__/',
{ recursive: true },
(err) => {
if (err) throw err;
}
);
},
async preRender(page, context) {
await injectAxe(page);
},
async postRender(page, context) {
const violations = await getViolations(page, '#root', {
detailedReport: true,
});
// Do something with violations
// For example, write them to a file
await new Promise((resolve, reject) => {
fs.writeFile(
process.cwd() + `/src/__accessibility__/${context.id}.json`,
JSON.stringify(violations, null, 2),
(err) => {
if (err) reject(err);
resolve();
}
);
});
},
};为可访问性树拍快照以检查页面结构
盲人和视障用户依赖屏幕阅读器等辅助技术来理解和与您的UI进行交互。浏览器将您的标记转换为称为可访问性树的内部表示。这是屏幕阅读器解析您的UI并将视觉界面转换为语音的机制。
为可访问性树拍快照有助于您了解UI如何被这些辅助设备解析。您可以检查页面结构是否正确以及内容是否按正确的顺序呈现。更重要的是,在修改或更新UI时,跟踪和差异这些快照以捕获回归。
// .storybook/test-runner.js
const { injectAxe, checkA11y } = require('axe-playwright');
module.exports = {
async preRender(page, context) {
await injectAxe(page);
},
async postRender(page, context) {
await checkA11y(page, '#root', {
detailedReport: true,
detailedReportOptions: {
html: true,
},
});
const accessibilityTree = await page.accessibility.snapshot();
expect(accessibilityTree).toMatchSnapshot();
},
};结论
美国有26%的成年人至少有一种残疾。提高可访问性可以对您的用户群产生重大影响。
自动化可访问性测试是QA的第一道防线,用于捕获明显的访问性违规。虽然自动化不能自动使您的UI可访问,但它可以缩短反馈循环,让您在开发过程中就能发现问题。
Storybook可访问性插件会审计您的故事并突出显示违规的DOM节点。当您准备好合并时,使用Storybook测试运行器在所有组件上运行检查以捕获回归。
通过我们的入门指南了解如何将测试运行器用于CI。
自动化可访问性测试可以加快您的工作流程并捕获明显的违规。
— Storybook (@storybookjs) 2022年5月19日
新教程——学习如何使用Storybook运行a11y检查。
♿ 使用a11y插件边编码边测试
🤖 使用测试运行器捕获回归
🌲 使用钩子为a11y树拍快照https://#/OZbnN0Az7o pic.twitter.com/Xzrbqy3Xb7