Claude Skills Guide

Claude Code for Browser Automation Workflow Guide

Browser automation has become an essential skill for developers, enabling automated testing, web scraping, form submission, and end-to-end workflow validation. Claude Code, combined with the Playwright Model Context Protocol (MCP) server, provides a powerful framework for building reliable browser automation workflows. This guide walks you through setting up browser automation, creating reusable skills, and implementing best practices for production-ready automation.

Setting Up Your Browser Automation Environment

Before building automation workflows, you need to configure Claude Code with the Playwright MCP server. This integration gives Claude direct control over headless browsers for various automation tasks.

First, install the Playwright MCP server using npm:

npm install -g @modelcontextprotocol/server-playwright

Next, configure your Claude Code settings to include the Playwright MCP server. Add the following to your MCP configuration file:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@modelcontextprotocol/server-playwright"]
    }
  }
}

Once configured, Claude Code gains access to browser automation tools including playwright_navigate, playwright_screenshot, playwright_click, playwright_fill, and playwright_evaluate. These tools form the foundation of your automation workflows.

Creating a Reusable Browser Automation Skill

The power of Claude Code lies in creating reusable skills that encapsulate browser automation patterns. A well-designed skill should handle initialization, common operations, and cleanup while exposing clear interfaces for specific tasks.

Here’s a basic browser automation skill structure:

---
name: web-scraper
description: "Extract data from web pages using Playwright automation"
---

# Web Scraper Skill

This skill handles web scraping tasks with configurable selectors and data extraction.

## Available Actions

- Navigate to target URLs
- Wait for dynamic content to load
- Extract data using CSS or XPath selectors
- Save results to specified output files

## Usage Examples

For simple text extraction, provide the URL and a descriptive selector:
- "Scrape the product titles from example.com/products"
- "Extract all article headlines from the news section"

For complex pages requiring interaction:
- "Fill out the search form on site.com and extract results"
- "Navigate through pagination and collect all listings"

This skill structure demonstrates the key principles: clear tool declaration, documented actions, and practical usage examples that help Claude understand when and how to apply the skill.

Building Common Automation Workflows

Browser automation tasks typically follow patterns that can be abstracted into reusable workflows. Let’s explore three common scenarios and how to implement them effectively with Claude Code.

Form Submission Automation

Form automation requires careful sequencing of actions: navigation, waiting for form load, filling fields, and submitting. The key challenge is handling dynamic content and validation:

// Example: Automated form submission workflow
async function fillAndSubmitForm(page, formConfig) {
  await page.goto(formConfig.url);
  
  // Wait for form to be ready
  await page.waitForSelector(formConfig.selector);
  
  // Fill each field with type-appropriate method
  for (const [field, value] of Object.entries(formConfig.fields)) {
    const inputType = await page.getAttribute(`[name="${field}"]`, 'type');
    
    if (inputType === 'checkbox') {
      await page.check(`[name="${field}"]`);
    } else if (inputType === 'select') {
      await page.select(`[name="${field}"]`, value);
    } else {
      await page.fill(`[name="${field}"]`, value);
    }
  }
  
  // Submit and handle response
  await page.click(formConfig.submitButton);
  await page.waitForNavigation();
  
  return await page.url();
}

When working with Claude Code, you can describe this workflow naturally: “Fill out the contact form on example.com/contact using the data from my contacts.json file, then verify the confirmation message appears.”

Web Scraping with Dynamic Content

Modern web applications load content dynamically via JavaScript, requiring waiting strategies rather than simple navigation. Claude Code’s playwright_evaluate tool executes custom JavaScript in the browser context, enabling sophisticated data extraction:

// Extract data from dynamic content
const productData = await page.evaluate(() => {
  const products = document.querySelectorAll('.product-card');
  return Array.from(products).map(product => ({
    title: product.querySelector('.title')?.textContent,
    price: product.querySelector('.price')?.textContent,
    rating: product.querySelector('.rating')?.dataset.value
  }));
});

For scraping tasks, provide Claude with clear extraction patterns: “Extract all job listings from the results table on example.com/jobs, including title, company, location, and date posted.”

End-to-End Testing Workflows

Browser automation excels at testing complex user flows. Create skills that encapsulate testing logic:

---
name: e2e-tester
description: "Run end-to-end tests on web applications"
---

# E2E Tester Skill

Execute end-to-end tests and validate application behavior.

## Testing Workflow

1. Navigate to the starting URL
2. Execute user interactions
3. Validate expected states
4. Capture evidence on failure

## Validation Examples

- "Test the checkout flow: add item to cart, proceed to checkout, fill shipping info, and verify order confirmation appears"
- "Verify the login flow: enter credentials, submit, and confirm dashboard loads with user name displayed"

Best Practices for Production Automation

Building reliable browser automation requires addressing common failure modes and implementing robust error handling.

Always implement explicit waits rather than arbitrary delays. Instead of sleep(5000), use waitForSelector or waitForFunction to wait for specific conditions:

// Prefer explicit waits
await page.waitForSelector('.loaded-content', { state: 'visible' });

// Over arbitrary delays
// await sleep(5000); // Avoid this approach

Handle authentication state thoughtfully. For workflows requiring login, persist authentication cookies rather than repeating login steps:

// Save authentication state
const state = await context.storageState();
await writeFile('auth-state.json', JSON.stringify(state));

// Restore for subsequent runs
const context = await browser.newContext({
  storageState: 'auth-state.json'
});

Implement retry logic for flaky operations. Network requests and dynamic content may fail intermittently:

async function retryOperation(operation, maxAttempts = 3) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await operation();
    } catch (error) {
      if (attempt === maxAttempts) throw error;
      await sleep(1000 * attempt); // Exponential backoff
    }
  }
}

Capture evidence on failure. Screenshots and page state dumps help diagnose automation failures:

try {
  await performAction();
} catch (error) {
  await page.screenshot({ path: `failure-${Date.now()}.png`, fullPage: true });
  const html = await page.content();
  await writeFile(`page-state-${Date.now()}.html`, html);
  throw error;
}

Conclusion

Browser automation with Claude Code combines natural language processing with powerful browser control, enabling developers to automate complex web interactions through descriptive commands. By setting up the Playwright MCP server, creating reusable skills, implementing robust workflows, and following production best practices, you can build reliable automation that handles real-world web scenarios effectively.

Start with simple workflows, validate their reliability, then gradually add complexity. The key is treating browser automation as a skill-building practice: each automation task teaches you something about both the target application and the automation framework itself.

Built by theluckystrike — More at zovo.one