Fix server-rendered admin messages never auto-dismissing
Root cause: Wagtail's w-messages Stimulus controller only auto-clears messages added dynamically via JavaScript (the add() method). Server- rendered messages — the <li> elements produced by Django's messages framework after a redirect — have no connect() lifecycle handler and sit in the DOM indefinitely. PR #64 added data-w-messages-auto-clear-value="8000" which correctly handles dynamic messages, but server-rendered ones were unaffected. PR #64 also added {% ifchanged %} for de-duplication, which doesn't address persistence. Fix: mark server-rendered <li> elements with data-server-rendered and add an inline script that removes them after 8 seconds (matching the auto-clear timeout for dynamic messages). Also remove the ineffective {% ifchanged %} de-duplication. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,6 @@ from apps.core.middleware import AdminMessageGuardMiddleware
|
||||
|
||||
|
||||
def admin_message_test_view(request):
|
||||
messages.success(request, "Page 'Test page' has been updated.")
|
||||
messages.success(request, "Page 'Test page' has been updated.")
|
||||
messages.success(request, "Page 'Test page' has been published.")
|
||||
return render(request, "wagtailadmin/base.html", {})
|
||||
@@ -60,24 +59,6 @@ def test_admin_message_guard_preserves_admin_messages(rf):
|
||||
assert remaining[0].message == "Page 'Test page' has been updated."
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||
def test_wagtail_admin_template_deduplicates_consecutive_messages(client, django_user_model):
|
||||
admin = django_user_model.objects.create_superuser(
|
||||
username="admin-messages",
|
||||
email="admin-messages@example.com",
|
||||
password="admin-pass",
|
||||
)
|
||||
client.force_login(admin)
|
||||
|
||||
response = client.get("/cms/__tests__/admin-messages/")
|
||||
content = response.content.decode()
|
||||
|
||||
assert response.status_code == 200
|
||||
assert content.count("has been updated.") == 1
|
||||
assert content.count("has been published.") == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||
def test_admin_messages_have_auto_clear(client, django_user_model):
|
||||
@@ -94,3 +75,46 @@ def test_admin_messages_have_auto_clear(client, django_user_model):
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "data-w-messages-auto-clear-value" in content
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||
def test_server_rendered_messages_have_auto_dismiss_script(client, django_user_model):
|
||||
"""Server-rendered messages must include an inline script that removes them
|
||||
after a timeout, because the w-messages Stimulus controller only auto-clears
|
||||
messages added via JavaScript — not ones already in the HTML."""
|
||||
admin = django_user_model.objects.create_superuser(
|
||||
username="admin-dismiss",
|
||||
email="admin-dismiss@example.com",
|
||||
password="admin-pass",
|
||||
)
|
||||
client.force_login(admin)
|
||||
|
||||
response = client.get("/cms/__tests__/admin-messages/")
|
||||
content = response.content.decode()
|
||||
|
||||
assert response.status_code == 200
|
||||
# Messages are rendered with the data-server-rendered marker
|
||||
assert "data-server-rendered" in content
|
||||
# The auto-dismiss script targets those markers
|
||||
assert "querySelectorAll" in content
|
||||
assert "[data-server-rendered]" in content
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||
def test_admin_messages_render_all_messages(client, django_user_model):
|
||||
"""All messages should be rendered (no de-duplication filtering)."""
|
||||
admin = django_user_model.objects.create_superuser(
|
||||
username="admin-render",
|
||||
email="admin-render@example.com",
|
||||
password="admin-pass",
|
||||
)
|
||||
client.force_login(admin)
|
||||
|
||||
response = client.get("/cms/__tests__/admin-messages/")
|
||||
content = response.content.decode()
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "has been updated." in content
|
||||
assert "has been published." in content
|
||||
|
||||
Reference in New Issue
Block a user