Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions templates/array_animation.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@
border: 3px solid #16c79a;
border-radius: 12px;
position: relative;
transition: all 0.3s ease;
/* Only transition transform/box-shadow, NOT background/border.
This prevents the flicker caused by clearing all classes
before applying new ones - background now changes instantly. */
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.array-cell.highlight-left {
Expand Down Expand Up @@ -113,7 +116,9 @@
padding: 4px 10px;
border-radius: 6px;
opacity: 0;
transition: all 0.4s ease;
/* Only transition opacity, not position-related properties.
Prevents flicker when pointers move between cells. */
transition: opacity 0.3s ease;
}

.pointer.left-pointer {
Expand All @@ -135,7 +140,7 @@
color: #f7d716;
text-align: center;
min-height: 36px;
transition: opacity 0.3s ease;
/* No transition - instant text updates prevent flicker */
}

.step-indicator {
Expand Down
60 changes: 60 additions & 0 deletions tests/test_animation_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,66 @@ def test_record_respects_duration(self, simple_html: str):
assert result.stat().st_size > 1000 # Should have meaningful content


class TestTemplateCSS:
"""Tests for CSS in animation templates to prevent regressions."""

@pytest.fixture
def template_path(self) -> Path:
"""Path to the array animation template."""
return Path(__file__).parent.parent / "templates" / "array_animation.html"

def test_no_transition_all_on_array_cell(self, template_path: Path):
"""Array cells should not use 'transition: all' to prevent flicker.

When using 'transition: all', the clearState() function causes a visible
flicker because background colors transition back to default before the
new state is applied. Instead, only specific properties should be animated.
"""
content = template_path.read_text()

# Extract the .array-cell CSS rule
import re
array_cell_match = re.search(
r'\.array-cell\s*\{[^}]+\}',
content,
re.DOTALL
)
assert array_cell_match, ".array-cell CSS rule not found"

array_cell_css = array_cell_match.group(0)

# Should NOT have 'transition: all'
assert 'transition: all' not in array_cell_css, (
"Found 'transition: all' in .array-cell CSS. "
"This causes flicker during state changes. "
"Use specific properties like 'transition: transform, box-shadow' instead."
)

# SHOULD have some transition for smooth animations
assert 'transition:' in array_cell_css or 'transition :' in array_cell_css, (
".array-cell should have transition for transform/box-shadow"
)

def test_no_transition_all_on_pointer(self, template_path: Path):
"""Pointer elements should not use 'transition: all' to prevent flicker."""
content = template_path.read_text()

import re
pointer_match = re.search(
r'\.pointer\s*\{[^}]+\}',
content,
re.DOTALL
)
assert pointer_match, ".pointer CSS rule not found"

pointer_css = pointer_match.group(0)

assert 'transition: all' not in pointer_css, (
"Found 'transition: all' in .pointer CSS. "
"This can cause flicker when pointers move between cells."
)


# Mark slow tests so they can be skipped with: pytest -m "not slow"
def pytest_configure(config):
config.addinivalue_line("markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')")