UNPKG

chromancer

Version:

A powerful command-line interface for automating Chrome browser using Playwright. Perfect for web scraping, automation, testing, and browser workflows.

136 lines (135 loc) 5.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const core_1 = require("@oclif/core"); const base_js_1 = require("../base.js"); const fs = tslib_1.__importStar(require("fs/promises")); const path = tslib_1.__importStar(require("path")); class Screenshot extends base_js_1.BaseCommand { static description = 'Take a screenshot of the current page'; static examples = [ '<%= config.bin %> <%= command.id %> screenshot.png', '<%= config.bin %> <%= command.id %> fullpage.png --full-page', '<%= config.bin %> <%= command.id %> element.png --selector ".main-content"', '<%= config.bin %> <%= command.id %> mobile.png --viewport 375x667', ]; static flags = { ...base_js_1.BaseCommand.baseFlags, 'full-page': core_1.Flags.boolean({ description: 'Capture full scrollable page', default: false, }), format: core_1.Flags.string({ description: 'Screenshot format', options: ['png', 'jpeg', 'webp'], default: 'png', }), quality: core_1.Flags.integer({ description: 'Quality (0-100) for JPEG/WebP format', default: 80, }), selector: core_1.Flags.string({ description: 'CSS selector of element to screenshot', }), 'omit-background': core_1.Flags.boolean({ description: 'Make background transparent (PNG only)', default: false, }), viewport: core_1.Flags.string({ description: 'Set viewport size before screenshot (format: widthxheight)', }), scale: core_1.Flags.string({ description: 'Device scale factor', options: ['css', 'device'], default: 'device', }), }; static args = { filename: core_1.Args.string({ description: 'Output filename', required: true, }), }; async run() { const { args, flags } = await this.parse(Screenshot); await this.connectToChrome(flags.port, flags.host, flags.launch, flags.profile, flags.headless, flags.verbose, flags.keepOpen); if (!this.page) { this.error('No page available'); } try { // Set viewport if specified if (flags.viewport) { const [width, height] = flags.viewport.split('x').map(n => parseInt(n, 10)); if (!isNaN(width) && !isNaN(height)) { this.log(`📐 Setting viewport to ${width}x${height}`); await this.page.setViewportSize({ width, height }); } else { this.warn('Invalid viewport format, ignoring viewport flag'); } } this.log(`📸 Taking screenshot...`); // Ensure directory exists const dir = path.dirname(args.filename); if (dir && dir !== '.') { await fs.mkdir(dir, { recursive: true }); } const screenshotOptions = { path: args.filename, fullPage: flags['full-page'], type: flags.format, scale: flags.scale, }; // Add quality for JPEG/WebP if (flags.format === 'jpeg' || flags.format === 'webp') { screenshotOptions.quality = flags.quality; } // Add transparent background option for PNG if (flags.format === 'png' && flags['omit-background']) { screenshotOptions.omitBackground = true; } // Take screenshot of specific element or full page if (flags.selector) { this.log(`🎯 Capturing element: ${flags.selector}`); const element = await this.page.$(flags.selector); if (!element) { this.error(`Element not found: ${flags.selector}`); } await element.screenshot(screenshotOptions); } else { await this.page.screenshot(screenshotOptions); } const absolutePath = path.resolve(args.filename); const stats = await fs.stat(args.filename); const sizeMB = (stats.size / 1024 / 1024).toFixed(2); this.log(`✅ Screenshot saved to: ${absolutePath}`); this.log(`📊 File size: ${sizeMB} MB`); // Log screenshot details if verbose if (flags.verbose) { const pageInfo = await this.page.evaluate(() => ({ title: document.title, url: window.location.href, viewport: { width: window.innerWidth, height: window.innerHeight, }, documentSize: { width: document.documentElement.scrollWidth, height: document.documentElement.scrollHeight, }, })); this.logVerbose('Screenshot details', { format: flags.format, fullPage: flags['full-page'], selector: flags.selector || 'page', ...pageInfo, }); } } catch (error) { this.error(`Failed to take screenshot: ${error.message}`); } } } exports.default = Screenshot;