test: add CSS consistency tests for shop and preview

Add tests to verify that:
- Both .shop-root and .preview-frame have theme data attributes
- Theme settings changes are reflected on shop pages
- CSS file has correct selectors for both contexts
- Generated CSS cache includes all theme variables

These tests catch regressions like the selector issue where
.preview-frame[data-mood="warm"] was incorrectly transformed to
.preview-frame, .shop-root[data-mood="warm"] instead of
.preview-frame[data-mood="warm"], .shop-root[data-mood="warm"]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jamey Greenwood 2026-01-17 16:28:22 +00:00
parent 0157f20ae9
commit 7491c34723

View File

@ -0,0 +1,163 @@
defmodule SimpleshopThemeWeb.ThemeCSSConsistencyTest do
@moduledoc """
Tests that verify CSS selectors work correctly for both the theme editor
preview (.preview-frame) and the shop pages (.shop-root).
These tests ensure that the theme-layer2-attributes.css file has correct
selectors for both contexts, and that CSS custom properties are resolved.
"""
use SimpleshopThemeWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import SimpleshopTheme.AccountsFixtures
alias SimpleshopTheme.Settings
setup do
user = user_fixture()
%{user: user}
end
describe "CSS selector consistency" do
test "shop home page has .shop-root with data attributes", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/")
# Verify shop-root element exists with theme data attributes
assert html =~ ~r/<div[^>]*class="shop-root/
assert html =~ ~r/data-mood="/
assert html =~ ~r/data-typography="/
assert html =~ ~r/data-shape="/
assert html =~ ~r/data-density="/
end
test "theme editor has .preview-frame with data attributes", %{conn: conn, user: user} do
conn = log_in_user(conn, user)
{:ok, _view, html} = live(conn, ~p"/admin/theme")
# Verify preview-frame element exists with theme data attributes
assert html =~ ~r/<div[^>]*class="preview-frame/
assert html =~ ~r/data-mood="/
assert html =~ ~r/data-typography="/
assert html =~ ~r/data-shape="/
assert html =~ ~r/data-density="/
end
test "shop page uses same theme settings as preview", %{conn: conn, user: user} do
# Set a specific theme configuration
{:ok, _settings} = Settings.apply_preset(:night)
# Check shop page
{:ok, _view, shop_html} = live(conn, ~p"/")
# Check preview (authenticated)
conn = log_in_user(conn, user)
{:ok, _view, preview_html} = live(conn, ~p"/admin/theme")
# Extract data-mood values from both
[_, shop_mood] = Regex.run(~r/data-mood="([^"]+)"/, shop_html)
[_, preview_mood] = Regex.run(~r/data-mood="([^"]+)"/, preview_html)
# They should match
assert shop_mood == preview_mood
assert shop_mood == "dark"
end
test "theme settings changes are reflected on shop page", %{conn: conn} do
# 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-layer2-attributes.css has both .preview-frame and .shop-root selectors" do
css_path = Path.join([File.cwd!(), "assets", "css", "theme-layer2-attributes.css"])
css_content = File.read!(css_path)
# Check that mood selectors exist for both
assert css_content =~ ".preview-frame[data-mood=\"dark\"]"
assert css_content =~ ".shop-root[data-mood=\"dark\"]"
assert css_content =~ ".preview-frame[data-mood=\"warm\"]"
assert css_content =~ ".shop-root[data-mood=\"warm\"]"
# Check typography selectors
assert css_content =~ ".preview-frame[data-typography=\"modern\"]"
assert css_content =~ ".shop-root[data-typography=\"modern\"]"
# Check shape selectors
assert css_content =~ ".preview-frame[data-shape=\"sharp\"]"
assert css_content =~ ".shop-root[data-shape=\"sharp\"]"
# Check descendant selectors (important for specificity)
assert css_content =~ ".preview-frame .product-grid"
assert css_content =~ ".shop-root .product-grid"
assert css_content =~ ".preview-frame .product-card"
assert css_content =~ ".shop-root .product-card"
end
test "default selectors include both .preview-frame and .shop-root" do
css_path = Path.join([File.cwd!(), "assets", "css", "theme-layer2-attributes.css"])
css_content = File.read!(css_path)
# The default (neutral) mood should apply to both
# This regex checks for the pattern where both selectors are grouped
assert Regex.match?(
~r/\.preview-frame,\s*\n\.shop-root\s*\{[^}]*--t-surface-base/,
css_content
)
end
end
describe "generated CSS cache" do
test "generated CSS includes theme variables" do
# Apply a preset
{:ok, settings} = Settings.apply_preset(:bold)
# Generate CSS
css = SimpleshopTheme.Theme.CSSGenerator.generate(settings)
# Check that key variables are present
assert css =~ "--t-accent-h:"
assert css =~ "--t-accent-s:"
assert css =~ "--t-accent-l:"
assert css =~ "--t-font-size-scale:"
assert css =~ "--t-heading-weight-override:"
end
test "CSS cache is warmed on startup and invalidated on settings change" do
# Ensure cache has content
SimpleshopTheme.Theme.CSSCache.warm()
{:ok, css1} = SimpleshopTheme.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} = SimpleshopTheme.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