Skip to content

Playwright MCP Server

Browser Testing No Auth Required

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.

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
Browser Navigation
// Navigate to a URL
await browserNavigate({ url: "https://example.com" })
// Go back to previous page
await browserNavigateBack()
// Resize browser window
await browserResize({ width: 1920, height: 1080 })
// Close browser session
await browserClose()
User Interactions
// Click on elements
await browserClick({
element: "Login button",
ref: "button[type='submit']"
})
// Type text into inputs
await browserType({
element: "Email input",
ref: "input[name='email']",
submit: false
})
// Press keyboard keys
await browserPressKey({ key: "Enter" })
Screenshots and Snapshots
// Take full page screenshot
await browserTakeScreenshot({
fullPage: true,
filename: "homepage-full.png",
type: "png"
})
// Screenshot specific element
await browserTakeScreenshot({
element: "Main content area",
ref: ".main-content",
filename: "content-area.jpg",
type: "jpeg"
})
// Get page accessibility snapshot
await browserSnapshot()
Monitoring and Debugging
// Get console messages
await browserConsoleMessages()
// Monitor network requests
await browserNetworkRequests()
// Handle dialogs (alerts, confirms, prompts)
await browserHandleDialog({
accept: true,
promptText: "User input text"
})
// Wait for conditions
await browserWaitFor({
text: "Loading complete",
time: 5
})

Complete end-to-end test workflow:

Authentication Flow Test
// Test user authentication flow
await browserNavigate({ url: "http://localhost:4321/login" })
// Fill login form
await browserFillForm({
fields: [
{
name: "Email",
type: "textbox",
ref: "input[name='email']",
},
{
name: "Password",
type: "textbox",
ref: "input[name='password']",
value: "password123"
}
]
})
// Submit form
await browserClick({
element: "Login button",
ref: "button[type='submit']"
})
// Wait for redirect
await browserWaitFor({ text: "Dashboard", time: 10 })
// Take screenshot of successful login
await browserTakeScreenshot({
filename: "dashboard-after-login.png",
fullPage: true
})
// Verify user is logged in
const snapshot = await browserSnapshot()
// Check if user navigation is visible in snapshot
astro-basics Testing
// Test astro-basics specific features
// 1. Test comment system
await browserNavigate({ url: "http://localhost:4321/posts/example-post" })
// Scroll to comments section
await 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 authentication
await browserNavigate({ url: "http://localhost:4321/dashboard" })
// Should redirect to sign-in if not authenticated
await browserWaitFor({ text: "Sign In", time: 5 })
// 3. Test component interactivity
await browserNavigate({ url: "http://localhost:4321" })
// Test navigation menu
await browserClick({
element: "Navigation menu toggle",
ref: ".menu-toggle"
})
await browserTakeScreenshot({
filename: "mobile-menu-open.png"
})
Reliable Test Patterns
// Good: Wait for specific conditions
await browserWaitFor({ text: "Data loaded", time: 10 })
// Good: Use stable selectors
await 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
// 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 CI
const browserOptions = {
headless: true,
args: [
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-extensions'
]
}
Debugging Test Failures
// Capture debugging information on failure
try {
await browserClick({
element: "Submit button",
ref: "button[type='submit']"
})
} catch (error) {
// Take screenshot of current state
await browserTakeScreenshot({
filename: "test-failure-screenshot.png",
fullPage: true
})
// Get console errors
const console = await browserConsoleMessages()
console.log('Console messages:', console)
// Get page snapshot for analysis
const snapshot = await browserSnapshot()
console.log('Page snapshot:', snapshot)
throw error // Re-throw to fail the test
}
  • 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

Browser fails to start:

  • Run npx playwright install to 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