chore: introduce response type (#738)

This commit is contained in:
Pavel Feldman
2025-07-22 16:36:21 -07:00
committed by GitHub
parent c2b98dc70b
commit 601a74305c
32 changed files with 443 additions and 526 deletions

View File

@@ -45,13 +45,7 @@ test('cdp server reuse tab', async ({ cdpServer, startClient, server }) => {
expect(await client.callTool({
name: 'browser_snapshot',
})).toHaveTextContent(`
### Ran Playwright code
\`\`\`js
// <internal code to capture accessibility snapshot>
\`\`\`
### Page state
})).toHaveTextContent(`### Page state
- Page URL: ${server.HELLO_WORLD}
- Page Title: Title
- Page Snapshot:

View File

@@ -38,6 +38,7 @@ test('browser_console_messages', async ({ client, server }) => {
name: 'browser_console_messages',
});
expect(resource).toHaveTextContent([
'### Result',
`[LOG] Hello, world! @ ${server.PREFIX}:4`,
`[ERROR] Error @ ${server.PREFIX}:5`,
].join('\n'));

View File

@@ -36,7 +36,8 @@ await page.getByRole('button', { name: 'Button' }).click();
\`\`\`
### Modal state
- ["alert" dialog with message "Alert"]: can be handled by the "browser_handle_dialog" tool`);
- ["alert" dialog with message "Alert"]: can be handled by the "browser_handle_dialog" tool
`);
const result = await client.callTool({
name: 'browser_handle_dialog',
@@ -46,17 +47,7 @@ await page.getByRole('button', { name: 'Button' }).click();
});
expect(result).not.toContainTextContent('### Modal state');
expect(result).toContainTextContent(`### Ran Playwright code
\`\`\`js
// <internal code to handle "alert" dialog>
\`\`\`
### Page state
- Page URL: ${server.PREFIX}
- Page Title:
- Page Snapshot:
\`\`\`yaml
- button "Button"`);
expect(result).toContainTextContent(`Page Snapshot:`);
});
test('two alert dialogs', async ({ client, server }) => {
@@ -85,7 +76,8 @@ await page.getByRole('button', { name: 'Button' }).click();
\`\`\`
### Modal state
- ["alert" dialog with message "Alert 1"]: can be handled by the "browser_handle_dialog" tool`);
- ["alert" dialog with message "Alert 1"]: can be handled by the "browser_handle_dialog" tool
`);
const result = await client.callTool({
name: 'browser_handle_dialog',
@@ -94,9 +86,9 @@ await page.getByRole('button', { name: 'Button' }).click();
},
});
expect(result).toContainTextContent(`
### Modal state
- ["alert" dialog with message "Alert 2"]: can be handled by the "browser_handle_dialog" tool`);
expect(result).toContainTextContent(`### Modal state
- ["alert" dialog with message "Alert 2"]: can be handled by the "browser_handle_dialog" tool
`);
const result2 = await client.callTool({
name: 'browser_handle_dialog',
@@ -138,7 +130,6 @@ test('confirm dialog (true)', async ({ client, server }) => {
});
expect(result).not.toContainTextContent('### Modal state');
expect(result).toContainTextContent('// <internal code to handle "confirm" dialog>');
expect(result).toContainTextContent(`- Page Snapshot:
\`\`\`yaml
- generic [active] [ref=e1]: "true"
@@ -165,7 +156,8 @@ test('confirm dialog (false)', async ({ client, server }) => {
ref: 'e2',
},
})).toContainTextContent(`### Modal state
- ["confirm" dialog with message "Confirm"]: can be handled by the "browser_handle_dialog" tool`);
- ["confirm" dialog with message "Confirm"]: can be handled by the "browser_handle_dialog" tool
`);
const result = await client.callTool({
name: 'browser_handle_dialog',
@@ -200,7 +192,8 @@ test('prompt dialog', async ({ client, server }) => {
ref: 'e2',
},
})).toContainTextContent(`### Modal state
- ["prompt" dialog with message "Prompt"]: can be handled by the "browser_handle_dialog" tool`);
- ["prompt" dialog with message "Prompt"]: can be handled by the "browser_handle_dialog" tool
`);
const result = await client.callTool({
name: 'browser_handle_dialog',
@@ -236,7 +229,8 @@ await page.getByRole('button', { name: 'Button' }).click();
\`\`\`
### Modal state
- ["alert" dialog with message "Alert"]: can be handled by the "browser_handle_dialog" tool`);
- ["alert" dialog with message "Alert"]: can be handled by the "browser_handle_dialog" tool
`);
const result = await client.callTool({
name: 'browser_handle_dialog',
@@ -246,12 +240,7 @@ await page.getByRole('button', { name: 'Button' }).click();
});
expect(result).not.toContainTextContent('### Modal state');
expect(result).toContainTextContent(`### Ran Playwright code
\`\`\`js
// <internal code to handle "alert" dialog>
\`\`\`
### Page state
expect(result).toContainTextContent(`### Page state
- Page URL: ${server.PREFIX}
- Page Title:
- Page Snapshot:

