@executeautomation/playwright-mcp-server
Version:
Model Context Protocol servers for Playwright
107 lines (106 loc) • 4.03 kB
JavaScript
import { BrowserToolBase } from './base.js';
import { createSuccessResponse, createErrorResponse } from '../common/types.js';
import { resetBrowserState } from '../../toolHandler.js';
/**
* Tool for navigating to URLs
*/
export class NavigationTool extends BrowserToolBase {
/**
* Execute the navigation tool
*/
async execute(args, context) {
// Check if browser is available
if (!context.browser || !context.browser.isConnected()) {
// If browser is not connected, we need to reset the state to force recreation
resetBrowserState();
return createErrorResponse("Browser is not connected. The connection has been reset - please retry your navigation.");
}
// Check if page is available and not closed
if (!context.page || context.page.isClosed()) {
return createErrorResponse("Page is not available or has been closed. Please retry your navigation.");
}
return this.safeExecute(context, async (page) => {
try {
await page.goto(args.url, {
timeout: args.timeout || 30000,
waitUntil: args.waitUntil || "load"
});
return createSuccessResponse(`Navigated to ${args.url}`);
}
catch (error) {
const errorMessage = error.message;
// Check for common disconnection errors
if (errorMessage.includes("Target page, context or browser has been closed") ||
errorMessage.includes("Target closed") ||
errorMessage.includes("Browser has been disconnected")) {
// Reset browser state to force recreation on next attempt
resetBrowserState();
return createErrorResponse(`Browser connection issue: ${errorMessage}. Connection has been reset - please retry your navigation.`);
}
// For other errors, return the standard error
throw error;
}
});
}
}
/**
* Tool for closing the browser
*/
export class CloseBrowserTool extends BrowserToolBase {
/**
* Execute the close browser tool
*/
async execute(args, context) {
if (context.browser) {
try {
// Check if browser is still connected
if (context.browser.isConnected()) {
await context.browser.close().catch(error => {
console.error("Error while closing browser:", error);
});
}
else {
console.error("Browser already disconnected, cleaning up state");
}
}
catch (error) {
console.error("Error during browser close operation:", error);
// Continue with resetting state even if close fails
}
finally {
// Always reset the global browser and page references
resetBrowserState();
}
return createSuccessResponse("Browser closed successfully");
}
return createSuccessResponse("No browser instance to close");
}
}
/**
* Tool for navigating back in browser history
*/
export class GoBackTool extends BrowserToolBase {
/**
* Execute the go back tool
*/
async execute(args, context) {
return this.safeExecute(context, async (page) => {
await page.goBack();
return createSuccessResponse("Navigated back in browser history");
});
}
}
/**
* Tool for navigating forward in browser history
*/
export class GoForwardTool extends BrowserToolBase {
/**
* Execute the go forward tool
*/
async execute(args, context) {
return this.safeExecute(context, async (page) => {
await page.goForward();
return createSuccessResponse("Navigated forward in browser history");
});
}
}