A Playwright-based challenge for implementing synchronized pan/zoom with grid and ruler overlays.
# Install dependencies
npm install
# Install Playwright browser
npx playwright install chromium
# Run tests (interactive UI mode - recommended)
npm run test:uiCreate an implementation file src/implementation_NAME.js that implements an interactive image viewer with:
- ✅ Pan/Drag - Drag the image to pan it around
- ✅ Zoom - Zoom in/out using buttons or mouse wheel
- ✅ Grid Synchronization - Grid overlay stays aligned with the image
- ✅ Ruler Synchronization - Top and left rulers sync with image position and scale
2025-GridChallenge/
├── README.md → This file - complete documentation
├── gen_spec.js → Generates SPEC.md for AI agents
├── generate_manual_test.js → Generates manual_test.html
├── playwright.config.js → Playwright configuration
├── package.json → Dependencies and scripts
├── challenge.css → Styles for the UI
│
├── src/ → Your implementations (auto-discovered)
│ └── implementation_reference.js (example only - not used in tests)
│
└── tests/
├── e2e/ → Test suites (auto-discovers all specs)
│ ├── translation_sync.spec.js
│ ├── zoom_sync.spec.js
│ └── grid_alignment.spec.js
│
└── fixtures/
└── challenge_template.html
- Create
src/implementation_YOURNAME.js - The test runner automatically discovers all files matching
implementation_*.js - No manual configuration needed!
Note: The point of this challenge is to write the implementation from scratch using only the specification. Looking at existing implementations defeats the purpose!
| Command | Description |
|---|---|
npm run test:ui |
Interactive UI mode (recommended) - opens browser |
npm test |
Run all tests - terminal output |
npm run test:headed |
Watch tests in browser |
npm run test:debug |
Debug mode |
npm run spec |
Generate complete specification |
npm run manual |
Generate manual_test.html for manual testing |
This challenge is designed to test whether AI systems can solve complex technical problems from specifications alone.
When working on the tests themselves (not implementations), you can generate a complete context dump for AI assistance:
npm run repomixThis will:
- Generate
SPEC.mdwith the current specification - Run all tests to generate
test-results.json - Scan the entire codebase with repomix
Then upload repomix-output.xml to your AI assistant for context-aware help with:
- Understanding test failures
- Improving test coverage
- Debugging test issues
- Understanding the codebase structure
The specification is generated on-the-fly from the current project state:
npm run spec > SPEC.mdThis generates SPEC.md containing:
- ✅ Complete HTML template
- ✅ All CSS styles
- ✅ JavaScript code examples
- ✅ Test requirements
- ✅ Configuration constants
- ✅ Helper function patterns
The spec is intentionally complete - it contains everything needed to write a working implementation without looking at existing code.
Step 1: Generate the specification
npm run spec > SPEC.mdThis creates SPEC.md in the project root containing the complete challenge specification.
Step 2: Send SPEC.md to AI
Give the AI ONLY the SPEC.md file (no access to src/implementation_*.js files). Ask them to:
"Read SPEC.md and create a file
src/implementation_AI.jsthat implements the required functionality and passes all tests."
Step 3: Save the AI's implementation
Put the AI-generated file in the src/ directory:
# AI generates: src/implementation_AI.js
# Just save it to src/Step 4: Test the implementation
# Run all tests (tests all implementations)
npm run test:ui
# Or test just one implementation in terminal:
npx playwright test --grep "implementation_AI"The goal is to see if an AI can one-shot solve this challenge using only the specification. No hints, no examples, no templates - just the spec.
For hands-on testing of implementations:
npm run manualThis generates manual_test.html with a dropdown selector to switch between implementations. Open manual_test.html in a browser to test implementations visually.
Note: manual_test.html is auto-generated and gitignored - regenerate it after adding new implementations.
Your implementation must:
-
Set global variables when image loads:
window.imgWidth = img.naturalWidth; window.imgHeight = img.naturalHeight; window.ZOOM_FACTOR = YOUR_ZOOM_FACTOR; // e.g., 1.2, 1.8, etc.
-
Use provided global variables (already in HTML template):
imageViewer,imageContainer,imggridOverlay,topLinesSvg,leftLinesSvgtopBar,leftBarzoomLevelSpan,zoomInButton,zoomOutButton
-
Implement these functions:
drawGridOverlay()- Draw 45x45 grid on imagedrawTopLines()- Draw horizontal ruler above imagedrawLeftLines()- Draw vertical ruler beside imageupdateTransform()- Synchronize all transformszoom()- Handle zoom with zoom-to-mouse logic
-
Handle these events:
- Mouse wheel (zoom)
- Mouse drag (pan)
- Zoom button clicks
- Window resize
Your implementation passes the tests if:
After dragging 50px right, 80px down:
- Image: translateX = 50, translateY = 80
- Top ruler: translateX = 50 (Y stays 0)
- Left ruler: translateY = 80 (X stays 0)
After clicking zoom-in:
- Scale equals your
ZOOM_FACTOR - Ruler lines scale proportionally
- Grid lines maintain relative positions
- The spec has everything - Complete HTML, CSS, and JavaScript patterns
- Start simple - Get pan/zoom working, then add rulers
- Test incrementally - Run
npm run test:uiafter each feature - Read error messages - Tests tell you exactly what's expected
- Use the helper functions - SPEC.md includes all needed patterns
Important: No access to existing implementations (like implementation_A.js) - that defeats the purpose of the challenge!
Tests can't find implementations?
- File must start with
implementation_and end with.js - File must be in the
src/directory
"img.onload is not a function" error?
- Set up
img.onload = () => { ... }in your implementation - Use the global
imgvariable provided by the template
Transform not synchronized?
- Update
topLinesSvg.style.transformandleftLinesSvg.style.transform - Both should use the same
translateXandtranslateYvalues
- 45 divisions in both X and Y directions
- Grid lines: Red, semi-transparent (0.5 opacity)
- Ruler lines: Black, solid
- Line width scales with zoom level
- Labels every 5 divisions on rulers
The challenge includes three test suites that automatically discover all implementations in src/:
- translation_sync.spec.js - Tests pan/drag synchronization between image, grid, and rulers
- zoom_sync.spec.js - Tests zoom behavior and synchronization after zoom
- grid_alignment.spec.js - Tests pixel-perfect grid-to-ruler alignment
Your implementation will be automatically tested by all three suites - just create a file named implementation_*.js in the src/ directory.
MIT