Skip to content

Commit 8281b75

Browse files
freemaclaude
andcommitted
fix: resolve lint and type errors from PR #50 merge
- Fix prettier formatting (long lines, missing line breaks) - Fix curly brace requirement for if statements - Fix no-base-to-string: use String() instead of .toString() - Fix no-floating-promises: void async kill() in reset() - Fix no-misused-promises: wrap async cleanup in void handler - Remove unused FirefoxDisconnectedError import - Fix IBiDi type to include subscribe method - Fix type narrowing for bidiConnection return Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6e17b50 commit 8281b75

2 files changed

Lines changed: 52 additions & 20 deletions

File tree

src/firefox/core.ts

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export interface IBiDiSocket {
3535

3636
export interface IBiDi {
3737
socket: IBiDiSocket;
38+
subscribe?: (event: string, contexts?: string[]) => Promise<void>;
3839
}
3940

4041
/* eslint-disable @typescript-eslint/no-explicit-any */
@@ -133,14 +134,22 @@ class GeckodriverHttpDriver implements IDriver {
133134
private webSocketUrl: string | null;
134135
private bidiConnection: IBiDi | null = null;
135136

136-
constructor(baseUrl: string, sessionId: string, gdProcess: ChildProcess, webSocketUrl: string | null) {
137+
constructor(
138+
baseUrl: string,
139+
sessionId: string,
140+
gdProcess: ChildProcess,
141+
webSocketUrl: string | null
142+
) {
137143
this.baseUrl = baseUrl;
138144
this.sessionId = sessionId;
139145
this.gdProcess = gdProcess;
140146
this.webSocketUrl = webSocketUrl;
141147
}
142148

143-
static async connect(marionettePort: number, marionetteHost = '127.0.0.1'): Promise<GeckodriverHttpDriver> {
149+
static async connect(
150+
marionettePort: number,
151+
marionetteHost = '127.0.0.1'
152+
): Promise<GeckodriverHttpDriver> {
144153
// Find geckodriver binary via selenium-manager
145154
const path = await import('node:path');
146155
const { execFileSync } = await import('node:child_process');
@@ -181,7 +190,15 @@ class GeckodriverHttpDriver implements IDriver {
181190
// Use --port=0 to let the OS assign a free port atomically (geckodriver ≥0.34.0)
182191
const gd = spawn(
183192
geckodriverPath,
184-
['--connect-existing', '--marionette-host', marionetteHost, '--marionette-port', String(marionettePort), '--port', '0'],
193+
[
194+
'--connect-existing',
195+
'--marionette-host',
196+
marionetteHost,
197+
'--marionette-port',
198+
String(marionettePort),
199+
'--port',
200+
'0',
201+
],
185202
{ stdio: ['ignore', 'pipe', 'pipe'] }
186203
);
187204

@@ -226,7 +243,9 @@ class GeckodriverHttpDriver implements IDriver {
226243
}
227244

228245
let wsUrl = json.value.capabilities.webSocketUrl as string | undefined;
229-
logDebug(`Session capabilities webSocketUrl: ${wsUrl ?? 'not present'}, marionetteHost: ${marionetteHost}`);
246+
logDebug(
247+
`Session capabilities webSocketUrl: ${wsUrl ?? 'not present'}, marionetteHost: ${marionetteHost}`
248+
);
230249
if (wsUrl && marionetteHost !== '127.0.0.1') {
231250
// Rewrite the URL to connect through the remote host / tunnel.
232251
const parsed = new URL(wsUrl);
@@ -236,7 +255,9 @@ class GeckodriverHttpDriver implements IDriver {
236255
if (wsUrl) {
237256
logDebug(`BiDi WebSocket URL: ${wsUrl}`);
238257
} else {
239-
logDebug('BiDi WebSocket URL not available (Firefox may not support it or Remote Agent is not running)');
258+
logDebug(
259+
'BiDi WebSocket URL not available (Firefox may not support it or Remote Agent is not running)'
260+
);
240261
}
241262

242263
return new GeckodriverHttpDriver(baseUrl, json.value.sessionId, gd, wsUrl ?? null);
@@ -474,19 +495,22 @@ class GeckodriverHttpDriver implements IDriver {
474495
* first call, using the webSocketUrl returned in the session capabilities.
475496
*/
476497
async getBidi(): Promise<IBiDi> {
477-
if (this.bidiConnection) return this.bidiConnection;
498+
if (this.bidiConnection) {
499+
return this.bidiConnection;
500+
}
478501
if (!this.webSocketUrl) {
479502
throw new Error(
480503
'BiDi is not available: no webSocketUrl in session capabilities. ' +
481-
'Ensure Firefox was started with --remote-debugging-port.'
504+
'Ensure Firefox was started with --remote-debugging-port.'
482505
);
483506
}
484507

485508
const ws = new WebSocket(this.webSocketUrl);
486509
await new Promise<void>((resolve, reject) => {
487510
ws.on('open', resolve);
488511
ws.on('error', (e: any) => {
489-
const msg = e?.message || e?.error?.message || e?.error || e?.type || JSON.stringify(e) || String(e);
512+
const msg =
513+
e?.message || e?.error?.message || e?.error || e?.type || JSON.stringify(e) || String(e);
490514
reject(new Error(`BiDi WS to ${this.webSocketUrl}: ${msg}`));
491515
});
492516
});
@@ -498,13 +522,18 @@ class GeckodriverHttpDriver implements IDriver {
498522
method: 'session.subscribe',
499523
params: { events: [event] },
500524
};
501-
if (contexts) msg.params = { events: [event], contexts };
525+
if (contexts) {
526+
msg.params = { events: [event], contexts };
527+
}
502528
ws.send(JSON.stringify(msg));
503529
await new Promise<void>((resolve, reject) => {
504-
const timeout = setTimeout(() => reject(new Error(`BiDi subscribe timeout for ${event}`)), 5000);
530+
const timeout = setTimeout(
531+
() => reject(new Error(`BiDi subscribe timeout for ${event}`)),
532+
5000
533+
);
505534
const onMsg = (data: WebSocket.Data) => {
506535
try {
507-
const payload = JSON.parse(data.toString());
536+
const payload = JSON.parse(String(data));
508537
if (payload.id === cmdId) {
509538
clearTimeout(timeout);
510539
ws.off('message', onMsg);
@@ -514,15 +543,18 @@ class GeckodriverHttpDriver implements IDriver {
514543
resolve();
515544
}
516545
}
517-
} catch { /* ignore parse errors from event messages */ }
546+
} catch {
547+
/* ignore parse errors from event messages */
548+
}
518549
};
519550
ws.on('message', onMsg);
520551
});
521552
logDebug(`BiDi subscribed to ${event}`);
522553
};
523554

524-
this.bidiConnection = { subscribe, socket: ws as unknown as IBiDiSocket } as any;
525-
return this.bidiConnection;
555+
const conn: IBiDi = { subscribe, socket: ws as unknown as IBiDiSocket };
556+
this.bidiConnection = conn;
557+
return conn;
526558
}
527559
}
528560

@@ -727,7 +759,7 @@ export class FirefoxCore {
727759
*/
728760
reset(): void {
729761
if (this.driver && this.options.connectExisting && 'kill' in this.driver) {
730-
(this.driver as { kill(): Promise<void> }).kill();
762+
void (this.driver as { kill(): Promise<void> }).kill();
731763
}
732764
this.driver = null;
733765
this.currentContextId = null;

src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import { FirefoxDevTools } from './firefox/index.js';
3939
import type { FirefoxLaunchOptions } from './firefox/types.js';
4040
import * as tools from './tools/index.js';
4141
import type { McpToolResponse } from './types/common.js';
42-
import { FirefoxDisconnectedError } from './utils/errors.js';
4342

4443
// Export for direct usage in scripts
4544
export { FirefoxDevTools } from './firefox/index.js';
@@ -373,11 +372,12 @@ async function main() {
373372
await server.close();
374373
process.exit(0);
375374
};
376-
process.on('SIGTERM', cleanup);
377-
process.on('SIGINT', cleanup);
375+
const onSignal = () => void cleanup();
376+
process.on('SIGTERM', onSignal);
377+
process.on('SIGINT', onSignal);
378378
// StdioServerTransport does not fire onclose on stdin EOF.
379-
process.stdin.on('end', cleanup);
380-
process.stdin.on('close', cleanup);
379+
process.stdin.on('end', onSignal);
380+
process.stdin.on('close', onSignal);
381381
}
382382

383383
// Only run main() if this file is executed directly (not imported)

0 commit comments

Comments
 (0)