File size: 3,058 Bytes
668d995 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /**
* Browser Manager - Handles Playwright browser lifecycle
*/
import { chromium, Browser, BrowserContext, Page } from 'playwright';
import { config } from './config.js';
export class BrowserManager {
private browser: Browser | null = null;
private context: BrowserContext | null = null;
private page: Page | null = null;
async initialize(): Promise<void> {
try {
// Try to connect to an existing browser first (Remote Debugging)
this.browser = await chromium.connectOverCDP('http://localhost:9222');
this.context = this.browser.contexts()[0];
this.page = this.context.pages()[0] || await this.context.newPage();
console.error('Connected to existing browser via Remote Debugging!');
} catch (error) {
console.error('Could not connect to existing browser, launching new instance...');
if (config.browser.userDataDir) {
// launchPersistentContext launches a browser and context in one go
this.context = await chromium.launchPersistentContext(
config.browser.userDataDir,
{
channel: config.browser.type === 'msedge' ? 'msedge' : undefined,
headless: config.browser.headless,
args: [
`--profile-directory=${config.browser.profile}`,
],
}
);
this.page = this.context.pages()[0] || await this.context.newPage();
} else {
this.browser = await chromium.launch({
channel: config.browser.type === 'msedge' ? 'msedge' : undefined,
headless: config.browser.headless,
});
this.context = await this.browser.newContext();
this.page = await this.context.newPage();
}
}
// Set default timeouts
if (this.page) {
this.page.setDefaultTimeout(config.timeouts.action);
this.page.setDefaultNavigationTimeout(config.timeouts.navigation);
}
}
async getPage(): Promise<Page> {
if (!this.page) {
await this.initialize();
}
return this.page!;
}
async close(): Promise<void> {
if (this.context) {
await this.context.close();
}
if (this.browser) {
await this.browser.close();
}
this.browser = null;
this.context = null;
this.page = null;
}
async setActivePage(page: Page): Promise<void> {
this.page = page;
this.page.setDefaultTimeout(config.timeouts.action);
this.page.setDefaultNavigationTimeout(config.timeouts.navigation);
}
isInitialized(): boolean {
return this.page !== null;
}
}
// Singleton instance
export const browserManager = new BrowserManager();
|