chore: allow multiple tabs (#129)

This commit is contained in:
Pavel Feldman
2025-04-03 19:24:17 -07:00
committed by GitHub
parent b358e47d71
commit e36d4ea695
10 changed files with 354 additions and 92 deletions

View File

@@ -37,6 +37,10 @@ test('test tool list', async ({ client, visionClient }) => {
'browser_save_as_pdf',
'browser_close',
'browser_install',
'browser_list_tabs',
'browser_new_tab',
'browser_select_tab',
'browser_close_tab',
]);
const { tools: visionTools } = await visionClient.listTools();
@@ -55,6 +59,10 @@ test('test tool list', async ({ client, visionClient }) => {
'browser_save_as_pdf',
'browser_close',
'browser_install',
'browser_list_tabs',
'browser_new_tab',
'browser_select_tab',
'browser_close_tab',
]);
});
@@ -75,6 +83,8 @@ test('test browser_navigate', async ({ client }) => {
url: 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>',
},
})).toHaveTextContent(`
Navigated to data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page URL: data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page Title: Title
- Page Snapshot
@@ -128,6 +138,8 @@ test('test reopen browser', async ({ client }) => {
url: 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>',
},
})).toHaveTextContent(`
Navigated to data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page URL: data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page Title: Title
- Page Snapshot
@@ -326,6 +338,8 @@ test('cdp server', async ({ cdpEndpoint, startClient }) => {
url: 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>',
},
})).toHaveTextContent(`
Navigated to data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page URL: data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page Title: Title
- Page Snapshot
@@ -343,6 +357,8 @@ test('save as pdf', async ({ client }) => {
url: 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>',
},
})).toHaveTextContent(`
Navigated to data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page URL: data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
- Page Title: Title
- Page Snapshot

View File

@@ -86,10 +86,17 @@ export const expect = baseExpect.extend({
const isNot = this.isNot;
try {
const text = (response.content as any)[0].text;
if (isNot)
baseExpect(text).not.toMatch(content);
else
baseExpect(text).toMatch(content);
if (typeof content === 'string') {
if (isNot)
baseExpect(text.trim()).not.toBe(content.trim());
else
baseExpect(text.trim()).toBe(content.trim());
} else {
if (isNot)
baseExpect(text).not.toMatch(content);
else
baseExpect(text).toMatch(content);
}
} catch (e) {
return {
pass: isNot,

90
tests/tabs.spec.ts Normal file
View File

@@ -0,0 +1,90 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { test, expect } from './fixtures';
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
async function createTab(client: Client, title: string, body: string) {
return await client.callTool({
name: 'browser_new_tab',
arguments: {
url: `data:text/html,<title>${title}</title><body>${body}</body>`,
},
});
}
test('create new tab', async ({ client }) => {
expect(await createTab(client, 'Tab one', 'Body one')).toHaveTextContent(`
- Page URL: data:text/html,<title>Tab one</title><body>Body one</body>
- Page Title: Tab one
- Page Snapshot
\`\`\`yaml
- text: Body one
\`\`\``);
expect(await createTab(client, 'Tab two', 'Body two')).toHaveTextContent(`
Open tabs:
- 1: [Tab one] (data:text/html,<title>Tab one</title><body>Body one</body>)
- 2: (current) [Tab two] (data:text/html,<title>Tab two</title><body>Body two</body>)
Current tab:
- Page URL: data:text/html,<title>Tab two</title><body>Body two</body>
- Page Title: Tab two
- Page Snapshot
\`\`\`yaml
- text: Body two
\`\`\``);
});
test('select tab', async ({ client }) => {
await createTab(client, 'Tab one', 'Body one');
await createTab(client, 'Tab two', 'Body two');
expect(await client.callTool({
name: 'browser_select_tab',
arguments: {
index: 1,
},
})).toHaveTextContent(`
Open tabs:
- 1: (current) [Tab one] (data:text/html,<title>Tab one</title><body>Body one</body>)
- 2: [Tab two] (data:text/html,<title>Tab two</title><body>Body two</body>)
Current tab:
- Page URL: data:text/html,<title>Tab one</title><body>Body one</body>
- Page Title: Tab one
- Page Snapshot
\`\`\`yaml
- text: Body one
\`\`\``);
});
test('close tab', async ({ client }) => {
await createTab(client, 'Tab one', 'Body one');
await createTab(client, 'Tab two', 'Body two');
expect(await client.callTool({
name: 'browser_close_tab',
arguments: {
index: 2,
},
})).toHaveTextContent(`
- Page URL: data:text/html,<title>Tab one</title><body>Body one</body>
- Page Title: Tab one
- Page Snapshot
\`\`\`yaml
- text: Body one
\`\`\``);
});