Test all themes for color contrast

main
Bob Mottram 2022-05-18 17:06:26 +01:00
parent 64b401da3d
commit 27ea5e560c
2 changed files with 90 additions and 0 deletions

View File

@ -148,6 +148,7 @@ from content import remove_long_words
from content import replace_content_duplicates from content import replace_content_duplicates
from content import remove_text_formatting from content import remove_text_formatting
from content import remove_html_tag from content import remove_html_tag
from theme import get_themes_list
from theme import update_default_themes_list from theme import update_default_themes_list
from theme import set_css_param from theme import set_css_param
from theme import scan_themes_for_scripts from theme import scan_themes_for_scripts
@ -182,6 +183,7 @@ from blocking import load_cw_lists
from blocking import add_cw_from_lists from blocking import add_cw_from_lists
from happening import dav_month_via_server from happening import dav_month_via_server
from happening import dav_day_via_server from happening import dav_day_via_server
from webapp_theme_designer import color_contrast
TEST_SERVER_GROUP_RUNNING = False TEST_SERVER_GROUP_RUNNING = False
@ -7092,6 +7094,44 @@ def _test_diff_content() -> None:
assert html_str == expected assert html_str == expected
def _test_color_contrast_value(base_dir: str) -> None:
print('test_color_contrast_value')
minimum_color_contrast = 4.5
background = 'black'
foreground = 'white'
contrast = color_contrast(background, foreground)
assert contrast
assert contrast > 20
assert contrast < 22
foreground = 'grey'
contrast = color_contrast(background, foreground)
assert contrast
assert contrast > 5
assert contrast < 6
themes = get_themes_list(base_dir)
for theme_name in themes:
theme_filename = base_dir + '/theme/' + theme_name + '/theme.json'
if not os.path.isfile(theme_filename):
continue
theme_json = load_json(theme_filename)
if not theme_json:
continue
if not theme_json.get('main-fg-color'):
continue
if not theme_json.get('main-bg-color'):
continue
foreground = theme_json['main-fg-color']
background = theme_json['main-bg-color']
contrast = color_contrast(background, foreground)
if contrast is None:
continue
if contrast < minimum_color_contrast:
print('Theme ' + theme_name + ' has not enough color contrast ' +
str(contrast) + ' < ' + str(minimum_color_contrast))
assert contrast >= minimum_color_contrast
print('Color contrast is ok for all themes')
def run_all_tests(): def run_all_tests():
base_dir = os.getcwd() base_dir = os.getcwd()
print('Running tests...') print('Running tests...')
@ -7109,6 +7149,7 @@ def run_all_tests():
_test_checkbox_names() _test_checkbox_names()
_test_thread_functions() _test_thread_functions()
_test_functions() _test_functions()
_test_color_contrast_value(base_dir)
_test_diff_content() _test_diff_content()
_test_bold_reading() _test_bold_reading()
_test_published_to_local_timezone() _test_published_to_local_timezone()

View File

@ -331,3 +331,52 @@ def html_theme_designer(css_cache: {}, base_dir: str,
theme_form += '</div>\n' theme_form += '</div>\n'
theme_form += html_footer() theme_form += html_footer()
return theme_form return theme_form
def _relative_luminance(color: str) -> float:
""" Returns the relative luminance for the given color
"""
color = color.lstrip('#')
rgb = list(int(color[i:i+2], 16) for i in (0, 2, 4))
srgb = (
rgb[0] / 255.0,
rgb[1] / 255.0,
rgb[2] / 255.0
)
if srgb[0] <= 0.03928:
rgb[0] = srgb[0] / 12.92
else:
rgb[0] = pow(((srgb[0] + 0.055) / 1.055), 2.4)
if srgb[1] <= 0.03928:
rgb[1] = srgb[1] / 12.92
else:
rgb[1] = pow(((srgb[1] + 0.055) / 1.055), 2.4)
if srgb[2] <= 0.03928:
rgb[2] = srgb[2] / 12.92
else:
rgb[2] = pow(((srgb[2] + 0.055) / 1.055), 2.4)
return \
0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]
def color_contrast(background: str, foreground: str) -> float:
"""returns the color contrast
"""
if not background.startswith('#'):
if color_to_hex.get(background):
background = color_to_hex[background]
else:
return None
if not foreground.startswith('#'):
if color_to_hex.get(foreground):
foreground = color_to_hex[foreground]
else:
return None
background_luminance = _relative_luminance(background)
foreground_luminance = _relative_luminance(foreground)
if background_luminance > foreground_luminance:
return (0.05 + background_luminance) / (0.05 + foreground_luminance)
else:
return (0.05 + foreground_luminance) / (0.05 + background_luminance)
return None