UNPKG

@knowcode/screenshotfetch

Version:

Web application spider with screenshot capture and customer journey documentation. Automate user flow documentation with authentication support.

198 lines (173 loc) • 7.75 kB
#!/usr/bin/env node const { program } = require('commander'); const fs = require('fs').promises; const path = require('path'); const chalk = require('chalk'); const ScreenshotCapture = require('./capture'); const ApplicationSpider = require('./lib/spider/ApplicationSpider'); program .name('screenshotfetch') .description('Web application spider with screenshot capture and customer journey documentation') .version('1.0.0'); program .command('capture <url>') .description('Capture a single screenshot') .option('-o, --output <path>', 'Output file path', './screenshot.png') .option('-f, --fullpage', 'Capture full page') .option('-w, --width <width>', 'Viewport width', '1920') .option('-h, --height <height>', 'Viewport height', '1080') .option('-t, --timeout <ms>', 'Navigation timeout', '30000') .option('-s, --cookie-strategy <strategy>', 'Cookie handling strategy (all|click|remove|block|none)', 'all') .option('--wait <ms>', 'Wait time after page load', '3000') .option('--headless <mode>', 'Headless mode (new|false)', 'new') .action(async (url, options) => { console.log(chalk.blue('šŸš€ Starting screenshot capture...')); const capture = new ScreenshotCapture({ viewport: { width: parseInt(options.width), height: parseInt(options.height), deviceScaleFactor: 1 }, timeout: parseInt(options.timeout), cookieStrategy: options.cookieStrategy, waitTime: parseInt(options.wait), headless: options.headless === 'false' ? false : 'new' }); try { await capture.init(); const result = await capture.captureScreenshot(url, options.output, { fullPage: options.fullpage }); if (result.success) { console.log(chalk.green('āœ… Screenshot captured successfully!')); } else { console.log(chalk.red('āŒ Failed to capture screenshot:', result.error)); } } catch (error) { console.error(chalk.red('Error:', error.message)); } finally { await capture.close(); } }); program .command('batch <file>') .description('Capture multiple screenshots from a JSON file') .option('-d, --delay <ms>', 'Delay between captures', '2000') .option('-s, --cookie-strategy <strategy>', 'Cookie handling strategy (all|click|remove|block|none)', 'all') .action(async (file, options) => { console.log(chalk.blue('šŸš€ Starting batch screenshot capture...')); try { const content = await fs.readFile(file, 'utf-8'); const screenshots = JSON.parse(content); if (!Array.isArray(screenshots)) { throw new Error('JSON file must contain an array of screenshot configurations'); } const capture = new ScreenshotCapture({ cookieStrategy: options.cookieStrategy }); await capture.init(); console.log(chalk.blue(`šŸ“ø Capturing ${screenshots.length} screenshots...`)); const results = await capture.captureMultiple(screenshots, { delay: parseInt(options.delay) }); const successful = results.filter(r => r.success).length; const failed = results.filter(r => !r.success).length; console.log(chalk.green(`āœ… Successful: ${successful}`)); if (failed > 0) { console.log(chalk.red(`āŒ Failed: ${failed}`)); } await capture.close(); } catch (error) { console.error(chalk.red('Error:', error.message)); } }); program .command('spider <start-url>') .description('Spider a web application and generate customer journey documentation') .option('-u, --username <username>', 'Username for authentication') .option('-p, --password <password>', 'Password for authentication') .option('-o, --output-dir <dir>', 'Output directory for documentation', './docs') .option('-d, --max-depth <depth>', 'Maximum crawl depth per flow', '10') .option('--max-flows <flows>', 'Maximum number of flows to discover', '5') .option('--max-pages <pages>', 'Maximum total pages to visit', '100') .option('--include-query-params', 'Include query parameters in URLs', true) .option('--flow-mode', 'Focus on customer journey flows', true) .option('-w, --width <width>', 'Viewport width', '1920') .option('-h, --height <height>', 'Viewport height', '1080') .option('--wait <ms>', 'Wait time between actions', '2000') .option('--headless <mode>', 'Headless mode (new|false)', 'new') .option('-s, --cookie-strategy <strategy>', 'Cookie handling strategy (all|click|remove|block|none)', 'all') .action(async (startUrl, options) => { console.log(chalk.blue('šŸ•·ļø Starting web application spider...')); console.log(chalk.gray(`šŸ“ Target: ${startUrl}`)); console.log(chalk.gray(`šŸ“ Output: ${options.outputDir}`)); // Validate required authentication if URL suggests it might need it if (!options.username || !options.password) { console.log(chalk.yellow('āš ļø No authentication credentials provided.')); console.log(chalk.yellow(' Use -u <username> -p <password> if the application requires login.')); } const spider = new ApplicationSpider({ viewport: { width: parseInt(options.width), height: parseInt(options.height), deviceScaleFactor: 1 }, headless: options.headless === 'false' ? false : 'new', cookieStrategy: options.cookieStrategy, waitTime: parseInt(options.wait), maxDepth: parseInt(options.maxDepth), maxFlows: parseInt(options.maxFlows), maxPages: parseInt(options.maxPages), flowMode: options.flowMode, includeQueryParams: options.includeQueryParams, outputDir: options.outputDir }); try { const result = await spider.spiderApplication( startUrl, options.username, options.password ); if (result.success) { console.log(chalk.green('\nāœ… Spider completed successfully!')); console.log(chalk.green(`šŸ“Š Summary:`)); console.log(chalk.white(` • Flows discovered: ${result.summary.completedFlows}`)); console.log(chalk.white(` • Total steps: ${result.summary.totalSteps}`)); console.log(chalk.white(` • Screenshots: ${result.summary.screenshotCount}`)); console.log(chalk.white(` • Unique URLs: ${result.summary.totalUrls}`)); console.log(chalk.cyan(`\nšŸ“ Documentation generated in: ${result.summary.outputDirectory}`)); console.log(chalk.cyan(`šŸ“„ Start with: ${path.join(result.summary.outputDirectory, 'index.md')}`)); } else { console.log(chalk.red('āŒ Spider completed with issues')); } } catch (error) { console.error(chalk.red('āŒ Spider failed:'), error.message); if (error.message.includes('Authentication failed')) { console.log(chalk.yellow('\nšŸ’” Tips:')); console.log(chalk.yellow(' • Check your username and password')); console.log(chalk.yellow(' • Ensure the start URL leads to a login page')); console.log(chalk.yellow(' • Try with --headless false to see what\'s happening')); } process.exit(1); } }); program .command('example') .description('Show example batch file format') .action(() => { const example = [ { url: 'https://example.com', output: './screenshots/example-home.png', fullPage: false }, { url: 'https://example.com/about', output: './screenshots/example-about.png', fullPage: true } ]; console.log(chalk.blue('Example batch file format:')); console.log(JSON.stringify(example, null, 2)); }); program.parse();