@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
JavaScript
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;