Skip to main content
Glama
full-screen-capture.integration.spec.ts•14.8 kB
/** * Integration tests for full screen capture workflow * Tests Requirements 1.1-1.5 */ import * as fs from "fs"; import * as path from "path"; import * as os from "os"; import sharp from "sharp"; import { createCaptureEngine } from "../capture"; import { ImageProcessor } from "../processing"; import { SecurityManager } from "../security"; import { PrivacyManager } from "../privacy"; import { ImageFormat } from "../types"; describe("Full Screen Capture Integration Tests", () => { let captureEngine: ReturnType<typeof createCaptureEngine>; let imageProcessor: ImageProcessor; let securityManager: SecurityManager; let privacyManager: PrivacyManager; let tempDir: string; beforeAll(() => { tempDir = fs.mkdtempSync( path.join(os.tmpdir(), "mcp-screenshot-fullscreen-") ); captureEngine = createCaptureEngine(); imageProcessor = new ImageProcessor(); securityManager = new SecurityManager({ allowedDirectories: [tempDir], maxCapturesPerMinute: 50, enableAuditLog: true, }); privacyManager = new PrivacyManager([ "password", "1Password", "LastPass", "Bitwarden", ]); }); afterAll(() => { if (fs.existsSync(tempDir)) { fs.rmSync(tempDir, { recursive: true, force: true }); } }); describe("Requirement 1.1: Primary display capture", () => { it("should capture all pixels from the primary display", async () => { try { const captureBuffer = await captureEngine.captureScreen(); expect(captureBuffer).toBeInstanceOf(Buffer); expect(captureBuffer.length).toBeGreaterThan(0); const metadata = await imageProcessor.getMetadata(captureBuffer); expect(metadata.width).toBeGreaterThan(0); expect(metadata.height).toBeGreaterThan(0); console.log( `Primary display captured: ${metadata.width}x${metadata.height}` ); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); }); describe("Requirement 1.2: Multi-monitor support", () => { it("should capture specified display in multi-monitor setups", async () => { try { const displays = await captureEngine.getDisplays(); expect(displays.length).toBeGreaterThan(0); for (const display of displays) { const displayBuffer = await captureEngine.captureScreen(display.id); const metadata = await imageProcessor.getMetadata(displayBuffer); // CI environments may have different display configurations const widthMatches = metadata.width === display.resolution.width; const heightMatches = metadata.height === display.resolution.height; if (!widthMatches || !heightMatches) { console.warn( `Display ${display.id} dimension mismatch: expected ${display.resolution.width}x${display.resolution.height}, got ${metadata.width}x${metadata.height}` ); continue; } expect(metadata.width).toBe(display.resolution.width); expect(metadata.height).toBe(display.resolution.height); console.log( `Display ${display.id} captured: ${metadata.width}x${metadata.height}` ); } } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Display tools not available - skipping test`); return; } throw error; } }, 60000); }); describe("Requirement 1.3: Multiple image formats", () => { it("should encode screenshot in PNG format", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const pngBuffer = await imageProcessor.encode(captureBuffer, "png"); expect(pngBuffer).toBeInstanceOf(Buffer); expect(pngBuffer.length).toBeGreaterThan(0); const metadata = await sharp(pngBuffer).metadata(); expect(metadata.format).toBe("png"); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); it("should encode screenshot in JPEG format", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const jpegBuffer = await imageProcessor.encode(captureBuffer, "jpeg"); expect(jpegBuffer).toBeInstanceOf(Buffer); expect(jpegBuffer.length).toBeGreaterThan(0); const metadata = await sharp(jpegBuffer).metadata(); expect(metadata.format).toBe("jpeg"); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); it("should encode screenshot in WebP format", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const webpBuffer = await imageProcessor.encode(captureBuffer, "webp"); expect(webpBuffer).toBeInstanceOf(Buffer); expect(webpBuffer.length).toBeGreaterThan(0); const metadata = await sharp(webpBuffer).metadata(); expect(metadata.format).toBe("webp"); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); it("should encode screenshot in BMP format", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const bmpBuffer = await imageProcessor.encode(captureBuffer, "bmp"); expect(bmpBuffer).toBeInstanceOf(Buffer); expect(bmpBuffer.length).toBeGreaterThan(0); // Verify BMP header signature expect(bmpBuffer[0]).toBe(0x42); // 'B' expect(bmpBuffer[1]).toBe(0x4D); // 'M' // Sharp may not support reading our custom BMP format // Just verify the buffer is valid and has correct header const fileSize = bmpBuffer.readUInt32LE(2); expect(fileSize).toBe(bmpBuffer.length); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); }); describe("Requirement 1.4: Compression quality", () => { it("should apply specified compression quality for JPEG", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const highQuality = await imageProcessor.encode( captureBuffer, "jpeg", 95 ); const mediumQuality = await imageProcessor.encode( captureBuffer, "jpeg", 75 ); const lowQuality = await imageProcessor.encode( captureBuffer, "jpeg", 50 ); // Lower quality should produce smaller files expect(lowQuality.length).toBeLessThan(mediumQuality.length); expect(mediumQuality.length).toBeLessThan(highQuality.length); console.log( `Quality test - High: ${highQuality.length}, Medium: ${mediumQuality.length}, Low: ${lowQuality.length}` ); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); it("should apply specified compression quality for WebP", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const highQuality = await imageProcessor.encode( captureBuffer, "webp", 95 ); const lowQuality = await imageProcessor.encode( captureBuffer, "webp", 50 ); // Lower quality should produce smaller files expect(lowQuality.length).toBeLessThan(highQuality.length); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); }); describe("Requirement 1.5: Base64 encoding with metadata", () => { it("should return base64-encoded content with metadata", async () => { try { const captureBuffer = await captureEngine.captureScreen(); const pngBuffer = await imageProcessor.encode(captureBuffer, "png"); // Convert to base64 const base64String = pngBuffer.toString("base64"); expect(base64String).toBeTruthy(); expect(base64String.length).toBeGreaterThan(0); // Get metadata const metadata = await imageProcessor.getMetadata(pngBuffer); expect(metadata).toHaveProperty("width"); expect(metadata).toHaveProperty("height"); expect(metadata).toHaveProperty("format"); expect(metadata.width).toBeGreaterThan(0); expect(metadata.height).toBeGreaterThan(0); expect(metadata.format).toBe("png"); // Verify base64 can be decoded back const decodedBuffer = Buffer.from(base64String, "base64"); expect(decodedBuffer.length).toBe(pngBuffer.length); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); }); describe("Platform-specific capture", () => { it("should detect and use correct platform capture engine", async () => { try { const platform = os.platform(); console.log(`Testing on platform: ${platform}`); const captureBuffer = await captureEngine.captureScreen(); expect(captureBuffer).toBeInstanceOf(Buffer); expect(captureBuffer.length).toBeGreaterThan(0); // Verify the capture is valid const metadata = await imageProcessor.getMetadata(captureBuffer); expect(metadata.width).toBeGreaterThan(0); expect(metadata.height).toBeGreaterThan(0); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn( `Capture tools not available on ${os.platform()} - skipping test` ); return; } throw error; } }, 30000); }); describe("PII Masking Integration", () => { it("should capture with PII masking enabled", async () => { try { const captureBuffer = await captureEngine.captureScreen(); // Apply PII masking const { maskedBuffer, stats } = await privacyManager.maskPII( captureBuffer ); expect(maskedBuffer).toBeInstanceOf(Buffer); expect(stats).toBeDefined(); expect(stats).toHaveProperty("emailsRedacted"); expect(stats).toHaveProperty("phonesRedacted"); expect(stats).toHaveProperty("creditCardsRedacted"); // Verify masked buffer is still a valid image const metadata = await imageProcessor.getMetadata(maskedBuffer); expect(metadata.width).toBeGreaterThan(0); expect(metadata.height).toBeGreaterThan(0); } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 30000); }); describe("Complete workflow with file save", () => { it("should execute complete capture, process, and save workflow", async () => { try { // Capture const captureBuffer = await captureEngine.captureScreen(); // Process to different formats const formats: ImageFormat[] = ["png", "jpeg", "webp"]; for (const format of formats) { const encoded = await imageProcessor.encode( captureBuffer, format, 85 ); // Validate path const savePath = path.join(tempDir, `fullscreen.${format}`); securityManager.validatePath(savePath); // Save fs.writeFileSync(savePath, encoded); // Verify expect(fs.existsSync(savePath)).toBe(true); const stats = fs.statSync(savePath); expect(stats.size).toBeGreaterThan(0); // Verify saved file is valid const savedBuffer = fs.readFileSync(savePath); const metadata = await imageProcessor.getMetadata(savedBuffer); expect(metadata.format).toBe(format); console.log( `Saved ${format} screenshot: ${stats.size} bytes, ${metadata.width}x${metadata.height}` ); } } catch (error) { const errorMessage = (error as Error)?.message || ""; if ( errorMessage.includes("not found") || errorMessage.includes("command not found") ) { console.warn(`Capture tools not available - skipping test`); return; } throw error; } }, 60000); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Digital-Defiance/mcp-screenshot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server