-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add screenshot capture functionality
- Loading branch information
1 parent
e59c15d
commit 49c3708
Showing
5 changed files
with
873 additions
and
51 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import http from 'http'; | ||
import ecstatic from 'ecstatic'; | ||
|
||
export default class HttpServer | ||
{ | ||
/** @var {http.Server} */ | ||
#server = null; | ||
|
||
get port() { | ||
return this.#server.address().port; | ||
} | ||
|
||
start() { | ||
return new Promise((resolve, reject) => { | ||
if (this.#server) { | ||
return resolve(); | ||
} | ||
|
||
const handler = ecstatic({ root: './dist' }); | ||
this.#server = http.createServer(handler); | ||
this.#server.on('listening', () => resolve()); | ||
this.#server.listen(); | ||
}); | ||
} | ||
|
||
async stop() { | ||
if (this.#server) { | ||
await this.#server.close(); | ||
this.#server = null; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { URL } from 'url'; | ||
import puppeteer from 'puppeteer'; | ||
import HttpServer from './HttpServer.mjs'; | ||
|
||
const defaultViewport = { | ||
// Using a 16:9 ratio here by default to match Twitter's image card dimensions | ||
width: 1200, | ||
height: 675, | ||
deviceScaleFactor: 2, | ||
}; | ||
|
||
export async function captureScreenshot(path, options = {}) { | ||
const httpServer = new HttpServer; | ||
await httpServer.start(); | ||
|
||
// Launch a new Chrome instance | ||
const browser = await puppeteer.launch({ | ||
args: [ | ||
'--no-sandbox', // Allow running as root inside the Docker container | ||
], | ||
// headless: false, // For testing | ||
}); | ||
|
||
// Create a new page and set the viewport | ||
const page = await browser.newPage(); | ||
const viewport = { ...defaultViewport, ...options.viewport }; | ||
await page.setViewport(viewport); | ||
|
||
// Navigate to the URL | ||
let url = new URL(`http://localhost:${httpServer.port}/screenshots/`); | ||
url.hash = path; | ||
await page.goto(url, { | ||
waitUntil: 'networkidle0', // Wait until the network is idle | ||
}); | ||
|
||
// Take the screenshot | ||
let result = await page.screenshot(); | ||
|
||
// Close the browser and HTTP server | ||
await browser.close(); | ||
await httpServer.stop(); | ||
|
||
return result; | ||
} |
Oops, something went wrong.