无障碍功能:JupyterLab 开发者指南#
如果您正在修改 JupyterLab 源代码,并且关注无障碍功能,那么此页面适合您。
正在寻找其他方式为 Jupyter 项目的无障碍功能做出贡献?
从何开始#
感谢您对改进 JupyterLab 无障碍功能的兴趣。无论是进行无障碍功能特定修复,还是考虑其他贡献对无障碍功能的影响,您的工作都能让所有 JupyterLab 用户受益。
对于有无障碍意识的开发者来说,JupyterLab 的一个常见问题是:我该从何开始?
如果您没有太多时间全身心投入 JupyterLab 无障碍功能的整体工作,那么标有“good first issue”和“accessibility”的 GitHub 问题是一个很好的起点。
如果您想更充分地投入到使 JupyterLab(或其他 Jupyter 项目)更具无障碍性的工作中,那么一个好的起点是加入每隔一周举行的 Jupyter 无障碍会议。如果您无法参加会议,可以查阅会议记录,并在 Jupyter 无障碍网站上找到其他资源的链接。
开发中的最佳实践#
JupyterLab 是一个 Web 应用程序和创作工具。因此,以下标准适用
WCAG - Web 内容无障碍指南
ARIA - 无障碍富互联网应用程序
ATAG - 创作工具无障碍指南
这些都是熟悉开发网站 (WCAG) 和 Web 应用程序 (ARIA) 无障碍最佳实践的好地方。请注意,尽管 WCAG 主要为静态网站创建,但这些指南同样适用于 JupyterLab 等 Web 应用程序。
对于寻求示例和最佳实践的开发者来说,一个特别有用的资源是 ARIA 模式。这个 Web 资源包含如何以更无障碍的方式实现 UI 元素(例如菜单、对话框、面包屑等)的示例。但是,请注意!仅仅因为您可以使用 div 和 aria 属性实现按钮,并不意味着您应该这样做!(最有可能的是,您应该只使用 button 标签。)作为最佳实践,您应该只在无法使用现有 HTML 元素(button、input、nav、aside 等)来实现您想要的 UX 时才使用 ARIA。
最后,互联网上的无障碍知识远比 JupyterLab 或 Jupyter 项目本身的更多。无论您决定从事什么工作,都可以考虑探索其他领域中类似的无障碍资源。无障碍社区倾向于慷慨地提供资源来改进网络无障碍性。很多时候,在搜索引擎中搜索任务或问题的名称并加上无障碍功能,会得到几个结果,并有机会立即从更广泛的社区中学习。
本节的其余部分包含 JupyterLab 及其开发特定的最佳实践。
使用 CSS 中的颜色变量#
在 JupyterLab 中修复对比度或其他视觉无障碍问题时,很容易选择一种颜色并将其应用于您正在处理的 UI 部分。然而,将颜色值分散在应用程序的不同 CSS 文件中很快就会变得难以管理。因此,JupyterLab 代码库定义了一组颜色变量,可用于边框、图标等。如果您添加任何需要颜色值的 CSS,请使用定义的变量之一。
Lumino 中的上游修复#
JupyterLab 使用了一个专门为其构建的前端框架,名为 Lumino。Lumino 在某些方面类似于 React、Vue 和 Angular,但它也提供了许多 UI 小部件,如菜单栏、标签栏和停靠面板。因此,JupyterLab GitHub 仓库中报告的一些无障碍问题需要在 Lumino 仓库中修复。学习 Lumino 的一个好资源:PhosphorJS(现为 Lumino)导师课程。PhosphorJS 是 Lumino 之前的名称。有一个页面包含PhosphorJS 课程笔记,其中还包含一些未上传到 YouTube 的额外视频的链接。
何时应在 JupyterLab 或 Lumino 中修复无障碍问题并不总是显而易见的。一些指导可帮助您确定应在何处进行更改:
一般来说,如果您可以在 Lumino 中修复问题,最好在 Lumino 中修复,因为这样修复会在更多地方被吸收。
然而,出于同样的原因,由于 Lumino 不仅被 JupyterLab 使用,还被 JupyterLab 扩展使用,因此在 Lumino 中进行更改时应小心,以免破坏下游消费者/扩展。
因此,另一个经验法则是:如果您无法在不破坏依赖项的情况下在 Lumino 中进行修复,那么最好在 JupyterLab 中进行修复。在这种情况下,您可能会采取双轨方法,在 JupyterLab 中修复无障碍问题,同时在 Lumino 中提交一个破坏性修复,目标是 Lumino 的未来主要 API 破坏性版本。
自动化回归测试#
如果您在源代码中修复了一个无障碍问题但没有添加测试,那么您的修复很可能会在未来对代码库的某些更改中被意外撤销。
有时,对无障碍修复进行单元测试是简单的,例如在工具栏按钮上启用键盘快捷键时。但通常很难对无障碍修复进行单元测试。
因此,目前正在努力使用 Playwright 为 JupyterLab 编写用户级无障碍测试。为了说明如何在开发过程中使用它,让我们来看一个例子。
此示例将涉及三个独立的 GitHub 仓库
这是一个真实世界的例子,取自实际的过去工作。
假设您对 JupyterLab UI 的起始页进行了无障碍审计,并在顶部菜单栏中发现了一个 Tab 陷阱,这意味着用户可以按下 Tab 键进入菜单栏,但无法仅使用键盘轻松地越过它。
您进一步深入研究,发现 Tab 陷阱错误位于 jupyterlab/lumino 仓库中,因此您分叉了 jupyterlab/lumino 仓库,创建了一个名为 fix-tab-trap
的新分支,并打开了一个拉取请求。
您决定编写一个测试。这是一个单元测试任务会很简单的情况。但是,单元测试只会检查顶部菜单栏,因此它不会阻止您决定一劳永逸地解决的问题再次出现,即:您不希望 JupyterLab 起始页上的任何地方都有 Tab 陷阱。
因此,您决定 向 Quansight-Labs/jupyter-a11y-testing 仓库添加一个回归测试。此测试通过使用 Playwright 打开 JupyterLab 并重复按下 Tab 键来检查 JupyterLab 起始页上没有 Tab 陷阱。因此,与 Lumino 仓库一样,您分叉了 Quansight-Labs/jupyter-a11y-testing 仓库,创建了一个名为 test-tab-trap
的分支,并打开了一个拉取请求。此步骤中的重要事项是,您将测试文件保存为 .test.ts
扩展名,与其他回归测试文件放在一起。
现在您想运行您的测试。具体来说,您想针对一个包含您的 Lumino 修复的 JupyterLab 构建运行测试。以下是操作方法。
假设您的 GitHub 用户名是 a11ydev,并且您已经分叉了 Lumino 和测试仓库,并在这些分叉上创建了以下分支,一个包含您的错误修复,另一个包含您的测试
a11ydev/lumino:fix-tab-trap
a11ydev/jupyter-a11y-testing:test-tab-trap
在 GitHub 上,转到您的测试仓库分叉,a11ydev/jupyter-a11y-testing。确保您位于 test-tab-trap 分支上,该分支包含您添加的 .test.ts
文件。然后转到 Actions 并单击标题为“Run accessibility tests on JupyterLab”的工作流程。单击“Run workflow”。这将打开一个表单来配置工作流程。
您应该这样填写表格
使用工作流程来自:
test-tab-trap
JupyterLab 仓库:
jupyterlab/jupyterlab
分支/标签/SHA:
main
测试套件:留空
外部包仓库:
a11ydev/lumino
外部包引用:
fix-tab-trap
然后按下“Run workflow”按钮。GitHub Action 应该会从源代码构建 JupyterLab,链接您的 Lumino 分叉和分支,然后运行测试套件,包括您的测试,最后显示测试结果,希望您的测试通过。
请注意,在此示例中,您没有分叉 jupyterlab/jupyterlab 仓库,也没有在工作流程配置表单中将分支名称更改为“main”以外的名称。这是因为您不需要修改 JupyterLab 代码库来解决此问题。但是,如果您正在处理需要修改 JupyterLab 代码库的问题,您将执行与 Lumino 相同的操作:分叉仓库,创建一个包含您的修复的分支,然后在运行工作流程之前在工作流程配置表单中输入您的分叉和分支。这应该会使其根据您的更改构建一个 JupyterLab 版本,然后对它运行测试套件。工作流程足够灵活,如果需要,您可以同时针对 JupyterLab 或 Lumino 或两者的更改进行测试。
注意
有关如何在测试仓库中使用 GitHub 工作流程的更详细说明。
PR 审查和手动测试#
在审查代码、文档或其他贡献时,您可以使用手动测试来帮助防止无障碍错误。通常,您会尝试使用无障碍辅助功能或设置来完成与您的修复或贡献相关的任务。常见选项包括
在测试时,请注意发生了什么,并将其与您在不使用所选无障碍辅助功能的情况下完成任务所能做的事情进行比较。如果有任何您无法完成的事情,那么您就有一个阻碍性的无障碍问题。尽管您使用辅助技术或无障碍辅助功能可能与经常使用它们的人有所不同,但了解结果有助于判断 JupyterLab 是否按您预期的方式运行。
GitPod#
如果您有 GitPod 帐户并且您已向 JupyterLab 提交了 PR,您可以通过复制您的 PR 的 GitHub URL 并将其连接到 gitpod.io/#
来手动测试它,如下所示
https://gitpod.io/#https://github.com/jupyterlab/jupyterlab/pull/您的 PR 号码
GitPod 将从源代码构建应用了您的 PR 的 JupyterLab,并设置一个隧道,以便您可以在浏览器中通过 localhost:8888 加载 UI。
有用的开发工具#
以下是开发者在 JupyterLab 中进行无障碍工作时发现有用的一些应用程序列表
Chrome 开发者工具用于发现和修复低对比度文本以及查看无障碍树
Axe DevTools,Chrome 开发者工具的扩展
颜色对比分析器,适用于 Windows 和 Mac 的桌面应用程序
Polypane,内置一些开发者工具的桌面浏览器(注意它不是免费的,但有免费试用期)
Axe Accessibility Linter,VS Code 的扩展
GitPod:请参阅上面“测试”部分的 GitPod 部分。
当然,还有 JAWS、NVDA 和 VoiceOver 等屏幕阅读器。