@@ -70,20 +70,69 @@ def url_base():
70
70
process .wait ()
71
71
72
72
73
- def fingerprint_violations ( accessibility_page_scan_violations ):
74
- """Create a fingerprint of the Axe violations array .
73
+ def filter_ignored_violations ( violations , url_pathname ):
74
+ """Filter out ignored axe-core violations.
75
75
76
- https://playwright.dev/docs/accessibility-testing#using-snapshots-to-allow-specific-known-issues
76
+ In some tests, we wish to ignore certain accessibility violations that we
77
+ won't ever fix or that we don't plan to fix soon.
77
78
"""
78
- return [
79
- {
80
- "id" : violation ["id" ],
81
- "help" : violation ["help" ],
82
- "helpUrl" : violation ["helpUrl" ],
83
- "targets" : [node ["target" ] for node in violation ["nodes" ]],
84
- }
85
- for violation in accessibility_page_scan_violations
86
- ]
79
+ # we allow empty table headers
80
+ # https://dequeuniversity.com/rules/axe/4.8/empty-table-header?application=RuleDescription
81
+ if url_pathname == "/examples/pydata.html" :
82
+ return [v for v in violations if v ["id" ] != "empty-table-header" ]
83
+ elif url_pathname in [
84
+ "/examples/kitchen-sink/generic.html" ,
85
+ "/user_guide/theme-elements.html" ,
86
+ ]:
87
+ filtered = []
88
+ for violation in violations :
89
+ # TODO: eventually fix this rule violation. See
90
+ # https://github.com/pydata/pydata-sphinx-theme/issues/1479.
91
+ if violation ["id" ] == "landmark-unique" :
92
+ # Ignore landmark-unique only for .sidebar targets. Don't ignore
93
+ # it for other targets because then the test might fail to catch
94
+ # a change that violates the rule in some other way.
95
+ unexpected_nodes = []
96
+ for node in violation ["nodes" ]:
97
+ # If some target is not .sidebar then we've found a rule
98
+ # violation we weren't expecting
99
+ if not all ([".sidebar" in target for target in node ["target" ]]):
100
+ unexpected_nodes .append (node )
101
+ if unexpected_nodes :
102
+ violation ["nodes" ] = unexpected_nodes
103
+ filtered .append (violation )
104
+ else :
105
+ filtered .append (violation )
106
+ return filtered
107
+ else :
108
+ return violations
109
+
110
+
111
+ def format_violations (violations ):
112
+ """Return a pretty string representation of Axe-core violations."""
113
+ result = f"""
114
+
115
+ Found { len (violations )} accessibility violation(s):
116
+ """
117
+
118
+ for violation in violations :
119
+ result += f"""
120
+
121
+ - Rule violated:
122
+ { violation ["id" ]} - { violation ["help" ]}
123
+ - URL: { violation ["helpUrl" ]}
124
+ - Impact: { violation ["impact" ]}
125
+ - Tags: { " " .join (violation ["tags" ])}
126
+ - Targets:"""
127
+
128
+ for node in violation ["nodes" ]:
129
+ for target in node ["target" ]:
130
+ result += f"""
131
+ - { target } """
132
+
133
+ result += "\n \n "
134
+
135
+ return result
87
136
88
137
89
138
@pytest .mark .a11y
@@ -122,7 +171,7 @@ def fingerprint_violations(accessibility_page_scan_violations):
122
171
"/examples/kitchen-sink/typography.html" ,
123
172
"#typography" ,
124
173
),
125
- ("/examples/pydata.html" , "#pydata-library-styles " ),
174
+ ("/examples/pydata.html" , "#PyData-Library-Styles " ),
126
175
(
127
176
"/user_guide/theme-elements.html" ,
128
177
"#theme-specific-elements" ,
@@ -142,16 +191,18 @@ def fingerprint_violations(accessibility_page_scan_violations):
142
191
# Using one of the simplest pages on the site, select the whole page for
143
192
# testing in order to effectively test repeated website elements like
144
193
# nav, sidebars, breadcrumbs, footer
145
- ("/user_guide/page-toc.html" , "" ),
194
+ (
195
+ "/user_guide/page-toc.html" ,
196
+ "" , # select whole page
197
+ ),
146
198
],
147
199
)
148
200
def test_axe_core (
149
- data_regression ,
150
- theme : str ,
201
+ page : Page ,
151
202
url_base : str ,
203
+ theme : str ,
152
204
url_pathname : str ,
153
205
selector : str ,
154
- page : Page ,
155
206
):
156
207
"""Should have no Axe-core violations at the provided theme and page section."""
157
208
# Load the page at the provided path
@@ -164,14 +215,13 @@ def test_axe_core(
164
215
# Inject the Axe-core JavaScript library into the page
165
216
page .add_script_tag (path = "node_modules/axe-core/axe.min.js" )
166
217
167
- # Run the Axe-core library against a section of the page. (Don't run it
168
- # against the whole page because in this test we're not trying to find
169
- # accessibility violations in the nav, sidebar, footer, or other parts of
170
- # the PyData Sphinx Theme documentation website.)
218
+ # Run the Axe-core library against a section of the page (unless the
219
+ # selector is empty, then run against the whole page)
171
220
results = page .evaluate ("axe.run()" if selector == "" else f"axe.run('{ selector } ')" )
172
221
173
222
# Check found violations against known violations that we do not plan to fix
174
- data_regression .check (fingerprint_violations (results ["violations" ]))
223
+ filtered_violations = filter_ignored_violations (results ["violations" ], url_pathname )
224
+ assert len (filtered_violations ) == 0 , format_violations (filtered_violations )
175
225
176
226
177
227
def test_version_switcher_highlighting (page : Page , url_base : str ) -> None :
0 commit comments