infinite-agents-public/generate_screenshots.js

215 lines
6.2 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Screenshot Generator for Infinite Agents Dashboard
*
* Automatically captures screenshots of all demos for preview thumbnails.
* Uses Playwright to render each demo and save a screenshot.
*
* Installation:
* npm install -D playwright
* npx playwright install chromium
*
* Usage:
* node generate_screenshots.js
* node generate_screenshots.js --category threejs
* node generate_screenshots.js --single threejs_viz/threejs_viz_1.html
*/
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
// Demo categories and their file patterns
const DEMO_CATEGORIES = {
threejs: {
pattern: 'threejs_viz/threejs_viz_*.html',
delay: 3000, // Extra time for WebGL to render
},
sdg: {
pattern: 'sdg_viz/sdg_viz_*.html',
delay: 2000,
},
d3: {
pattern: 'd3_test/d3_viz_*.html',
delay: 1500,
},
mapbox: {
pattern: 'mapbox_test/mapbox_globe_*/index.html',
delay: 3000, // Mapbox needs time to load tiles
},
claudeDevTools: {
pattern: 'claude_code_devtools/claude_devtool_*.html',
delay: 1000,
},
uiSingle: {
pattern: 'src/ui_hybrid_*.html',
delay: 800,
},
uiInfinite: {
pattern: 'src_infinite/ui_hybrid_*.html',
delay: 800,
},
uiModular: {
pattern: 'src_group/ui_hybrid_*/index.html',
delay: 800,
},
infiniteVariants: {
pattern: 'infinite_variants/infinite_variant_*/test_output/*.html',
delay: 1500, // Mixed content, some may have animations
},
};
// Parse command line arguments
const args = process.argv.slice(2);
const categoryFilter = args.find(arg => arg.startsWith('--category='))?.split('=')[1];
const singleFile = args.find(arg => arg.startsWith('--single='))?.split('=')[1];
const PORT = args.find(arg => arg.startsWith('--port='))?.split('=')[1] || 8889;
// Create screenshots directory
const SCREENSHOTS_DIR = path.join(__dirname, 'screenshots');
if (!fs.existsSync(SCREENSHOTS_DIR)) {
fs.mkdirSync(SCREENSHOTS_DIR, { recursive: true });
console.log(`✅ Created screenshots directory: ${SCREENSHOTS_DIR}`);
}
// Scan directory for demo files
function scanDirectory(pattern) {
const glob = require('glob');
return glob.sync(pattern);
}
// Get all demo files
function getAllDemos() {
const demos = [];
for (const [category, config] of Object.entries(DEMO_CATEGORIES)) {
if (categoryFilter && category !== categoryFilter) continue;
const files = scanDirectory(config.pattern);
files.forEach(file => {
demos.push({
path: file,
category,
delay: config.delay,
});
});
}
return demos;
}
// Capture screenshot for a single demo
async function captureScreenshot(browser, demo, index, total) {
const page = await browser.newPage();
try {
// Set viewport size (desktop resolution)
await page.setViewportSize({ width: 1920, height: 1080 });
const url = `http://localhost:${PORT}/${demo.path}`;
console.log(`\n📸 [${index + 1}/${total}] ${demo.path}`);
// Navigate to demo
await page.goto(url, {
waitUntil: 'networkidle',
timeout: 30000,
});
// Wait for demo to render
await page.waitForTimeout(demo.delay);
// Generate screenshot filename
const screenshotFilename = demo.path.replace(/\//g, '_').replace('.html', '.png');
const screenshotPath = path.join(SCREENSHOTS_DIR, screenshotFilename);
// Capture screenshot
await page.screenshot({
path: screenshotPath,
fullPage: false, // Just viewport, not entire scrollable page
});
console.log(` ✅ Saved: ${screenshotFilename}`);
} catch (error) {
console.error(` ❌ Failed: ${error.message}`);
} finally {
await page.close();
}
}
// Main execution
async function main() {
console.log('🚀 Infinite Agents Screenshot Generator\n');
// Get demo files
let demos;
if (singleFile) {
demos = [{
path: singleFile,
category: 'custom',
delay: 2000,
}];
} else {
demos = getAllDemos();
}
if (demos.length === 0) {
console.error('❌ No demo files found!');
console.log('\nMake sure:');
console.log(' 1. You are in the project root directory');
console.log(' 2. Demo files exist in their respective directories');
console.log(' 3. Category filter is correct (if using --category)');
process.exit(1);
}
console.log(`📊 Found ${demos.length} demos to screenshot\n`);
// Check if server is running
console.log(`🔍 Checking if server is running on http://localhost:${PORT}...`);
try {
const http = require('http');
await new Promise((resolve, reject) => {
const req = http.get(`http://localhost:${PORT}`, (res) => {
resolve();
});
req.on('error', reject);
req.setTimeout(3000, () => reject(new Error('Timeout')));
});
console.log(' ✅ Server is running\n');
} catch (error) {
console.error(' ❌ Server is not running!');
console.log(`\n🔧 Start the server first:`);
console.log(` python3 -m http.server ${PORT}\n`);
process.exit(1);
}
// Launch browser
console.log('🌐 Launching browser...');
const browser = await chromium.launch({
headless: true,
});
console.log(' ✅ Browser ready\n');
// Capture screenshots
console.log('📸 Capturing screenshots...');
console.log('━'.repeat(50));
for (let i = 0; i < demos.length; i++) {
await captureScreenshot(browser, demos[i], i, demos.length);
}
// Cleanup
await browser.close();
console.log('\n' + '━'.repeat(50));
console.log(`\n✨ Done! Captured ${demos.length} screenshots`);
console.log(`📁 Screenshots saved to: ${SCREENSHOTS_DIR}\n`);
}
// Run
main().catch(error => {
console.error('\n❌ Fatal error:', error);
process.exit(1);
});