-
Notifications
You must be signed in to change notification settings - Fork 0
feat: validate fixtures #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mfranzke
wants to merge
13
commits into
main
Choose a base branch
from
38-validate-fixtures-by-chromium-rendering
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
d10ec69
feat: validate fixtures
mfranzke aed8eac
refactor: enhanced tests
mfranzke 91aab28
Merge branch 'main' into 38-validate-fixtures-by-chromium-rendering
mfranzke 85567f9
fix: we need a build previous to a test
mfranzke 7b3ce19
Update test/fixtures-validation/fixture-validation.test.js
mfranzke e94ff86
Merge branch 'main' into 38-validate-fixtures-by-chromium-rendering
mfranzke 65b3fa9
refactor: added lint-staged script again
mfranzke 488f2f4
Merge branch 'main' into 38-validate-fixtures-by-chromium-rendering
mfranzke 3ce85be
refactor: corrected node package manager
mfranzke 691bb8c
refactor: simplifications
mfranzke bfcfc38
Merge branch '38-validate-fixtures-by-chromium-rendering' of https://…
mfranzke 5707748
refactor: let's run the fixtures test within the pipeline
mfranzke 91b2947
Apply suggestions from code review
mfranzke File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,5 @@ npm-debug.log | |
dist | ||
_site | ||
packages/*/coverage | ||
/test-results | ||
/playwright-report |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
# CSS if() Polyfill Fixture Validation | ||
|
||
This document explains the fixture validation system for the CSS if() polyfill, which ensures that your CSS transformations work correctly in real browser environments. | ||
|
||
## Overview | ||
|
||
The fixture validation system uses **Playwright** to test CSS fixture pairs in a headless Chromium browser. This approach validates that: | ||
|
||
1. **Input CSS** (with `if()` functions) gets properly transformed by the polyfill | ||
2. **Expected CSS** (the desired output) produces the same visual results | ||
3. **Media queries** respond correctly to viewport changes | ||
4. **@supports queries** work as expected | ||
|
||
## How It Works | ||
|
||
### 1. Fixture Structure | ||
|
||
Fixtures come in pairs located in `test/fixtures/`: | ||
|
||
- `*.input.css` - CSS containing `if()` functions | ||
- `*.expected.css` - Expected transformation result | ||
|
||
Example: | ||
|
||
```text | ||
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 | ||
``` | ||
|
||
### 2. Browser Testing Process | ||
|
||
For each fixture pair, the system: | ||
|
||
1. **Creates an HTML page** with both input and expected CSS | ||
2. **Loads the polyfill** and applies it to the input CSS | ||
3. **Captures computed styles** from the polyfilled version | ||
4. **Switches to expected CSS** and captures those styles | ||
5. **Compares the results** to ensure they match | ||
|
||
### 3. Validation Types | ||
|
||
#### Basic Style Validation | ||
|
||
Compares computed styles for properties like: | ||
|
||
- `color` | ||
- `width` | ||
- `display` | ||
- `backgroundColor` | ||
- `fontSize` | ||
- `margin`, `padding`, `border` | ||
|
||
#### Media Query Testing | ||
|
||
Tests responsive behavior at different viewports: | ||
|
||
- Desktop (1200x800) | ||
- Tablet (768x600) | ||
- Mobile (375x667) | ||
|
||
#### @supports Testing | ||
|
||
Validates CSS feature detection with properties like: | ||
|
||
- `display: grid` | ||
- `display: flex` | ||
- `color: color(display-p3 1 0 0)` | ||
|
||
## Running Tests | ||
|
||
### Command Line | ||
|
||
```bash | ||
# Run all fixture tests | ||
npm run test:fixtures | ||
|
||
# Run specific fixture with config | ||
npx playwright test --config=test/fixtures-validation/fixture-validation.playwright.config.js --grep "basic-media" | ||
|
||
# Run with browser UI (for debugging) | ||
npx playwright test --config=test/fixtures-validation/fixture-validation.playwright.config.js --ui | ||
``` | ||
|
||
### Using the Helper Script | ||
|
||
```bash | ||
# 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 | ||
``` | ||
|
||
## Adding New Fixtures | ||
|
||
1. **Create input CSS** with `if()` functions: | ||
|
||
```css | ||
/* my-feature.input.css */ | ||
.element { | ||
color: if( | ||
supports(color: lab(50% 20 -30)): lab(50% 20 -30) ; else: #blue | ||
); | ||
} | ||
``` | ||
|
||
2. **Create expected CSS** with the desired output: | ||
|
||
```css | ||
/* my-feature.expected.css */ | ||
.element { | ||
color: #blue; | ||
} | ||
@supports (color: lab(50% 20 -30)) { | ||
.element { | ||
color: lab(50% 20 -30); | ||
} | ||
} | ||
``` | ||
|
||
3. **Test automatically** - the validation will pick up new fixtures | ||
|
||
## Understanding Test Results | ||
|
||
### ✅ Passing Tests | ||
|
||
All computed styles match between polyfill and expected CSS. | ||
|
||
### ❌ Failing Tests | ||
|
||
Common failure reasons: | ||
|
||
1. **Style Mismatch**: Polyfill produces different computed values | ||
|
||
```text | ||
Property 'width' should match between polyfill and expected CSS | ||
Expected: "400px" | ||
Received: "50%" | ||
``` | ||
|
||
2. **Media Query Issues**: Responsive behavior doesn't match | ||
|
||
```text | ||
Property 'width' should match at mobile viewport (375x667) | ||
``` | ||
|
||
3. **Polyfill Errors**: JavaScript errors in the polyfill code | ||
```text | ||
Error: if() function parsing failed | ||
``` | ||
|
||
## Browser Support | ||
|
||
The tests run on: | ||
|
||
- **Chromium** (primary - matches most real-world usage) | ||
- **Firefox** (cross-browser validation) | ||
- **WebKit** (Safari compatibility) | ||
|
||
## Benefits | ||
|
||
This validation system provides: | ||
|
||
1. **Real Browser Testing** - No mocking, actual CSS computation | ||
2. **Visual Accuracy** - Ensures polyfill produces identical rendering | ||
3. **Regression Detection** - Catches breaking changes automatically | ||
4. **Cross-Browser Validation** - Tests on multiple engines | ||
5. **Responsive Testing** - Validates media query behavior | ||
6. **Feature Detection** - Ensures @supports works correctly | ||
|
||
## Troubleshooting | ||
|
||
### Tests Won't Start | ||
|
||
- Ensure Playwright is installed: `npx playwright install` | ||
- Check that fixtures exist in `test/fixtures/` | ||
|
||
### Style Mismatches | ||
|
||
- Check if polyfill is correctly transforming CSS | ||
- Verify expected CSS is accurate | ||
- Test manually in browser to confirm behavior | ||
|
||
### Performance Issues | ||
|
||
- Tests run in parallel by default | ||
- Use `--workers=1` to 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. | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* Fixture Test Runner | ||
* | ||
* This script helps validate CSS if() polyfill fixtures by running them through | ||
* a real browser environment using Playwright. | ||
* | ||
* Usage: | ||
* node scripts/validate-fixtures.js [fixture-name] | ||
* | ||
* Examples: | ||
* node scripts/validate-fixtures.js # Run all fixtures | ||
* node scripts/validate-fixtures.js basic-media # Run specific fixture | ||
*/ | ||
|
||
import { execSync } from 'node:child_process'; | ||
import { readdirSync } from 'node:fs'; | ||
import path from 'node:path'; | ||
import process from 'node:process'; | ||
import { fileURLToPath } from 'node:url'; | ||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
const fixturesDir = path.join(__dirname, '..', 'test', 'fixtures'); | ||
|
||
function getAvailableFixtures() { | ||
const files = readdirSync(fixturesDir); | ||
const inputFiles = files.filter((file) => file.endsWith('.input.css')); | ||
return inputFiles.map((file) => file.replace('.input.css', '')); | ||
} | ||
|
||
function runFixtureTests(fixtureName = null) { | ||
console.log('🎭 CSS if() Polyfill Fixture Validation'); | ||
console.log('==========================================\n'); | ||
|
||
const availableFixtures = getAvailableFixtures(); | ||
|
||
if (fixtureName) { | ||
if (!availableFixtures.includes(fixtureName)) { | ||
console.error(`❌ Fixture "${fixtureName}" not found.`); | ||
console.log('\nAvailable fixtures:'); | ||
for (const name of availableFixtures) console.log(` - ${name}`); | ||
process.exit(1); | ||
} | ||
|
||
console.log(`🧪 Running fixture: ${fixtureName}\n`); | ||
} else { | ||
console.log(`🧪 Running all ${availableFixtures.length} fixtures:\n`); | ||
for (const name of availableFixtures) console.log(` ✓ ${name}`); | ||
console.log(''); | ||
} | ||
|
||
try { | ||
// Run Playwright tests | ||
const grepPattern = fixtureName | ||
? `--grep "validates ${fixtureName} fixture"` | ||
: ''; | ||
const command = `npx playwright test test/fixtures-validation/fixture-validation.test.js --config=test/fixtures-validation/fixture-validation.playwright.config.js ${grepPattern}`; | ||
|
||
console.log('🚀 Starting browser-based validation...\n'); | ||
|
||
execSync(command, { | ||
stdio: 'inherit', | ||
cwd: path.join(__dirname, '..') | ||
}); | ||
|
||
console.log('\n✅ All fixture validations passed!'); | ||
console.log('\nThis means:'); | ||
console.log(' • Your polyfill correctly transforms input CSS'); | ||
console.log(' • Browser rendering matches expected output'); | ||
console.log(' • Media queries work responsively'); | ||
console.log(' • @supports queries function properly'); | ||
} catch { | ||
console.error('\n❌ Fixture validation failed!'); | ||
console.error('Please check the test output above for details.'); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
// Parse command line arguments | ||
const fixtureName = process.argv[2]; | ||
|
||
// Show help if requested | ||
if (fixtureName === '--help' || fixtureName === '-h') { | ||
console.log('CSS if() Polyfill Fixture Validator\n'); | ||
console.log('Usage:'); | ||
console.log(' node scripts/validate-fixtures.js [fixture-name]\n'); | ||
console.log('Examples:'); | ||
console.log( | ||
' node scripts/validate-fixtures.js # Run all fixtures' | ||
); | ||
console.log( | ||
' node scripts/validate-fixtures.js basic-media # Run specific fixture' | ||
); | ||
console.log( | ||
' node scripts/validate-fixtures.js --list # List available fixtures\n' | ||
); | ||
process.exit(0); | ||
} | ||
|
||
// List fixtures if requested | ||
if (fixtureName === '--list' || fixtureName === '-l') { | ||
console.log('Available fixtures:'); | ||
for (const name of getAvailableFixtures()) console.log(` ${name}`); | ||
process.exit(0); | ||
} | ||
|
||
// Run the tests | ||
runFixtureTests(fixtureName); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.