# Screenshot Helper Guide for capturing screenshots using Chrome MCP. ## Overview This script helps capture screenshots of web interfaces for the software manual using Chrome MCP or fallback methods. ## Chrome MCP Prerequisites ### Check MCP Availability ```javascript async function checkChromeMCPAvailability() { try { // Attempt to get Chrome version via MCP const version = await mcp__chrome__getVersion(); return { available: true, browser: version.browser, version: version.version }; } catch (error) { return { available: false, error: error.message }; } } ``` ### MCP Configuration Expected Claude configuration for Chrome MCP: ```json { "mcpServers": { "chrome": { "command": "npx", "args": ["@anthropic-ai/mcp-chrome"], "env": { "CHROME_PATH": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" } } } } ``` ## Screenshot Workflow ### Step 1: Prepare Environment ```javascript async function prepareScreenshotEnvironment(workDir, config) { const screenshotDir = `${workDir}/screenshots`; // Create directory Bash({ command: `mkdir -p "${screenshotDir}"` }); // Check Chrome MCP const chromeMCP = await checkChromeMCPAvailability(); if (!chromeMCP.available) { console.log('Chrome MCP not available. Will generate manual guide.'); return { mode: 'manual' }; } // Start development server if needed if (config.screenshot_config?.dev_command) { const server = await startDevServer(config); return { mode: 'auto', server, screenshotDir }; } return { mode: 'auto', screenshotDir }; } ``` ### Step 2: Start Development Server ```javascript async function startDevServer(config) { const devCommand = config.screenshot_config.dev_command; const devUrl = config.screenshot_config.dev_url; // Start server in background const server = Bash({ command: devCommand, run_in_background: true }); console.log(`Starting dev server: ${devCommand}`); // Wait for server to be ready const ready = await waitForServer(devUrl, 30000); if (!ready) { throw new Error(`Server at ${devUrl} did not start in time`); } console.log(`Dev server ready at ${devUrl}`); return server; } async function waitForServer(url, timeout = 30000) { const start = Date.now(); while (Date.now() - start < timeout) { try { const response = await fetch(url, { method: 'HEAD' }); if (response.ok) return true; } catch (e) { // Server not ready } await sleep(1000); } return false; } ``` ### Step 3: Capture Screenshots ```javascript async function captureScreenshots(screenshots, config, workDir) { const results = { captured: [], failed: [] }; const devUrl = config.screenshot_config.dev_url; const screenshotDir = `${workDir}/screenshots`; for (const ss of screenshots) { try { // Build full URL const fullUrl = new URL(ss.url, devUrl).href; console.log(`Capturing: ${ss.id} (${fullUrl})`); // Configure capture options const options = { url: fullUrl, viewport: { width: 1280, height: 800 }, fullPage: ss.fullPage || false }; // Wait for specific element if specified if (ss.wait_for) { options.waitFor = ss.wait_for; } // Capture specific element if selector provided if (ss.selector) { options.selector = ss.selector; } // Add delay for animations await sleep(500); // Capture via Chrome MCP const result = await mcp__chrome__screenshot(options); // Save as PNG const filename = `${ss.id}.png`; Write(`${screenshotDir}/${filename}`, result.data, { encoding: 'base64' }); results.captured.push({ id: ss.id, file: filename, url: ss.url, description: ss.description, size: result.data.length }); } catch (error) { console.error(`Failed to capture ${ss.id}:`, error.message); results.failed.push({ id: ss.id, url: ss.url, error: error.message }); } } return results; } ``` ### Step 4: Generate Manifest ```javascript function generateScreenshotManifest(results, workDir) { const manifest = { generated: new Date().toISOString(), total: results.captured.length + results.failed.length, captured: results.captured.length, failed: results.failed.length, screenshots: results.captured, failures: results.failed }; Write(`${workDir}/screenshots/screenshots-manifest.json`, JSON.stringify(manifest, null, 2)); return manifest; } ``` ### Step 5: Cleanup ```javascript async function cleanupScreenshotEnvironment(env) { if (env.server) { console.log('Stopping dev server...'); KillShell({ shell_id: env.server.task_id }); } } ``` ## Main Runner ```javascript async function runScreenshotCapture(workDir, screenshots) { const config = JSON.parse(Read(`${workDir}/manual-config.json`)); // Prepare environment const env = await prepareScreenshotEnvironment(workDir, config); if (env.mode === 'manual') { // Generate manual capture guide generateManualCaptureGuide(screenshots, workDir); return { success: false, mode: 'manual' }; } try { // Capture screenshots const results = await captureScreenshots(screenshots, config, workDir); // Generate manifest const manifest = generateScreenshotManifest(results, workDir); // Generate manual guide for failed captures if (results.failed.length > 0) { generateManualCaptureGuide(results.failed, workDir); } return { success: true, captured: results.captured.length, failed: results.failed.length, manifest }; } finally { // Cleanup await cleanupScreenshotEnvironment(env); } } ``` ## Manual Capture Fallback When Chrome MCP is unavailable: ```javascript function generateManualCaptureGuide(screenshots, workDir) { const guide = ` # Manual Screenshot Capture Guide Chrome MCP is not available. Please capture screenshots manually. ## Prerequisites 1. Start your development server 2. Open a browser 3. Use a screenshot tool (Snipping Tool, Screenshot, etc.) ## Screenshots Required ${screenshots.map((ss, i) => ` ### ${i + 1}. ${ss.id} - **URL**: ${ss.url} - **Description**: ${ss.description} - **Save as**: \`screenshots/${ss.id}.png\` ${ss.selector ? `- **Capture area**: \`${ss.selector}\` element only` : '- **Type**: Full page or viewport'} ${ss.wait_for ? `- **Wait for**: \`${ss.wait_for}\` to be visible` : ''} **Steps:** 1. Navigate to ${ss.url} ${ss.wait_for ? `2. Wait for ${ss.wait_for} to appear` : ''} ${ss.selector ? `2. Capture only the ${ss.selector} area` : '2. Capture the full viewport'} 3. Save as \`${ss.id}.png\` `).join('\n')} ## After Capturing 1. Place all PNG files in the \`screenshots/\` directory 2. Ensure filenames match exactly (case-sensitive) 3. Run Phase 5 (HTML Assembly) to continue ## Screenshot Specifications - **Format**: PNG - **Width**: 1280px recommended - **Quality**: High - **Annotations**: None (add in post-processing if needed) `; Write(`${workDir}/screenshots/MANUAL_CAPTURE.md`, guide); } ``` ## Advanced Options ### Viewport Sizes ```javascript const viewportPresets = { desktop: { width: 1280, height: 800 }, tablet: { width: 768, height: 1024 }, mobile: { width: 375, height: 667 }, wide: { width: 1920, height: 1080 } }; async function captureResponsive(ss, config, workDir) { const results = []; for (const [name, viewport] of Object.entries(viewportPresets)) { const result = await mcp__chrome__screenshot({ url: ss.url, viewport }); const filename = `${ss.id}-${name}.png`; Write(`${workDir}/screenshots/${filename}`, result.data, { encoding: 'base64' }); results.push({ viewport: name, file: filename }); } return results; } ``` ### Before/After Comparisons ```javascript async function captureInteraction(ss, config, workDir) { const baseUrl = config.screenshot_config.dev_url; const fullUrl = new URL(ss.url, baseUrl).href; // Capture before state const before = await mcp__chrome__screenshot({ url: fullUrl, viewport: { width: 1280, height: 800 } }); Write(`${workDir}/screenshots/${ss.id}-before.png`, before.data, { encoding: 'base64' }); // Perform interaction (click, type, etc.) if (ss.interaction) { await mcp__chrome__click({ selector: ss.interaction.click }); await sleep(500); } // Capture after state const after = await mcp__chrome__screenshot({ url: fullUrl, viewport: { width: 1280, height: 800 } }); Write(`${workDir}/screenshots/${ss.id}-after.png`, after.data, { encoding: 'base64' }); return { before: `${ss.id}-before.png`, after: `${ss.id}-after.png` }; } ``` ### Screenshot Annotation ```javascript function generateAnnotationGuide(screenshots, workDir) { const guide = ` # Screenshot Annotation Guide For screenshots requiring callouts or highlights: ## Tools - macOS: Preview, Skitch - Windows: Snipping Tool, ShareX - Cross-platform: Greenshot, Lightshot ## Annotation Guidelines 1. **Callouts**: Use numbered circles (1, 2, 3) 2. **Highlights**: Use semi-transparent rectangles 3. **Arrows**: Point from text to element 4. **Text**: Use sans-serif font, 12-14pt ## Color Scheme - Primary: #0d6efd (blue) - Secondary: #6c757d (gray) - Success: #198754 (green) - Warning: #ffc107 (yellow) - Danger: #dc3545 (red) ## Screenshots Needing Annotation ${screenshots.filter(s => s.annotate).map(ss => ` - **${ss.id}**: ${ss.description} - Highlight: ${ss.annotate.highlight || 'N/A'} - Callouts: ${ss.annotate.callouts?.join(', ') || 'N/A'} `).join('\n')} `; Write(`${workDir}/screenshots/ANNOTATION_GUIDE.md`, guide); } ``` ## Troubleshooting ### Chrome MCP Not Found 1. Check Claude MCP configuration 2. Verify Chrome is installed 3. Check CHROME_PATH environment variable ### Screenshots Are Blank 1. Increase wait time before capture 2. Check if page requires authentication 3. Verify URL is correct ### Elements Not Visible 1. Scroll element into view 2. Expand collapsed sections 3. Wait for animations to complete ### Server Not Starting 1. Check if port is already in use 2. Verify dev command is correct 3. Check for startup errors in logs