mirror of https://github.com/django/django.git
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>
This commit is contained in:
parent
01ed59f753
commit
e4a693f50a
|
@ -18,6 +18,7 @@ from django.db.models.fields.related import (
|
|||
from django.forms.utils import flatatt
|
||||
from django.template.defaultfilters import capfirst, linebreaksbr
|
||||
from django.urls import NoReverseMatch, reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import conditional_escape, format_html
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext
|
||||
|
@ -116,10 +117,14 @@ class Fieldset:
|
|||
|
||||
@property
|
||||
def media(self):
|
||||
if "collapse" in self.classes:
|
||||
return forms.Media(js=["admin/js/collapse.js"])
|
||||
return forms.Media()
|
||||
|
||||
@cached_property
|
||||
def is_collapsible(self):
|
||||
if any([field in self.fields for field in self.form.errors]):
|
||||
return False
|
||||
return "collapse" in self.classes
|
||||
|
||||
def __iter__(self):
|
||||
for field in self.fields:
|
||||
yield Fieldline(
|
||||
|
@ -438,6 +443,12 @@ class InlineAdminFormSet:
|
|||
def forms(self):
|
||||
return self.formset.forms
|
||||
|
||||
@cached_property
|
||||
def is_collapsible(self):
|
||||
if any(self.formset.errors):
|
||||
return False
|
||||
return "collapse" in self.classes
|
||||
|
||||
def non_form_errors(self):
|
||||
return self.formset.non_form_errors()
|
||||
|
||||
|
|
|
@ -2398,8 +2398,6 @@ class InlineModelAdmin(BaseModelAdmin):
|
|||
js = ["vendor/jquery/jquery%s.js" % extra, "jquery.init.js", "inlines.js"]
|
||||
if self.filter_vertical or self.filter_horizontal:
|
||||
js.extend(["SelectBox.js", "SelectFilter2.js"])
|
||||
if self.classes and "collapse" in self.classes:
|
||||
js.append("collapse.js")
|
||||
return forms.Media(js=["admin/js/%s" % url for url in js])
|
||||
|
||||
def get_extra(self, request, obj=None, **kwargs):
|
||||
|
|
|
@ -76,6 +76,20 @@ form ul.inline li {
|
|||
padding-right: 7px;
|
||||
}
|
||||
|
||||
/* FIELDSETS */
|
||||
|
||||
fieldset .fieldset-heading,
|
||||
fieldset .inline-heading,
|
||||
:not(.inline-related) .collapse summary {
|
||||
border: 1px solid var(--header-bg);
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
font-weight: 400;
|
||||
font-size: 0.8125rem;
|
||||
background: var(--header-bg);
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
/* ALIGNED FIELDSETS */
|
||||
|
||||
.aligned label {
|
||||
|
@ -207,35 +221,16 @@ form div.help ul {
|
|||
width: 450px;
|
||||
}
|
||||
|
||||
/* COLLAPSED FIELDSETS */
|
||||
/* COLLAPSIBLE FIELDSETS */
|
||||
|
||||
fieldset.collapsed * {
|
||||
display: none;
|
||||
}
|
||||
|
||||
fieldset.collapsed h2, fieldset.collapsed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
fieldset.collapsed {
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
fieldset.collapsed h2 {
|
||||
background: var(--darkened-bg);
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
fieldset .collapse-toggle {
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
fieldset.collapsed .collapse-toggle {
|
||||
.collapse summary .fieldset-heading,
|
||||
.collapse summary .inline-heading {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: currentColor;
|
||||
display: inline;
|
||||
color: var(--link-fg);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* MONOSPACE TEXTAREAS */
|
||||
|
@ -387,14 +382,16 @@ body.popup .submit-row {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.inline-related h3 {
|
||||
.inline-related h4,
|
||||
.inline-related:not(.tabular) .collapse summary {
|
||||
margin: 0;
|
||||
color: var(--body-quiet-color);
|
||||
padding: 5px;
|
||||
font-size: 0.8125rem;
|
||||
background: var(--darkened-bg);
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-left-color: var(--darkened-bg);
|
||||
border-right-color: var(--darkened-bg);
|
||||
}
|
||||
|
||||
.inline-related h3 span.delete {
|
||||
|
|
|
@ -565,10 +565,6 @@ input[type="submit"], button {
|
|||
padding-top: 15px;
|
||||
}
|
||||
|
||||
fieldset.collapsed .form-row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aligned label {
|
||||
width: 100%;
|
||||
min-width: auto;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
data-inline-type="stacked"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
|
||||
{% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
|
||||
<h2 id="{{ inline_admin_formset.formset.prefix }}-heading" class="inline-heading">
|
||||
{% if inline_admin_formset.formset.max_num == 1 %}
|
||||
{{ inline_admin_formset.opts.verbose_name|capfirst }}
|
||||
|
@ -11,6 +12,7 @@
|
|||
{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}
|
||||
{% endif %}
|
||||
</h2>
|
||||
{% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
|
||||
|
@ -31,5 +33,6 @@
|
|||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %}
|
||||
</div>{% endfor %}
|
||||
{% if inline_admin_formset.is_collapsible %}</details>{% endif %}
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
|
||||
{% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
|
||||
<h2 id="{{ inline_admin_formset.formset.prefix }}-heading" class="inline-heading">
|
||||
{% if inline_admin_formset.formset.max_num == 1 %}
|
||||
{{ inline_admin_formset.opts.verbose_name|capfirst }}
|
||||
|
@ -12,6 +13,7 @@
|
|||
{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}
|
||||
{% endif %}
|
||||
</h2>
|
||||
{% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
<table>
|
||||
<thead><tr>
|
||||
|
@ -63,6 +65,7 @@
|
|||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if inline_admin_formset.is_collapsible %}</details>{% endif %}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{% with prefix=fieldset.formset.prefix|default:"fieldset" id_prefix=id_prefix|default:"0" id_suffix=id_suffix|default:"0" name=fieldset.name|default:""|slugify %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}"{% if name %} aria-labelledby="{{ prefix }}-{{ id_prefix}}-{{ name }}-{{ id_suffix }}-heading"{% endif %}>
|
||||
{% if name %}
|
||||
{% if fieldset.is_collapsible %}<details><summary>{% endif %}
|
||||
<h{{ heading_level|default:2 }} id="{{ prefix }}-{{ id_prefix}}-{{ name }}-{{ id_suffix }}-heading" class="fieldset-heading">{{ fieldset.name }}</h{{ heading_level|default:2 }}>
|
||||
{% if fieldset.is_collapsible %}</summary>{% endif %}
|
||||
{% endif %}
|
||||
{% if fieldset.description %}
|
||||
<div class="description">{{ fieldset.description|safe }}</div>
|
||||
|
@ -34,5 +36,6 @@
|
|||
{% if not line.fields|length == 1 %}</div>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if name and fieldset.is_collapsible %}</details>{% endif %}
|
||||
</fieldset>
|
||||
{% endwith %}
|
||||
|
|
|
@ -424,9 +424,16 @@ subclass::
|
|||
"classes": ["wide", "collapse"],
|
||||
}
|
||||
|
||||
Fieldsets with the ``collapse`` style will be initially collapsed in
|
||||
the admin and replaced with a small "click to expand" link. Fieldsets
|
||||
with the ``wide`` style will be given extra horizontal space.
|
||||
Fieldsets with the ``wide`` style will be given extra horizontal
|
||||
space in the admin interface.
|
||||
Fieldsets with a name and the ``collapse`` style will be initially
|
||||
collapsed, using an expandable widget with a toggle for switching
|
||||
their visibility.
|
||||
|
||||
.. versionchanged:: 5.1
|
||||
|
||||
``fieldsets`` using the ``collapse`` class now use ``<details>``
|
||||
and ``<summary>`` elements, provided they define a ``name``.
|
||||
|
||||
* ``description``
|
||||
A string of optional extra text to be displayed at the top of each
|
||||
|
@ -2308,8 +2315,12 @@ The ``InlineModelAdmin`` class adds or customizes:
|
|||
A list or tuple containing extra CSS classes to apply to the fieldset that
|
||||
is rendered for the inlines. Defaults to ``None``. As with classes
|
||||
configured in :attr:`~ModelAdmin.fieldsets`, inlines with a ``collapse``
|
||||
class will be initially collapsed and their header will have a small "show"
|
||||
link.
|
||||
class will be initially collapsed using an expandable widget.
|
||||
|
||||
.. versionchanged:: 5.1
|
||||
|
||||
``fieldsets`` using the ``collapse`` class now use ``<details>`` and
|
||||
``<summary>`` elements, provided they define a ``name``.
|
||||
|
||||
.. attribute:: InlineModelAdmin.extra
|
||||
|
||||
|
|
|
@ -419,6 +419,12 @@ Miscellaneous
|
|||
a ``<footer>`` tag instead of a ``<div>``, and also moved below the
|
||||
``<div id="main">`` element.
|
||||
|
||||
* In order to improve accessibility, the expandable widget used for
|
||||
:attr:`ModelAdmin.fieldsets <django.contrib.admin.ModelAdmin.fieldsets>` and
|
||||
:attr:`InlineModelAdmin.fieldsets <django.contrib.admin.InlineModelAdmin>`,
|
||||
when the fieldset has a name and use the ``collapse`` class, now includes
|
||||
``<details>`` and ``<summary>`` elements.
|
||||
|
||||
* :meth:`.SimpleTestCase.assertURLEqual` and
|
||||
:meth:`~django.test.SimpleTestCase.assertInHTML` now add ``": "`` to the
|
||||
``msg_prefix``. This is consistent with the behavior of other assertions.
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -1939,7 +1939,6 @@ class AdminJavaScriptTest(TestCase):
|
|||
self.assertContains(response, "vendor/jquery/jquery.min.js")
|
||||
self.assertContains(response, "prepopulate.js")
|
||||
self.assertContains(response, "actions.js")
|
||||
self.assertContains(response, "collapse.js")
|
||||
self.assertContains(response, "inlines.js")
|
||||
with override_settings(DEBUG=True):
|
||||
response = self.client.get(reverse("admin:admin_views_section_add"))
|
||||
|
@ -1947,7 +1946,6 @@ class AdminJavaScriptTest(TestCase):
|
|||
self.assertNotContains(response, "vendor/jquery/jquery.min.js")
|
||||
self.assertContains(response, "prepopulate.js")
|
||||
self.assertContains(response, "actions.js")
|
||||
self.assertContains(response, "collapse.js")
|
||||
self.assertContains(response, "inlines.js")
|
||||
|
||||
|
||||
|
@ -6086,11 +6084,8 @@ class SeleniumTests(AdminSeleniumTestCase):
|
|||
)
|
||||
self.assertFalse(self.selenium.find_element(By.ID, "id_title").is_displayed())
|
||||
self.take_screenshot("collapsed")
|
||||
self.selenium.find_elements(By.LINK_TEXT, "Show")[0].click()
|
||||
self.selenium.find_elements(By.TAG_NAME, "summary")[0].click()
|
||||
self.assertTrue(self.selenium.find_element(By.ID, "id_title").is_displayed())
|
||||
self.assertEqual(
|
||||
self.selenium.find_element(By.ID, "fieldsetcollapser0").text, "Hide"
|
||||
)
|
||||
self.take_screenshot("expanded")
|
||||
|
||||
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
|
||||
|
@ -6104,7 +6099,7 @@ class SeleniumTests(AdminSeleniumTestCase):
|
|||
)
|
||||
url = self.live_server_url + reverse("admin7:admin_views_pizza_add")
|
||||
self.selenium.get(url)
|
||||
self.selenium.find_elements(By.ID, "fieldsetcollapser0")[0].click()
|
||||
self.selenium.find_elements(By.TAG_NAME, "summary")[0].click()
|
||||
from_filter_box = self.selenium.find_element(By.ID, "id_toppings_filter")
|
||||
from_box = self.selenium.find_element(By.ID, "id_toppings_from")
|
||||
to_filter_box = self.selenium.find_element(By.ID, "id_toppings_filter_selected")
|
||||
|
|
Loading…
Reference in New Issue