feat: implement Playwright service for browser automation
- Add playwright types for Credentials, Session, and LoginResult - Implement PlaywrightService with launchBrowser, login, closeBrowser, and newPage methods - Support browser configuration (headless mode, slowMo, timeout) - Integrate with LoggerService for comprehensive logging - Handle HTTPS errors via ERP configuration Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
17
src/main/models/playwright.types.ts
Normal file
17
src/main/models/playwright.types.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Browser, Page, Frame } from 'playwright';
|
||||
|
||||
export interface Credentials {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
browser: Browser;
|
||||
context: any;
|
||||
page: Page;
|
||||
mainFrame: Frame;
|
||||
}
|
||||
|
||||
export interface LoginResult extends Session {
|
||||
success: boolean;
|
||||
}
|
||||
99
src/main/services/playwright.service.ts
Normal file
99
src/main/services/playwright.service.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { chromium, Browser, BrowserContext, Page, Frame } from 'playwright';
|
||||
import { Credentials, Session, LoginResult } from '../models/playwright.types';
|
||||
import { BrowserConfig, ERPConfig } from '../models/config.types';
|
||||
import { LoggerService } from './logger.service';
|
||||
|
||||
export class PlaywrightService {
|
||||
private browser?: Browser;
|
||||
private context?: BrowserContext;
|
||||
|
||||
constructor(
|
||||
private browserConfig: BrowserConfig,
|
||||
private erpConfig: ERPConfig
|
||||
) {}
|
||||
|
||||
async launchBrowser(): Promise<Browser> {
|
||||
try {
|
||||
LoggerService.info('Launching Chromium browser...');
|
||||
|
||||
this.browser = await chromium.launch({
|
||||
headless: this.browserConfig.headless,
|
||||
slowMo: this.browserConfig.slowMo,
|
||||
});
|
||||
|
||||
this.context = await this.browser.newContext({
|
||||
ignoreHTTPSErrors: this.erpConfig.ignoreHttpsErrors,
|
||||
});
|
||||
|
||||
LoggerService.info('Browser launched successfully');
|
||||
return this.browser;
|
||||
} catch (error) {
|
||||
LoggerService.error('Failed to launch browser', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async login(credentials: Credentials): Promise<LoginResult> {
|
||||
if (!this.browser || !this.context) {
|
||||
throw new Error('Browser not launched');
|
||||
}
|
||||
|
||||
try {
|
||||
LoggerService.info('Attempting ERP login...');
|
||||
|
||||
const page = await this.context.newPage();
|
||||
await page.goto(this.erpConfig.baseUrl, {
|
||||
timeout: this.browserConfig.timeout,
|
||||
});
|
||||
|
||||
// Wait for login form
|
||||
await page.waitForSelector('input[name="username"]', {
|
||||
timeout: this.browserConfig.timeout,
|
||||
});
|
||||
|
||||
// Fill credentials
|
||||
await page.fill('input[name="username"]', credentials.username);
|
||||
await page.fill('input[name="password"]', credentials.password);
|
||||
|
||||
// Click login button
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Wait for navigation
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Get main frame
|
||||
const mainFrame = page.mainFrame();
|
||||
|
||||
LoggerService.info('Login successful');
|
||||
|
||||
return {
|
||||
success: true,
|
||||
browser: this.browser,
|
||||
context: this.context,
|
||||
page,
|
||||
mainFrame,
|
||||
};
|
||||
} catch (error) {
|
||||
LoggerService.error('Login failed', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async closeBrowser(): Promise<void> {
|
||||
if (this.context) {
|
||||
await this.context.close();
|
||||
LoggerService.info('Browser context closed');
|
||||
}
|
||||
if (this.browser) {
|
||||
await this.browser.close();
|
||||
LoggerService.info('Browser closed');
|
||||
}
|
||||
}
|
||||
|
||||
async newPage(): Promise<Page> {
|
||||
if (!this.context) {
|
||||
throw new Error('Browser context not initialized');
|
||||
}
|
||||
return await this.context.newPage();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user