Skip to main content
Glama

MCP Xcode

by Stefan-Nitu
ShutdownSimulatorMCP.e2e.test.ts5.33 kB
/** * E2E Test for Shutdown Simulator through MCP Protocol * * Tests critical user journey: Shutting down a simulator through MCP * Following testing philosophy: E2E tests for critical paths only (10%) * * Focus: MCP protocol interaction, not simulator shutdown logic * The controller tests already verify shutdown works with real simulators * This test verifies the MCP transport/serialization/protocol works * * NO MOCKS - Uses real MCP server, real simulators */ import { describe, it, expect, beforeAll, afterAll } from '@jest/globals'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js'; import { createAndConnectClient, cleanupClientAndTransport } from '../../../../shared/tests/utils/testHelpers.js'; import { TestSimulatorManager } from '../../../../shared/tests/utils/TestSimulatorManager.js'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); describe('Shutdown Simulator MCP E2E', () => { let client: Client; let transport: StdioClientTransport; let testSimManager: TestSimulatorManager; beforeAll(async () => { // Build the server const { execSync } = await import('child_process'); execSync('npm run build', { stdio: 'inherit' }); // Set up test simulator testSimManager = new TestSimulatorManager(); await testSimManager.getOrCreateSimulator('TestSimulator-ShutdownMCP'); // Connect to MCP server ({ client, transport } = await createAndConnectClient()); }); afterAll(async () => { // Cleanup test simulator await testSimManager.cleanup(); // Cleanup MCP connection await cleanupClientAndTransport(client, transport); }); describe('shutdown simulator through MCP', () => { it('should shutdown simulator via MCP protocol', async () => { // Arrange - Boot the simulator first await testSimManager.bootAndWait(30); // Act - Call tool through MCP const result = await client.callTool({ name: 'shutdown_simulator', arguments: { deviceId: testSimManager.getSimulatorName() } }); // Assert - Verify MCP response const parsed = CallToolResultSchema.parse(result); expect(parsed.content[0].type).toBe('text'); expect(parsed.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`); // Verify simulator is actually shutdown const listResult = await execAsync('xcrun simctl list devices --json'); const devices = JSON.parse(listResult.stdout); let found = false; for (const runtime of Object.values(devices.devices) as any[]) { const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId()); if (device) { expect(device.state).toBe('Shutdown'); found = true; break; } } expect(found).toBe(true); }); it('should handle already shutdown simulator via MCP', async () => { // Arrange - ensure simulator is shutdown await testSimManager.shutdownAndWait(); // Act - Call tool through MCP const result = await client.callTool({ name: 'shutdown_simulator', arguments: { deviceId: testSimManager.getSimulatorId() } }); // Assert const parsed = CallToolResultSchema.parse(result); expect(parsed.content[0].text).toBe(`✅ Simulator already shutdown: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`); }); it('should shutdown simulator by UUID via MCP', async () => { // Arrange - Boot the simulator first await testSimManager.bootAndWait(30); // Act - Call tool with UUID const result = await client.callTool({ name: 'shutdown_simulator', arguments: { deviceId: testSimManager.getSimulatorId() } }); // Assert const parsed = CallToolResultSchema.parse(result); expect(parsed.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`); // Verify simulator is actually shutdown const listResult = await execAsync('xcrun simctl list devices --json'); const devices = JSON.parse(listResult.stdout); for (const runtime of Object.values(devices.devices) as any[]) { const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId()); if (device) { expect(device.state).toBe('Shutdown'); break; } } }); }); describe('error handling through MCP', () => { it('should return error for non-existent simulator', async () => { // Act const result = await client.callTool({ name: 'shutdown_simulator', arguments: { deviceId: 'NonExistentSimulator-MCP' } }); // Assert const parsed = CallToolResultSchema.parse(result); expect(parsed.content[0].text).toBe('❌ Simulator not found: NonExistentSimulator-MCP'); }); }); });

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/Stefan-Nitu/mcp-xcode'

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