Skip to content

Commit 939630e

Browse files
committed
Fix e2e tests for MCP
1 parent fac881b commit 939630e

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

src/api/api-server.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,17 @@ export class HttpToolkitServerApi extends events.EventEmitter {
140140
exposeGraphQLAPI(this.server, apiModel);
141141
}
142142

143-
start() {
144-
return new Promise<void>((resolve, reject) => {
143+
async start() {
144+
const socketReady = this.startBridgeApiServer();
145+
146+
await new Promise<void>((resolve, reject) => {
145147
const httpServer: http.Server = this.server.listen(45457, '127.0.0.1', resolve);
146148
httpServer.once('error', reject);
147149

148150
this.attachWebSocketBridge(httpServer);
149-
this.startBridgeApiServer();
150151
});
152+
153+
await socketReady;
151154
}
152155

153156
private attachWebSocketBridge(httpServer: http.Server) {
@@ -190,10 +193,10 @@ export class HttpToolkitServerApi extends events.EventEmitter {
190193
});
191194
}
192195

193-
private startBridgeApiServer() {
196+
private async startBridgeApiServer(): Promise<void> {
194197
try {
195198
const socketPath = getSocketPath();
196-
this.bridge.startApiServer(socketPath);
199+
await this.bridge.startApiServer(socketPath);
197200
} catch (err: any) {
198201
console.warn(
199202
`Failed to start UI Bridge socket server: ${err.message}. ` +

src/api/bridge-client.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export function apiRequest(
1717
socketPath: getSocketPath(),
1818
headers: {
1919
'Content-Type': 'application/json'
20-
}
20+
},
21+
timeout: 5000
2122
}, (res) => {
2223
const chunks: Buffer[] = [];
2324
res.on('error', (err) => result.reject(err));
@@ -41,6 +42,10 @@ export function apiRequest(
4142
});
4243
});
4344

45+
req.on('timeout', () => {
46+
req.destroy(new Error('Request timed out'));
47+
});
48+
4449
req.on('error', (err: any) => {
4550
if (err.code === 'ECONNREFUSED' || err.code === 'ENOENT') {
4651
result.reject(new Error('HTTP Toolkit is not running. Start HTTP Toolkit first.'));

src/api/ui-operation-bridge.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export class UiOperationBridge extends EventEmitter {
140140
});
141141
}
142142

143-
startApiServer(socketPath: string): http.Server {
143+
startApiServer(socketPath: string): Promise<void> {
144144
// Clean up stale socket file if it exists (Unix only)
145145
if (process.platform !== 'win32') {
146146
try { fs.unlinkSync(socketPath); } catch {}
@@ -170,15 +170,22 @@ export class UiOperationBridge extends EventEmitter {
170170
}
171171
});
172172

173-
server.listen(socketPath, () => {
174-
if (process.platform !== 'win32') {
175-
fs.chmodSync(socketPath, 0o600);
176-
}
177-
console.log(`UI Bridge API server listening on ${socketPath}`);
178-
});
179-
180173
this.socketServer = server;
181-
return server;
174+
175+
return new Promise<void>((resolve, reject) => {
176+
server.once('error', reject);
177+
server.listen(socketPath, () => {
178+
server.removeListener('error', reject);
179+
server.on('error', (err) => {
180+
console.warn(`UI Bridge socket server error: ${err.message}`);
181+
});
182+
if (process.platform !== 'win32') {
183+
fs.chmodSync(socketPath, 0o600);
184+
}
185+
console.log(`UI Bridge API server listening on ${socketPath}`);
186+
resolve();
187+
});
188+
});
182189
}
183190

184191
private handleApiStatus(res: http.ServerResponse): void {

test/integration/e2e-api-test.spec.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,11 +323,13 @@ describe('End-to-end server API test', function () {
323323
execFile(serverRunPath, ['ctl', ...args], {
324324
timeout: 10000
325325
}, (error, stdout, stderr) => {
326-
resolve({
326+
const result = {
327327
stdout: stdout.toString(),
328328
stderr: stderr.toString(),
329329
exitCode: error ? (error as any).code ?? 1 : 0
330-
});
330+
};
331+
if (result.stderr) console.warn(`[ctl ${args.join(' ')}] stderr: ${result.stderr}`);
332+
resolve(result);
331333
});
332334
});
333335
}
@@ -363,6 +365,13 @@ describe('End-to-end server API test', function () {
363365
stdio: ['pipe', 'pipe', 'pipe']
364366
});
365367

368+
let mcpStderr = '';
369+
mcpProcess.stderr!.on('data', (d) => { mcpStderr += d.toString(); });
370+
mcpProcess.on('exit', (code) => {
371+
if (mcpStderr) console.warn(`[mcp] stderr: ${mcpStderr}`);
372+
if (code !== null && code !== 0) console.warn(`[mcp] exited with code ${code}`);
373+
});
374+
366375
const initMessage = JSON.stringify({
367376
jsonrpc: '2.0',
368377
id: 1,

0 commit comments

Comments
 (0)