# ScreenshotCapture Service Documentation

## Overview

`ScreenshotCapture` is a Node.js service class that uses Playwright's headless Chromium to capture high-quality screenshots from URLs. It's designed for automation, batch processing, and supports various viewport resolutions and session management via cookies.

## Features

✓ **Headless Chromium Automation** - Full browser rendering without UI
✓ **Custom Viewports** - Multiple resolution presets + custom sizes
✓ **Cookie Support** - Session persistence and authentication
✓ **Full-Page Capture** - PNG screenshots of entire scrollable content
✓ **Network Idle Detection** - Waits for resources to load completely
✓ **Dynamic Content Delay** - 2.5s additional wait for JS-rendered content
✓ **Buffer Return** - Direct PNG buffer (no file I/O required)
✓ **Batch Processing** - Capture multiple URLs efficiently
✓ **Error Resilience** - Graceful handling of failed captures
✓ **Resource Cleanup** - Proper browser lifecycle management

## Installation

```bash
npm install playwright
```

The package already includes Playwright as a dev dependency in `package.json`.

## Basic Usage

### 1. Simple Screenshot

```javascript
import ScreenshotCapture from './src/services/ScreenshotCapture.js';

const capturer = new ScreenshotCapture();

const buffer = await capturer.capture('https://example.com');
// buffer is a PNG image as Buffer

// Save to file
const fs = require('fs');
fs.writeFileSync('screenshot.png', buffer);

// Cleanup
await capturer.close();
```

### 2. Custom Viewport

```javascript
// Mobile device (iPhone 12)
const mobileBuffer = await capturer.capture('https://example.com', {
  viewport: { width: 375, height: 667 }
});

// Tablet (iPad)
const tabletBuffer = await capturer.capture('https://example.com', {
  viewport: { width: 768, height: 1024 }
});

// Desktop (1440p)
const desktopBuffer = await capturer.capture('https://example.com', {
  viewport: { width: 1920, height: 1080 }
});
```

### 3. With Authentication Cookies

```javascript
const buffer = await capturer.capture('https://example.com/dashboard', {
  cookies: [
    {
      name: 'session_token',
      value: 'eyJhbGc...',
      domain: 'example.com',
      path: '/',
      secure: true,
      httpOnly: false,
    }
  ]
});
```

### 4. Extended Wait for Dynamic Content

```javascript
// Wait 5 seconds for heavy JS-rendered content
const buffer = await capturer.capture('https://example.com', {
  waitTime: 5000
});
```

### 5. Custom HTTP Headers

```javascript
const buffer = await capturer.capture('https://example.com', {
  headers: {
    'Accept-Language': 'ru-RU,ru;q=0.9',
    'Referer': 'https://google.com/',
    'X-Custom-Header': 'value'
  }
});
```

### 6. Batch Capture

```javascript
const targets = [
  { url: 'https://example.com' },
  { url: 'https://example.org', viewport: { width: 1920, height: 1080 } },
  { url: 'https://example.net', viewport: { width: 375, height: 667 } },
];

const results = await capturer.captureMultiple(targets);

for (const result of results) {
  if (result.success) {
    console.log(`✓ ${result.url} (${result.buffer.length} bytes)`);
    // Use result.buffer
  } else {
    console.log(`✗ ${result.url}: ${result.error}`);
  }
}
```

## API Reference

### Constructor

```javascript
new ScreenshotCapture(options)
```

**Options:**
- `headless` (boolean, default: `true`) - Run in headless mode
- `timeout` (number, default: `30000`) - Page load timeout in milliseconds
- `networkIdleWait` (number, default: `2500`) - Additional wait after networkidle in ms
- `defaultViewport` (object, default: `{width: 1280, height: 720}`) - Default viewport size

### Methods

#### `capture(url, options)`

Capture a single screenshot.

**Parameters:**
- `url` (string, required) - Target URL to capture
- `options` (object, optional):
  - `cookies` (Array<Cookie>) - Browser cookies to set
  - `viewport` ({width, height}) - Custom viewport dimensions
  - `waitTime` (number) - Override wait time in ms
  - `headers` (object) - Custom HTTP headers

**Returns:** `Promise<Buffer>` - PNG image data

**Throws:** `Error` if URL is invalid or capture fails

#### `captureMultiple(targets)`

Capture multiple screenshots.

**Parameters:**
- `targets` (Array) - Array of `{url, options?}` objects

**Returns:** `Promise<Array>` - Results array with `success`, `buffer`, and `error` fields

#### `close()`

