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