Skip to content

Commit 88698d3

Browse files
committed
feat(mcp): refactor code structure for improved readability and maintainability
1 parent 0ee904f commit 88698d3

File tree

25 files changed

+637
-310
lines changed

25 files changed

+637
-310
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"dev": "nx run-many --target=build:watch --exclude=android-playground,chrome-extension,@midscene/report,doc --verbose --parallel=6",
77
"build": "nx run-many --target=build --exclude=doc --verbose",
88
"build:skip-cache": "nx run-many --target=build --exclude=doc --verbose --skip-nx-cache",
9-
"test": "nx run-many --target=test --projects=@midscene/core,@midscene/shared,@midscene/visualizer,@midscene/web,@midscene/cli,@midscene/android,@midscene/ios,@midscene/mcp,@midscene/android-mcp,@midscene/ios-mcp,@midscene/web-bridge-mcp,@midscene/playground --verbose",
9+
"test": "nx run-many --target=test --projects=@midscene/core,@midscene/shared,@midscene/visualizer,@midscene/web,@midscene/cli,@midscene/android,@midscene/ios,@midscene/android-mcp,@midscene/ios-mcp,@midscene/web-bridge-mcp,@midscene/playground --verbose",
1010
"test:ai": "nx run-many --target=test:ai --projects=@midscene/core,@midscene/web,@midscene/cli --verbose",
1111
"e2e": "nx run @midscene/web:e2e --verbose --exclude-task-dependencies",
1212
"e2e:cache": "nx run @midscene/web:e2e:cache --verbose --exclude-task-dependencies",
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
2+
import { AndroidMCPServer } from '../src/server.js';
3+
4+
describe('AndroidMCPServer HTTP mode', () => {
5+
let server: AndroidMCPServer;
6+
const testPort = 13580; // Use different port than web-bridge-mcp
7+
const testHost = 'localhost';
8+
9+
beforeAll(async () => {
10+
server = new AndroidMCPServer();
11+
});
12+
13+
afterAll(async () => {
14+
// Cleanup will be handled by process exit
15+
});
16+
17+
it('should start HTTP server successfully', async () => {
18+
// Mock process.exit to prevent test exit
19+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
20+
throw new Error('process.exit called');
21+
}) as any);
22+
23+
try {
24+
// Start server in background
25+
const serverPromise = server.launchHttp({
26+
port: testPort,
27+
host: testHost,
28+
});
29+
30+
// Give server time to start
31+
await new Promise((resolve) => setTimeout(resolve, 1500));
32+
33+
// Simply verify the server is listening by trying to connect
34+
const response = await fetch(`http://${testHost}:${testPort}/mcp`, {
35+
method: 'POST',
36+
headers: {
37+
'Content-Type': 'application/json',
38+
},
39+
body: JSON.stringify({
40+
jsonrpc: '2.0',
41+
method: 'initialize',
42+
params: {
43+
protocolVersion: '2024-11-05',
44+
capabilities: {},
45+
clientInfo: {
46+
name: 'test-client',
47+
version: '1.0.0',
48+
},
49+
},
50+
id: 1,
51+
}),
52+
});
53+
54+
// Server should respond (even if initialization fails without device)
55+
expect(response.status).toBeGreaterThanOrEqual(200);
56+
expect(response.status).toBeLessThan(600);
57+
58+
console.log('✓ Android MCP server started and responding');
59+
} finally {
60+
exitSpy.mockRestore();
61+
}
62+
}, 10000);
63+
64+
it('should reject invalid port numbers', async () => {
65+
const invalidServer = new AndroidMCPServer();
66+
67+
await expect(
68+
invalidServer.launchHttp({
69+
port: -1,
70+
host: testHost,
71+
}),
72+
).rejects.toThrow(/Invalid port number/);
73+
74+
await expect(
75+
invalidServer.launchHttp({
76+
port: 99999,
77+
host: testHost,
78+
}),
79+
).rejects.toThrow(/Invalid port number/);
80+
});
81+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import { defineConfig } from 'vitest/config';
2+
import { version } from './package.json';
23

34
export default defineConfig({
45
test: {
56
globals: true,
67
environment: 'node',
78
},
9+
define: {
10+
__VERSION__: JSON.stringify(version),
11+
},
12+
ssr: {
13+
external: ['@silvia-odwyer/photon'],
14+
},
815
});

packages/android-playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"socket.io": "^4.8.1"
3434
},
3535
"devDependencies": {
36-
"@rslib/core": "^0.18.2",
36+
"@rslib/core": "^0.18.3",
3737
"@types/cors": "^2.8.17",
3838
"@types/express": "^4.17.21",
3939
"@types/node": "^18.0.0",

packages/android/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
},
3939
"devDependencies": {
4040
"@midscene/playground": "workspace:*",
41-
"@rslib/core": "^0.18.2",
41+
"@rslib/core": "^0.18.3",
4242
"@types/node": "^18.0.0",
4343
"dotenv": "^16.4.5",
4444
"typescript": "^5.8.3",

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"puppeteer": "24.2.0"
3030
},
3131
"devDependencies": {
32-
"@rslib/core": "^0.18.2",
32+
"@rslib/core": "^0.18.3",
3333
"@types/js-yaml": "4.0.9",
3434
"@types/lodash.merge": "4.6.9",
3535
"@types/minimist": "1.2.5",

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"socks-proxy-agent": "8.0.4"
8686
},
8787
"devDependencies": {
88-
"@rslib/core": "^0.18.2",
88+
"@rslib/core": "^0.18.3",
8989
"@types/node": "^18.0.0",
9090
"@types/node-fetch": "2.6.11",
9191
"@types/js-yaml": "4.0.9",
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
2+
import { IOSMCPServer } from '../src/server.js';
3+
4+
describe('IOSMCPServer HTTP mode', () => {
5+
let server: IOSMCPServer;
6+
const testPort = 13581; // Use different port than other MCP servers
7+
const testHost = 'localhost';
8+
9+
beforeAll(async () => {
10+
server = new IOSMCPServer();
11+
});
12+
13+
afterAll(async () => {
14+
// Cleanup will be handled by process exit
15+
});
16+
17+
it('should start HTTP server successfully', async () => {
18+
// Mock process.exit to prevent test exit
19+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
20+
throw new Error('process.exit called');
21+
}) as any);
22+
23+
try {
24+
// Start server in background
25+
const serverPromise = server.launchHttp({
26+
port: testPort,
27+
host: testHost,
28+
});
29+
30+
// Give server time to start
31+
await new Promise((resolve) => setTimeout(resolve, 1500));
32+
33+
// Simply verify the server is listening by trying to connect
34+
const response = await fetch(`http://${testHost}:${testPort}/mcp`, {
35+
method: 'POST',
36+
headers: {
37+
'Content-Type': 'application/json',
38+
},
39+
body: JSON.stringify({
40+
jsonrpc: '2.0',
41+
method: 'initialize',
42+
params: {
43+
protocolVersion: '2024-11-05',
44+
capabilities: {},
45+
clientInfo: {
46+
name: 'test-client',
47+
version: '1.0.0',
48+
},
49+
},
50+
id: 1,
51+
}),
52+
});
53+
54+
// Server should respond (even if initialization fails without device)
55+
expect(response.status).toBeGreaterThanOrEqual(200);
56+
expect(response.status).toBeLessThan(600);
57+
58+
console.log('✓ iOS MCP server started and responding');
59+
} finally {
60+
exitSpy.mockRestore();
61+
}
62+
}, 10000);
63+
64+
it('should reject invalid port numbers', async () => {
65+
const invalidServer = new IOSMCPServer();
66+
67+
await expect(
68+
invalidServer.launchHttp({
69+
port: -1,
70+
host: testHost,
71+
}),
72+
).rejects.toThrow(/Invalid port number/);
73+
74+
await expect(
75+
invalidServer.launchHttp({
76+
port: 99999,
77+
host: testHost,
78+
}),
79+
).rejects.toThrow(/Invalid port number/);
80+
});
81+
});

packages/ios-mcp/vitest.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import { defineConfig } from 'vitest/config';
2+
import { version } from './package.json';
23

34
export default defineConfig({
45
test: {
56
globals: true,
67
environment: 'node',
78
},
9+
define: {
10+
__VERSION__: JSON.stringify(version),
11+
},
12+
ssr: {
13+
external: ['@silvia-odwyer/photon'],
14+
},
815
});

packages/ios-playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@midscene/ios": "workspace:*"
2121
},
2222
"devDependencies": {
23-
"@rslib/core": "^0.18.2",
23+
"@rslib/core": "^0.18.3",
2424
"@types/node": "^18.0.0",
2525
"typescript": "^5.8.3"
2626
},

0 commit comments

Comments
 (0)