mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2026-02-02 20:43:39 +00:00
Merge branch 'main' into vscode-client-factory
This commit is contained in:
@@ -40,15 +40,18 @@ type CDPServer = {
|
||||
start: () => Promise<BrowserContext>;
|
||||
};
|
||||
|
||||
export type StartClient = (options?: {
|
||||
clientName?: string,
|
||||
args?: string[],
|
||||
config?: Config,
|
||||
roots?: { name: string, uri: string }[],
|
||||
rootsResponseDelay?: number,
|
||||
}) => Promise<{ client: Client, stderr: () => string }>;
|
||||
|
||||
|
||||
type TestFixtures = {
|
||||
client: Client;
|
||||
startClient: (options?: {
|
||||
clientName?: string,
|
||||
args?: string[],
|
||||
config?: Config,
|
||||
roots?: { name: string, uri: string }[],
|
||||
rootsResponseDelay?: number,
|
||||
}) => Promise<{ client: Client, stderr: () => string }>;
|
||||
startClient: StartClient;
|
||||
wsEndpoint: string;
|
||||
cdpServer: CDPServer;
|
||||
server: TestServer;
|
||||
@@ -69,7 +72,7 @@ export const test = baseTest.extend<TestFixtures & TestOptions, WorkerFixtures>(
|
||||
|
||||
startClient: async ({ mcpHeadless, mcpBrowser, mcpMode }, use, testInfo) => {
|
||||
const configDir = path.dirname(test.info().config.configFile!);
|
||||
let client: Client | undefined;
|
||||
const clients: Client[] = [];
|
||||
|
||||
await use(async options => {
|
||||
const args: string[] = [];
|
||||
@@ -87,7 +90,7 @@ export const test = baseTest.extend<TestFixtures & TestOptions, WorkerFixtures>(
|
||||
args.push(`--config=${path.relative(configDir, configFile)}`);
|
||||
}
|
||||
|
||||
client = new Client({ name: options?.clientName ?? 'test', version: '1.0.0' }, options?.roots ? { capabilities: { roots: {} } } : undefined);
|
||||
const client = new Client({ name: options?.clientName ?? 'test', version: '1.0.0' }, options?.roots ? { capabilities: { roots: {} } } : undefined);
|
||||
if (options?.roots) {
|
||||
client.setRequestHandler(ListRootsRequestSchema, async request => {
|
||||
if (options.rootsResponseDelay)
|
||||
@@ -104,12 +107,13 @@ export const test = baseTest.extend<TestFixtures & TestOptions, WorkerFixtures>(
|
||||
process.stderr.write(data);
|
||||
stderrBuffer += data.toString();
|
||||
});
|
||||
clients.push(client);
|
||||
await client.connect(transport);
|
||||
await client.ping();
|
||||
return { client, stderr: () => stderrBuffer };
|
||||
});
|
||||
|
||||
await client?.close();
|
||||
await Promise.all(clients.map(client => client.close()));
|
||||
},
|
||||
|
||||
wsEndpoint: async ({ }, use) => {
|
||||
@@ -126,6 +130,8 @@ export const test = baseTest.extend<TestFixtures & TestOptions, WorkerFixtures>(
|
||||
await use({
|
||||
endpoint: `http://localhost:${port}`,
|
||||
start: async () => {
|
||||
if (browserContext)
|
||||
throw new Error('CDP server already exists');
|
||||
browserContext = await chromium.launchPersistentContext(testInfo.outputPath('cdp-user-data-dir'), {
|
||||
channel: mcpBrowser,
|
||||
headless: true,
|
||||
|
||||
@@ -23,65 +23,57 @@ import { createHash } from '../src/utils/guid.js';
|
||||
|
||||
const p = process.platform === 'win32' ? 'c:\\non\\existent\\folder' : '/non/existent/folder';
|
||||
|
||||
for (const mode of ['default', 'proxy']) {
|
||||
const extraArgs = mode === 'proxy' ? ['--connect-tool'] : [];
|
||||
|
||||
test.describe(`${mode} mode`, () => {
|
||||
test('should use separate user data by root path', async ({ startClient, server }, testInfo) => {
|
||||
const { client } = await startClient({
|
||||
args: extraArgs,
|
||||
clientName: 'Visual Studio Code', // Simulate VS Code client, roots only work with it
|
||||
roots: [
|
||||
{
|
||||
name: 'test',
|
||||
uri: 'file://' + p.replace(/\\/g, '/'),
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
await client.callTool({
|
||||
name: 'browser_navigate',
|
||||
arguments: { url: server.HELLO_WORLD },
|
||||
});
|
||||
|
||||
const hash = createHash(p);
|
||||
const [file] = await fs.promises.readdir(testInfo.outputPath('ms-playwright'));
|
||||
expect(file).toContain(hash);
|
||||
});
|
||||
|
||||
|
||||
test('check that trace is saved in workspace', async ({ startClient, server }, testInfo) => {
|
||||
const rootPath = testInfo.outputPath('workspace');
|
||||
const { client } = await startClient({
|
||||
args: ['--save-trace', ...extraArgs],
|
||||
clientName: 'Visual Studio Code - Insiders', // Simulate VS Code client, roots only work with it
|
||||
roots: [
|
||||
{
|
||||
name: 'workspace',
|
||||
uri: pathToFileURL(rootPath).toString(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(await client.callTool({
|
||||
name: 'browser_navigate',
|
||||
arguments: { url: server.HELLO_WORLD },
|
||||
})).toHaveResponse({
|
||||
code: expect.stringContaining(`page.goto('http://localhost`),
|
||||
});
|
||||
|
||||
const [file] = await fs.promises.readdir(path.join(rootPath, '.playwright-mcp'));
|
||||
expect(file).toContain('traces');
|
||||
});
|
||||
|
||||
test('should list all tools when listRoots is slow', async ({ startClient, server }, testInfo) => {
|
||||
const { client } = await startClient({
|
||||
clientName: 'Visual Studio Code', // Simulate VS Code client, roots only work with it
|
||||
roots: [],
|
||||
rootsResponseDelay: 1000,
|
||||
});
|
||||
const tools = await client.listTools();
|
||||
expect(tools.tools.length).toBeGreaterThan(20);
|
||||
});
|
||||
test('should use separate user data by root path', async ({ startClient, server }, testInfo) => {
|
||||
const { client } = await startClient({
|
||||
clientName: 'Visual Studio Code',
|
||||
roots: [
|
||||
{
|
||||
name: 'test',
|
||||
uri: 'file://' + p.replace(/\\/g, '/'),
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
await client.callTool({
|
||||
name: 'browser_navigate',
|
||||
arguments: { url: server.HELLO_WORLD },
|
||||
});
|
||||
|
||||
const hash = createHash(p);
|
||||
const [file] = await fs.promises.readdir(testInfo.outputPath('ms-playwright'));
|
||||
expect(file).toContain(hash);
|
||||
});
|
||||
|
||||
test('check that trace is saved in workspace', async ({ startClient, server }, testInfo) => {
|
||||
const rootPath = testInfo.outputPath('workspace');
|
||||
const { client } = await startClient({
|
||||
args: ['--save-trace'],
|
||||
clientName: 'My client',
|
||||
roots: [
|
||||
{
|
||||
name: 'workspace',
|
||||
uri: pathToFileURL(rootPath).toString(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(await client.callTool({
|
||||
name: 'browser_navigate',
|
||||
arguments: { url: server.HELLO_WORLD },
|
||||
})).toHaveResponse({
|
||||
code: expect.stringContaining(`page.goto('http://localhost`),
|
||||
});
|
||||
|
||||
const [file] = await fs.promises.readdir(path.join(rootPath, '.playwright-mcp'));
|
||||
expect(file).toContain('traces');
|
||||
});
|
||||
|
||||
test('should list all tools when listRoots is slow', async ({ startClient, server }, testInfo) => {
|
||||
const { client } = await startClient({
|
||||
clientName: 'Another custom client',
|
||||
roots: [],
|
||||
rootsResponseDelay: 1000,
|
||||
});
|
||||
const tools = await client.listTools();
|
||||
expect(tools.tools.length).toBeGreaterThan(20);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user