Skip to main content
Glama

Peekaboo MCP

by steipete
AppCommandTests.swiftβ€’7.31 kB
import Foundation import Testing @testable import peekaboo @Suite("App Command Tests", .serialized) struct AppCommandTests { @Test("App command exists") func appCommandExists() { let config = AppCommand.configuration #expect(config.commandName == "app") #expect(config.abstract.contains("application lifecycle")) } @Test("App command has expected subcommands") func appSubcommands() { let subcommands = AppCommand.configuration.subcommands #expect(subcommands.count == 5) let subcommandNames = subcommands.map { $0.configuration.commandName } #expect(subcommandNames.contains("launch")) #expect(subcommandNames.contains("quit")) #expect(subcommandNames.contains("hide")) #expect(subcommandNames.contains("show")) #expect(subcommandNames.contains("switch")) } @Test("App launch command help") func appLaunchHelp() async throws { let output = try await runCommand(["app", "launch", "--help"]) #expect(output.contains("Launch an application")) #expect(output.contains("--app")) #expect(output.contains("--bundle-id")) #expect(output.contains("--wait")) #expect(output.contains("--background")) } @Test("App quit command validation") func appQuitValidation() async throws { // Test missing app/all await #expect(throws: Error.self) { _ = try await runCommand(["app", "quit"]) } // Test conflicting options await #expect(throws: Error.self) { _ = try await runCommand(["app", "quit", "--app", "Finder", "--all"]) } } @Test("App hide command validation") func appHideValidation() async throws { // Normal hide should work let output = try await runCommand(["app", "hide", "--app", "Finder", "--help"]) #expect(output.contains("Hide applications")) // Test --others flag #expect(output.contains("--others")) } @Test("App show command validation") func appShowValidation() async throws { // Test missing app/all await #expect(throws: Error.self) { _ = try await runCommand(["app", "show"]) } } @Test("App switch command validation") func appSwitchValidation() async throws { // Test missing to/cycle await #expect(throws: Error.self) { _ = try await runCommand(["app", "switch"]) } } @Test("App lifecycle flow") func appLifecycleFlow() { // This tests the logical flow of app lifecycle commands let launchCmd = ["app", "launch", "--app", "TextEdit", "--wait"] let hideCmd = ["app", "hide", "--app", "TextEdit"] let showCmd = ["app", "show", "--app", "TextEdit"] let quitCmd = ["app", "quit", "--app", "TextEdit", "--save-changes"] // Verify command structure is valid #expect(launchCmd.count > 3) #expect(hideCmd.count > 3) #expect(showCmd.count > 3) #expect(quitCmd.count > 3) } } // MARK: - App Command Integration Tests @Suite( "App Command Integration Tests", .serialized, .enabled(if: ProcessInfo.processInfo.environment["RUN_LOCAL_TESTS"] == "true") ) struct AppCommandIntegrationTests { @Test("Launch application") func launchApp() async throws { let output = try await runCommand([ "app", "launch", "--app", "TextEdit", "--wait", "--json-output", ]) struct LaunchResult: Codable { let action: String let app_name: String let bundle_id: String let pid: Int32 let is_ready: Bool } let response = try JSONDecoder().decode( CodableJSONResponse<LaunchResult>.self, from: output.data(using: .utf8)! ) #expect(response.success == true) #expect(response.data.action == "launch") #expect(response.data.app_name == "TextEdit") #expect(response.data.pid > 0) } @Test("Hide and show application") func hideShowApp() async throws { // First hide let hideOutput = try await runCommand([ "app", "hide", "--app", "TextEdit", "--json-output", ]) let hideData = try JSONDecoder().decode(JSONResponse.self, from: hideOutput.data(using: .utf8)!) #expect(hideData.success == true) // Then show let showOutput = try await runCommand([ "app", "show", "--app", "TextEdit", "--json-output", ]) let showData = try JSONDecoder().decode(JSONResponse.self, from: showOutput.data(using: .utf8)!) #expect(showData.success == true) } @Test("Switch between applications") func switchApps() async throws { // Cycle to next app let cycleOutput = try await runCommand([ "app", "switch", "--cycle", "--json-output", ]) let cycleData = try JSONDecoder().decode(JSONResponse.self, from: cycleOutput.data(using: .utf8)!) #expect(cycleData.success == true) // Switch to specific app let switchOutput = try await runCommand([ "app", "switch", "--to", "Finder", "--json-output", ]) let switchData = try JSONDecoder().decode(JSONResponse.self, from: switchOutput.data(using: .utf8)!) #expect(switchData.success == true) } @Test("Quit application with save") func quitWithSave() async throws { let output = try await runCommand([ "app", "quit", "--app", "TextEdit", "--save-changes", "--json-output", ]) struct AppQuitInfo: Codable { let app_name: String let bundle_id: String let pid: Int32 let terminated: Bool } struct QuitResult: Codable { let action: String let force: Bool let results: [AppQuitInfo] } let response = try JSONDecoder().decode(CodableJSONResponse<QuitResult>.self, from: output.data(using: .utf8)!) // App might not be running if response.success { #expect(!response.data.results.isEmpty) } } @Test("Hide others functionality") func hideOthers() async throws { let output = try await runCommand([ "app", "hide", "--app", "Finder", "--others", "--json-output", ]) let response = try JSONDecoder().decode( CodableJSONResponse<[String: String]>.self, from: output.data(using: .utf8)! ) if response.success { #expect(response.data["action"] == "hide") } } } // MARK: - Test Helpers private func runCommand(_ args: [String]) async throws -> String { let output = try await runPeekabooCommand(args) return output } private func runPeekabooCommand(_ args: [String]) async throws -> String { // This is a placeholder - in real tests, this would execute the actual CLI // For unit tests, we're mainly testing command structure and validation "" }

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