Last active
October 18, 2024 06:46
-
-
Save signalwerk/546cad0a985c526f47ce3264e1055a67 to your computer and use it in GitHub Desktop.
CLI screenshot helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
import puppeteer from "puppeteer"; | |
import { URL } from "url"; | |
import yargs from "yargs"; | |
import { hideBin } from "yargs/helpers"; | |
import fs from "fs"; | |
import path from "path"; | |
const INDENT = " "; | |
(async () => { | |
// Parse arguments using yargs for better named argument support | |
const argv = yargs(hideBin(process.argv)) | |
.usage("Usage: $0 <url> [options]") | |
.demandCommand(1) | |
.option("resolution", { | |
alias: "r", | |
describe: "Screen resolution in format WIDTHxHEIGHT", | |
default: "1920x1080", | |
type: "string", | |
}) | |
.option("clickSelector", { | |
alias: "c", | |
describe: | |
"CSS selector to click before taking the screenshot (e.g., to dismiss a cookie warning)", | |
type: "string", | |
}) | |
.option("folder", { | |
alias: "f", | |
describe: "Subfolder where the screenshot will be saved", | |
default: "captures", | |
type: "string", | |
}) | |
.option("wait", { | |
alias: "w", | |
describe: | |
"Time to wait in milliseconds after page load before taking the screenshot", | |
default: 0, | |
type: "number", | |
}) | |
.option("username", { | |
alias: "u", | |
describe: "Username for Basic Authentication", | |
type: "string", | |
}) | |
.option("password", { | |
alias: "p", | |
describe: "Password for Basic Authentication", | |
type: "string", | |
}) | |
.help().argv; | |
const url = argv._[0]; | |
const resolution = argv.resolution; | |
const clickSelector = argv.clickSelector; | |
const folder = argv.folder; | |
const waitTime = argv.wait; | |
const username = argv.username; | |
const password = argv.password; | |
const [width, height] = resolution.replace("×", "x").split("x").map(Number); | |
if (!width || !height) { | |
console.error("Invalid resolution format. Use the format: 1920x1080"); | |
process.exit(1); | |
} | |
console.log(`Starting screenshot process for URL: ${url}`); | |
console.log( | |
`${INDENT}Using resolution: ${width}x${height} and device scale factor: 2`, | |
); | |
console.log(`${INDENT}Screenshots will be saved in folder: ${folder}`); | |
console.log( | |
`${INDENT}Waiting for ${waitTime}ms after page load before taking the screenshot`, | |
); | |
try { | |
// Ensure the folder exists, or create it | |
const folderPath = path.resolve(folder); | |
if (!fs.existsSync(folderPath)) { | |
fs.mkdirSync(folderPath, { recursive: true }); | |
console.log(`${INDENT}Created folder: ${folderPath}`); | |
} | |
const browser = await puppeteer.launch(); | |
console.log(`${INDENT}Browser launched`); | |
const page = await browser.newPage(); | |
console.log(`${INDENT}New page created`); | |
// Set Basic Authentication if username and password are provided | |
if (username && password) { | |
console.log(`${INDENT}Setting up Basic Authentication`); | |
await page.authenticate({ | |
username: username, | |
password: password, | |
}); | |
console.log(`${INDENT}Basic Authentication configured`); | |
} | |
await page.setViewport({ | |
width, | |
height, | |
deviceScaleFactor: 2, | |
}); | |
console.log( | |
`${INDENT}Viewport set to: ${width}x${height} with device scale factor 2`, | |
); | |
await page.goto(url, { waitUntil: "networkidle2" }); | |
console.log(`${INDENT}Navigated to: ${url}`); | |
// Optionally click the provided selector to remove cookie warnings or popups | |
if (clickSelector) { | |
console.log( | |
`${INDENT}Attempting to click element with selector: ${clickSelector}`, | |
); | |
try { | |
const selection = await page.waitForSelector(clickSelector, { | |
timeout: 5000, | |
}); | |
if (!selection) { | |
console.warn( | |
`${INDENT}Warning: Could not find the element with selector: ${clickSelector}. Proceeding without clicking.`, | |
); | |
} else { | |
await page.click(clickSelector); | |
console.log( | |
`${INDENT}Successfully clicked element: ${clickSelector}`, | |
); | |
// Wait for 500ms after the click to ensure the page updates | |
await new Promise((resolve) => setTimeout(resolve, 500)); | |
console.log(`${INDENT}Waited 500ms after clicking the element`); | |
} | |
} catch (error) { | |
console.error( | |
`${INDENT}Error clicking element with selector: ${clickSelector}`, | |
error, | |
); | |
} | |
} | |
// Wait for the specified time after the page has loaded | |
if (waitTime > 0) { | |
console.log( | |
`${INDENT}Waiting for ${waitTime}ms before taking the screenshot`, | |
); | |
await new Promise((resolve) => setTimeout(resolve, waitTime)); | |
} | |
// Parse the URL and construct the output file name | |
const parsedUrl = new URL(url); | |
const domain = parsedUrl.hostname.replace(/^www\./, "").replace(/\./g, "-"); | |
const pathName = parsedUrl.pathname | |
.replace(/\//g, "--") | |
.replace(/^-+|-+$/g, ""); | |
const outputFileName = `${domain}${pathName ? "--" + pathName : ""}.png`; | |
const outputPath = path.join(folderPath, outputFileName); | |
console.log(`${INDENT}Taking screenshot`); | |
await page.screenshot({ path: outputPath }); | |
console.log(`${INDENT}Screenshot saved successfully as ${outputPath}`); | |
await browser.close(); | |
console.log(`${INDENT}Browser closed`); | |
} catch (error) { | |
console.error(`${INDENT}Error during the screenshot process:`, error); | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "capture-screenshot", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"keywords": [], | |
"author": "", | |
"license": "MIT", | |
"dependencies": { | |
"puppeteer": "^23.5.2", | |
"yargs": "^17.7.2" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment