diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index 55b7a33..ba7ed8f 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -188,10 +188,10 @@ const selectOption: Tool = { const screenshotSchema = z.object({ raw: z.boolean().optional().describe('Whether to return without compression (in PNG format). Default is false, which returns a JPEG image.'), - element: z.string().optional().describe('Human-readable element description used to obtain permission to interact with the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.'), + element: z.string().optional().describe('Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.'), ref: z.string().optional().describe('Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.'), }).refine(data => { - return (!data.element) === (!data.ref); + return !!data.element === !!data.ref; }, { message: 'Both element and ref must be provided or neither.', path: ['ref', 'element'] @@ -215,7 +215,7 @@ const screenshot: Tool = { return await context.currentTab().runAndWaitWithSnapshot(async snapshot => { let screenshot: Buffer | undefined; const code = [ - `// Screenshot ${isElementScreenshot ? validatedParams.element : 'viewport'}`, + `// Screenshot ${isElementScreenshot ? validatedParams.element : 'viewport'} and save it as ${fileName}`, ]; if (isElementScreenshot) { const locator = snapshot.refLocator(validatedParams.ref!); @@ -225,7 +225,6 @@ const screenshot: Tool = { code.push(`await page.screenshot(${javascript.formatObject(options)});`); screenshot = await tab.page.screenshot(options); } - code.push(`// Screenshot saved as ${fileName}`); return { code, images: [{ @@ -233,7 +232,7 @@ const screenshot: Tool = { mimeType: fileType === 'png' ? 'image/png' : 'image/jpeg', }] }; - }, { captureSnapshot: false }); + }); } }; diff --git a/tests/screenshot.spec.ts b/tests/screenshot.spec.ts new file mode 100644 index 0000000..e052569 --- /dev/null +++ b/tests/screenshot.spec.ts @@ -0,0 +1,72 @@ +/** + * 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'; + +test('browser_take_screenshot (viewport)', async ({ client }) => { + expect(await client.callTool({ + name: 'browser_navigate', + arguments: { + url: 'data:text/html,TitleHello, world!', + }, + })).toContainTextContent(`Navigate to data:text/html`); + + expect(await client.callTool({ + name: 'browser_take_screenshot', + arguments: {}, + })).toEqual({ + content: [ + { + data: expect.any(String), + mimeType: 'image/jpeg', + type: 'image', + }, + { + text: expect.stringContaining(`Screenshot viewport and save it as`), + type: 'text', + }, + ], + }); +}); + +test('browser_take_screenshot (element)', async ({ client }) => { + expect(await client.callTool({ + name: 'browser_navigate', + arguments: { + url: 'data:text/html,Title', + }, + })).toContainTextContent(`[ref=s1e3]`); + + expect(await client.callTool({ + name: 'browser_take_screenshot', + arguments: { + element: 'hello button', + ref: 's1e3', + }, + })).toEqual({ + content: [ + { + data: expect.any(String), + mimeType: 'image/jpeg', + type: 'image', + }, + { + text: expect.stringContaining(`page.getByRole('button', { name: 'Hello, world!' }).screenshot`), + type: 'text', + }, + ], + }); +});