mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-26 16:42:27 +08:00
chore: sanitize file path when saving (#99)
Fixes https://github.com/microsoft/playwright-mcp/issues/96
This commit is contained in:
parent
aeb4cf65e9
commit
d316441142
@ -20,7 +20,7 @@ import path from 'path';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { zodToJsonSchema } from 'zod-to-json-schema';
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
||||||
|
|
||||||
import { captureAriaSnapshot, runAndWait } from './utils';
|
import { captureAriaSnapshot, runAndWait, sanitizeForFilePath } from './utils';
|
||||||
|
|
||||||
import type { ToolFactory, Tool } from './tool';
|
import type { ToolFactory, Tool } from './tool';
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ export const pdf: Tool = {
|
|||||||
},
|
},
|
||||||
handle: async context => {
|
handle: async context => {
|
||||||
const page = context.existingPage();
|
const page = context.existingPage();
|
||||||
const fileName = path.join(os.tmpdir(), `/page-${new Date().toISOString()}.pdf`);
|
const fileName = path.join(os.tmpdir(), sanitizeForFilePath(`page-${new Date().toISOString()}`)) + '.pdf';
|
||||||
await page.pdf({ path: fileName });
|
await page.pdf({ path: fileName });
|
||||||
return {
|
return {
|
||||||
content: [{
|
content: [{
|
||||||
|
@ -106,3 +106,7 @@ export async function captureAriaSnapshot(context: Context, status: string = '')
|
|||||||
content: [{ type: 'text', text: lines.join('\n') }],
|
content: [{ type: 'text', text: lines.join('\n') }],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sanitizeForFilePath(s: string) {
|
||||||
|
return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-');
|
||||||
|
}
|
||||||
|
@ -331,3 +331,25 @@ test('cdp server', async ({ cdpEndpoint, startClient }) => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('save as pdf', async ({ client }) => {
|
||||||
|
expect(await client.callTool({
|
||||||
|
name: 'browser_navigate',
|
||||||
|
arguments: {
|
||||||
|
url: 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>',
|
||||||
|
},
|
||||||
|
})).toHaveTextContent(`
|
||||||
|
- Page URL: data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
|
||||||
|
- Page Title: Title
|
||||||
|
- Page Snapshot
|
||||||
|
\`\`\`yaml
|
||||||
|
- document [ref=s1e2]: Hello, world!
|
||||||
|
\`\`\`
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await client.callTool({
|
||||||
|
name: 'browser_save_as_pdf',
|
||||||
|
});
|
||||||
|
expect(response).toHaveTextContent(/^Saved as.*page-[^:]+.pdf$/);
|
||||||
|
});
|
||||||
|
@ -81,15 +81,14 @@ export const test = baseTest.extend<Fixtures>({
|
|||||||
type Response = Awaited<ReturnType<Client['callTool']>>;
|
type Response = Awaited<ReturnType<Client['callTool']>>;
|
||||||
|
|
||||||
export const expect = baseExpect.extend({
|
export const expect = baseExpect.extend({
|
||||||
toHaveTextContent(response: Response, content: string | string[]) {
|
toHaveTextContent(response: Response, content: string | RegExp) {
|
||||||
const isNot = this.isNot;
|
const isNot = this.isNot;
|
||||||
try {
|
try {
|
||||||
content = Array.isArray(content) ? content : [content];
|
const text = (response.content as any)[0].text;
|
||||||
const texts = (response.content as any).map(c => c.text);
|
|
||||||
if (isNot)
|
if (isNot)
|
||||||
baseExpect(texts).not.toEqual(content);
|
baseExpect(text).not.toMatch(content);
|
||||||
else
|
else
|
||||||
baseExpect(texts).toEqual(content);
|
baseExpect(text).toMatch(content);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
pass: isNot,
|
pass: isNot,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user