import { unlink } from 'node:fs/promises'; import { runCommand } from '../../utils/run-command'; import { log, LogLevel } from '../../utils/log'; import { CURRENT_PLATFORM, SupportedPlatform } from '../../utils/platform'; import { exists } from '../../utils/io'; export async function captureScreen( imagePath: string, ): Promise { if (!imagePath) { throw new Error('Path for screenshot not provided'); } if (await exists(imagePath)) { log(`Screenshot file already exists at ${imagePath}. It will be overwritten.`, LogLevel.Warn); unlink(imagePath); } const platformCommands: { readonly [K in SupportedPlatform]: string; } = { [SupportedPlatform.macOS]: `screencapture -x ${imagePath}`, [SupportedPlatform.Linux]: `import -window root ${imagePath}`, [SupportedPlatform.Windows]: `powershell -NoProfile -EncodedCommand ${encodeForPowershell(getScreenshotPowershellScript(imagePath))}`, }; const commandForPlatform = platformCommands[CURRENT_PLATFORM]; if (!commandForPlatform) { log(`Screenshot capture not supported on: ${SupportedPlatform[CURRENT_PLATFORM]}`, LogLevel.Warn); return; } log(`Capturing screenshot to ${imagePath} using command:\n\t> ${commandForPlatform}`); const { error } = await runCommand(commandForPlatform); if (error) { log(`Failed to capture screenshot.\n${error}`, LogLevel.Warn); return; } log(`Captured screenshot to ${imagePath}.`); } function getScreenshotPowershellScript(imagePath: string): string { return ` $ProgressPreference = 'SilentlyContinue' # Do not pollute stderr Add-Type -AssemblyName System.Windows.Forms $screenBounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds $bmp = New-Object System.Drawing.Bitmap $screenBounds.Width, $screenBounds.Height $graphics = [System.Drawing.Graphics]::FromImage($bmp) $graphics.CopyFromScreen([System.Drawing.Point]::Empty, [System.Drawing.Point]::Empty, $screenBounds.Size) $bmp.Save('${imagePath}') $graphics.Dispose() $bmp.Dispose() `; } function encodeForPowershell(script: string): string { const buffer = Buffer.from(script, 'utf16le'); return buffer.toString('base64'); }