UNPKG

@knowcode/screenshotfetch

Version:

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

130 lines (105 loc) 3.78 kB
const puppeteer = require('puppeteer'); const fs = require('fs').promises; const path = require('path'); const CookieHandler = require('./cookie-handler'); class ScreenshotCapture { constructor(options = {}) { this.options = { viewport: { width: 1920, height: 1080, deviceScaleFactor: 1 }, timeout: 30000, headless: 'new', cookieStrategy: 'all', // 'all', 'click', 'remove', 'block', 'none' waitTime: 3000, ...options }; this.browser = null; this.cookieHandler = new CookieHandler(); } async init() { this.browser = await puppeteer.launch({ headless: this.options.headless, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process' ] }); } async captureScreenshot(url, outputPath, options = {}) { const page = await this.browser.newPage(); try { // Set viewport await page.setViewport(this.options.viewport); // Apply cookie blocking if requested if (this.options.cookieStrategy === 'all' || this.options.cookieStrategy === 'block') { await this.cookieHandler.blockCookieServices(page); } // Navigate to page const navigationOptions = { waitUntil: options.waitUntil || 'networkidle2', timeout: options.timeout || this.options.timeout }; await page.goto(url, navigationOptions); // Wait for dynamic content await new Promise(resolve => setTimeout(resolve, this.options.waitTime)); // Handle cookie consent based on strategy if (this.options.cookieStrategy !== 'none') { await this.handleCookieConsent(page); } // Additional wait after cookie handling if (this.options.cookieStrategy !== 'none') { await new Promise(resolve => setTimeout(resolve, 1000)); } // Take screenshot const screenshotOptions = { path: outputPath, fullPage: options.fullPage || false, ...options }; // Ensure directory exists const dir = path.dirname(outputPath); await fs.mkdir(dir, { recursive: true }); await page.screenshot(screenshotOptions); console.log(`✅ Screenshot saved: ${outputPath}`); return { success: true, path: outputPath }; } catch (error) { console.error(`❌ Error capturing ${url}:`, error.message); return { success: false, error: error.message }; } finally { await page.close(); } } async handleCookieConsent(page) { const strategy = this.options.cookieStrategy; if (strategy === 'all' || strategy === 'click') { const dismissed = await this.cookieHandler.dismissCookieConsent(page); if (dismissed) return; } if (strategy === 'all' || strategy === 'remove') { await this.cookieHandler.removeCookieBanners(page); } } async captureMultiple(screenshots, options = {}) { const results = []; const delay = options.delay || 2000; for (let i = 0; i < screenshots.length; i++) { const { url, output, ...screenshotOptions } = screenshots[i]; console.log(`[${i + 1}/${screenshots.length}] Capturing: ${url}`); const result = await this.captureScreenshot(url, output, screenshotOptions); results.push(result); // Add delay between captures if (i < screenshots.length - 1) { await new Promise(resolve => setTimeout(resolve, delay)); } } return results; } async close() { if (this.browser) { await this.browser.close(); this.browser = null; } } } module.exports = ScreenshotCapture;