创建 Web Inspector 审计
这篇博文是Web Inspector 中的审计博文的后续,解释了审计的功能以及如何编写审计。
测试用例格式
在页面中运行的实际测试只是一个字符串化的 JavaScript 函数。允许使用 async 函数,也允许使用返回 Promise 的非 async 函数。唯一的要求是函数(或 Promise)的返回值符合以下规则
- 返回
true/false将转换为通过/失败结果,不带额外数据。 - 返回字符串值将转换为相应的结果(例如,
"pass"是通过结果),不带额外数据。 - 返回一个对象提供了最大的灵活性,因为它允许在“审计”选项卡中显示除审计结果之外的额外数据。结果级别首先从
"level"值(如果存在)中获取,并以与返回字符串相同的方式进行转换(例如,"pass"是通过结果)。或者,使用任何结果字符串作为键,并将其值设为true也会有相同的效果(例如,"pass": true)。
共有五种结果级别
"pass"对应于通过结果,表示一切正常。"warning"对应于警告结果,这是一种“软通过”,表示没有错误,但有些地方应该更改。"fail"对应于失败结果,表示某些地方不符合预期。"error"对应于错误结果,当运行的 JavaScript 抛出错误时发生。"unsupported"对应于不支持结果,这是一种特殊情况,可用于指示当前页面不支持被测试数据(例如,缺少某些 API)时。
此外,结果对象中还可以返回三个额外的数据,它们拥有专门的接口
domNodes,这是一个 DOM 节点数组,将在“审计”选项卡中显示,类似于它们被记录到控制台的方式。domAttributes,这是一个字符串数组,如果数组中的任何字符串存在于domNodes中的任何 DOM 节点上,则该字符串将被高亮显示。errors,这是一个Error对象数组,可用于暴露在运行审计时遇到的错误。- 如果此数组有任何值,审计结果将自动更改为错误。
- 如果在运行审计时抛出错误,它将自动添加到此列表。
对于自定义数据,您可以将其添加到结果对象中,它将在“审计”选项卡中显示,只要它是可 JSON 序列化的并且不与上述任何项重叠。
容器结构
Web Inspector 审计遵循一种简单且高度灵活的 JSON 对象结构。这些对象分为两大类:测试和组。
测试的格式如下
{
"type": "test-case",
"name": "...",
"test": "<stringified JavaScript function>"
}
组的格式如下
{
"type": "test-group",
"name": "...",
"tests": [...]
}
在这种情况下,tests 内部的值既可以是单独的测试用例,也可以是额外的组。
测试和组都支持一些可选属性
description是一个基本字符串值,显示在“审计”选项卡中,用于提供有关该特定审计的更多信息,例如它做什么或它试图测试什么。supports可以用作功能检查的替代方案,因为它会阻止审计运行,除非其数值与 Web Inspector 的审计版本号匹配,该版本号可以在“审计”选项卡中处于编辑模式时在 Web Inspector 窗口底部找到。在撰写本文时,当前版本是3。setup类似于测试用例的test值,但它仅在为顶级审计提供时才有效。此值的目的是能够在组中的所有审计之间共享代码,因为它在组中的第一个审计之前执行。
特殊暴露的数据
由于审计是从 Web Inspector 运行的,因此可以向每个正在执行的 test 函数暴露额外信息。这些数据大部分已经暴露给 Web Inspector,但从未以任何方式通过 JavaScript 访问过。
信息通过一个 WebInspectorAudit 对象暴露,该对象传递给每个 test 函数。请注意,此对象在给定顶级审计下的所有 test 之间共享,顶级审计被定义为没有父级的审计。因此,鼓励将数据附加到此对象以在 test 之间共享。
版本
在 test 中访问 Web Inspector 的审计版本号就像获取 WebInspectorAudit.Version 的值一样简单。
资源
以下所有内容都与处理页面加载的资源有关,并由 WebInspectorAudit.Resources 持有。
getResources()将返回一个对象列表,每个对象对应于被检查页面加载的特定资源,由字符串url、字符串mimeType和审计特有的id标识。getResourceContent(id)将返回一个对象,其中包含给定审计特有id的资源的字符串data和布尔值base64Encoded内容。
DOM
以下所有内容都与处理 DOM 树有关,并由 WebInspectorAudit.Resources 持有。
hasEventListeners(node[, type])返回true/false,取决于给定 DOMnode是否有任何事件监听器,或者是否有针对给定type的事件监听器(如果指定)。
可访问性
以下所有内容都与处理可访问性树有关,并由 WebInspectorAudit.Accessibility 持有。更多信息可在 WAI-ARIA 规范中找到。
getElementsByComputedRole(role[, container])返回一个 DOM 节点数组,这些节点与给定的 role 匹配,并且是containerDOM 节点(如果指定)或主文档的子节点。getActiveDescendant(node)返回给定 DOMnode的活动后代。getMouseEventNode(node)返回将处理鼠标事件的 DOM 节点,该节点是给定 DOM 节点或其子节点。getParentNode(node)返回给定 DOMnode在可访问性树中的父 DOM 节点。getChildNodes(node)返回一个 DOM 节点数组,这些节点是给定 DOMnode在可访问性树中的子节点。getSelectedChildNodes(node)返回一个当前选定的 DOM 节点数组,这些节点是给定 DOMnode在可访问性树中的子节点。getControlledNodes(node)返回一个 DOM 节点数组,这些节点由给定 DOMnode控制。getFlowedNodes(node)返回一个 DOM 节点数组,这些节点从给定 DOMnode流向。getOwnedNodes(node)返回一个 DOM 节点数组,这些节点由给定 DOMnode拥有。getComputedProperties(node)返回一个对象,其中包含给定 DOMnode的各种可访问性属性。由于 HTML 允许标记中出现“不正确”的值(例如,属性的无效值),以下属性使用 WebKit 确定的计算值busy是一个布尔值,与 aria-busy 属性相关。checked是一个字符串,与 aria-checked 属性相关。currentState是一个字符串,与 aria-current 属性相关。disabled是一个布尔值,与 aria-disabled 属性相关。expanded是一个布尔值,与 aria-expanded 属性相关。focused是一个布尔值,表示给定node是否聚焦。headingLevel是一个数字,与 aria-level 属性和各种 HTML 标题元素相关。hidden是一个布尔值,与 aria-hidden 属性相关。hierarchicalLevel是一个数字,与 aria-level 属性相关。ignored是一个布尔值,表示给定node当前在可访问性树中是否被忽略。ignoredByDefault是一个布尔值,表示给定node是否始终被可访问性树忽略。invalidStatus是一个字符串,与 aria-invalid 属性相关。isPopUpButton是一个布尔值,与 aria-haspopup 属性相关。label是一个字符串,与 aria-label 属性相关。liveRegionAtomic是一个布尔值,与 aria-atomic 属性相关。liveRegionRelevant是一个字符串数组,与 aria-relevant 属性相关。liveRegionStatus是一个字符串,与 aria-live 属性相关。pressed是一个布尔值,与 aria-pressed 属性相关。readonly是一个布尔值,与 aria-readonly 属性相关。required是一个布尔值,与 aria-required 属性相关。role是一个字符串,与 role 属性相关。selected是一个布尔值,与 aria-selected 属性相关。
入门
如“Web Inspector 中的审计”博文所述,Web Inspector 中包含的演示审计和可访问性审计可用作 Web Inspector 审计格式和结构的良好入门模板。
或者,eslint.json 审计(它对从被检查页面的主源加载的每个 *.js 资源运行 ESLint)可以作为更复杂的 async 审计示例,它利用了上述一些特殊暴露的数据。
反馈
“审计”选项卡已在 Safari Technology Preview 75 中添加。在编写/运行审计时,是否有不支持的工作流或未暴露的数据是您希望使用的?您对 Web Inspector 中应该包含的默认审计有什么想法吗?请告诉我们!欢迎通过 Twitter(@dcrousso 或 @jonathandavis)或提交错误来向我们发送反馈。