skills/browser-debugging/SKILL.md
Browser debugging escalation protocol for when tests pass but the feature doesn't work in the user's browser. Triggers on: tests pass but doesn't work, feature broken in browser, works in playwright but not browser, console screenshot, browser debugging.
npx skillsauth add mdmagnuson-creator/yo-go browser-debuggingInstall 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.
Load this skill when ANY of these triggers occur:
- User says "it's not working" but code inspection shows it should work
- Two rounds of code analysis haven't found the issue
- User provides a screenshot showing unexpected behavior
- Tests pass but feature doesn't work in browser
- User explicitly mentions visual discrepancy
Do NOT wait for 5+ rounds of back-and-forth. Escalate early when there's a disconnect between expected and actual behavior.
This protocol provides a structured debugging escalation for "works in tests, fails in browser" scenarios. It minimizes wasted rounds by gathering evidence early and injecting diagnostics proactively.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ LEVEL 1 │ ──► │ LEVEL 2 │ ──► │ LEVEL 3 │ ──► │ LEVEL 4 │
│ Quick Verify │ │ Inject Version │ │ Runtime Diag │ │ Env Comparison │
│ │ │ │ │ │ │ │
│ Browser info, │ │ Module-load │ │ Console.log at │ │ Different │
│ console output │ │ markers │ │ decision points │ │ browser/headed │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
Activate this protocol when:
Do NOT assume caching first. Get browser info and console state before suggesting cache clears.
When user reports a feature doesn't work but tests pass, your first response should ask:
I see the tests are passing. Let me gather some diagnostic info:
1. Which browser are you using? (Brave, Chrome, Safari, Firefox, Edge)
2. Can you open DevTools (F12) → Console tab and share a screenshot?
3. Are there any red errors or yellow warnings?
This will help me understand what's happening in your environment.
Key principle: Get console output BEFORE suggesting any fixes.
If user's console shows no errors, inject a version marker to verify code freshness:
Run @developer to add a highly visible console.log at module load time:
// Temporary debug - remove after issue resolved
console.log('%c[ComponentName] v2026-02-24-v1', 'background: #ff0; color: #000; font-size: 16px;');
Properties of a good version marker:
I've added a diagnostic marker. Please:
1. Hard refresh the page (Ctrl/Cmd + Shift + R)
2. Open DevTools → Console
3. Do you see a bright yellow "[ComponentName] v2026-02-24-v1" message?
If YES → Code is loading correctly, issue is runtime behavior (go to Level 3)
If NO → Code isn't loading, likely a caching or build issue (debug that path)
If the version marker appears but the feature still doesn't work, add targeted logging:
Map out where the feature could fail:
Run @developer to add console.log statements:
// Event handler entry
const handleClick = useCallback(() => {
console.log('[ComponentName] handleClick called');
// ... rest of function
}, [deps]);
// Conditional branches
if (someCondition) {
console.log('[ComponentName] branch A, condition value:', someCondition);
// ...
} else {
console.log('[ComponentName] branch B, condition value:', someCondition);
// ...
}
// State/ref access
console.log('[ComponentName] checking ref:', {
refCurrent: ref.current,
activeElement: document.activeElement,
matches: ref.current === document.activeElement
});
I've added diagnostic logging. Please:
1. Refresh the page
2. Try to use the feature that's not working
3. Share a screenshot of the Console output
I'm looking for which logs appear and what values they show.
When user shares console output:
undefined, null, or stale valuesIf runtime diagnostics don't reveal the issue, compare environments:
Let's test in a different environment:
1. Try the feature in a different browser (or incognito/private window)
2. Does it work there?
If YES → Browser-specific issue (extensions, settings, cached state)
If NO → Issue is consistent, likely a subtle code bug
Run the E2E test in headed mode to see exactly what Playwright sees:
npx playwright test path/to/test.spec.ts --headed --project=chromium
Watch the browser:
If the project uses React, check for StrictMode-related issues:
Is this a development build with React StrictMode enabled?
StrictMode double-mounts components, which can cause:
- Event listeners capturing stale DOM references
- Effects running twice with cleanup issues
- Closures capturing first-mount values
Check for patterns like:
- `const element = ref.current` captured in a closure
- `document.activeElement === capturedElement` comparisons
- Event handlers that don't read ref.current at event time
See: React StrictMode / Stale Closure patterns in CONVENTIONS.md
After running this protocol, common issues found include:
| Symptom | Likely Cause | Fix | |---------|--------------|-----| | Handler never called | Event listener not attached, wrong element | Check effect dependencies, verify element exists | | Handler called but condition fails | Stale closure, wrong comparison | Read refs at event time, not capture time | | Works in test, fails in dev | React StrictMode double-mount | Use refs instead of captured variables | | Works after HMR, fails on fresh load | Initialization timing | Check effect dependencies, add proper guards | | Works in Chrome, fails in Safari | Browser API differences | Check for unsupported APIs, add polyfills |
When Builder reports "user says feature doesn't work but tests pass", @developer should:
// Temporary debug - remove after issue resolved
console.log('%c[ComponentName] v2026-02-24', 'background: yellow; font-size: 14px;');
const handleSomething = useCallback(() => {
console.log('[ComponentName] handleSomething called');
// ... rest of function
}, []);
if (someCondition) {
console.log('[ComponentName] branch A, value:', someValue);
} else {
console.log('[ComponentName] branch B, value:', someValue);
}
console.log('[ComponentName] DOM state:', {
refCurrent: ref.current,
activeElement: document.activeElement,
comparison: ref.current === document.activeElement
});
These logs help Builder identify where behavior diverges between test and user browser.
After the issue is resolved:
console.log statementsBefore (10+ rounds):
After (3-4 rounds):
Half the rounds, faster resolution, less user frustration.
data-ai
Generate verification contracts before delegating tasks to sub-agents, defining how success will be measured. Triggers on: verification contract, delegation contract, task verification, contract-first delegation.
testing
Verify that Vercel environment variables point to the correct Supabase project for each environment to prevent staging/production cross-wiring. Triggers on: vercel supabase check, environment alignment, env var check, supabase environment.
development
Manage codebase and database vectorization for semantic search. Use when initializing, refreshing, or querying the vector index. Triggers on: vectorize init, vectorize refresh, vectorize search, semantic search, vector index, enable vectorization.
testing
Patterns for XCUITest UI tests for native Apple apps (macOS/iOS). Use when writing or reviewing XCUITest tests for Swift apps. Triggers on: XCUITest, xcuitest, native app testing, Apple UI tests, SwiftUI tests, AppKit tests, UIKit tests.