plugins/browser-use/skills/debug-ui/SKILL.md
Visual UI debugging — screenshot capture and analysis, responsive layout checking at multiple viewport sizes, CSS validation via DOM state, visual regression detection, before/after state comparison.
npx skillsauth add madappgang/magus debug-uiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns for detecting visual bugs, checking responsive layouts, validating CSS properties, and performing before/after visual comparisons using Browser Use's screenshot and DOM state tools.
The baseline pattern for any UI debugging task:
Step 1: Navigate to the page under investigation
mcp__browser-use__browser_navigate(url="https://app.example.com/dashboard")
→ session_id: "debug_01"
Step 2: Capture visual state
mcp__browser-use__browser_screenshot(session_id="debug_01")
→ base64 image — Claude can analyze this directly
Step 3: Inspect DOM state for element details
mcp__browser-use__browser_get_state(session_id="debug_01")
→ selector_map with element positions, classes, attributes, text
Step 4: Get HTML for CSS/class inspection
mcp__browser-use__browser_get_html(
selector=".problematic-component",
session_id="debug_01"
)
→ raw HTML with class names, inline styles, data attributes
Step 5: Close session
mcp__browser-use__browser_close_session(session_id="debug_01")
When analyzing a screenshot from browser_screenshot:
Test how the UI looks at different viewport widths. Browser Use does not support viewport resizing via a direct tool parameter, so use one of two approaches.
Open separate sessions with different browser configurations (different window sizes). Each session gets an independent Chromium instance.
# Desktop session
session_desktop = browser_navigate(url="https://app.example.com")["session_id"]
screenshot_desktop = browser_screenshot(session_id=session_desktop, full_page=True)
# Mobile session (simulate via JS before screenshot)
session_mobile = browser_navigate(url="https://app.example.com")["session_id"]
# Resize viewport via JS using retry_with_browser_use_agent
retry_with_browser_use_agent(
task="Resize the viewport to 390x844 (iPhone 14 size) using window.resizeTo or meta viewport manipulation, then take a screenshot",
session_id=session_mobile,
max_steps=5
)
screenshot_mobile = browser_screenshot(session_id=session_mobile, full_page=True)
# Compare: Claude analyzes both screenshots
browser_close_session(session_id=session_desktop)
browser_close_session(session_id=session_mobile)
| Breakpoint | Width | Device Class | |------------|-------|--------------| | Mobile S | 320px | Small phones | | Mobile M | 375px | iPhone SE, iPhone 12 mini | | Mobile L | 414px | iPhone Plus/Max, Android large | | Tablet | 768px | iPad portrait | | Laptop | 1024px | Small laptop | | Desktop | 1280px | Standard monitor | | Wide | 1440px+ | Large monitor |
After taking screenshots at each breakpoint, look for:
Use browser_get_state and browser_get_html to inspect CSS classes, attributes, and computed styles without needing browser DevTools.
# Get HTML of a specific component to see its CSS classes and inline styles
browser_get_html(
selector=".checkout-button",
session_id=session_id
)
→ "<button class='checkout-button btn btn-primary disabled' style='opacity: 0.5;' disabled>Check Out</button>"
From this HTML you can detect:
disabled attribute (button non-interactive)opacity: 0.5 (intentionally dimmed, but should it be?)disabled (added by application state)# Get full page HTML and search for hidden elements
browser_get_html(session_id=session_id)
→ scan for: display:none, visibility:hidden, opacity:0, height:0, overflow:hidden
# Or get DOM state and look for:
browser_get_state(session_id=session_id)
→ selector_map elements missing from expected positions may be hidden
From browser_get_state, the selector_map includes element attributes. Check for:
| Attribute | What to Verify |
|-----------|---------------|
| class | Expected CSS classes applied, no conflicting classes |
| aria-label | Accessible label present for interactive elements |
| aria-disabled | Matches visual disabled state |
| href | Correct URL (not "#" or javascript:void(0)) |
| data-* | Application state attributes set correctly |
| type (input) | Correct type (e.g., "email" for email fields) |
Capture visual state before and after an action or code change.
# BEFORE state: capture baseline
session_id = browser_navigate(url="https://app.example.com/cart")["session_id"]
screenshot_before = browser_screenshot(session_id=session_id, full_page=True)
# Analyze: Claude describes the visual state
# Apply action (e.g., add item to cart)
state = browser_get_state(session_id=session_id)
# Find "Add to Cart" button → index N
browser_click(index=N, session_id=session_id)
# AFTER state: capture changed state
screenshot_after = browser_screenshot(session_id=session_id, full_page=True)
# Analyze: Claude describes what changed
# Save screenshots to files for documentation
Bash: python3 -c "import base64; open('before.png','wb').write(base64.b64decode('<before_base64>'))"
Bash: python3 -c "import base64; open('after.png','wb').write(base64.b64decode('<after_base64>'))"
browser_close_session(session_id=session_id)
For tracking regressions across deployments:
Step 1: Capture baseline (production/main branch)
screenshot_prod = browser_screenshot(session_id=prod_session, full_page=True)
→ save as "baseline-homepage-2026-03-03.png"
Step 2: Capture candidate (staging/PR branch)
screenshot_staging = browser_screenshot(session_id=staging_session, full_page=True)
→ save as "candidate-homepage-2026-03-03.png"
Step 3: Report differences
Claude analyzes both screenshots and describes:
- Layout changes
- Color changes
- Missing or new elements
- Font/size changes
- Spacing differences
Limitation: Browser Use cannot do pixel-level diff. Claude provides a descriptive comparison, not a numerical diff percentage. For automated CI regression testing with pixel diff, use Playwright + Percy or BackstopJS instead.
Detection:
# Screenshot reveals two elements occupying the same space
browser_screenshot(session_id)
# → Claude can see: tooltip covered by navbar, modal behind overlay, etc.
# Confirm via HTML: check z-index in inline styles or classes
browser_get_html(selector=".navbar, .tooltip", session_id)
→ look for z-index values, position:fixed, position:absolute
Detection:
# Screenshot shows "..." in unexpected places
browser_screenshot(session_id)
# Confirm via HTML: find overflow:hidden, white-space:nowrap, text-overflow:ellipsis
browser_get_html(selector=".product-title, .card-description", session_id)
Detection:
# Screenshot shows elements stacked that should be side-by-side, or vice versa
browser_screenshot(session_id)
# Confirm via HTML: check display:flex, display:grid, flex-direction, grid-template-columns
browser_get_html(selector=".product-grid, .card-container", session_id)
Detection:
# Get HTML and check img tags for broken src attributes
browser_get_html(selector="img", session_id)
→ look for: src="" (empty), src="/undefined", missing alt attributes
Detection:
# Button appears active but doesn't respond to clicks
browser_get_state(session_id)
# Check selector_map element attributes for: disabled, aria-disabled, tabindex="-1"
browser_get_html(selector="#checkout-btn", session_id)
# Check for: pointer-events:none, opacity:0.5 without disabled attr (just visually disabled)
Browser Use can detect visual bugs and inspect DOM/CSS. But some debugging signals require browser DevTools access, which is only available via claude-in-chrome (when available).
Escalate to claude-in-chrome when you need:
| Signal | Tool Required |
|--------|--------------|
| JavaScript console errors | mcp__claude-in-chrome__read_console_messages |
| Network request failures (404, 500, CORS) | mcp__claude-in-chrome__read_network_requests |
| React/Vue component state | mcp__claude-in-chrome__javascript_tool (run DevTools API) |
| Computed CSS (after all stylesheets applied) | mcp__claude-in-chrome__javascript_tool (getComputedStyle) |
| Event listener inspection | mcp__claude-in-chrome__javascript_tool |
| Performance timeline | mcp__claude-in-chrome__javascript_tool (PerformanceObserver) |
| Animated GIF of user interaction | mcp__claude-in-chrome__gif_creator |
See the browser-use:hybrid-debugging skill for combined Browser Use + claude-in-chrome workflows.
When reporting UI bugs, use this structured format:
## UI Bug Report: [Component Name]
**URL**: https://app.example.com/page
**Viewport**: 1280x720 (desktop) / 375x812 (mobile)
**Detected Via**: screenshot + DOM inspection
### Issue
[One-line description of the visual bug]
### Evidence
- Screenshot before/after: [attached or described]
- DOM state: [relevant selector_map entries]
- HTML/CSS: [relevant HTML snippet with problematic classes/styles]
### Root Cause (Suspected)
[CSS property or DOM attribute that is causing the issue]
### Reproduction Steps
1. Navigate to [URL]
2. [Action that triggers the bug]
3. Observe: [what you see]
Expected: [what you should see]
### Recommended Fix
[Specific CSS property or DOM attribute change to investigate]
testing
A test skill for validation testing. Use when testing skill parsing and validation logic.
tools
--- name: bad-skill description: This skill has invalid YAML in frontmatter allowed-tools: [invalid, array, syntax prerequisites: not-an-array --- # Bad Skill This skill has malformed frontmatter that should fail parsing. The YAML has: - Unclosed array bracket - Wrong type for prerequisites (should be array, not string)
development
Sync model aliases from the curated Firebase database. Fetches default model assignments, short aliases, team compositions, and known model metadata from the claudish API. Run this to get fresh model recommendations.
tools
Release one or more Magus plugins to the distribution repos (magus, magus-alpha, magus-marketing). Handles version inference from git history, marketplace.json updates, tagging, and force-push to lean dist repos. Use whenever the user says "release kanban", "release the dev plugin", "cut a new version of gtd", "bump kanban to 1.7", or hands you a batch like "release kanban and gtd". Also use for multi-plugin releases and for checking what a release would contain before committing.