@apexcli/browser
v0.5.0
Published
Browser automation capabilities for APEX using Playwright
Maintainers
Readme
@apexcli/browser
Browser automation capabilities for APEX using Playwright. This package provides browser automation tools for AI agents with comprehensive lifecycle management.
Features
- Browser Instance Management: Centralized management of browser instances with pooling and reuse
- Context Isolation: Create isolated browser contexts for different automation tasks
- Resource Monitoring: Track memory usage and automatically cleanup idle instances
- Console & Error Capture: Real-time capture of browser console messages and JavaScript errors
- Screenshot Support: Capture full-page or element-specific screenshots with format and quality control
- Screenshot Utilities: Base utility functions for direct page/context screenshot capture
- Element Interaction: Click, type, scroll, and interact with page elements
- Navigation Control: Advanced navigation with wait strategies and timeout controls
- Event Streaming: Real-time events for browser and context lifecycle
Quick Start
import { createBrowserManager, createBrowserSession } from '@apexcli/browser';
// Create a browser manager
const manager = createBrowserManager({
maxInstances: 5,
reuseInstances: true
});
// Create and launch a browser session
const session = createBrowserSession(manager, {
browserType: 'chromium',
headless: true,
viewport: { width: 1280, height: 720 }
});
await session.launch();
// Navigate and interact with pages
await session.navigate('https://example.com');
await session.click('button#submit');
await session.type('#input', 'Hello World');
// Take screenshots
const screenshot = await session.screenshot({ fullPage: true });
// Clean up
await session.close();
await manager.shutdown();Screenshot Utilities
For direct screenshot capture from Playwright Page or BrowserContext objects:
import { captureScreenshot, capturePNG, captureJPEG } from '@apexcli/browser';
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Base screenshot utility with format and quality support
const pngResult = await captureScreenshot(page, {
format: 'png',
fullPage: true
});
const jpegResult = await captureScreenshot(page, {
format: 'jpeg',
quality: 80,
path: './screenshot.jpg'
});
// Convenience functions
const pngScreenshot = await capturePNG(page, { fullPage: true });
const jpegScreenshot = await captureJPEG(page, 90); // 90% quality
// Works with BrowserContext too
const contextResult = await captureScreenshot(context, {
format: 'png',
omitBackground: true
});
if (jpegResult.success) {
console.log(`Screenshot captured: ${jpegResult.data!.length} bytes`);
console.log(`Capture took: ${jpegResult.duration}ms`);
}Screenshot Utility Functions
captureScreenshot(target, options): Base utility accepting Page/BrowserContext- Format: PNG (default) or JPEG
- Quality: 1-100 for JPEG (default 80)
- Full page or viewport capture
- Optional file saving
- Returns Buffer with metadata
capturePNG(target, options): Convenience function for PNG screenshotscaptureJPEG(target, quality, options): Convenience function for JPEG screenshotscaptureFullPageScreenshot(target, options): Full scrollable page capturecaptureViewportScreenshot(target, options): Viewport-only capture
Core Classes
BrowserManager
Manages browser instances and their lifecycle:
import { BrowserManager } from '@apexcli/browser';
const manager = new BrowserManager({
maxInstances: 3,
instanceIdleTimeout: 300000, // 5 minutes
reuseInstances: true,
resourceLimits: {
maxMemoryMB: 1024,
maxCpuPercent: 80
}
});
// Launch browser instance
const result = await manager.launchBrowser({ browserType: 'chromium' });
// Create isolated contexts
const context = await manager.createContext(result.data.id);
// Monitor resource usage
const usage = await manager.getResourceUsage();
console.log(`Active instances: ${usage.totalInstances}`);BrowserSession
High-level interface for browser automation:
import { BrowserSession } from '@apexcli/browser';
const session = new BrowserSession(manager, {
browserType: 'firefox',
headless: false,
userAgent: 'Custom Agent String'
});
await session.launch();
// Page navigation
await session.navigate('https://example.com', {
waitUntil: 'networkidle',
timeout: 30000
});
// Element interaction
await session.click({ type: 'testId', value: 'submit-button' });
await session.waitForElement('#result', { state: 'visible' });
// JavaScript evaluation
const result = await session.evaluate(() => {
return document.title;
});
// Console monitoring
session.on('consoleMessage', (message) => {
console.log(`Browser: ${message.text}`);
});Configuration Options
Browser Session Config
interface BrowserSessionConfig {
browserType: 'chromium' | 'firefox' | 'webkit';
headless: boolean;
viewport?: { width: number; height: number };
timeout?: number;
userAgent?: string;
ignoreHTTPSErrors?: boolean;
launchOptions?: LaunchOptions;
contextOptions?: BrowserContextOptions;
}Manager Config
interface BrowserManagerConfig {
maxInstances?: number;
defaultSessionConfig?: Partial<BrowserSessionConfig>;
instanceIdleTimeout?: number;
reuseInstances?: boolean;
resourceLimits?: {
maxMemoryMB?: number;
maxCpuPercent?: number;
};
}Capture Config
interface CaptureConfig {
captureConsole: boolean;
consoleLevels?: ConsoleLogLevel[];
captureErrors: boolean;
maxBufferSize?: number;
includeStackTraces?: boolean;
}Element Selectors
Support for multiple selector types:
// String selectors
await session.click('#button');
await session.click('[data-testid="submit"]');
// Typed selectors
await session.click({ type: 'css', value: '#button' });
await session.click({ type: 'xpath', value: '//button[text()="Submit"]' });
await session.click({ type: 'text', value: 'Click me' });
await session.click({ type: 'role', value: 'button' });
await session.click({ type: 'testId', value: 'submit-btn' });Error Handling
All browser operations return a standardized result format:
interface BrowserActionResult<T> {
success: boolean;
data?: T;
error?: string;
duration: number;
}
const result = await session.navigate('https://example.com');
if (result.success) {
console.log(`Navigated to: ${result.data}`);
} else {
console.error(`Navigation failed: ${result.error}`);
}Resource Management
The browser manager automatically:
- Limits concurrent browser instances
- Reuses instances when possible
- Monitors memory and CPU usage
- Cleans up idle instances
- Provides resource usage statistics
// Get current resource usage
const usage = await manager.getResourceUsage();
console.log(`Memory: ${usage.memoryUsageMB}MB`);
console.log(`Active browsers: ${usage.activeBrowsers}`);
// Force cleanup of idle instances
const cleanedCount = await manager.cleanupIdleInstances();
console.log(`Cleaned up ${cleanedCount} idle instances`);
// Listen for resource limit events
manager.on('resourceLimitExceeded', (info) => {
console.warn(`${info.type} limit exceeded: ${info.value}/${info.limit}`);
});Event Monitoring
Real-time events for monitoring and debugging:
// Browser lifecycle events
manager.on('browserCreated', (info) => {
console.log(`Browser created: ${info.id} (${info.type})`);
});
manager.on('contextCreated', (info) => {
console.log(`Context created: ${info.id}`);
});
// Console and error capture
session.on('consoleMessage', (message) => {
console.log(`[${message.type}] ${message.text}`);
});
session.on('javascriptError', (error) => {
console.error(`JS Error: ${error.message}`);
});
session.on('pageError', (error) => {
console.error(`Page Error: ${error.message}`);
});Testing
Run the test suite:
npm testThe package includes comprehensive tests for:
- Browser manager lifecycle
- Session management
- Element interaction
- Error handling
- Resource management
- Integration scenarios
Dependencies
- playwright: Browser automation library
- eventemitter3: Event emitter for real-time events
- @apexcli/core: Core APEX types and utilities
License
MIT - See LICENSE file for details
