Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a high contrast mode to screenshot cases. #18080

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions django/test/selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,26 @@ def dark(self):
finally:
self.selenium.execute_script("localStorage.removeItem('theme');")

def set_emulated_media(self, features, media=""):
if self.browser != "chrome":
self.skipTest("Emulated media controls are only supported on Chrome.")
# Chrome Dev Tools Protocol Emulation.setEmulatedMedia
# https://chromedevtools.github.io/devtools-protocol/1-3/Emulation/#method-setEmulatedMedia
self.selenium.execute_cdp_cmd(
"Emulation.setEmulatedMedia", {"media": media, "features": features}
)

@contextmanager
def high_contrast(self):
self.set_emulated_media(features=[{"name": "forced-colors", "value": "active"}])
with self.desktop_size():
try:
yield
finally:
self.set_emulated_media(
features=[{"name": "forced-colors", "value": "none"}]
)

def take_screenshot(self, name):
if not self.screenshots:
return
Expand Down
11 changes: 6 additions & 5 deletions docs/internals/contributing/writing-code/unit-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,24 +278,25 @@ For testing changes to the admin UI, the selenium tests can be run with the
To define when screenshots should be taken during a selenium test, the test
class must use the ``@django.test.selenium.screenshot_cases`` decorator with a
list of supported screenshot types (``"desktop_size"``, ``"mobile_size"``,
``"small_screen_size"``, ``"rtl"``, and ``"dark"``). It can then call
``self.take_screenshot("unique-screenshot-name")`` at the desired point to
generate the screenshots. For example::
``"small_screen_size"``, ``"rtl"``, ``"dark"``, and ``"high_contrast"``). It
can then call ``self.take_screenshot("unique-screenshot-name")`` at the desired
point to generate the screenshots. For example::

from django.test.selenium import SeleniumTestCase, screenshot_cases
from django.urls import reverse


class SeleniumTests(SeleniumTestCase):
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_login_button_centered(self):
self.selenium.get(self.live_server_url + reverse("admin:login"))
self.take_screenshot("login")
...

This generates multiple screenshots of the login page - one for a desktop
screen, one for a mobile screen, one for right-to-left languages on desktop,
and one for the dark mode on desktop.
one for the dark mode on desktop, and one for high contrast mode on desktop
when using chrome.

.. versionchanged:: 5.1

Expand Down
10 changes: 5 additions & 5 deletions tests/admin_views/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5764,7 +5764,7 @@ def setUp(self):
title="A Long Title", published=True, slug="a-long-title"
)

@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_login_button_centered(self):
from selenium.webdriver.common.by import By

Expand Down Expand Up @@ -6070,7 +6070,7 @@ def test_populate_existing_object(self):
self.assertEqual(slug1, "this-is-the-main-name-the-best-2012-02-18")
self.assertEqual(slug2, "option-two-this-is-the-main-name-the-best")

@screenshot_cases(["desktop_size", "mobile_size", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "dark", "high_contrast"])
def test_collapsible_fieldset(self):
"""
The 'collapse' class in fieldsets definition allows to
Expand All @@ -6093,7 +6093,7 @@ def test_collapsible_fieldset(self):
)
self.take_screenshot("expanded")

@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_selectbox_height_collapsible_fieldset(self):
from selenium.webdriver.common.by import By

Expand Down Expand Up @@ -6121,7 +6121,7 @@ def test_selectbox_height_collapsible_fieldset(self):
)
self.take_screenshot("selectbox-collapsible")

@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_selectbox_height_not_collapsible_fieldset(self):
from selenium.webdriver.common.by import By

Expand Down Expand Up @@ -6152,7 +6152,7 @@ def test_selectbox_height_not_collapsible_fieldset(self):
)
self.take_screenshot("selectbox-non-collapsible")

@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark"])
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
def test_first_field_focus(self):
"""JavaScript-assisted auto-focus on first usable form field."""
from selenium.webdriver.common.by import By
Expand Down