summaryrefslogtreecommitdiff
path: root/tests/admin_inlines
diff options
context:
space:
mode:
authorMarijke Luttekes <mail@marijkeluttekes.dev>2024-05-20 14:39:09 -0300
committernessita <124304+nessita@users.noreply.github.com>2024-05-22 00:13:55 -0300
commite4a693f50a8342ed1a54b74e1a202b44c8e62981 (patch)
treefe5924414b2edafaec2ee4c7709cbf86dfc94220 /tests/admin_inlines
parent01ed59f753139afb514170ee7f7384c155ecbc2d (diff)
Fixed #35189 -- Improved admin collapsible fieldsets by using <details> elements.
This work improves the accessibility of the add and change pages in the admin site by adding <details> and <summary> elements to the collapsible fieldsets. This has the nice side effect of no longer requiring custom JavaScript helpers to implement the fieldsets' show/hide capabilities. Thanks to James Scholes for the accessibility advice, and to Sarah Boyce and Tom Carrick for reviews. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Diffstat (limited to 'tests/admin_inlines')
-rw-r--r--tests/admin_inlines/tests.py86
1 files changed, 47 insertions, 39 deletions
diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py
index 7b38619cc0..dee703825d 100644
--- a/tests/admin_inlines/tests.py
+++ b/tests/admin_inlines/tests.py
@@ -4,7 +4,9 @@ from django.contrib.admin.tests import AdminSeleniumTestCase
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.test import RequestFactory, TestCase, override_settings
+from django.test.selenium import screenshot_cases
from django.urls import reverse
+from django.utils.translation import gettext
from .admin import InnerInline
from .admin import site as admin_site
@@ -1790,6 +1792,10 @@ class TestInlineWithFieldsets(TestDataMixin, TestCase):
if "tabular" in inline_admin_formset.opts.template:
continue
+ if "collapse" in inline_admin_formset.classes:
+ formset_heading = f"<summary>{formset_heading}</summary>"
+ self.assertContains(response, formset_heading, html=True, count=1)
+
# Headings for every formset (the amount depends on `extra`).
for y, inline_admin_form in enumerate(inline_admin_formset):
y_plus_one = y + 1
@@ -1813,6 +1819,12 @@ class TestInlineWithFieldsets(TestDataMixin, TestCase):
f"Details</h4>"
)
self.assertContains(response, fieldset_heading)
+ if "collapse" in fieldset.classes:
+ self.assertContains(
+ response,
+ f"<summary>{fieldset_heading}</summary>",
+ html=True,
+ )
self.assertContains(response, f'id="{heading_id}"', count=1)
else:
@@ -2182,10 +2194,11 @@ class SeleniumTests(AdminSeleniumTestCase):
"form#profilecollection_form tr.dynamic-profile_set#profile_set-2", 1
)
+ @screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_collapsed_inlines(self):
from selenium.webdriver.common.by import By
- # Collapsed inlines have SHOW/HIDE links.
+ # Collapsed inlines use details and summary elements.
self.admin_login(username="super", password="secret")
self.selenium.get(
self.live_server_url + reverse("admin:admin_inlines_author_add")
@@ -2195,19 +2208,21 @@ class SeleniumTests(AdminSeleniumTestCase):
"#id_nonautopkbook_set-0-title",
"#id_nonautopkbook_set-2-0-title",
]
- show_links = self.selenium.find_elements(By.LINK_TEXT, "SHOW")
- self.assertEqual(len(show_links), 3)
+ summaries = self.selenium.find_elements(By.TAG_NAME, "summary")
+ self.assertEqual(len(summaries), 3)
+ self.take_screenshot("loaded")
for show_index, field_name in enumerate(test_fields, 0):
self.wait_until_invisible(field_name)
- show_links[show_index].click()
+ summaries[show_index].click()
self.wait_until_visible(field_name)
- hide_links = self.selenium.find_elements(By.LINK_TEXT, "HIDE")
- self.assertEqual(len(hide_links), 2)
+ self.take_screenshot("expanded")
for hide_index, field_name in enumerate(test_fields, 0):
self.wait_until_visible(field_name)
- hide_links[hide_index].click()
+ summaries[hide_index].click()
self.wait_until_invisible(field_name)
+ self.take_screenshot("collapsed")
+ @screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_added_stacked_inline_with_collapsed_fields(self):
from selenium.webdriver.common.by import By
@@ -2215,20 +2230,22 @@ class SeleniumTests(AdminSeleniumTestCase):
self.selenium.get(
self.live_server_url + reverse("admin:admin_inlines_teacher_add")
)
- self.selenium.find_element(By.LINK_TEXT, "Add another Child").click()
+ add_text = gettext("Add another %(verbose_name)s") % {"verbose_name": "Child"}
+ self.selenium.find_element(By.LINK_TEXT, add_text).click()
test_fields = ["#id_child_set-0-name", "#id_child_set-1-name"]
- show_links = self.selenium.find_elements(By.LINK_TEXT, "SHOW")
- self.assertEqual(len(show_links), 2)
+ summaries = self.selenium.find_elements(By.TAG_NAME, "summary")
+ self.assertEqual(len(summaries), 3)
+ self.take_screenshot("loaded")
for show_index, field_name in enumerate(test_fields, 0):
self.wait_until_invisible(field_name)
- show_links[show_index].click()
+ summaries[show_index].click()
self.wait_until_visible(field_name)
- hide_links = self.selenium.find_elements(By.LINK_TEXT, "HIDE")
- self.assertEqual(len(hide_links), 2)
+ self.take_screenshot("expanded")
for hide_index, field_name in enumerate(test_fields, 0):
self.wait_until_visible(field_name)
- hide_links[hide_index].click()
+ summaries[hide_index].click()
self.wait_until_invisible(field_name)
+ self.take_screenshot("collapsed")
def assertBorder(self, element, border):
width, style, color = border.split(" ")
@@ -2264,9 +2281,9 @@ class SeleniumTests(AdminSeleniumTestCase):
self.wait_until_visible("#id_dummy")
self.selenium.find_element(By.ID, "id_dummy").send_keys(1)
fields = ["id_inner5stacked_set-0-dummy", "id_inner5tabular_set-0-dummy"]
- show_links = self.selenium.find_elements(By.LINK_TEXT, "SHOW")
+ summaries = self.selenium.find_elements(By.TAG_NAME, "summary")
for show_index, field_name in enumerate(fields):
- show_links[show_index].click()
+ summaries[show_index].click()
self.wait_until_visible("#" + field_name)
self.selenium.find_element(By.ID, field_name).send_keys(1)
@@ -2304,49 +2321,40 @@ class SeleniumTests(AdminSeleniumTestCase):
self.selenium.get(
self.live_server_url + reverse("admin:admin_inlines_holder5_add")
)
- stacked_inline_formset_selector = (
- "div#inner5stacked_set-group fieldset.module.collapse"
+ stacked_inline_details_selector = (
+ "div#inner5stacked_set-group fieldset.module.collapse details"
)
- tabular_inline_formset_selector = (
- "div#inner5tabular_set-group fieldset.module.collapse"
+ tabular_inline_details_selector = (
+ "div#inner5tabular_set-group fieldset.module.collapse details"
)
# Inlines without errors, both inlines collapsed
self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
self.assertCountSeleniumElements(
- stacked_inline_formset_selector + ".collapsed", 1
+ stacked_inline_details_selector + ":not([open])", 1
)
self.assertCountSeleniumElements(
- tabular_inline_formset_selector + ".collapsed", 1
+ tabular_inline_details_selector + ":not([open])", 1
)
- show_links = self.selenium.find_elements(By.LINK_TEXT, "SHOW")
- self.assertEqual(len(show_links), 2)
+ summaries = self.selenium.find_elements(By.TAG_NAME, "summary")
+ self.assertEqual(len(summaries), 2)
# Inlines with errors, both inlines expanded
test_fields = ["#id_inner5stacked_set-0-dummy", "#id_inner5tabular_set-0-dummy"]
for show_index, field_name in enumerate(test_fields):
- show_links[show_index].click()
+ summaries[show_index].click()
self.wait_until_visible(field_name)
self.selenium.find_element(By.ID, field_name[1:]).send_keys(1)
- hide_links = self.selenium.find_elements(By.LINK_TEXT, "HIDE")
- self.assertEqual(len(hide_links), 2)
for hide_index, field_name in enumerate(test_fields):
- hide_link = hide_links[hide_index]
+ summary = summaries[hide_index]
self.selenium.execute_script(
- "window.scrollTo(0, %s);" % hide_link.location["y"]
+ "window.scrollTo(0, %s);" % summary.location["y"]
)
- hide_link.click()
+ summary.click()
self.wait_until_invisible(field_name)
with self.wait_page_loaded():
self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
- with self.disable_implicit_wait():
- self.assertCountSeleniumElements(
- stacked_inline_formset_selector + ".collapsed", 0
- )
- self.assertCountSeleniumElements(
- tabular_inline_formset_selector + ".collapsed", 0
- )
- self.assertCountSeleniumElements(stacked_inline_formset_selector, 1)
- self.assertCountSeleniumElements(tabular_inline_formset_selector, 1)
+ self.assertCountSeleniumElements(stacked_inline_details_selector, 0)
+ self.assertCountSeleniumElements(tabular_inline_details_selector, 0)
def test_inlines_verbose_name(self):
"""