/** * Playwright Browser IPC Handlers * Handles browser download requests from renderer process */ import { app, ipcMain, IpcMainInvokeEvent } from 'electron' import { join } from 'path' import { IPC_CHANNELS } from '../../shared/ipc-channels' import { withErrorHandling, type IpcResult } from './index' import { DownloadService } from '../services/playwright-browser' import { ConfigManager } from '../services/config/config-manager' import { S3Client } from '@aws-sdk/client-s3' import type { DownloadProgress } from '../services/playwright-browser' /** * Create S3 client from config */ function createS3Client(): S3Client { const config = ConfigManager.getInstance().getConfig().update if (!config) { throw new Error('Update config is not available') } return new S3Client({ region: config.region, endpoint: config.endpoint, credentials: { accessKeyId: config.accessKey, secretAccessKey: config.secretKey }, forcePathStyle: true }) } /** * Check if Playwright browsers are installed */ async function checkBrowsersExist(): Promise { const fs = await import('fs') const browsersPath = join(app.getPath('userData'), 'ms-playwright') const newChromiumPath = join(browsersPath, 'chromium-1208', 'chrome-win64', 'chrome.exe') const oldChromiumPath = join(browsersPath, 'chromium-win32', 'chrome.exe') const chromiumPath = fs.default.existsSync(newChromiumPath) ? newChromiumPath : oldChromiumPath if (fs.default.existsSync(chromiumPath)) { return true } let foundRevision = false try { const entries = fs.default.readdirSync(browsersPath) for (const entry of entries) { if (entry.startsWith('chromium-') && !entry.includes('headless')) { const revisionPath = join(browsersPath, entry, 'chrome-win64', 'chrome.exe') if (fs.default.existsSync(revisionPath)) { foundRevision = true break } } } } catch { // Ignore browser directory probing failures } return foundRevision } /** * Track active download for cancellation */ let activeDownload: { service: DownloadService; cancelled: boolean } | null = null export function registerPlaywrightBrowserHandlers(): void { ipcMain.handle(IPC_CHANNELS.PLAYWRIGHT_BROWSER_CHECK, async (): Promise> => { return withErrorHandling(async () => { return checkBrowsersExist() }, 'playwright-browser:check') }) ipcMain.handle( IPC_CHANNELS.PLAYWRIGHT_BROWSER_DOWNLOAD, async (event: IpcMainInvokeEvent): Promise> => { return withErrorHandling(async () => { const s3Client = createS3Client() const service = new DownloadService({ s3Client }) activeDownload = { service, cancelled: false } await service.downloadAll((progress: DownloadProgress) => { if (activeDownload?.cancelled) { throw new Error('Download cancelled by user') } event.sender.send(IPC_CHANNELS.PLAYWRIGHT_BROWSER_PROGRESS, progress) }) activeDownload = null }, 'playwright-browser:download') } ) ipcMain.handle(IPC_CHANNELS.PLAYWRIGHT_BROWSER_CANCEL, async (): Promise> => { return withErrorHandling(async () => { if (activeDownload) { activeDownload.cancelled = true activeDownload = null } }, 'playwright-browser:cancel') }) }