Agent skill

chrome

Browser automation using Puppeteer or Playwright. Use for web testing, screenshots, form filling, and automated browser interactions.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/testing/chrome-johnlindquist-claude

SKILL.md

Chrome Automation

Automate browser interactions using Puppeteer or Playwright.

Prerequisites

bash
# Puppeteer
npm install puppeteer

# Or Playwright
npm install playwright
npx playwright install chromium

Puppeteer Quick Start

Basic Script

javascript
// script.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'screenshot.png' });
  await browser.close();
})();

Run: node script.js

With Visible Browser

javascript
const browser = await puppeteer.launch({
  headless: false,
  slowMo: 50,  // Slow down operations
});

Playwright Quick Start

Basic Script

javascript
// script.js
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'screenshot.png' });
  await browser.close();
})();

Common Operations

Navigation

javascript
// Go to URL
await page.goto('https://example.com');

// Wait for navigation
await page.goto('https://example.com', { waitUntil: 'networkidle0' });

// Go back/forward
await page.goBack();
await page.goForward();

// Reload
await page.reload();

Screenshots

javascript
// Full page
await page.screenshot({ path: 'full.png', fullPage: true });

// Specific element
const element = await page.$('#header');
await element.screenshot({ path: 'header.png' });

// With options
await page.screenshot({
  path: 'screenshot.png',
  type: 'png',
  quality: 90,  // For jpeg
  clip: { x: 0, y: 0, width: 800, height: 600 }
});

Click Actions

javascript
// Click element
await page.click('#button');
await page.click('button.submit');

// Double click
await page.dblclick('#item');

// Right click
await page.click('#element', { button: 'right' });

// Click and wait for navigation
await Promise.all([
  page.waitForNavigation(),
  page.click('a.link')
]);

Form Filling

javascript
// Type text
await page.type('#email', 'user@example.com');

// Clear and type
await page.fill('#email', 'user@example.com');  // Playwright
await page.$eval('#email', el => el.value = '');  // Puppeteer clear
await page.type('#email', 'user@example.com');

// Select dropdown
await page.select('#country', 'US');

// Checkbox
await page.check('#agree');  // Playwright
await page.click('#agree');  // Puppeteer

// File upload
await page.setInputFiles('#file', '/path/to/file.pdf');  // Playwright
const input = await page.$('#file');
await input.uploadFile('/path/to/file.pdf');  // Puppeteer

Waiting

javascript
// Wait for selector
await page.waitForSelector('#loaded');

// Wait for text
await page.waitForFunction(() =>
  document.body.textContent.includes('Success')
);

// Wait for navigation
await page.waitForNavigation();

// Wait for network idle
await page.waitForLoadState('networkidle');  // Playwright

// Explicit wait
await page.waitForTimeout(1000);  // Not recommended for production

Extract Data

javascript
// Get text content
const text = await page.textContent('#element');
const text = await page.$eval('#element', el => el.textContent);

// Get attribute
const href = await page.getAttribute('a', 'href');
const href = await page.$eval('a', el => el.href);

// Get multiple elements
const items = await page.$$eval('.item', els =>
  els.map(el => el.textContent)
);

// Get page content
const html = await page.content();

Evaluate JavaScript

javascript
// Run in browser context
const result = await page.evaluate(() => {
  return document.title;
});

// With arguments
const text = await page.evaluate((selector) => {
  return document.querySelector(selector).textContent;
}, '#element');

Testing Patterns

Login Flow

javascript
async function login(page, username, password) {
  await page.goto('https://app.example.com/login');
  await page.fill('#username', username);
  await page.fill('#password', password);
  await page.click('button[type="submit"]');
  await page.waitForSelector('#dashboard');
}

Form Submission Test

javascript
async function testForm(page) {
  await page.goto('https://example.com/form');

  // Fill form
  await page.fill('#name', 'Test User');
  await page.fill('#email', 'test@example.com');
  await page.select('#country', 'US');
  await page.check('#agree');

  // Submit
  await page.click('button[type="submit"]');

  // Verify success
  await page.waitForSelector('.success-message');
  const message = await page.textContent('.success-message');
  console.assert(message.includes('Thank you'));
}

Visual Regression

javascript
// Take baseline
await page.screenshot({ path: 'baseline.png', fullPage: true });

// Later, compare
await page.screenshot({ path: 'current.png', fullPage: true });
// Use image comparison tool

Device Emulation

javascript
// Puppeteer
const iPhone = puppeteer.devices['iPhone 12'];
await page.emulate(iPhone);

// Playwright
const iPhone = playwright.devices['iPhone 12'];
const context = await browser.newContext({ ...iPhone });

// Manual viewport
await page.setViewportSize({ width: 375, height: 812 });

Network

javascript
// Intercept requests (Playwright)
await page.route('**/api/*', route => {
  route.fulfill({ status: 200, body: JSON.stringify({ mocked: true }) });
});

// Block resources
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());

// Monitor requests
page.on('request', req => console.log(req.url()));
page.on('response', res => console.log(res.status(), res.url()));

Best Practices

  1. Use explicit waits - Not timeouts
  2. Handle errors - try/catch important
  3. Close browsers - Always clean up
  4. Use headless for CI - Faster, no display needed
  5. Test selectors - Prefer data-testid
  6. Screenshot on failure - Debug easier
  7. Reuse contexts - Faster than new browsers

Didn't find tool you were looking for?

Be as detailed as possible for better results