Skip to content

Commit 8a68998

Browse files
authored
fix(accessibility): add visually hidden description text in tables (#896)
* fix(accessibility): add visually hidden description text in tables * use column not table in if * test: add integration test for blank column descriptions * suggestion for empty description text
1 parent b9fe912 commit 8a68998

5 files changed

+52
-13
lines changed

templates/details_dashboard.html

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
<tr class="govuk-table__row">
2121
<td class="govuk-table__cell"><a href="{% url 'home:details' result_type=chart_type urn=chart.entity_ref.urn %}" class="govuk-link">{{chart.entity_ref.display_name}}</a></td>
2222
<td class="govuk-table__cell">
23-
{{ chart.description|markdown:3 }}
23+
{% if chart.description %}
24+
{{ chart.description|markdown:3 }}
25+
{% else %}
26+
<p class="govuk-visually-hidden">A description for {{chart.entity_ref.display_name}} does not exist</p>
27+
{% endif %}
2428
</td>
2529
</tr>
2630
{% endwith %}

templates/details_database.html

+4
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
<tr class="govuk-table__row">
2121
<td class="govuk-table__cell"><a href="{% url 'home:details' result_type=table_type urn=table.entity_ref.urn %}" class="govuk-link">{{table.entity_ref.display_name}}</a></td>
2222
<td class="govuk-table__cell">
23+
{% if table.description %}
2324
{% if table.description|length > 200 %}
2425
{{ table.description|slice:":200"|add:"..."|markdown:3 }}
2526
{% else %}
2627
{{ table.description|markdown:3 }}
2728
{% endif %}
29+
{% else %}
30+
<p class="govuk-visually-hidden">A description for {{table.entity_ref.display_name}} does not exist</p>
31+
{% endif %}
2832
</td>
2933
</tr>
3034
{% endwith %}

templates/details_table.html

+7-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@
2020
{% for column in entity.column_details %}
2121
<tr class="govuk-table__row">
2222
<td class="govuk-table__cell">{{column.display_name}}</td>
23-
<td class="govuk-table__cell column-description">{{column.description|default:''|markdown:3|truncatechars_html:300}}</td>
23+
<td class="govuk-table__cell column-description">
24+
{% if column.description %}
25+
{{column.description|default:''|markdown:3|truncatechars_html:300}}</td>
26+
{% else %}
27+
<p class="govuk-visually-hidden">A description for {{column.display_name}} does not exist</p>
28+
{% endif %}
29+
</td>
2430
<td class="govuk-table__cell">{{column.type|title}}</td>
2531
<td class="govuk-table__cell">{{column.nullable|yesno:"Yes,No,"}}</td>
2632
</tr>

tests/conftest.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ def search_result_from_database(database: Database):
329329
def generate_table_metadata(
330330
name: str = fake.unique.name(),
331331
description: str = fake.unique.paragraph(),
332+
column_description: str = "description **with markdown**",
332333
relations=None,
333334
custom_properties=None,
334335
) -> Table:
@@ -367,7 +368,7 @@ def generate_table_metadata(
367368
name="urn",
368369
display_name="urn",
369370
type="string",
370-
description="description **with markdown**",
371+
description=column_description,
371372
nullable=False,
372373
is_primary_key=True,
373374
foreign_keys=[
@@ -553,6 +554,11 @@ def example_dashboard(name="example_dashboard"):
553554
return generate_dashboard_metadata(name=name)
554555

555556

557+
@pytest.fixture(autouse=True)
558+
def example_table(name="example_table"):
559+
return generate_table_metadata(name=name)
560+
561+
556562
def generate_page(page_size=20, result_type: ResultType | None = None):
557563
"""
558564
Generate a fake search page
@@ -570,7 +576,7 @@ def client():
570576

571577

572578
@pytest.fixture(autouse=True)
573-
def mock_catalogue(request, example_database, example_dashboard):
579+
def mock_catalogue(request, example_database, example_dashboard, example_table):
574580
if "datahub" in request.keywords:
575581
yield None
576582
return
@@ -629,7 +635,7 @@ def mock_catalogue(request, example_database, example_dashboard):
629635
)
630636
mock_get_glossary_terms_response(mock_catalogue)
631637
mock_get_chart_details_response(mock_catalogue)
632-
mock_get_table_details_response(mock_catalogue)
638+
mock_get_table_details_response(mock_catalogue, example_table)
633639
mock_get_database_details_response(mock_catalogue, example_database)
634640
mock_get_dashboard_details_response(mock_catalogue, example_dashboard)
635641
mock_get_tags_response(mock_catalogue)
@@ -650,8 +656,8 @@ def mock_get_chart_details_response(mock_catalogue):
650656
mock_catalogue.get_chart_details.return_value = generate_chart_metadata()
651657

652658

653-
def mock_get_table_details_response(mock_catalogue):
654-
mock_catalogue.get_table_details.return_value = generate_table_metadata()
659+
def mock_get_table_details_response(mock_catalogue, example_table):
660+
mock_catalogue.get_table_details.return_value = example_table
655661

656662

657663
def mock_get_dashboard_details_response(mock_catalogue, example_dashboard):

tests/integration/test_interact_with_search_results.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from tests.conftest import (
55
generate_page,
6+
generate_table_metadata,
7+
mock_get_table_details_response,
68
mock_search_response,
79
search_result_from_database,
810
)
@@ -49,7 +51,26 @@ def test_table_search_to_details(self, mock_catalogue):
4951
self.start_on_the_search_page()
5052
self.enter_a_query_and_submit("court timeliness")
5153
self.click_on_the_first_result()
52-
self.verify_i_am_on_the_table_details_page()
54+
self.verify_i_am_on_the_table_details_page("description with markdown")
55+
56+
def test_table_search_to_details_accessibility(self, mock_catalogue):
57+
"""
58+
Users with accessibility needs are presented with useful description info in details
59+
tables, e.g. for missing details of a column in a table
60+
"""
61+
mock_search_response(
62+
mock_catalogue=mock_catalogue,
63+
page_results=generate_page(result_type=ResultType.TABLE),
64+
total_results=100,
65+
)
66+
table_no_column_description = generate_table_metadata(column_description="")
67+
mock_get_table_details_response(mock_catalogue, table_no_column_description)
68+
self.start_on_the_search_page()
69+
self.enter_a_query_and_submit("court timeliness")
70+
self.click_on_the_first_result()
71+
self.verify_i_am_on_the_table_details_page(
72+
"A description for urn does not exist"
73+
)
5374

5475
def test_database_search_to_table_details(self, mock_catalogue, example_database):
5576
"""
@@ -67,7 +88,7 @@ def test_database_search_to_table_details(self, mock_catalogue, example_database
6788
self.verify_database_details()
6889
self.verify_database_tables_listed()
6990
self.click_on_table()
70-
self.verify_i_am_on_the_table_details_page()
91+
self.verify_i_am_on_the_table_details_page("description with markdown")
7192

7293
def start_on_the_search_page(self):
7394
self.selenium.get(f"{self.live_server_url}/search?new=True")
@@ -112,12 +133,10 @@ def verify_database_details(self):
112133
def click_on_table(self):
113134
self.details_database_page.table_link().click()
114135

115-
def verify_i_am_on_the_table_details_page(self):
136+
def verify_i_am_on_the_table_details_page(self, column_description):
116137
heading_text = self.details_database_page.primary_heading().text.replace(
117138
" Table", ""
118139
)
119140
assert heading_text == self.selenium.title.split("-")[0].strip()
120141

121-
assert self.table_details_page.column_descriptions() == [
122-
"description with markdown"
123-
]
142+
assert self.table_details_page.column_descriptions() == [column_description]

0 commit comments

Comments
 (0)