MCP ACS Screenshot Testing Guide
December 12, 2025 · View on GitHub
Test Structure
packages/mcp-screenshot/
├── src/
│ ├── capture/
│ │ └── capture-engine.property.spec.ts # Property-based tests
│ ├── e2e/
│ │ └── screenshot-workflow.e2e.spec.ts # End-to-end integration tests
│ └── types/
│ └── index.spec.ts # Basic unit tests
Test Types
1. Property-Based Tests (PBT)
Located in: src/capture/capture-engine.property.spec.ts
Uses fast-check to test universal properties across many inputs.
Property 1: Full screen capture dimensions match display resolution
- Validates that captured images match display resolution
- Tests both primary and multi-display scenarios
- Runs with graceful fallback for missing tools
npm test -- capture-engine.property.spec.ts
2. End-to-End Tests
Located in: src/e2e/screenshot-workflow.e2e.spec.ts
Tests complete workflows integrating all components:
- Full screen capture workflow
- Region capture workflow
- Window capture workflow
- Image processing workflow
- Security workflow
- Privacy workflow
- Complete end-to-end workflow
npm test -- screenshot-workflow.e2e.spec.ts
3. Unit Tests
Located in: src/types/index.spec.ts
Basic tests for type definitions and infrastructure.
npm test -- index.spec.ts
Running Tests
Run all tests
npm test
Run specific test file
npm test -- <filename>
Run tests in watch mode
npm run test:watch
Run with coverage
npm test -- --coverage
Test Configuration
Jest Configuration
File: jest.config.js
- Test environment: Node.js
- Transform: SWC for fast TypeScript compilation
- Test match:
**/?(*.)+(spec|test).[jt]s?(x) - Coverage directory:
test-output/jest/coverage
SWC Configuration
File: .spec.swcrc
Optimized TypeScript compilation for tests.
Writing Tests
Property-Based Test Template
import * as fc from "fast-check";
describe("Component Property Tests", () => {
it("should satisfy property X", () => {
fc.assert(
fc.property(
fc.integer(), // arbitrary generator
(value) => {
// Test property
expect(someFunction(value)).toBe(expectedResult);
}
),
{ numRuns: 100 } // Run 100 iterations
);
});
});
E2E Test Template
describe("Workflow E2E Tests", () => {
let component: Component;
let tempDir: string;
beforeAll(() => {
// Setup
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "test-"));
component = new Component();
});
afterAll(() => {
// Cleanup
fs.rmSync(tempDir, { recursive: true, force: true });
});
it("should complete workflow", async () => {
try {
// Test workflow
const result = await component.doSomething();
expect(result).toBeDefined();
} catch (error) {
// Handle missing tools gracefully
if (error.message.includes("not found")) {
console.warn("Tools not available - skipping test");
return;
}
throw error;
}
});
});
CI/CD Integration
GitHub Actions Example
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm test
Test Behavior in CI
Tests are designed to work in CI environments:
- Graceful degradation: Skip tests when system tools unavailable
- No display required: Handle headless environments
- Temporary files: Auto-cleanup after tests
- Fast execution: Complete in ~4 seconds
- Clear output: Warning messages for skipped tests
Test Coverage Goals
- Unit tests: Core logic and utilities
- Property tests: Universal properties and invariants
- Integration tests: Component interactions
- E2E tests: Complete workflows
Debugging Tests
Run single test
npm test -- -t "test name"
Enable verbose output
npm test -- --verbose
Debug in VS Code
Add to .vscode/launch.json:
{
"type": "node",
"request": "launch",
"name": "Jest Debug",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand", "--no-cache"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
Best Practices
- Test isolation: Each test should be independent
- Cleanup: Always clean up resources in
afterAll/afterEach - Error handling: Handle missing tools gracefully
- Timeouts: Set appropriate timeouts for async operations
- Descriptive names: Use clear, descriptive test names
- Comments: Document what each test validates
Platform-Specific Considerations
Linux
- Requires
grim(Wayland) orimport(X11) for screen capture - Requires
wmctrlorswaymsgfor window enumeration - Tests skip gracefully if tools missing
macOS
- Uses
screencapturecommand - Uses AppleScript for window enumeration
- Generally available on all macOS systems
Windows
- Uses PowerShell for capture and enumeration
- Requires Windows Forms assemblies
- May need elevated permissions
Troubleshooting
Tests skipping due to missing tools
Linux (Wayland):
sudo apt-get install grim slurp
Linux (X11):
sudo apt-get install imagemagick wmctrl
macOS: Tools are built-in, no installation needed.
Windows: PowerShell is built-in, no installation needed.
Tests timing out
Increase timeout in test:
it("test name", async () => {
// test code
}, 60000); // 60 second timeout
Memory issues
Reduce concurrent test execution:
npm test -- --maxWorkers=2
Contributing
When adding new features:
- Write property-based tests for universal properties
- Write e2e tests for complete workflows
- Ensure tests work in CI environments
- Update this documentation