Last active
February 20, 2024 02:54
-
-
Save paceaux/f2aaf4f16342d3107d464627766181ec to your computer and use it in GitHub Desktop.
Improved command line options for headless screenshots in Chrome
This file contains hidden or 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
/** Pre requisites | |
* MAC ONLY FOR RIGHT NOW! Not my fault. We have to wait for Headless Chrome to hit Windows users | |
1) Make an Alias to Chrome | |
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" | |
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary" | |
2) Make Sure yarn is installed (it caches packages so you don't have to download them again) | |
`npm i yarn` | |
3) Use yarn to install dependencies: | |
`yarn add lighthouse` | |
`yarn add chrome-remote-interface` | |
* USAGE: | |
* `node headless-screenshot.js -w 1024 -h 768 --url=http://google.com` | |
* `node headless-screenshot.js --widths=1024,768 -h 768 --url=http://google.com` | |
* `node headless-screenshot.js --widths=1024,768 --heights=1024,768 --url=http://google.com` | |
* `node headless-screenshot.js --widths=1024,768 --heights=1024,768 --urls=http://google.com, http://amazon.com` | |
* `node headless-screenshot.js --widths=1024,768 --urlFile=myurls.json | |
* myurls.json should be an array of urls | |
*/ | |
/* Dependencies */ | |
const chromeLauncher = require('lighthouse/chrome-launcher/chrome-launcher'); | |
const CDP = require('chrome-remote-interface'); | |
const fs = require('fs'); | |
/** ARGUMENTS AND CONFIGUIRATION | |
* expects arguments to be | |
* -w int (width) | |
* -h int (height) | |
* -p int (port) | |
* --url string (url) | |
* --widths | |
*/ | |
const argv = require('minimist')(process.argv.slice(2)); | |
const windowWidth = argv.w ? argv.w : 1024; | |
const windowHeight = argv.h ? argv.h : 1024; | |
let urls = argv.urls ? argv.urls.split(',') : [argv.url]; | |
windowWidths = argv.widths ? argv.widths.split(',') : [windowWidth]; | |
windowHeights = argv.heights ? argv.heights.split(',') : [windowHeight]; | |
if (argv.urlFile && argv.urlFile.indexOf('.json') != -1) { | |
urls = require(`./${argv.urlFile}`); | |
} else { | |
} | |
/** | |
* Saves a screenshot to the file system, in the folder where this file is being run | |
* @param {String} imageData base64 string of image data | |
* @param {String} pageURL url of the page (used for generating file name) | |
* @param {String} windowWidth width of page (used in filename) | |
* @param {String} windowHeight height of page (used in filename) | |
*/ | |
function saveScreenshot(imageData, pageURL, windowWidth, windowHeight) { | |
const filename = `${pageURL.replace('http://','').replace(/\//g,'_')}.${windowWidth}x${windowHeight}.png`; | |
fs.writeFile( | |
filename, | |
imageData.data, {encoding:'base64'}, | |
(err)=>{ | |
console.warn('error', err); | |
} | |
); | |
} | |
/** | |
* Launches a debugging instance of Chrome. | |
* False launches a full version of Chrome. | |
* @return {Promise<ChromeLauncher>} | |
*/ | |
async function launchChrome(launchConfig) { | |
return await chromeLauncher.launch(launchConfig); | |
} | |
/** | |
* Generates instance of chrome, based on dimensions, saves a screenshot of it | |
* @param {string} pageURL : url of page | |
* @param {string} windowWidth: width of window as an int | |
* @param {string} windowHeight: height of window as an int | |
*/ | |
async function saveScreenShotFromURL(pageURL, windowWidth, windowHeight) { | |
const launchConfig = { | |
chromeFlags: [ | |
`--window-size=${windowWidth},${windowHeight}`, | |
'--disable-gpu', | |
'--headless' | |
] | |
}; | |
const chrome = await chromeLauncher.launch(launchConfig);; | |
const protocol = await CDP({port: chrome.port}); | |
const {Page, Runtime} = protocol; | |
await Promise.all([Page.enable(), Runtime.enable()]); | |
Page.navigate({url: pageURL}); | |
Page.loadEventFired(async () => { | |
const titleJS = "document.querySelector('title').textContent"; | |
const pageTitle = await Runtime.evaluate({expression: titleJS}); | |
const screenshot = await Page.captureScreenshot(); | |
console.log(`title of page: ${pageTitle.result.value}`); | |
await saveScreenshot(screenshot,pageURL, windowWidth, windowHeight); | |
protocol.close(); | |
chrome.kill(); | |
}); | |
} | |
/** | |
* | |
* @param {Array} urls | |
* @param {Array} widths | |
* @param {Array} heights | |
*/ | |
async function loopOverParameters(urls, widths, heights) { | |
const screenshots = []; | |
urls.forEach((url) => { | |
widths.forEach((width) => { | |
heights.forEach((height) => { | |
screenshots.push( saveScreenShotFromURL(url, width,height)); | |
}); | |
}); | |
}); | |
await Promise.all(screenshots); | |
} | |
loopOverParameters(urls, windowWidths, windowHeights); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment