# UI Automation Troubleshooting Guide ## Overview This guide helps troubleshoot common issues with the UI Automation and Reflection system. It covers problems with component registration, UI state visibility, automation server connectivity, and debugging techniques. ## Quick Diagnostic Tools ### 1. Browser Console UI State Inspection Inspect current component registration directly in the browser console via `window.__UI_STATE__`: ```javascript // In the browser console: window.__UI_STATE__ // Full UI state object JSON.stringify(window.__UI_STATE__, null, 2) // Pretty-printed JSON output Object.keys(window.__UI_STATE__).length // Component count ``` ### 2. Claude Code Slash Command Use the `/ui-state` command in Claude Code to get automated analysis: ``` /ui-state ``` This will run the dump tool and provide AI-powered analysis of your UI state. ### 3. Browser Console Logging Enable detailed logging by checking browser console for UI reflection messages: - `🔄 [UI-STATE]` - Component registration updates - `🔌 [WEBSOCKET]` - WebSocket connection status - `📡 [UI_STATE_UPDATE]` - State change broadcasts ## Common Issues and Solutions ### Issue 1: Components Not Showing in UI State **Symptoms:** - UI state dump shows only sidebar/navigation components - Screen-specific components are missing - Empty or minimal component count **Root Causes & Solutions:** #### A. Missing UI Reflection Integration **Problem:** Component doesn't use `useAutomationIdAndRegister` hook. **Solution:** Add UI reflection to the component: ```tsx // Before: No UI reflection function MyComponent() { return (
); } // After: With UI reflection function MyComponent() { const { automationIdProps } = useAutomationIdAndRegister({ id: 'my-component', type: 'container', label: 'My Component' }); const { automationIdProps: buttonProps } = useAutomationIdAndRegister({ id: 'my-button', type: 'button', label: 'Click me' }); return (
); } ``` #### B. Incorrect Import Paths **Problem:** Import paths are wrong, causing hook to be undefined. **Error Message:** ``` TypeError: useAutomationIdAndRegister is not a function ``` **Solution:** Use correct import paths: ```tsx // Correct imports import { useAutomationIdAndRegister } from 'packages/ui/src/ui-reflection/useAutomationIdAndRegister'; import { ReflectionContainer } from 'packages/ui/src/ui-reflection/ReflectionContainer'; ``` #### C. Missing ReflectionContainer Wrapper **Problem:** Components are registered but not properly nested. **Solution:** Wrap main content with ReflectionContainer: ```tsx function PageComponent() { const { automationIdProps: pageProps } = useAutomationIdAndRegister({ id: 'my-page', type: 'container', label: 'My Page' }); return ( {/* All page content goes here */}
{/* ... */}
); } ``` ### Issue 2: Automation Server Connection Problems **Symptoms:** - `window.__UI_STATE__` returns undefined or empty - WebSocket connection failures in browser console - UI state not updating in real-time **Diagnostic Steps:** 1. **Check Automation Server Status:** ```bash # Check if automation server is running curl http://localhost:4000/api/ui-state ``` 2. **Verify Server Logs:** ```bash # In the main project directory docker-compose logs | grep automation ``` 3. **Check WebSocket Connection:** Open browser console and look for: ``` [WEBSOCKET] 🔌 Client connected [WEBSOCKET] 📡 UI_STATE_UPDATE received ``` **Solutions:** #### A. Start Automation Server ```bash # Start the automation server cd tools/ai-automation npm start ``` #### B. Check Port Conflicts If port 4000 is in use, update configuration: ```bash # Check what's using port 4000 lsof -i :4000 # Kill conflicting process if needed kill -9 ``` #### C. Restart Docker Services ```bash # Restart all services docker-compose down docker-compose up -d ``` ### Issue 3: UI State Not Updating **Symptoms:** - Components show in initial dump but don't update - State changes not reflected in UI state - Stale component metadata **Root Causes & Solutions:** #### A. Missing Metadata Updates **Problem:** Component state changes but metadata isn't updated. **Solution:** Use `updateMetadata` function: ```tsx function DynamicButton({ label, disabled }) { const { automationIdProps, updateMetadata } = useAutomationIdAndRegister({ id: 'dynamic-button', type: 'button', label, disabled }); // Update metadata when props change useEffect(() => { updateMetadata({ label, disabled }); }, [label, disabled, updateMetadata]); return ; } ``` #### B. Module Instance Mismatch **Problem:** Different UIStateManager instances in different processes. **Solution:** Ensure automation server is used as source of truth: - Use HTTP API endpoints instead of direct module access - Verify WebSocket connections are active - Check for multiple server instances ### Issue 4: Component Hierarchy Issues **Symptoms:** - Components appear as root-level instead of nested - Parent-child relationships are incorrect - Auto-generated IDs are wrong **Solutions:** #### A. Proper Context Usage ```tsx // Correct: Parent sets context for children function ParentContainer() { const { automationIdProps } = useAutomationIdAndRegister({ id: 'parent-container', type: 'container', label: 'Parent' }); return ( {/* Children inherit parent context automatically */} {/* Will be parent-container-child */} ); } function ChildComponent() { // No explicit parentId needed - inherited from context const { automationIdProps } = useAutomationIdAndRegister({ type: 'button', label: 'Child Button' }); return ; } ``` #### B. ID Naming Conventions Follow consistent naming patterns: - Screen/Page: `my-screen` - Subcontainer: `${parentId}-section` (e.g., `my-screen-filters`) - Component: `${parentId}-type` (e.g., `my-screen-filters-select`) ### Issue 5: Form Field Naming and Override ID Support **Symptoms:** - Form fields show generic auto-generated names like `formField-1`, `formField-2` - Meaningful field names like `email`, `phone_no` are not appearing - Components ignore `data-automation-id` attributes **Root Causes & Solutions:** #### A. Missing Override ID Support **Problem:** Components auto-generate IDs instead of using provided `data-automation-id`. **Solution:** Implement the override ID pattern in form components: ```tsx // Enhanced useAutomationIdAndRegister with actions support export function useAutomationIdAndRegister( component: Omit & { id?: string }, actionsOrShouldRegister: ActionConfig | boolean = [], overrideId?: string ): { automationIdProps: { id: string; 'data-automation-id': string }; updateMetadata: (partial: Partial) => void; updateActions: (newActions: ActionConfig) => void; } // Where ActionConfig = ComponentAction[] | (() => ComponentAction[]) // In form components (Input, CustomSelect, TextArea): const { automationIdProps } = useAutomationIdAndRegister({ type: 'formField', fieldType: 'textField', id, label }, true, dataAutomationId); // Pass override ID as third parameter ``` #### B. Implementing Override ID Pattern in Components **Solution:** Update form components to support `data-automation-id`: ```tsx // Before: No override support export const Input = forwardRef( ({ label, id, ...props }, ref) => { const { automationIdProps } = useAutomationIdAndRegister({ id, type: 'formField', fieldType: 'textField' }); return ; } ); // After: With override support export const Input = forwardRef( ({ label, id, "data-automation-id": dataAutomationId, ...props }, ref) => { const { automationIdProps } = useAutomationIdAndRegister({ id, type: 'formField', fieldType: 'textField' }, true, dataAutomationId); // Pass override ID return ; } ); ``` #### C. Usage Pattern for Meaningful Field Names **Solution:** Use `data-automation-id` for meaningful form field names: ```tsx // Form with meaningful field names function MyForm() { return (
setFormData({...formData, companyName: e.target.value})} /> setFormData({...formData, clientType: value})} />