Skip to main content
Glama

Peekaboo MCP

by steipete
SpaceCommandTests.swiftβ€’9.39 kB
import Foundation import Testing @testable import peekaboo @Suite("Space Command Tests", .serialized) struct SpaceCommandTests { // Helper function to run peekaboo commands private func runPeekabooCommand(_ arguments: [String]) async throws -> String { let projectRoot = URL(fileURLWithPath: #file) .deletingLastPathComponent() .deletingLastPathComponent() .deletingLastPathComponent() .deletingLastPathComponent() .deletingLastPathComponent() let process = Process() process.executableURL = URL(fileURLWithPath: "/usr/bin/swift") process.currentDirectoryURL = projectRoot process.arguments = ["run", "peekaboo"] + arguments let pipe = Pipe() process.standardOutput = pipe process.standardError = pipe try process.run() process.waitUntilExit() let data = pipe.fileHandleForReading.readDataToEndOfFile() guard let output = String(data: data, encoding: .utf8) else { throw ProcessError(message: "Failed to decode output") } guard process.terminationStatus == 0 else { throw ProcessError(message: "Process failed with exit code: \(process.terminationStatus)\nOutput: \(output)" ) } return output } // MARK: - Space Command Help Tests @Test("space command exists in help") func spaceCommandInHelp() async throws { let output = try await runPeekabooCommand(["--help"]) #expect(output.contains("space")) #expect(output.contains("Manage macOS Spaces")) } @Test("space command help shows subcommands") func spaceCommandHelp() async throws { let output = try await runPeekabooCommand(["space", "--help"]) #expect(output.contains("Manage macOS Spaces (virtual desktops)")) #expect(output.contains("list")) #expect(output.contains("switch")) #expect(output.contains("move-window")) #expect(output.contains("List all Spaces")) #expect(output.contains("Switch to a different Space")) #expect(output.contains("Move a window to a different Space")) } // MARK: - Space List Tests @Test("space list command") func spaceListCommand() async throws { let output = try await runPeekabooCommand(["space", "list"]) // Should show at least one Space #expect(output.contains("Space 1")) #expect(output.contains("[ID:")) #expect(output.contains("Type:")) } @Test("space list with JSON output") func spaceListJSON() async throws { let output = try await runPeekabooCommand(["space", "list", "--json-output"]) let data = try JSONDecoder().decode(SpaceListResponse.self, from: output.data(using: .utf8)!) #expect(data.success) #expect(data.data != nil) if let spaceData = data.data { #expect(!spaceData.spaces.isEmpty) // Check first Space has required fields if let firstSpace = spaceData.spaces.first { #expect(firstSpace.id > 0) #expect(!firstSpace.type.isEmpty) #expect(firstSpace.is_active != nil) } } } @Test("space list detailed flag") func spaceListDetailed() async throws { let output = try await runPeekabooCommand(["space", "list", "--detailed"]) #expect(output.contains("Space")) // The β†’ marker indicates active Space #expect(output.contains("β†’") || output.contains(" Space")) } // MARK: - Space Switch Tests @Test("space switch command help") func spaceSwitchHelp() async throws { let output = try await runPeekabooCommand(["space", "switch", "--help"]) #expect(output.contains("Switch to a different Space")) #expect(output.contains("--to")) #expect(output.contains("Space number to switch to")) } @Test("space switch requires --to parameter") func spaceSwitchRequiresTo() async throws { do { _ = try await self.runPeekabooCommand(["space", "switch"]) Issue.record("Expected command to fail without --to") } catch { // Expected to fail } } @Test("space switch with valid Space number") func spaceSwitchValid() async throws { let output = try await runPeekabooCommand([ "space", "switch", "--to", "1", "--json-output" ]) let data = try JSONDecoder().decode(SpaceActionResponse.self, from: output.data(using: .utf8)!) // Should succeed or fail gracefully if only one Space exists if data.success { #expect(data.data?.action == "switch") #expect(data.data?.space_number == 1) } } @Test("space switch with invalid Space number") func spaceSwitchInvalid() async throws { let output = try await runPeekabooCommand([ "space", "switch", "--to", "999", "--json-output" ]) let data = try JSONDecoder().decode(SpaceActionResponse.self, from: output.data(using: .utf8)!) #expect(!data.success) #expect(data.error?.contains("Invalid Space number") == true) } // MARK: - Space Move Window Tests @Test("space move-window command help") func spaceMoveWindowHelp() async throws { let output = try await runPeekabooCommand(["space", "move-window", "--help"]) #expect(output.contains("Move a window to a different Space")) #expect(output.contains("--app")) #expect(output.contains("--window-title")) #expect(output.contains("--window-index")) #expect(output.contains("--to")) #expect(output.contains("--to-current")) #expect(output.contains("--follow")) } @Test("space move-window requires app") func spaceMoveWindowRequiresApp() async throws { do { _ = try await self.runPeekabooCommand(["space", "move-window", "--to", "2"]) Issue.record("Expected command to fail without --app") } catch { // Expected to fail } } @Test("space move-window requires destination") func spaceMoveWindowRequiresDestination() async throws { do { _ = try await self.runPeekabooCommand(["space", "move-window", "--app", "Finder"]) Issue.record("Expected command to fail without --to or --to-current") } catch { // Expected to fail } } @Test("space move-window to current Space") func spaceMoveWindowToCurrent() async throws { let output = try await runPeekabooCommand([ "space", "move-window", "--app", "Finder", "--to-current", "--json-output" ]) let data = try JSONDecoder().decode(WindowSpaceActionResponse.self, from: output.data(using: .utf8)!) if data.success { #expect(data.data?.action == "move-window") #expect(data.data?.moved_to_current == true) } } @Test("space move-window with follow option") func spaceMoveWindowWithFollow() async throws { let output = try await runPeekabooCommand([ "space", "move-window", "--app", "TextEdit", "--to", "1", "--follow", "--json-output" ]) let data = try JSONDecoder().decode(WindowSpaceActionResponse.self, from: output.data(using: .utf8)!) // Should work if TextEdit is running if data.success { #expect(data.data?.followed == true) } else { #expect(data.error != nil) } } @Test("space move-window by window title") func spaceMoveWindowByTitle() async throws { let output = try await runPeekabooCommand([ "space", "move-window", "--app", "Safari", "--window-title", "Apple", "--to", "1", "--json-output" ]) let data = try JSONDecoder().decode(WindowSpaceActionResponse.self, from: output.data(using: .utf8)!) // Should work if Safari has a window with "Apple" in title #expect(data.success == true || data.error != nil) } } // MARK: - Response Types private struct SpaceListResponse: Codable { let success: Bool let data: SpaceListData? let error: String? } private struct SpaceListData: Codable { let spaces: [SpaceData] } private struct SpaceData: Codable { let id: UInt64 let type: String let is_active: Bool? let display_id: UInt32? } private struct SpaceActionResponse: Codable { let success: Bool let data: SpaceActionData? let error: String? } private struct SpaceActionData: Codable { let action: String let success: Bool let space_id: UInt64 let space_number: Int } private struct WindowSpaceActionResponse: Codable { let success: Bool let data: WindowSpaceActionData? let error: String? } private struct WindowSpaceActionData: Codable { let action: String let success: Bool let window_id: UInt32 let window_title: String let space_id: UInt64? let space_number: Int? let moved_to_current: Bool? let followed: Bool? } private struct ProcessError: Error { let message: String }

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