This document explains the fixture validation system for the CSS if() polyfill, which ensures that your CSS transformations work correctly in real browser environments.
The fixture validation system uses Playwright to test CSS fixture pairs in a headless Chromium browser. This approach validates that:
- Input CSS (with
if()functions) gets properly transformed by the polyfill - Expected CSS (the desired output) produces the same visual results
- Media queries respond correctly to viewport changes
- @supports queries work as expected
Fixtures come in pairs located in test/fixtures/:
*.input.css- CSS containingif()functions*.expected.css- Expected transformation result
Example:
test/fixtures/
├── basic-media.input.css # if(media(max-width: 768px): 100%; else: 50%)
├── basic-media.expected.css # Standard media query equivalent
├── basic-style.input.css # if(style(--theme): var(--primary); else: blue)
└── basic-style.expected.css # Resolved conditional styles
For each fixture pair, the system:
- Creates an HTML page with both input and expected CSS
- Loads the polyfill and applies it to the input CSS
- Captures computed styles from the polyfilled version
- Switches to expected CSS and captures those styles
- Compares the results to ensure they match
Compares computed styles for properties like:
colorwidthdisplaybackgroundColorfontSizemargin,padding,border
Tests responsive behavior at different viewports:
- Desktop (1200x800)
- Tablet (768x600)
- Mobile (375x667)
Validates CSS feature detection with properties like:
display: griddisplay: flexcolor: color(display-p3 1 0 0)
# Run all fixture tests
pnpm run test:fixtures
# Run specific fixture with config
pnpm exec playwright test --config=test/fixtures-validation/fixture-validation.playwright.config.js --grep "basic-media"
# Run with browser UI (for debugging)
pnpm exec playwright test --config=test/fixtures-validation/fixture-validation.playwright.config.js --ui# Run all fixtures
node scripts/validate-fixtures.js
# Run specific fixture
node scripts/validate-fixtures.js basic-media
# List available fixtures
node scripts/validate-fixtures.js --list
# Show help
node scripts/validate-fixtures.js --help-
Create input CSS with
if()functions:/* my-feature.input.css */ .element { color: if( supports(color: lab(50% 20 -30)): lab(50% 20 -30) ; else: #blue ); }
-
Create expected CSS with the desired output:
/* my-feature.expected.css */ .element { color: #blue; } @supports (color: lab(50% 20 -30)) { .element { color: lab(50% 20 -30); } }
-
Test automatically - the validation will pick up new fixtures
All computed styles match between polyfill and expected CSS.
Common failure reasons:
-
Style Mismatch: Polyfill produces different computed values
Property 'width' should match between polyfill and expected CSS Expected: "400px" Received: "50%" -
Media Query Issues: Responsive behavior doesn't match
Property 'width' should match at mobile viewport (375x667) -
Polyfill Errors: JavaScript errors in the polyfill code
Error: if() function parsing failed
The tests run on:
- Chromium (primary - matches most real-world usage)
- Firefox (cross-browser validation)
- WebKit (Safari compatibility)
This validation system provides:
- Real Browser Testing - No mocking, actual CSS computation
- Visual Accuracy - Ensures polyfill produces identical rendering
- Regression Detection - Catches breaking changes automatically
- Cross-Browser Validation - Tests on multiple engines
- Responsive Testing - Validates media query behavior
- Feature Detection - Ensures @supports works correctly
- Ensure Playwright is installed:
npx playwright install - Check that fixtures exist in
test/fixtures/
- Check if polyfill is correctly transforming CSS
- Verify expected CSS is accurate
- Test manually in browser to confirm behavior
- Tests run in parallel by default
- Use
--workers=1to run sequentially if needed - Consider reducing viewport testing for faster runs
This fixture validation system gives you confidence that your CSS if() polyfill works correctly across different browsers and scenarios, providing the same visual results as native CSS would.