@@ -38,8 +38,9 @@ def filter_ignored_violations(violations, url_pathname):
38
38
]:
39
39
filtered = []
40
40
for violation in violations :
41
- # TODO: eventually fix this rule violation. See
42
- # https://github.com/pydata/pydata-sphinx-theme/issues/1479.
41
+ # TODO: remove this exclusion once the following update to Axe is
42
+ # released and we upgrade:
43
+ # https://github.com/dequelabs/axe-core/pull/4469
43
44
if violation ["id" ] == "landmark-unique" :
44
45
# Ignore landmark-unique only for .sidebar targets. Don't ignore
45
46
# it for other targets because then the test might fail to catch
@@ -167,6 +168,13 @@ def test_axe_core(
167
168
# Wait for CSS transitions (Bootstrap's transitions are 300 ms)
168
169
page .wait_for_timeout (301 )
169
170
171
+ # On the PyData Library Styles page, wait for ipywidget to load and for our
172
+ # JavaScript to apply tabindex="0" before running Axe checker (to avoid
173
+ # false positives for scrollable-region-focusable).
174
+ if url_pathname == "/examples/pydata.html" :
175
+ ipywidgets_pandas_table = page .locator ("css=.jp-RenderedHTMLCommon" ).first
176
+ expect (ipywidgets_pandas_table ).to_have_attribute ("tabindex" , "0" )
177
+
170
178
# Inject the Axe-core JavaScript library into the page
171
179
page .add_script_tag (path = "node_modules/axe-core/axe.min.js" )
172
180
@@ -176,6 +184,35 @@ def test_axe_core(
176
184
177
185
# Check found violations against known violations that we do not plan to fix
178
186
filtered_violations = filter_ignored_violations (results ["violations" ], url_pathname )
187
+
188
+ # We expect notebook outputs on the PyData Library Styles page to have color
189
+ # contrast failures.
190
+ if url_pathname == "/examples/pydata.html" :
191
+ # All violations should be color contrast violations
192
+ for violation in filtered_violations :
193
+ assert (
194
+ violation ["id" ] == "color-contrast"
195
+ ), f"Found { violation ['id' ]} violation (expected color-contrast): { format_violations ([violation ])} "
196
+
197
+ # Now check that when we exclude notebook outputs, the page has no violations
198
+
199
+ results_sans_nbout = page .evaluate (
200
+ f"axe.run({{ include: '{ selector } ', exclude: '.nboutput > .output_area' }})"
201
+ )
202
+ violations_sans_nbout = filter_ignored_violations (
203
+ results_sans_nbout ["violations" ], url_pathname
204
+ )
205
+
206
+ # No violations on page when excluding notebook outputs
207
+ assert len (violations_sans_nbout ) == 0 , format_violations (violations_sans_nbout )
208
+
209
+ # TODO: for color contrast issues with common notebook outputs
210
+ # (ipywidget tabbed panels, Xarray, etc.), should we override
211
+ # third-party CSS with our own CSS or/and work with NbSphinx, MyST-NB,
212
+ # ipywidgets, and other third parties to use higher contrast colors in
213
+ # their CSS?
214
+ pytest .xfail ("notebook outputs have color contrast violations" )
215
+
179
216
assert len (filtered_violations ) == 0 , format_violations (filtered_violations )
180
217
181
218
0 commit comments