View File

@@ -47,7 +47,8 @@ test('browser_evaluate (element)', async ({ client, server }) => {
element: 'body',
ref: 'e1',
},
})).toContainTextContent(`- Result: "red"`);
})).toContainTextContent(`### Result
"red"`);
});
test('browser_evaluate (error)', async ({ client, server }) => {

View File

@@ -113,8 +113,7 @@ test('clicking on download link emits download', async ({ startClient, server, m
ref: 'e2',
},
});
await expect.poll(() => client.callTool({ name: 'browser_snapshot' })).toContainTextContent(`
### Downloads
await expect.poll(() => client.callTool({ name: 'browser_snapshot' })).toContainTextContent(`### Downloads
- Downloaded file test.txt to ${testInfo.outputPath('output', 'test.txt')}`);
});
@@ -123,7 +122,7 @@ test('navigating to download link emits download', async ({ startClient, server,
config: { outputDir: testInfo.outputPath('output') },
});
test.skip(mcpBrowser === 'webkit' && process.platform === 'linux', 'https://github.com/microsoft/playwright/blob/8e08fdb52c27bb75de9bf87627bf740fadab2122/tests/library/download.spec.ts#L436');
test.skip(mcpBrowser !== 'chromium', 'This test is racy');
server.route('/download', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/plain',

View File

@@ -20,5 +20,5 @@ test('browser_install', async ({ client, mcpBrowser }) => {
test.skip(mcpBrowser !== 'chromium', 'Test only chromium');
expect(await client.callTool({
name: 'browser_install',
})).toContainTextContent(`No open pages available.`);
})).toContainTextContent(`### No open tabs`);
});

View File

@@ -27,7 +27,13 @@ test('test reopen browser', async ({ startClient, server, mcpMode }) => {
expect(await client.callTool({
name: 'browser_close',
})).toContainTextContent('No open pages available');
})).toContainTextContent(`### Ran Playwright code
\`\`\`js
await page.close()
\`\`\`
### No open tabs
Use the "browser_navigate" tool to navigate to a page first.`);
expect(await client.callTool({
name: 'browser_navigate',

View File

@@ -40,6 +40,7 @@ test('browser_network_requests', async ({ client, server }) => {
await expect.poll(() => client.callTool({
name: 'browser_network_requests',
})).toHaveTextContent(`[GET] ${`${server.PREFIX}`} => [200] OK
})).toHaveTextContent(`### Result
[GET] ${`${server.PREFIX}`} => [200] OK
[GET] ${`${server.PREFIX}json`} => [200] OK`);
});

View File

@@ -65,14 +65,7 @@ test('save as pdf (filename: output.pdf)', async ({ startClient, mcpBrowser, ser
arguments: {
filename: 'output.pdf',
},
})).toEqual({
content: [
{
type: 'text',
text: expect.stringContaining(`output.pdf`),
},
],
});
})).toContainTextContent(`output.pdf`);
const files = [...fs.readdirSync(outputDir)];

View File

@@ -31,15 +31,15 @@ test('browser_take_screenshot (viewport)', async ({ startClient, server }, testI
name: 'browser_take_screenshot',
})).toEqual({
content: [
{
text: expect.stringContaining(`Screenshot viewport and save it as`),
type: 'text',
},
{
data: expect.any(String),
mimeType: 'image/jpeg',
type: 'image',
},
{
text: expect.stringContaining(`Screenshot viewport and save it as`),
type: 'text',
},
],
});
});
@@ -61,15 +61,15 @@ test('browser_take_screenshot (element)', async ({ startClient, server }, testIn
},
})).toEqual({
content: [
{
text: expect.stringContaining(`page.getByText('Hello, world!').screenshot`),
type: 'text',
},
{
data: expect.any(String),
mimeType: 'image/jpeg',
type: 'image',
},
{
text: expect.stringContaining(`page.getByText('Hello, world!').screenshot`),
type: 'text',
},
],
});
});
@@ -111,17 +111,17 @@ for (const raw of [undefined, true]) {
arguments: { raw },
})).toEqual({
content: [
{
data: expect.any(String),
mimeType: `image/${ext}`,
type: 'image',
},
{
text: expect.stringMatching(
new RegExp(`page-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}\\-\\d{3}Z\\.${ext}`)
),
type: 'text',
},
{
data: expect.any(String),
mimeType: `image/${ext}`,
type: 'image',
},
],
});
@@ -153,15 +153,15 @@ test('browser_take_screenshot (filename: "output.jpeg")', async ({ startClient,
},
})).toEqual({
content: [
{
text: expect.stringContaining(`output.jpeg`),
type: 'text',
},
{
data: expect.any(String),
mimeType: 'image/jpeg',
type: 'image',
},
{
text: expect.stringContaining(`output.jpeg`),
type: 'text',
},
],
});
@@ -216,15 +216,15 @@ test('browser_take_screenshot (fullPage: true)', async ({ startClient, server },
arguments: { fullPage: true },
})).toEqual({
content: [
{
text: expect.stringContaining(`Screenshot full page and save it as`),
type: 'text',
},
{
data: expect.any(String),
mimeType: 'image/jpeg',
type: 'image',
},
{
text: expect.stringContaining(`Screenshot full page and save it as`),
type: 'text',
},
],
});
});
@@ -266,15 +266,15 @@ test('browser_take_screenshot (viewport without snapshot)', async ({ startClient
name: 'browser_take_screenshot',
})).toEqual({
content: [
{
text: expect.stringContaining(`Screenshot viewport and save it as`),
type: 'text',
},
{
data: expect.any(String),
mimeType: 'image/jpeg',
type: 'image',
},
{
text: expect.stringContaining(`Screenshot viewport and save it as`),
type: 'text',
},
],
});
});

View File

@@ -44,11 +44,13 @@ test('list first tab', async ({ client }) => {
});
test('create new tab', async ({ client }) => {
expect(await createTab(client, 'Tab one', 'Body one')).toContainTextContent(`
### Open tabs
const result = await createTab(client, 'Tab one', 'Body one');
expect(result).toContainTextContent(`### Open tabs
- 0: [] (about:blank)
- 1: (current) [Tab one] (data:text/html,<title>Tab one</title><body>Body one</body>)
`);
expect(result).toContainTextContent(`
### Page state
- Page URL: data:text/html,<title>Tab one</title><body>Body one</body>
- Page Title: Tab one
@@ -57,12 +59,14 @@ test('create new tab', async ({ client }) => {
- generic [active] [ref=e1]: Body one
\`\`\``);
expect(await createTab(client, 'Tab two', 'Body two')).toContainTextContent(`
### Open tabs
const result2 = await createTab(client, 'Tab two', 'Body two');
expect(result2).toContainTextContent(`### Open tabs
- 0: [] (about:blank)
- 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>)
`);
expect(result2).toContainTextContent(`
### Page state
- Page URL: data:text/html,<title>Tab two</title><body>Body two</body>
- Page Title: Tab two
@@ -82,8 +86,7 @@ test('select tab', async ({ client }) => {
index: 1,
},
});
expect(result).toContainTextContent(`
### Open tabs
expect(result).toContainTextContent(`### Open tabs
- 0: [] (about:blank)
- 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>)`);
@@ -108,8 +111,7 @@ test('close tab', async ({ client }) => {
index: 2,
},
});
expect(result).toContainTextContent(`
### Open tabs
expect(result).toContainTextContent(`### Open tabs
- 0: [] (about:blank)
- 1: (current) [Tab one] (data:text/html,<title>Tab one</title><body>Body one</body>)`);