创建 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 匹配,并且是container
DOM 节点(如果指定)或主文档的子节点。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)或提交错误来向我们发送反馈。