mirror of
https://github.com/django/django.git
synced 2025-10-26 15:16:09 +00:00
Refs #35189 -- Improved admin fieldset's accessibility by setting aria-labelledby.
Before this change, HTML <fieldset> elements in the admin site did not have an associated label to describe them. This commit defines a unique HTML id for the heading labeling a fieldset, and sets its aria-labelledby property to link the heading with the fieldset.
This commit is contained in:
committed by
nessita
parent
9c5fe93349
commit
01ed59f753
@@ -117,7 +117,14 @@ class TestInline(TestDataMixin, TestCase):
|
||||
"Autogenerated many-to-many inlines are displayed correctly (#13407)"
|
||||
response = self.client.get(reverse("admin:admin_inlines_author_add"))
|
||||
# The heading for the m2m inline block uses the right text
|
||||
self.assertContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
# The "add another" label is correct
|
||||
self.assertContains(response, "Add another Author-book relationship")
|
||||
# The '+' is dropped from the autogenerated form prefix (Author_books+)
|
||||
@@ -737,13 +744,35 @@ class TestInline(TestDataMixin, TestCase):
|
||||
|
||||
def test_inlines_plural_heading_foreign_key(self):
|
||||
response = self.client.get(reverse("admin:admin_inlines_holder4_add"))
|
||||
self.assertContains(response, "<h2>Inner4 stackeds</h2>", html=True)
|
||||
self.assertContains(response, "<h2>Inner4 tabulars</h2>", html=True)
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="inner4stacked_set-heading" class="inline-heading">'
|
||||
"Inner4 stackeds</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="inner4tabular_set-heading" class="inline-heading">'
|
||||
"Inner4 tabulars</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_inlines_singular_heading_one_to_one(self):
|
||||
response = self.client.get(reverse("admin:admin_inlines_person_add"))
|
||||
self.assertContains(response, "<h2>Author</h2>", html=True) # Tabular.
|
||||
self.assertContains(response, "<h2>Fashionista</h2>", html=True) # Stacked.
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="author-heading" class="inline-heading">Author</h2>',
|
||||
html=True,
|
||||
) # Tabular.
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="fashionista-heading" class="inline-heading">Fashionista</h2>',
|
||||
html=True,
|
||||
) # Stacked.
|
||||
|
||||
def test_inlines_based_on_model_state(self):
|
||||
parent = ShowInlineParent.objects.create(show_inlines=False)
|
||||
@@ -914,28 +943,50 @@ class TestInlinePermissions(TestCase):
|
||||
def test_inline_add_m2m_noperm(self):
|
||||
response = self.client.get(reverse("admin:admin_inlines_author_add"))
|
||||
# No change permission on books, so no inline
|
||||
self.assertNotContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Author-Book Relationship")
|
||||
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
|
||||
|
||||
def test_inline_add_fk_noperm(self):
|
||||
response = self.client.get(reverse("admin:admin_inlines_holder2_add"))
|
||||
# No permissions on Inner2s, so no inline
|
||||
self.assertNotContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Inner2")
|
||||
self.assertNotContains(response, 'id="id_inner2_set-TOTAL_FORMS"')
|
||||
|
||||
def test_inline_change_m2m_noperm(self):
|
||||
response = self.client.get(self.author_change_url)
|
||||
# No change permission on books, so no inline
|
||||
self.assertNotContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Author-Book Relationship")
|
||||
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
|
||||
|
||||
def test_inline_change_fk_noperm(self):
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# No permissions on Inner2s, so no inline
|
||||
self.assertNotContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Inner2")
|
||||
self.assertNotContains(response, 'id="id_inner2_set-TOTAL_FORMS"')
|
||||
|
||||
@@ -959,7 +1010,14 @@ class TestInlinePermissions(TestCase):
|
||||
self.assertIs(
|
||||
response.context["inline_admin_formset"].has_delete_permission, False
|
||||
)
|
||||
self.assertContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<input type="hidden" name="Author_books-TOTAL_FORMS" value="0" '
|
||||
@@ -975,7 +1033,14 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(reverse("admin:admin_inlines_author_add"))
|
||||
# No change permission on Books, so no inline
|
||||
self.assertNotContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Author-Book Relationship")
|
||||
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
|
||||
|
||||
@@ -986,7 +1051,11 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(reverse("admin:admin_inlines_holder2_add"))
|
||||
# Add permission on inner2s, so we get the inline
|
||||
self.assertContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Inner2")
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1002,7 +1071,14 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.author_change_url)
|
||||
# No change permission on books, so no inline
|
||||
self.assertNotContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Author-Book Relationship")
|
||||
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
|
||||
self.assertNotContains(response, 'id="id_Author_books-0-DELETE"')
|
||||
@@ -1026,7 +1102,14 @@ class TestInlinePermissions(TestCase):
|
||||
self.assertIs(
|
||||
response.context["inline_admin_formset"].has_delete_permission, False
|
||||
)
|
||||
self.assertContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<input type="hidden" name="Author_books-TOTAL_FORMS" value="1" '
|
||||
@@ -1059,7 +1142,14 @@ class TestInlinePermissions(TestCase):
|
||||
self.assertIs(
|
||||
response.context["inline_admin_formset"].has_delete_permission, True
|
||||
)
|
||||
self.assertContains(response, "<h2>Author-book relationships</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="Author_books-heading" class="inline-heading">'
|
||||
"Author-book relationships</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Author-book relationship")
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1082,7 +1172,11 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# Add permission on inner2s, so we can add but not modify existing
|
||||
self.assertContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Inner2")
|
||||
# 3 extra forms only, not the existing instance form
|
||||
self.assertContains(
|
||||
@@ -1105,7 +1199,16 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# Change permission on inner2s, so we can change existing but not add new
|
||||
self.assertContains(response, "<h2>Inner2s</h2>", count=2)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
# Just the one form for existing instances
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1148,7 +1251,11 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# Add/change perm, so we can add new and change existing
|
||||
self.assertContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
# One form for existing instance and three extra for new
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1174,7 +1281,11 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# Change/delete perm on inner2s, so we can change/delete existing
|
||||
self.assertContains(response, "<h2>Inner2s</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
# One form for existing instance only, no new
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1205,7 +1316,16 @@ class TestInlinePermissions(TestCase):
|
||||
self.user.user_permissions.add(permission)
|
||||
response = self.client.get(self.holder_change_url)
|
||||
# All perms on inner2s, so we can add/change/delete
|
||||
self.assertContains(response, "<h2>Inner2s</h2>", count=2)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="inner2_set-2-heading" class="inline-heading">Inner2s</h2>',
|
||||
html=True,
|
||||
)
|
||||
# One form for existing instance only, three for new
|
||||
self.assertContains(
|
||||
response,
|
||||
@@ -1367,22 +1487,69 @@ class TestVerboseNameInlineForms(TestDataMixin, TestCase):
|
||||
response = modeladmin.changeform_view(request)
|
||||
self.assertNotContains(response, "Add another Profile")
|
||||
# Non-verbose model.
|
||||
self.assertContains(response, "<h2>Non-verbose childss</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="profile_set-heading" class="inline-heading">'
|
||||
"Non-verbose childss</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Non-verbose child")
|
||||
self.assertNotContains(response, "<h2>Profiles</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="profile_set-heading" class="inline-heading">Profiles</h2>',
|
||||
html=True,
|
||||
)
|
||||
# Model with verbose name.
|
||||
self.assertContains(response, "<h2>Childs with verbose names</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose names</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Childs with verbose name")
|
||||
self.assertNotContains(response, "<h2>Model with verbose name onlys</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name onlys</h2>",
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Model with verbose name only")
|
||||
# Model with verbose name plural.
|
||||
self.assertContains(response, "<h2>Childs with verbose name plurals</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose name plurals</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Childs with verbose name plural")
|
||||
self.assertNotContains(response, "<h2>Model with verbose name plural only</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name plural only</h2>",
|
||||
html=True,
|
||||
)
|
||||
# Model with both verbose names.
|
||||
self.assertContains(response, "<h2>Childs with both verbose namess</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with both verbose namess</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Childs with both verbose names")
|
||||
self.assertNotContains(response, "<h2>Model with both - plural name</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with both - plural name</h2>",
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Model with both - name")
|
||||
|
||||
def test_verbose_name_plural_inline(self):
|
||||
@@ -1415,21 +1582,68 @@ class TestVerboseNameInlineForms(TestDataMixin, TestCase):
|
||||
request.user = self.superuser
|
||||
response = modeladmin.changeform_view(request)
|
||||
# Non-verbose model.
|
||||
self.assertContains(response, "<h2>Non-verbose childs</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="profile_set-heading" class="inline-heading">'
|
||||
"Non-verbose childs</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Profile")
|
||||
self.assertNotContains(response, "<h2>Profiles</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="profile_set-heading" class="inline-heading">Profiles</h2>',
|
||||
html=True,
|
||||
)
|
||||
# Model with verbose name.
|
||||
self.assertContains(response, "<h2>Childs with verbose name</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose name</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Model with verbose name only")
|
||||
self.assertNotContains(response, "<h2>Model with verbose name onlys</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name onlys</h2>",
|
||||
html=True,
|
||||
)
|
||||
# Model with verbose name plural.
|
||||
self.assertContains(response, "<h2>Childs with verbose name plural</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose name plural</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Profile")
|
||||
self.assertNotContains(response, "<h2>Model with verbose name plural only</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name plural only</h2>",
|
||||
html=True,
|
||||
)
|
||||
# Model with both verbose names.
|
||||
self.assertContains(response, "<h2>Childs with both verbose names</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with both verbose names</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Model with both - name")
|
||||
self.assertNotContains(response, "<h2>Model with both - plural name</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with both - plural name</h2>",
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_both_verbose_names_inline(self):
|
||||
class NonVerboseProfileInline(TabularInline):
|
||||
@@ -1466,30 +1680,148 @@ class TestVerboseNameInlineForms(TestDataMixin, TestCase):
|
||||
response = modeladmin.changeform_view(request)
|
||||
self.assertNotContains(response, "Add another Profile")
|
||||
# Non-verbose model.
|
||||
self.assertContains(response, "<h2>Non-verbose childs - plural name</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="profile_set-heading" class="inline-heading">'
|
||||
"Non-verbose childs - plural name</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Non-verbose childs - name")
|
||||
self.assertNotContains(response, "<h2>Profiles</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="profile_set-heading" class="inline-heading">Profiles</h2>',
|
||||
html=True,
|
||||
)
|
||||
# Model with verbose name.
|
||||
self.assertContains(response, "<h2>Childs with verbose name - plural name</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
(
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose name - plural name</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Childs with verbose name - name")
|
||||
self.assertNotContains(response, "<h2>Model with verbose name onlys</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name onlys</h2>",
|
||||
html=True,
|
||||
)
|
||||
# Model with verbose name plural.
|
||||
self.assertContains(
|
||||
response,
|
||||
"<h2>Childs with verbose name plural - plural name</h2>",
|
||||
(
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Childs with verbose name plural - plural name</h2>"
|
||||
),
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
"Add another Childs with verbose name plural - name",
|
||||
)
|
||||
self.assertNotContains(response, "<h2>Model with verbose name plural only</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="verbosenamepluralprofile_set-heading" class="inline-heading">'
|
||||
"Model with verbose name plural only</h2>",
|
||||
html=True,
|
||||
)
|
||||
# Model with both verbose names.
|
||||
self.assertContains(response, "<h2>Childs with both - plural name</h2>")
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Childs with both - plural name</h2>",
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(response, "Add another Childs with both - name")
|
||||
self.assertNotContains(response, "<h2>Model with both - plural name</h2>")
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<h2 id="bothverbosenameprofile_set-heading" class="inline-heading">'
|
||||
"Model with both - plural name</h2>",
|
||||
html=True,
|
||||
)
|
||||
self.assertNotContains(response, "Add another Model with both - name")
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF="admin_inlines.urls")
|
||||
class TestInlineWithFieldsets(TestDataMixin, TestCase):
|
||||
def setUp(self):
|
||||
self.client.force_login(self.superuser)
|
||||
|
||||
def test_inline_headings(self):
|
||||
response = self.client.get(reverse("admin:admin_inlines_photographer_add"))
|
||||
# Page main title.
|
||||
self.assertContains(response, "<h1>Add photographer</h1>", html=True)
|
||||
|
||||
# Headings for the toplevel fieldsets. The first one has no name.
|
||||
self.assertContains(response, '<fieldset class="module aligned ">')
|
||||
# The second and third have the same "Advanced options" name, but the
|
||||
# second one has the "collapse" class.
|
||||
for x, classes in ((1, ""), (2, "collapse")):
|
||||
heading_id = f"fieldset-0-advanced-options-{x}-heading"
|
||||
with self.subTest(heading_id=heading_id):
|
||||
self.assertContains(
|
||||
response,
|
||||
f'<fieldset class="module aligned {classes}" '
|
||||
f'aria-labelledby="{heading_id}">',
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
f'<h2 id="{heading_id}" class="fieldset-heading">'
|
||||
"Advanced options</h2>",
|
||||
)
|
||||
self.assertContains(response, f'id="{heading_id}"', count=1)
|
||||
|
||||
# Headings and subheadings for all the inlines.
|
||||
for inline_admin_formset in response.context["inline_admin_formsets"]:
|
||||
prefix = inline_admin_formset.formset.prefix
|
||||
heading_id = f"{prefix}-heading"
|
||||
formset_heading = (
|
||||
f'<h2 id="{heading_id}" class="inline-heading">Photos</h2>'
|
||||
)
|
||||
self.assertContains(response, formset_heading, html=True)
|
||||
self.assertContains(response, f'id="{heading_id}"', count=1)
|
||||
|
||||
# If this is a TabularInline, do not make further asserts since
|
||||
# fieldsets are not shown as such in this table layout.
|
||||
if "tabular" in inline_admin_formset.opts.template:
|
||||
continue
|
||||
|
||||
# Headings for every formset (the amount depends on `extra`).
|
||||
for y, inline_admin_form in enumerate(inline_admin_formset):
|
||||
y_plus_one = y + 1
|
||||
form_heading = (
|
||||
f'<h3><b>Photo:</b> <span class="inline_label">#{y_plus_one}</span>'
|
||||
"</h3>"
|
||||
)
|
||||
self.assertContains(response, form_heading, html=True)
|
||||
|
||||
# Every fieldset defined for an inline's form.
|
||||
for z, fieldset in enumerate(inline_admin_form):
|
||||
if fieldset.name:
|
||||
heading_id = f"{prefix}-{y}-details-{z}-heading"
|
||||
self.assertContains(
|
||||
response,
|
||||
f'<fieldset class="module aligned {fieldset.classes}" '
|
||||
f'aria-labelledby="{heading_id}">',
|
||||
)
|
||||
fieldset_heading = (
|
||||
f'<h4 id="{heading_id}" class="fieldset-heading">'
|
||||
f"Details</h4>"
|
||||
)
|
||||
self.assertContains(response, fieldset_heading)
|
||||
self.assertContains(response, f'id="{heading_id}"', count=1)
|
||||
|
||||
else:
|
||||
fieldset_html = (
|
||||
f'<fieldset class="module aligned {fieldset.classes}">'
|
||||
)
|
||||
self.assertContains(response, fieldset_html)
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF="admin_inlines.urls")
|
||||
class SeleniumTests(AdminSeleniumTestCase):
|
||||
available_apps = ["admin_inlines"] + AdminSeleniumTestCase.available_apps
|
||||
|
||||
Reference in New Issue
Block a user