fix: createConnection() via public API (#384)

Fixes https://github.com/microsoft/playwright-mcp/issues/382
This commit is contained in:
Max Schmitt 2025-05-09 21:50:38 +02:00 committed by GitHub
parent 75f74a54bc
commit 65716b60dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 6 deletions

View File

@ -231,7 +231,7 @@ http.createServer(async (req, res) => {
// ...
// Creates a headless Playwright MCP server with SSE transport
const connection = await createConnection({ headless: true });
const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
const transport = new SSEServerTransport('/messages', res);
await connection.connect(transport);

View File

@ -16,4 +16,4 @@
*/
import { createConnection } from './lib/index';
export default { createConnection };
export { createConnection };

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import { Connection } from './connection.js';
import { Connection, createConnection as createConnectionImpl } from './connection.js';
import type { Config } from '../config.js';
export async function createConnection(config: Config = {}): Promise<Connection> {
return createConnection(config);
return createConnectionImpl(config);
}

View File

@ -15,14 +15,19 @@
*/
import url from 'node:url';
import http from 'node:http';
import { spawn } from 'node:child_process';
import path from 'node:path';
import { test as baseTest } from './fixtures.js';
import { expect } from 'playwright/test';
import type { AddressInfo } from 'node:net';
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { createConnection } from '@playwright/mcp';
import { test as baseTest, expect } from './fixtures.js';
// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.
const __filename = url.fileURLToPath(import.meta.url);
@ -59,3 +64,40 @@ test('streamable http transport', async ({ serverEndpoint }) => {
await client.ping();
expect(transport.sessionId, 'has session support').toBeDefined();
});
test('sse transport via public API', async ({ server }) => {
const sessions = new Map<string, SSEServerTransport>();
const mcpServer = http.createServer(async (req, res) => {
if (req.method === 'GET') {
const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
const transport = new SSEServerTransport('/sse', res);
sessions.set(transport.sessionId, transport);
await connection.connect(transport);
} else if (req.method === 'POST') {
const url = new URL(`http://localhost${req.url}`);
const sessionId = url.searchParams.get('sessionId');
if (!sessionId) {
res.statusCode = 400;
return res.end('Missing sessionId');
}
const transport = sessions.get(sessionId);
if (!transport) {
res.statusCode = 404;
return res.end('Session not found');
}
void transport.handlePostMessage(req, res);
}
});
await new Promise<void>(resolve => mcpServer.listen(0, () => resolve()));
const serverUrl = `http://localhost:${(mcpServer.address() as AddressInfo).port}/sse`;
const transport = new SSEClientTransport(new URL(serverUrl));
const client = new Client({ name: 'test', version: '1.0.0' });
await client.connect(transport);
await client.ping();
expect(await client.callTool({
name: 'browser_navigate',
arguments: { url: server.HELLO_WORLD },
})).toContainTextContent(`- generic [ref=s1e2]: Hello, world!`);
await client.close();
mcpServer.close();
});