Cypress无障碍测试高级解决方案
attributeFilters
Cypress 无障碍测试基于属性组合及周边 DOM 结构来识别元素。
某些用于识别的属性可能是自动生成的、动态的或不具代表性的,这会导致识别或分组不准确。通过配置 attributeFilters
属性,您可以排除不应用于这些目的的特定属性或模式。
使用 attributeFilters
能确保 Cypress 选择更合适的标识符,从而生成更清晰准确的报告,并在被测应用的不同状态间实现更好的元素去重。
为何使用属性过滤器?
- 处理库特定属性:由库生成的属性可能无法代表元素的用途,应予以忽略。
- 提高分组准确性:通过过滤无关属性,确保相似元素被正确分组。
- 简化报告:去除冗余属性可减少 Cypress 无障碍或 UI 覆盖率报告中的杂乱信息,使其更易于理解和处理。
适用范围
info
注意: 如果在配置的根节点设置 attributeFilters
,将同时影响 Cypress 无障碍和 UI 覆盖率报告。如需分别配置,可将该属性嵌套在 accessibility
或 uiCoverage
键下。
语法
{
"attributeFilters": [
{
"attribute": string,
"value": string,
"include": boolean
}
]
}
选项
对于元素的每个属性,第一个 attributeFilters
规则(其中 attribute
属性匹配属性名且 value
属性匹配属性值)的 include
值将决定该属性是否用于元素识别和分组。未匹配任何规则的属性默认会被包含。
选项 | 是否必填 | 默认值 | 描述 |
---|---|---|---|
attribute | 必填 | 用于匹配属性名的正则表达式字符串 | |
value | 可选 | .* | 用于匹配属性值的正则表达式字符串 |
include | 可选 | true | 布尔值,指定匹配到的属性是否应被包含 |
示例
排除常见的自动生成 ID 值
{
"uiCoverage": {
"attributeFilters": [
{
"attribute": "id",
"value": ":r.*:",
"include": false
}
]
}
}
HTML
<body>
<button id=":r11:" name="my-button">按钮 1</button>
<button id=":r12:" name="other-button">按钮 2</button>
</body>
UI 覆盖率中显示的元素
[name="my-button"]
[name="other-button"]
排除自动生成的属性名
{
"uiCoverage": {
"attributeFilters": [
{
"attribute": "ng-include-me",
"value": ".*",
"include": true
},
{
"attribute": "ng-.*",
"value": ".*",
"include": false
}
]
}
}
HTML
<body>
<button ng-include-me="my-button">按钮 1</button>
<button ng-but-not-me="other-button">按钮 2</button>
</body>
UI 覆盖率中显示的元素
[ng-include-me="my-button"]
:nth-child(2)
忽略动态属性以实现准确分组
{
"uiCoverage": {
"attributeFilters": [
{
"attribute": "data-cy",
"value": "user-\\d+",
"include": false
}
]
}
}
HTML
<button data-cy="user-123" class="user">Harper</button>
<button data-cy="user-456" class="user">Amara</button>
UI 覆盖率中显示的元素
.user (2 个实例)
过滤相关的动态属性
过滤动态 id
属性时,还应过滤引用这些 ID 的属性,以防止通过这些相关的动态值识别元素。常见关联包括:
- 表单关联(标签上的
for
属性) - ARIA 关系(
aria-labelledby
、aria-describedby
、aria-controls
、aria-owns
、aria-details
) - 某些框架中可能镜像 ID 的 name 属性
{
"uiCoverage": {
"attributeFilters": [
{
"attribute": "id|for|name|aria-.*",
"value": "dynamic-.*",
"include": false
}
]
}
}
HTML
<div>
<label for="dynamic-input-1">姓氏</label>
<input id="dynamic-input-1" name="dynamic-input-1" aria-describedby="dynamic-help-1" />
<p id="dynamic-help-1">请输入您的姓氏</p>
</div>