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:
parent
0157f20ae9
commit
7491c34723
163
test/simpleshop_theme_web/live/theme_css_consistency_test.exs
Normal file
163
test/simpleshop_theme_web/live/theme_css_consistency_test.exs
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user