From 9cd2cfd72910d8e7ffb9b7e86b331e60a8887d43 Mon Sep 17 00:00:00 2001 From: Rohit Rajan Date: Sun, 7 Dec 2025 22:15:22 +0530 Subject: [PATCH] feat: create validation browser --- server/src/browser-management/controller.ts | 62 ++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/server/src/browser-management/controller.ts b/server/src/browser-management/controller.ts index 4058fa56..a0fbf5a2 100644 --- a/server/src/browser-management/controller.ts +++ b/server/src/browser-management/controller.ts @@ -4,7 +4,7 @@ */ import { Socket } from "socket.io"; import { v4 as uuid } from "uuid"; - +import { Page } from "playwright-core"; import { createSocketConnection, createSocketConnectionForRun } from "../socket-connection/connection"; import { io, browserPool } from "../server"; import { RemoteBrowser } from "./classes/RemoteBrowser"; @@ -434,3 +434,63 @@ const initializeBrowserAsync = async (id: string, userId: string) => { throw error; } }; + +/** + * Creates a RemoteBrowser instance specifically for SDK validation + * Uses dummy socket and returns browser ID and Page for validation tasks + * @param userId User ID for browser ownership + * @returns Promise with browser ID and Page instance + * @category BrowserManagement-Controller + */ +export const createRemoteBrowserForValidation = async ( + userId: string +): Promise<{ browserId: string; page: Page }> => { + const id = uuid(); + + logger.log('info', `Creating validation browser ${id} for user ${userId}`); + + try { + const dummySocket = { + emit: (event: string, data?: any) => { + logger.log('debug', `Browser ${id} emitted ${event}`); + }, + on: () => {}, + off: () => {}, + id: `validation-${id}`, + } as any; + + const browserSession = new RemoteBrowser(dummySocket, userId, id); + + const VALIDATION_INIT_TIMEOUT = 45000; + const initPromise = browserSession.initialize(userId); + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Validation browser initialization timeout')), VALIDATION_INIT_TIMEOUT); + }); + + await Promise.race([initPromise, timeoutPromise]); + + const added = browserPool.addRemoteBrowser(id, browserSession, userId, true, 'run'); + if (!added) { + await browserSession.switchOff(); + throw new Error('Failed to add validation browser to pool'); + } + + const page = browserSession.getCurrentPage(); + if (!page) { + await destroyRemoteBrowser(id, userId); + throw new Error('Failed to get page from validation browser'); + } + + logger.log('info', `Browser ${id} initialized successfully`); + + return { browserId: id, page }; + } catch (error: any) { + logger.log('error', `Failed to create validation browser ${id}: ${error.message}`); + try { + await destroyRemoteBrowser(id, userId); + } catch (cleanupError) { + logger.log('warn', `Failed to cleanup browser ${id}: ${cleanupError}`); + } + throw error; + } +}; \ No newline at end of file