Skip to main content
Glama

browser_endtoend

Run end-to-end browser tests using LLMs with Playwright's accessibility tree to validate test cases efficiently.

Instructions

Run an end to end test suit in the browser

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
testDefinitionYesThe test case definition

Implementation Reference

  • Primary handler for 'browser_endtoend' tool. Orchestrates E2E testing using GPT-4o AI agent with browser sub-tools like navigate, click, screenshot, etc., based on testDefinition input.
    export const limetest: Tool = { schema: { name: 'browser_endtoend', description: 'Run an end to end test suit in the browser', inputSchema: zodToJsonSchema(limetestSchema) }, handle: async (context, params) => { const validatedParams = limetestSchema.parse(params); const content = `${systemMessage} - List of Urls in target for end to end testing : ${JSON.stringify(validatedParams)}`; const apiKey = context.apiKey; process.env.OPENAI_API_KEY = apiKey; while (true) { const result = generateText({ model: openai('gpt-4o'), messages: [{ role: 'system', content: content }], tools: { // snapshot tools snapshot: tool({ description: 'Capture accessibility snapshot of the current page, this is better than screenshot', parameters: z.object({}), execute: async () => { return await snapshot.snapshot.handle(context); } }), clickSnapshot: tool({ description: 'Perform click on a web page', parameters: snapshot.elementSchema, execute: async (params: z.infer<typeof snapshot.elementSchema>) => { const validatedParams = snapshot.elementSchema.parse(params); return await snapshot.click.handle(context, validatedParams, true); } }), dragSnapshot: tool({ description: 'Perform drag and drop between two elements', parameters: snapshot.dragSchema, execute: async (params: z.infer<typeof snapshot.dragSchema>) => { const validatedParams = snapshot.dragSchema.parse(params); return await snapshot.drag.handle(context, validatedParams, true); } }), hoverSnapshot: tool({ description: 'Hover over element on page', parameters: snapshot.elementSchema, execute: async (params: z.infer<typeof snapshot.elementSchema>) => { const validatedParams = snapshot.elementSchema.parse(params); return await snapshot.hover.handle(context, validatedParams, true); } }), typeSnapshot: tool({ description: 'Type text into editable element', parameters: snapshot.typeSchema, execute: async (params: z.infer<typeof snapshot.typeSchema>) => { const validatedParams = snapshot.typeSchema.parse(params); return await snapshot.type.handle(context, validatedParams, true); } }), selectOptionSnapshot: tool({ description: 'Select an option in a dropdown', parameters: snapshot.selectOptionSchema, execute: async (params: z.infer<typeof snapshot.selectOptionSchema>) => { const validatedParams = snapshot.selectOptionSchema.parse(params); return await snapshot.selectOption.handle(context, validatedParams, true); } }), // screenshot tools screenshot: tool({ description: 'Take a screenshot of the current page', parameters: z.object({}), execute: async () => { return await screenshot.screenshot.handle(context); } }), moveMouseVision: tool({ description: 'Move mouse to a given position', parameters: screenshot.moveMouseSchema, execute: async (params: z.infer<typeof screenshot.moveMouseSchema>) => { const validatedParams = screenshot.moveMouseSchema.parse(params); return await screenshot.moveMouse.handle(context, validatedParams); } }), clickVision: tool({ description: 'Click on a web page', parameters: screenshot.clickVisionkSchema, execute: async (params: z.infer<typeof screenshot.clickVisionkSchema>) => { const validatedParams = screenshot.clickVisionkSchema.parse(params); return await screenshot.clickVision.handle(context, validatedParams); } }), dragVision: tool({ description: 'Drag and drop between two elements', parameters: screenshot.dragVisionkSchema, execute: async (params: z.infer<typeof screenshot.dragVisionkSchema>) => { const validatedParams = screenshot.dragVisionkSchema.parse(params); return await screenshot.dragVision.handle(context, validatedParams); } }), typeVision: tool({ description: 'Type text into editable element', parameters: screenshot.typeVisionkSchema, execute: async (params: z.infer<typeof screenshot.typeVisionkSchema>) => { const validatedParams = screenshot.typeVisionkSchema.parse(params); return await screenshot.typeVision.handle(context, validatedParams); } }), // common tools navigate: tool({ description: 'Navigate to a URL', parameters: common.navigateSchema, execute: async (params: z.infer<typeof common.navigateSchema>) => { const validatedParams = common.navigateSchema.parse(params); return await common.navigate(true).handle(context, validatedParams); } }), goBack: tool({ description: 'Go back to the previous page', parameters: common.goBackSchema, execute: async (params: z.infer<typeof common.goBackSchema>) => { return await common.goBack(true).handle(context); } }), goForward: tool({ description: 'Go back to the previous page', parameters: common.goForwardSchema, execute: async (params: z.infer<typeof common.goBackSchema>) => { return await common.goForward(true).handle(context); } }), wait: tool({ description: 'Wait for a specified time in seconds', parameters: common.waitSchema, execute: async (params: z.infer<typeof common.waitSchema>) => { const validatedParams = common.waitSchema.parse(params); return await common.wait.handle(context, validatedParams, true); } }), pressKey: tool({ description: 'Press a key on the keyboard', parameters: common.pressKeySchema, execute: async (params: z.infer<typeof common.pressKeySchema>) => { const validatedParams = common.pressKeySchema.parse(params); return await common.pressKey.handle(context, validatedParams, true); } }), pdf: tool({ description: 'Save page as PDF', parameters: common.pdfSchema, execute: async (params: z.infer<typeof common.pdfSchema>) => { const validatedParams = common.pdfSchema.parse(params); return await common.pdf.handle(context, validatedParams, true); } }), close: tool({ description: 'Close the page', parameters: common.closeSchema, execute: async (params: z.infer<typeof common.closeSchema>) => { const validatedParams = common.closeSchema.parse(params); return await common.close.handle(context, validatedParams, true); } }), chooseFile: tool({ description: 'Choose one or multiple files to upload', parameters: common.chooseFileSchema, execute: async (params: z.infer<typeof common.chooseFileSchema>) => { const validatedParams = common.chooseFileSchema.parse(params); return await common.chooseFile(true).handle(context, validatedParams); } }) }, maxSteps: 5 }); let fullResponse = ''; for await (const delta of (await result).text) fullResponse += delta; return { content: [{ type: 'text', text: fullResponse }] }; } } };
  • Zod schema defining input for browser_endtoend tool: a string testDefinition.
    const limetestSchema = z.object({ testDefinition: z.string().describe('The test case definition'), // expect: z.string().optional().describe('The expected result of running the test case') });
  • Registers the browser_endtoend tool by importing limetest.limetest and including it in the tools array for the MCP server.
    import { createServerWithTools } from './server'; import * as limetest from '@limetest/limetest'; import { console } from '@limetest/core'; import type { Tool } from '@limetest/core'; import type { Resource } from '@limetest/core'; import type { Server } from '@modelcontextprotocol/sdk/server/index.js'; import type { LaunchOptions } from 'playwright'; const limetestTools: Tool[] = [ limetest.limetest ]; // const commonTools: Tool[] = [ // common.pressKey, // common.wait, // common.pdf, // common.close, // ]; // const snapshotTools: Tool[] = [ // common.navigate(true), // common.goBack(true), // common.goForward(true), // common.chooseFile(true), // snapshot.snapshot, // snapshot.click, // snapshot.drag, // snapshot.hover, // snapshot.type, // snapshot.selectOption, // snapshot.screenshot, // ...commonTools, // ]; // const screenshotTools: Tool[] = [ // common.navigate(false), // common.goBack(false), // common.goForward(false), // common.chooseFile(false), // screenshot.screenshot, // screenshot.moveMouse, // screenshot.click, // screenshot.drag, // screenshot.type, // ...commonTools, // ]; const resources: Resource[] = [ console, ]; type Options = { userDataDir?: string; launchOptions?: LaunchOptions; cdpEndpoint?: string; // vision?: boolean; // endtoend?: boolean; apiKey?: string; }; const packageJSON = require('../package.json'); export function createServer(options?: Options): Server { // const tools = options?.endtoend ? qaTools : (options?.vision ? screenshotTools : snapshotTools); const tools = limetestTools; return createServerWithTools({ name: 'Playwright', version: packageJSON.version, tools, resources, userDataDir: options?.userDataDir ?? '', launchOptions: options?.launchOptions, cdpEndpoint: options?.cdpEndpoint, apiKey: options?.apiKey, }); }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/m2rads/limetest'

If you have feedback or need assistance with the MCP directory API, please join our Discord server