Playwright MCP Server
Playwright MCP Server
Section titled “Playwright MCP Server”The Playwright MCP server provides powerful browser automation capabilities, enabling you to test web applications, take screenshots, interact with web pages, and perform comprehensive end-to-end testing.
Overview
Section titled “Overview”This server enables comprehensive browser automation including:
- Multi-browser testing (Chromium, Firefox, Safari)
- Page navigation and interaction
- Screenshot and video capture
- Network request monitoring
- Mobile device emulation
- Accessibility testing
Available Functions
Section titled “Available Functions”Browser Management
Section titled “Browser Management”// Navigate to a URLawait browserNavigate({ url: "https://example.com" })
// Go back to previous pageawait browserNavigateBack()
// Resize browser windowawait browserResize({ width: 1920, height: 1080 })
// Close browser sessionawait browserClose()Page Interaction
Section titled “Page Interaction”// Click on elementsawait browserClick({element: "Login button",ref: "button[type='submit']"})
// Type text into inputsawait browserType({element: "Email input",ref: "input[name='email']",submit: false})
// Press keyboard keysawait browserPressKey({ key: "Enter" })// Fill multiple form fieldsawait browserFillForm({fields: [ { name: "Email", type: "textbox", ref: "input[name='email']", }, { name: "Subscribe to newsletter", type: "checkbox", ref: "input[name='newsletter']", value: "true" }, { name: "Country", type: "combobox", ref: "select[name='country']", value: "United States" }]})
// Select dropdown optionsawait browserSelectOption({element: "Country selector",ref: "select[name='country']",values: ["US"]})// Drag and dropawait browserDrag({startElement: "Draggable item",startRef: ".draggable-item",endElement: "Drop zone",endRef: ".drop-zone"})
// Hover over elementsawait browserHover({element: "Menu item",ref: ".menu-item"})
// Handle file uploadsawait browserFileUpload({paths: ["/path/to/file.pdf", "/path/to/image.jpg"]})Screenshots & Capture
Section titled “Screenshots & Capture”// Take full page screenshotawait browserTakeScreenshot({fullPage: true,filename: "homepage-full.png",type: "png"})
// Screenshot specific elementawait browserTakeScreenshot({element: "Main content area",ref: ".main-content",filename: "content-area.jpg",type: "jpeg"})
// Get page accessibility snapshotawait browserSnapshot()Monitoring & Debugging
Section titled “Monitoring & Debugging”// Get console messagesawait browserConsoleMessages()
// Monitor network requestsawait browserNetworkRequests()
// Handle dialogs (alerts, confirms, prompts)await browserHandleDialog({accept: true,promptText: "User input text"})
// Wait for conditionsawait browserWaitFor({text: "Loading complete",time: 5})Usage Examples
Section titled “Usage Examples”Complete end-to-end test workflow:
// Test user authentication flowawait browserNavigate({ url: "http://localhost:4321/login" })
// Fill login formawait browserFillForm({fields: [ { name: "Email", type: "textbox", ref: "input[name='email']", }, { name: "Password", type: "textbox", ref: "input[name='password']", value: "password123" }]})
// Submit formawait browserClick({element: "Login button",ref: "button[type='submit']"})
// Wait for redirectawait browserWaitFor({ text: "Dashboard", time: 10 })
// Take screenshot of successful loginawait browserTakeScreenshot({filename: "dashboard-after-login.png",fullPage: true})
// Verify user is logged inconst snapshot = await browserSnapshot()// Check if user navigation is visible in snapshotCompare visual changes across deployments:
// Navigate to pageawait browserNavigate({ url: "https://your-site.netlify.app" })
// Set consistent viewportawait browserResize({ width: 1920, height: 1080 })
// Take baseline screenshotawait browserTakeScreenshot({filename: "homepage-baseline.png",fullPage: true})
// Test different screen sizesconst viewports = [{ width: 375, height: 667 }, // iPhone SE{ width: 768, height: 1024 }, // iPad{ width: 1440, height: 900 } // Desktop]
for (const viewport of viewports) {await browserResize(viewport)await browserTakeScreenshot({ filename: `homepage-${viewport.width}x${viewport.height}.png`, fullPage: true})}Monitor performance and network activity:
// Navigate and monitor networkawait browserNavigate({ url: "https://your-site.com" })
// Get network requests after page loadconst networkRequests = await browserNetworkRequests()
// Analyze performanceconst largeImages = networkRequests.filter(req =>req.resourceType === 'image' && req.responseSize > 100000)
const slowRequests = networkRequests.filter(req =>req.duration > 2000)
console.log(`Found ${largeImages.length} large images`)console.log(`Found ${slowRequests.length} slow requests`)
// Check console for errorsconst consoleMessages = await browserConsoleMessages()const errors = consoleMessages.filter(msg => msg.type === 'error')
if (errors.length > 0) {console.log('Console errors detected:', errors)
// Take screenshot for debuggingawait browserTakeScreenshot({ filename: "error-state.png", fullPage: true})}Integration with astro-basics
Section titled “Integration with astro-basics”// Test astro-basics specific features// 1. Test comment systemawait browserNavigate({ url: "http://localhost:4321/posts/example-post" })
// Scroll to comments sectionawait browserEvaluate({function: "() => document.querySelector('.comments-section').scrollIntoView()"})
// Test comment submission (requires authentication)await browserClick({element: "Comment textarea",ref: "textarea[name='comment']"})
await browserType({element: "Comment textarea",ref: "textarea[name='comment']",text: "This is a test comment"})
await browserClick({element: "Submit comment button",ref: "button[type='submit']"})
// 2. Test dashboard authenticationawait browserNavigate({ url: "http://localhost:4321/dashboard" })
// Should redirect to sign-in if not authenticatedawait browserWaitFor({ text: "Sign In", time: 5 })
// 3. Test component interactivityawait browserNavigate({ url: "http://localhost:4321" })
// Test navigation menuawait browserClick({element: "Navigation menu toggle",ref: ".menu-toggle"})
await browserTakeScreenshot({filename: "mobile-menu-open.png"})Best Practices
Section titled “Best Practices”Test Reliability
Section titled “Test Reliability”// Good: Wait for specific conditionsawait browserWaitFor({ text: "Data loaded", time: 10 })
// Good: Use stable selectorsawait browserClick({element: "Submit button",ref: "[data-testid='submit-btn']"})
// Avoid: Fixed delays// await new Promise(resolve => setTimeout(resolve, 3000))
// Avoid: Fragile selectors// ref: ".btn.btn-primary.large"Performance Optimization
Section titled “Performance Optimization”// Optimize for faster tests// 1. Reuse browser sessions when possible// 2. Use headless mode for CI/CD// 3. Disable unnecessary features for speed
// Example: Minimal browser setup for CIconst browserOptions = {headless: true,args: [ '--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu', '--disable-extensions']}Debugging Failed Tests
Section titled “Debugging Failed Tests”// Capture debugging information on failuretry {await browserClick({ element: "Submit button", ref: "button[type='submit']"})} catch (error) {// Take screenshot of current stateawait browserTakeScreenshot({ filename: "test-failure-screenshot.png", fullPage: true})
// Get console errorsconst console = await browserConsoleMessages()console.log('Console messages:', console)
// Get page snapshot for analysisconst snapshot = await browserSnapshot()console.log('Page snapshot:', snapshot)
throw error // Re-throw to fail the test}Limitations
Section titled “Limitations”- Browser Installation: Requires Playwright browsers to be installed
- Resource Usage: Browser automation is memory and CPU intensive
- Network Dependency: Tests require stable network connectivity
- Platform Differences: Some behaviors may vary across operating systems
Security Considerations
Section titled “Security Considerations”Related Resources
Section titled “Related Resources”- IDE Server - For development environment integration
- Web Tools Server - For web content fetching
- MCP Examples - See complete testing workflows
Troubleshooting
Section titled “Troubleshooting”Browser fails to start:
- Run
npx playwright installto install browser binaries - Check system requirements for your operating system
- Try running in headless mode if display issues occur
Element not found errors:
- Use
await browserSnapshot()to see current page state - Verify element selectors with browser developer tools
- Add waits for dynamic content to load
Tests are flaky:
- Add explicit waits for asynchronous operations
- Use more specific element selectors
- Handle network delays and loading states properly