Skip to main content
Glama

Peekaboo MCP

by steipete
AnnotationCoordinateTests.swiftβ€’5.41 kB
import CoreGraphics import Foundation import PeekabooCore import Testing @testable import peekaboo @Suite("Annotation Coordinate Tests") struct AnnotationCoordinateTests { @Test("Window-relative coordinate transformation") func windowRelativeTransformation() { // Given screen coordinates let screenBounds = CGRect(x: 500, y: 300, width: 100, height: 50) let windowBounds = CGRect(x: 400, y: 200, width: 800, height: 600) // When transforming to window-relative (as done in UIAutomationServiceEnhanced) var windowRelativeBounds = screenBounds windowRelativeBounds.origin.x -= windowBounds.origin.x windowRelativeBounds.origin.y -= windowBounds.origin.y // Then coordinates should be relative to window origin #expect(windowRelativeBounds.origin.x == 100) // 500 - 400 #expect(windowRelativeBounds.origin.y == 100) // 300 - 200 #expect(windowRelativeBounds.size == screenBounds.size) // Size unchanged } @Test("Y-coordinate flip for NSGraphicsContext") func yCoordinateFlip() { // Given window-relative bounds with top-left origin let elementBounds = CGRect(x: 100, y: 150, width: 80, height: 40) let imageHeight: CGFloat = 600 // When converting to NSGraphicsContext coordinates (bottom-left origin) let flippedY = imageHeight - elementBounds.origin.y - elementBounds.height let drawingBounds = NSRect( x: elementBounds.origin.x, y: flippedY, width: elementBounds.width, height: elementBounds.height ) // Then Y should be flipped correctly #expect(drawingBounds.origin.x == 100) // X unchanged #expect(drawingBounds.origin.y == 410) // 600 - 150 - 40 #expect(drawingBounds.size == elementBounds.size) // Size unchanged } @Test("Complete transformation pipeline") func completeTransformationPipeline() { // Given: Element in screen coordinates let screenElement = CGRect(x: 600, y: 250, width: 120, height: 60) let windowBounds = CGRect(x: 450, y: 150, width: 1000, height: 700) let imageHeight: CGFloat = 700 // Same as window height // Step 1: Transform to window-relative (done in UIAutomationServiceEnhanced) var windowRelative = screenElement windowRelative.origin.x -= windowBounds.origin.x windowRelative.origin.y -= windowBounds.origin.y // Verify window-relative coordinates #expect(windowRelative.origin.x == 150) // 600 - 450 #expect(windowRelative.origin.y == 100) // 250 - 150 // Step 2: Flip Y for drawing (done in SeeCommand annotation) let flippedY = imageHeight - windowRelative.origin.y - windowRelative.height let finalDrawingRect = NSRect( x: windowRelative.origin.x, y: flippedY, width: windowRelative.width, height: windowRelative.height ) // Verify final drawing coordinates #expect(finalDrawingRect.origin.x == 150) // X unchanged #expect(finalDrawingRect.origin.y == 540) // 700 - 100 - 60 #expect(finalDrawingRect.width == 120) #expect(finalDrawingRect.height == 60) } @Test("Annotation file path generation") func annotationFilePathGeneration() { let testPaths = [ ("/tmp/screenshot.png", "/tmp/screenshot_annotated.png"), ("/Users/test/image.png", "/Users/test/image_annotated.png"), ("screenshot.png", "screenshot_annotated.png"), ("/path/with spaces/file.png", "/path/with spaces/file_annotated.png") ] for (original, expected) in testPaths { let annotatedPath = (original as NSString).deletingPathExtension + "_annotated.png" #expect(annotatedPath == expected) } } @Test("Element filtering for annotation") func elementFilteringForAnnotation() { // Create test elements let enabledButton = self.createTestElement(id: "B1", isEnabled: true) let disabledButton = self.createTestElement(id: "B2", isEnabled: false) let enabledTextField = self.createTestElement(id: "T1", isEnabled: true, type: .textField) let disabledLink = self.createTestElement(id: "L1", isEnabled: false, type: .link) let allElements = [enabledButton, disabledButton, enabledTextField, disabledLink] // Filter as done in annotation code let annotatedElements = allElements.filter(\.isEnabled) // Only enabled elements should be annotated #expect(annotatedElements.count == 2) #expect(annotatedElements.contains { $0.id == "B1" }) #expect(annotatedElements.contains { $0.id == "T1" }) #expect(!annotatedElements.contains { $0.id == "B2" }) #expect(!annotatedElements.contains { $0.id == "L1" }) } // Helper function to create test elements private func createTestElement( id: String, isEnabled: Bool, type: ElementType = .button ) -> DetectedElement { DetectedElement( id: id, type: type, label: "Test \(type)", value: nil, bounds: CGRect(x: 10, y: 10, width: 100, height: 50), isEnabled: isEnabled, isSelected: nil, attributes: [:] ) } }

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/steipete/Peekaboo'

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