Skip to content

Commit b3aa98c

Browse files
Merge pull request #818 from mozilla/vs/refactor-theme-toolbar
vs/refactor-themes
2 parents 75bbbdd + ffad1ec commit b3aa98c

File tree

2 files changed

+91
-46
lines changed

2 files changed

+91
-46
lines changed
Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import pytest
22
from selenium.webdriver import Firefox
3-
43
from modules.browser_object import Navigation, PanelUi
54
from modules.page_object import AboutAddons
65

@@ -10,82 +9,121 @@ def test_case():
109
return "118173"
1110

1211

13-
themes = {
14-
"firefox-compact-dark_mozilla_org-heading": "rgb(43, 42, 51)",
15-
"firefox-compact-light_mozilla_org-heading": "rgb(249, 249, 251)",
12+
THEMES: dict[str, list[str]] = {
13+
"firefox-compact-dark_mozilla_org-heading": [
14+
"rgb(43, 42, 51)", # classic darker tone
15+
"rgb(143, 143, 148)", # focused dark
16+
"rgb(120, 119, 126)", # dark without focus
17+
],
18+
# Compact Light
19+
"firefox-compact-light_mozilla_org-heading": [
20+
"rgb(249, 249, 251)",
21+
],
22+
}
23+
24+
ALPENGLOW_MAP: dict[str, str] = {
25+
"light": "rgba(255, 255, 255, 0.76)",
26+
"dark": "rgba(40, 29, 78, 0.96)",
1627
}
1728

18-
alpenglow_map = {"light": "rgba(255, 255, 255, 0.76)", "dark": "rgba(40, 29, 78, 0.96)"}
1929

30+
def colors_match(a: str, b: str, tolerance: float = 0.14) -> bool:
31+
"""
32+
Compare two CSS color strings and determine if they are close enough to be considered equal.
2033
21-
def colors_match(a, b):
22-
"""Determine if two colors are close enough to be considered matches"""
23-
tolerance = 0.14
24-
a_colorstring = a.split("(")[1][:-1]
25-
b_colorstring = b.split("(")[1][:-1]
26-
a_colors = [float(n) for n in a_colorstring.split(",")]
27-
b_colors = [float(n) for n in b_colorstring.split(",")]
28-
for i in range(len(a_colors)):
29-
diff = abs((a_colors[i] / b_colors[i]) - 1.0)
34+
Args:
35+
a (str): First CSS color string in 'rgb(r,g,b)' or 'rgba(r,g,b,a)' format.
36+
b (str): Second CSS color string in 'rgb(r,g,b)' or 'rgba(r,g,b,a)' format.
37+
tolerance (float, optional): Allowed relative difference between each color channel.
38+
Defaults to 0.14. A higher value means colors can differ more and still match.
39+
40+
Returns:
41+
bool: True if the two colors are considered a match within the given tolerance.
42+
False if the color strings are invalid.
43+
"""
44+
try:
45+
a_vals = a.split("(")[1][:-1]
46+
b_vals = b.split("(")[1][:-1]
47+
a_nums = [float(n.strip()) for n in a_vals.split(",")]
48+
b_nums = [float(n.strip()) for n in b_vals.split(",")]
49+
except (IndexError, ValueError):
50+
# Raised if string doesn't contain expected format or non-numeric parts
51+
return False
52+
53+
# Compare up to the shortest length (rgb vs rgba)
54+
for i in range(min(len(a_nums), len(b_nums))):
55+
base = b_nums[i] if b_nums[i] != 0 else 1.0
56+
diff = abs((a_nums[i] / base) - 1.0)
3057
if diff > tolerance:
3158
return False
59+
3260
return True
3361

3462

3563
@pytest.mark.ci
36-
def test_redirect_to_addons(driver: Firefox):
64+
def test_redirect_to_addons(driver: Firefox) -> None:
3765
"""
38-
C118173, ensures that the user is redirected to about:addons through the ui panel
66+
C118173: Ensure the user is redirected to about:addons via the UI panel.
3967
"""
4068
panel_ui = PanelUi(driver)
4169
panel_ui.open()
4270
panel_ui.open_panel_menu()
4371
panel_ui.navigate_to_about_addons()
44-
windows = driver.window_handles
45-
driver.switch_to.window(windows[2])
72+
73+
# remember original window, then switch to newly opened one
74+
orig = driver.window_handles[0]
75+
new = driver.window_handles[-1]
76+
driver.switch_to.window(new)
4677
assert driver.current_url == "about:addons"
4778

79+
# cleanup: close the tab we opened and restore focus
80+
driver.close()
81+
driver.switch_to.window(orig)
82+
4883

49-
@pytest.mark.parametrize("theme_name", list(themes.keys()))
50-
def test_open_addons(driver: Firefox, theme_name: str):
84+
@pytest.mark.parametrize("theme_name", list(THEMES.keys()))
85+
def test_activate_theme_background_matches_expected(driver: Firefox, theme_name: str) -> None:
5186
"""
52-
C118173, continuation ensures that all the themes are set correctly
87+
C118173: Ensure that activating each theme in about:addons applies the expected background color.
88+
Handles Developer Edition vs standard Firefox defaults.
5389
"""
90+
5491
nav = Navigation(driver)
5592
abt_addons = AboutAddons(driver).open()
5693
abt_addons.choose_sidebar_option("theme")
5794

5895
# Dynamically detect if running Developer Edition
5996
if abt_addons.is_devedition():
60-
# Adjust expectations for Developer Edition
6197
if theme_name == "firefox-compact-dark_mozilla_org-heading":
62-
# Already default on Developer Edition; skip activation/assertion
6398
pytest.skip("Compact Dark is default on DevEdition, skipping.")
6499
else:
65-
# Adjust expectations for standard Firefox
66100
if theme_name == "firefox-compact-light_mozilla_org-heading":
67-
# Already default on Firefox standard; skip activation/assertion
68101
pytest.skip("Compact Light is default on Firefox, skipping.")
69102

70103
current_bg = abt_addons.activate_theme(
71-
nav, theme_name, themes[theme_name], perform_assert=False
104+
nav, theme_name, "", perform_assert=False
105+
)
106+
107+
expected_list = THEMES[theme_name]
108+
assert any(colors_match(current_bg, exp) for exp in expected_list), (
109+
f"Got {current_bg} for {theme_name}; expected one of {expected_list}"
72110
)
73-
assert colors_match(current_bg, themes[theme_name])
74111

75112

76-
def test_alpenglow_theme(driver: Firefox):
113+
def test_alpenglow_theme(driver: Firefox) -> None:
77114
"""
78-
C118173, specifically for alpenglow theme because color can be two values for dark or light mode
115+
C118173: Alpenglow theme can render two values depending on light / dark mode.
116+
Accept either using the tolerance-based comparison.
79117
"""
80118

81119
nav = Navigation(driver)
82120
abt_addons = AboutAddons(driver).open()
83121
abt_addons.choose_sidebar_option("theme")
122+
84123
current_bg = abt_addons.activate_theme(
85124
nav, "firefox-alpenglow_mozilla_org-heading", "", perform_assert=False
86125
)
87126

88-
# assert current_bg == alpenglow_map["light"] or current_bg == alpenglow_map["dark"]
89-
assert colors_match(current_bg, alpenglow_map["light"]) or colors_match(
90-
current_bg, alpenglow_map["dark"]
127+
assert colors_match(current_bg, ALPENGLOW_MAP["light"]) or colors_match(
128+
current_bg, ALPENGLOW_MAP["dark"]
91129
)

tests/theme_and_toolbar/test_installed_theme_enabled.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,46 @@ def test_case():
1212
return "118174"
1313

1414

15-
MAC_GHA = environ.get("GITHUB_ACTIONS") == "true" and sys.platform.startswith("darwin")
15+
MAC_GHA: bool = environ.get("GITHUB_ACTIONS") == "true" and sys.platform.startswith("darwin")
16+
17+
AMO_HOST: str = "addons.mozilla.org"
18+
AMO_THEMES_PATH: str = "firefox/themes"
1619

1720

1821
@pytest.mark.skipif(MAC_GHA, reason="Test unstable in MacOS Github Actions")
19-
def test_find_more_themes(driver: Firefox):
22+
def test_find_more_themes(driver: Firefox) -> None:
2023
"""
21-
C118174, first part
24+
C118174 (part 1): From about:addons > Themes, 'Find more themes' opens AMO in a new tab.
25+
Verify AMO host and themes path are present in the URL.
2226
"""
2327
about_addons = AboutAddons(driver).open()
2428
about_addons.choose_sidebar_option("theme")
2529
about_addons.get_element("find-more-themes-button").click()
30+
2631
driver.switch_to.window(driver.window_handles[-1])
2732

28-
# Continuing to call the object "about_addons" is confusing
2933
base = about_addons
30-
base.url_contains("addons.mozilla.org")
31-
base.url_contains("firefox/themes")
34+
base.url_contains(AMO_HOST)
35+
base.url_contains(AMO_THEMES_PATH)
3236

3337

3438
@pytest.mark.skipif(MAC_GHA, reason="Test unstable in MacOS Github Actions")
35-
def test_installed_theme_enabled(driver: Firefox):
39+
def test_installed_theme_enabled(driver: Firefox) -> None:
3640
"""
37-
C118174: install a theme and make sure it is set to enabled immediately
41+
C118174 (part 2): Install a recommended theme from AMO and ensure it becomes enabled immediately.
3842
"""
3943
about_addons = AboutAddons(driver).open()
4044
about_addons.choose_sidebar_option("theme")
41-
starting_theme = about_addons.get_element("enabled-theme-title").get_attribute(
42-
"innerText"
43-
)
44-
amo = AmoThemes(driver).open()
45-
amo.install_recommended_theme()
45+
46+
# Capture currently enabled theme title
47+
starting_theme = about_addons.get_element("enabled-theme-title").get_attribute("innerText")
48+
49+
# Go to AMO and install a recommended theme (POM encapsulates waits and flows)
50+
AmoThemes(driver).open().install_recommended_theme()
51+
52+
# Return to about:addons > Themes and verify the enabled theme changed
4653
about_addons = AboutAddons(driver).open()
4754
about_addons.choose_sidebar_option("theme")
4855

49-
# NOTE: AMO does not enforce that the listed theme name remains the same after installation
56+
# AMO may change display names; we only assert that the enabled theme is different
5057
about_addons.check_theme_has_changed(starting_theme)

0 commit comments

Comments
 (0)