Close browser and cleanup resources.

**Returns:** `Promise<void>`

#### `isHealthy()`

Check if browser is connected and ready.

**Returns:** `Promise<boolean>`

## Supported Resolutions

Common preset resolutions:

| Name | Dimensions | Use Case |
|------|-----------|----------|
| Mobile | 375×667 | iPhone 12/13 |
| Mobile (Large) | 428×926 | iPhone 14 Pro Max |
| Tablet | 768×1024 | iPad |
| Desktop | 1280×720 | HD (720p) |
| Desktop (Full) | 1920×1080 | Full HD (1080p) |
| UHD | 2560×1440 | 2K / Retina |
| 4K | 3840×2160 | Ultra HD |

## HTTP API Integration

The Express server includes built-in endpoints:

### `POST /api/screenshot`

Capture a screenshot via HTTP.

**Request Body:**
```json
{
  "url": "https://example.com",
  "cookies": [
    {"name": "session", "value": "abc123", "domain": "example.com"}
  ],
  "viewport": {"width": 1280, "height": 720},
  "waitTime": 2500,
  "headers": {"Accept-Language": "en-US"}
}
```

**Response:** PNG image (image/png content-type)

**Error Response:**
```json
{
  "error": "Screenshot capture failed",
  "message": "..."
}
```

### `POST /api/screenshot/batch`

Capture multiple screenshots.

**Request Body:**
```json
{
  "targets": [
    {"url": "https://example.com"},
    {"url": "https://example.org", "viewport": {"width": 1920, "height": 1080}},
    {"url": "https://example.net", "viewport": {"width": 375, "height": 667}}
  ]
}
```

**Response:**
```json
{
  "totalRequests": 3,
  "successCount": 2,
  "failureCount": 1,
  "results": [
    {"url": "...", "success": true, "size": 123456, "base64": "..."},
    {"url": "...", "success": false, "error": "..."}
  ]
}
```

### `GET /api/screenshot/info`

Get service capabilities and health status.

**Response:**
```json
{
  "service": "ScreenshotCapture",
  "version": "1.0.0",
  "healthy": true,
  "defaultViewport": {"width": 1280, "height": 720},
  "supportedResolutions": [...],
  "maxTimeout": 30000,
  "networkIdleWait": 2500
}
```

## Performance Characteristics

- **Single Screenshot:** ~2-5 seconds (including network wait)
- **Buffer Size:** Typically 100-500 KB per screenshot (depends on content)
- **Concurrent Captures:** Sequential processing (one at a time) to avoid resource contention
- **Memory Usage:** ~50-100 MB per active page
- **Browser Startup:** ~1-2 seconds (lazy-loaded, reused across captures)

## Error Handling

The service handles various error scenarios gracefully:

```javascript
try {
  const buffer = await capturer.capture('https://invalid-site-xyz.com');
} catch (error) {
  console.error(error.message);
  // Error: Screenshot capture failed: Invalid URL format: https://invalid-site-xyz.com
}
```

Common errors:
- **Invalid URL format** - Malformed or unreachable URLs
- **Navigation timeout** - Page took too long to load (30s default)
- **Cookie setup failed** - Invalid cookie format or domain mismatch
- **Browser initialization failed** - Chromium/Playwright issues

## Best Practices

1. **Reuse Capturer Instance** - Create once, use for multiple captures
2. **Proper Cleanup** - Call `close()` when finished
3. **Timeout Management** - Increase timeout for slow/heavy pages
4. **Cookie Domain Matching** - Ensure cookie domain matches target URL
5. **Rate Limiting** - Implement delays between rapid requests
6. **Error Logging** - Log all capture failures for debugging
7. **Buffer Memory** - Consider memory when processing many screenshots
8. **Viewport Testing** - Test key device sizes (mobile, tablet, desktop)

## Examples

See `/workspace/docs/ScreenshotCapture-examples.js` for complete working examples.

## Troubleshooting

### Browser fails to launch
- Ensure Playwright is installed: `npm install playwright`
- Check if system has required dependencies: `npx playwright install-deps`
- Verify enough disk space for Chromium binary

### Screenshots are blank
- Increase `waitTime` for JS-heavy content
- Check if page requires authentication (add cookies)
- Verify URL is correct and accessible

### Timeout errors
- Increase `timeout` option for slow servers
- Extend `waitTime` for dynamic rendering
- Check network connectivity

### Memory issues
- Process fewer URLs concurrently
- Call `close()` after batch processing
- Monitor system resources

## License

MIT
