defmodule BerrypodWeb.ThemeCSSConsistencyTest do @moduledoc """ Tests that verify CSS works correctly for shop pages using the .themed class. Architecture: - Shop pages use .themed class for theme-aware styles - Theme editor is on-site (/?edit=theme) so it uses the same CSS as shop pages - Shop pages get theme values via inline CSS from CSSGenerator - Component styles use .themed for shared styling (theme-layer2-attributes.css) """ use BerrypodWeb.ConnCase, async: false import Phoenix.LiveViewTest import Berrypod.AccountsFixtures alias Berrypod.Settings setup do user = user_fixture() %{user: user} end describe "CSS selector consistency" do test "shop home page has .themed with data attributes", %{conn: conn, user: user} do {:ok, _view, html} = live(log_in_user(conn, user), ~p"/") # Verify themed element exists with theme data attributes assert html =~ ~r/class="[^"]*themed/ assert html =~ ~r/data-mood="/ assert html =~ ~r/data-typography="/ assert html =~ ~r/data-shape="/ assert html =~ ~r/data-density="/ end test "on-site theme editor has .themed with data attributes", %{conn: conn, user: user} do conn = log_in_user(conn, user) # Theme editor is now on-site at /?edit=theme {:ok, _view, html} = live(conn, ~p"/?edit=theme") # Verify themed element exists with theme data attributes assert html =~ ~r/class="[^"]*themed/ assert html =~ ~r/data-mood="/ assert html =~ ~r/data-typography="/ assert html =~ ~r/data-shape="/ assert html =~ ~r/data-density="/ end test "theme settings changes are reflected on shop page", %{conn: conn, user: user} do conn = log_in_user(conn, user) # Start with minimal preset (neutral mood) {:ok, _settings} = Settings.apply_preset(:minimal) {:ok, _view, html} = live(conn, ~p"/") assert html =~ ~s(data-mood="neutral") # Change to night preset (dark mood) {:ok, _settings} = Settings.apply_preset(:night) {:ok, _view, html} = live(conn, ~p"/") assert html =~ ~s(data-mood="dark") # Change to gallery preset (warm mood) {:ok, _settings} = Settings.apply_preset(:gallery) {:ok, _view, html} = live(conn, ~p"/") assert html =~ ~s(data-mood="warm") end end describe "CSS file structure" do test "theme.css imports shared theme layers" do css_path = Path.join([File.cwd!(), "assets", "css", "theme.css"]) css_content = File.read!(css_path) # Theme bundle imports all three shared layers assert css_content =~ "theme-primitives.css" assert css_content =~ "theme-layer2-attributes.css" assert css_content =~ "theme-semantic.css" end test "theme-layer2-attributes.css has shared .themed component styles" do css_path = Path.join([File.cwd!(), "assets", "css", "theme-layer2-attributes.css"]) css_content = File.read!(css_path) # Component styles use .themed for shared styling (both shop and preview) assert css_content =~ ".themed" # Uses CSS nesting syntax assert css_content =~ "& .product-card" assert css_content =~ "& .filter-pill" end end describe "generated CSS cache" do test "generated CSS includes ALL theme token categories" do # Apply a preset with specific values {:ok, settings} = Settings.apply_preset(:night) # Generate CSS css = Berrypod.Theme.CSSGenerator.generate(settings) # Mood tokens (surface, text, border colors) assert css =~ "--t-surface-base:" assert css =~ "--t-text-primary:" assert css =~ "--t-border-default:" # Typography tokens assert css =~ "--t-font-heading:" assert css =~ "--t-font-body:" assert css =~ "--t-heading-weight:" # Shape tokens (border radii) assert css =~ "--t-radius-sm:" assert css =~ "--t-radius-button:" assert css =~ "--t-radius-card:" # Density tokens assert css =~ "--t-density:" assert css =~ "--space-md:" assert css =~ "--space-lg:" # Slider-controlled values assert css =~ "--t-accent-l:" assert css =~ "--t-accent-c:" assert css =~ "--t-accent-h:" assert css =~ "--t-font-size-scale:" assert css =~ "--t-heading-weight-override:" end test "generated CSS uses correct values for dark mood" do {:ok, settings} = Settings.apply_preset(:night) css = Berrypod.Theme.CSSGenerator.generate(settings) # Dark mood should have dark surface colors assert css =~ "--t-surface-base: #0a0a0a" assert css =~ "--t-text-primary: #fafafa" end test "generated CSS uses correct values for warm mood" do {:ok, settings} = Settings.apply_preset(:gallery) css = Berrypod.Theme.CSSGenerator.generate(settings) # Warm mood should have warm surface colors assert css =~ "--t-surface-base: #fdf8f3" end test "CSS cache is warmed on startup and invalidated on settings change" do # Ensure cache has content Berrypod.Theme.CSSCache.warm() {:ok, css1} = Berrypod.Theme.CSSCache.get() assert is_binary(css1) assert css1 =~ "--t-accent-h:" # Change settings (this should invalidate and rewarm cache) {:ok, _settings} = Settings.apply_preset(:night) {:ok, css2} = Berrypod.Theme.CSSCache.get() assert is_binary(css2) # The CSS should be different (different accent color) # Note: this may or may not be true depending on preset colors assert css2 =~ "--t-accent-h:" end end end