6.8 KiB
6.8 KiB
Self-Debugging Workflow
Patterns for Claude and AI agents to verify and fix their own frontend work.
Core Principle
After making any frontend change, verify it worked:
- Screenshot - Visual verification
- Console - Check for errors
- DOM - Confirm structure
- Iterate - Fix issues and repeat
Basic Verification Loop
# After modifying HTML/CSS/JS files:
# 1. Reload the page (if not using hot reload)
./browser-nav.js http://localhost:3000
# 2. Take screenshot to verify visual result
./browser-screenshot.js
# 3. Check for any JavaScript errors
./browser-console.js --errors
# 4. If issues found, fix and repeat
Structured Debugging Protocol
Phase 1: Initial Assessment
# Get page summary
./browser-dom.js
# Take baseline screenshot
./browser-screenshot.js --output=/tmp/current-state.png
# Capture any errors
./browser-console.js --errors > /tmp/errors.txt
Phase 2: Make Changes
After editing source files:
# Force reload (bypass cache)
./browser-eval.js 'location.reload(true)'
# Wait for page load
sleep 2
# Take new screenshot
./browser-screenshot.js --output=/tmp/after-change.png
Phase 3: Verify
# Check for new errors
./browser-console.js --errors
# Verify element exists (example: new button)
./browser-eval.js 'document.querySelector(".new-button") ? "Found" : "Missing"'
# Verify styling applied
./browser-eval.js 'getComputedStyle(document.querySelector(".new-button")).backgroundColor'
Phase 4: Iterate
If issues found:
- Identify the problem from screenshot/console
- Fix the source code
- Return to Phase 2
Common Self-Fix Patterns
CSS Not Applying
Symptom: Element exists but looks wrong Diagnosis:
# Check if styles computed correctly
./browser-eval.js 'getComputedStyle(document.querySelector(".my-element")).cssText.slice(0, 500)'
# Check for conflicting selectors
./browser-eval.js '(() => {
const el = document.querySelector(".my-element");
const sheets = [...document.styleSheets];
const matches = [];
sheets.forEach(sheet => {
try {
[...sheet.cssRules].forEach(rule => {
if (el.matches(rule.selectorText)) matches.push(rule.selectorText);
});
} catch {}
});
return matches;
})()'
Fixes to try:
- Increase specificity
- Check for
!importantoverrides - Verify selector matches element
Element Not Visible
Symptom: DOM shows element but not visible Diagnosis:
./browser-eval.js '(() => {
const el = document.querySelector(".my-element");
const s = getComputedStyle(el);
const r = el.getBoundingClientRect();
return {
exists: !!el,
display: s.display,
visibility: s.visibility,
opacity: s.opacity,
width: r.width,
height: r.height,
inViewport: r.top < window.innerHeight && r.bottom > 0
};
})()'
Fixes based on result:
display: none→ Check CSS rules hiding itwidth/height: 0→ Add dimensions or contentopacity: 0→ Check for fade animations- Not in viewport → Check positioning/scroll
JavaScript Not Running
Symptom: Interactive features don't work Diagnosis:
# Check for errors
./browser-console.js --errors
# Check if script loaded
./browser-eval.js 'document.querySelectorAll("script").length'
# Check if function exists
./browser-eval.js 'typeof myFunction'
Fixes based on result:
- Syntax error → Fix the JavaScript
- Script not loaded → Check path/build process
- Function undefined → Check load order, exports
Layout Broken
Symptom: Elements positioned incorrectly Diagnosis:
# Take screenshot
./browser-screenshot.js
# Check flex/grid container
./browser-eval.js '(() => {
const container = document.querySelector(".container");
const s = getComputedStyle(container);
return { display: s.display, flexDirection: s.flexDirection, gridTemplateColumns: s.gridTemplateColumns };
})()'
Common fixes:
- Missing
display: flex/gridon container - Wrong
flex-direction - Missing
widthon flex children - Grid columns not matching children
Responsive Verification
Test All Breakpoints
# Mobile
./browser-resize.js --mobile
./browser-screenshot.js --output=/tmp/mobile.png
./browser-console.js --errors
# Tablet
./browser-resize.js --tablet
./browser-screenshot.js --output=/tmp/tablet.png
# Desktop
./browser-resize.js --desktop
./browser-screenshot.js --output=/tmp/desktop.png
Compare Screenshots
After each breakpoint, Claude should analyze the screenshot for:
- Layout shifts
- Overlapping elements
- Text overflow
- Hidden/missing elements
- Incorrect spacing
Interactive Feature Testing
Form Validation
# Fill form with test data
./browser-eval.js 'document.querySelector("#email").value = "test@example.com"'
./browser-eval.js 'document.querySelector("#password").value = "test123"'
# Submit and check result
./browser-eval.js 'document.querySelector("form").submit()'
./browser-screenshot.js
./browser-console.js --errors
Click/Hover States
# Test button click
./browser-eval.js 'document.querySelector(".button").click()'
./browser-screenshot.js
# Check state changed
./browser-eval.js 'document.querySelector(".modal")?.style.display'
Automated Verification Script
For repeated checks, use this pattern:
#!/bin/bash
# verify-page.sh - Run after changes
URL="${1:-http://localhost:3000}"
OUT_DIR="/tmp/debug-$(date +%s)"
mkdir -p "$OUT_DIR"
echo "Verifying $URL..."
# Navigate
./browser-nav.js "$URL"
sleep 2
# Screenshot
./browser-screenshot.js --output="$OUT_DIR/screenshot.png"
echo "Screenshot: $OUT_DIR/screenshot.png"
# Errors
./browser-console.js --errors > "$OUT_DIR/errors.txt"
if [ -s "$OUT_DIR/errors.txt" ]; then
echo "⚠️ Errors found:"
cat "$OUT_DIR/errors.txt"
else
echo "✓ No JavaScript errors"
fi
# DOM summary
./browser-dom.js > "$OUT_DIR/dom.txt"
echo "DOM summary saved"
echo "Done. Files in $OUT_DIR"
Error Recovery Strategies
When Screenshot Shows Blank Page
- Check console for critical errors
- Verify server is running
- Check network requests (404, 500)
- Verify correct URL
When Console Shows Many Errors
- Fix first error (often causes cascade)
- Reload and recheck
- Address errors in order
When Element Is "Almost Right"
- Use picker to select element:
./browser-pick.js "Select the problematic element" - Get full computed styles
- Compare to expected values
- Adjust CSS incrementally
Best Practices
- Always screenshot after changes - Visual verification catches most issues
- Check console immediately - Catch JS errors early
- Test responsive early - Layout issues compound
- Verify one change at a time - Easier to identify what broke
- Save debug output - Reference for comparison
- Use the picker for precision - Get exact selectors from user