
Puppeteer Automation
- 1.6k installs
- 215 repo stars
- Updated June 9, 2026
- mindrally/skills
Puppeteer is a Node.js library providing a high-level API to control Chrome or Chromium over the DevTools Protocol, enabling headless browser automation.
About
Puppeteer is a Node.js library for controlling Chrome or Chromium over the DevTools Protocol, enabling browser automation without a visible UI. Developers use it for web scraping, automated testing, screenshot and PDF generation, and JavaScript execution in headless mode. Core workflows include page navigation with network idle detection, element selection and interaction via CSS/XPath, network request interception, authentication handling, and performance optimization through resource blocking. The skill covers async/await patterns, proper browser lifecycle management, waiting strategies for dynamic content, and error handling with retry logic.
- Page navigation with configurable wait conditions (load, domcontentloaded, networkidle0/2)
- Element selection via CSS selectors, XPath expressions, and page context evaluation
- Screenshot and PDF generation with clipping, quality control, and background rendering
- Network request interception to block resources, modify headers, and monitor responses
- Browser context isolation, multi-page management, and stealth plugin integration for anti-bot bypass
Puppeteer Automation by the numbers
- 1,613 all-time installs (skills.sh)
- +28 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #311 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
puppeteer-automation capabilities & compatibility
- Capabilities
- headless and headful browser launch with configu · page navigation with intelligent wait strategies · element selection and interaction (click, type, · screenshot and pdf generation with formatting op · network request interception and response monito · authentication and cookie management · browser context isolation and multi page coordin
- Works with
- github
- Use cases
- web scraping · testing · debugging · api development
- Platforms
- macOS · Windows · Linux
- Runs
- Runs locally
- Pricing
- Free
npx skills add https://github.com/mindrally/skills --skill puppeteer-automationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.6k |
|---|---|
| repo stars | ★ 215 |
| Security audit | 2 / 3 scanners passed |
| Last updated | June 9, 2026 |
| Repository | mindrally/skills ↗ |
What it does
Automate browser interactions, scrape web content, generate screenshots and PDFs, and test web applications using headless Chrome.
Who is it for?
Web scraping, automated testing, screenshot/PDF generation, network monitoring, JavaScript execution, login automation, form filling.
Skip if: Interactive desktop applications, native mobile automation, low-level browser protocol debugging, real-time user interaction capture.
When should I use this skill?
Need to automate Chrome/Chromium interactions, test web apps headlessly, scrape dynamic content, or generate visual documents.
What you get
Automate browser workflows, extract web data reliably, generate visual outputs, and test applications with headless Chrome instances.
- Automated browser scripts
- scraped data outputs
- screenshots and PDF documents
By the numbers
- Supports headless and headful modes for visible debugging
- Network idle detection includes networkidle0 (zero connections) and networkidle2 (up to 2 connections)
- Multiple waiting strategies: selectors, functions, requests, responses, navigation, fixed timeouts
Files
Puppeteer Browser Automation
You are an expert in Puppeteer, Node.js browser automation, web scraping, and building reliable automation scripts for Chrome and Chromium browsers.
Core Expertise
- Puppeteer API and browser automation patterns
- Page navigation and interaction
- Element selection and manipulation
- Screenshot and PDF generation
- Network request interception
- Headless and headful browser modes
- Performance optimization and memory management
- Integration with testing frameworks (Jest, Mocha)
Key Principles
- Write clean, async/await based code for readability
- Use proper error handling with try/catch blocks
- Implement robust waiting strategies for dynamic content
- Close browser instances properly to prevent memory leaks
- Follow modular design patterns for reusable automation code
- Handle browser context and page lifecycle appropriately
Project Setup
npm init -y
npm install puppeteerBasic Structure
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
try {
const page = await browser.newPage();
await page.goto('https://example.com');
// Your automation code here
} finally {
await browser.close();
}
}
main().catch(console.error);Browser Launch Options
const browser = await puppeteer.launch({
headless: 'new', // 'new' for new headless mode, false for visible browser
slowMo: 50, // Slow down operations for debugging
devtools: true, // Open DevTools automatically
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu',
'--window-size=1920,1080'
],
defaultViewport: {
width: 1920,
height: 1080
}
});Page Navigation
// Navigate to URL
await page.goto('https://example.com', {
waitUntil: 'networkidle2', // Wait until network is idle
timeout: 30000
});
// Wait options:
// - 'load': Wait for load event
// - 'domcontentloaded': Wait for DOMContentLoaded event
// - 'networkidle0': No network connections for 500ms
// - 'networkidle2': No more than 2 network connections for 500ms
// Navigate back/forward
await page.goBack();
await page.goForward();
// Reload page
await page.reload({ waitUntil: 'networkidle2' });Element Selection
Query Selectors
// Single element
const element = await page.$('selector');
// Multiple elements
const elements = await page.$$('selector');
// Wait for element
const element = await page.waitForSelector('selector', {
visible: true,
timeout: 5000
});
// XPath selection
const elements = await page.$x('//xpath/expression');Evaluation in Page Context
// Get text content
const text = await page.$eval('selector', el => el.textContent);
// Get attribute
const href = await page.$eval('a', el => el.getAttribute('href'));
// Multiple elements
const texts = await page.$$eval('.items', elements =>
elements.map(el => el.textContent)
);
// Execute arbitrary JavaScript
const result = await page.evaluate(() => {
return document.title;
});Page Interactions
Clicking
await page.click('button#submit');
// Click with options
await page.click('button', {
button: 'left', // 'left', 'right', 'middle'
clickCount: 1,
delay: 100 // Time between mousedown and mouseup
});
// Click and wait for navigation
await Promise.all([
page.waitForNavigation(),
page.click('a.nav-link')
]);Typing
// Type text
await page.type('input#username', 'myuser', { delay: 50 });
// Clear and type
await page.click('input#username', { clickCount: 3 });
await page.type('input#username', 'newvalue');
// Press keys
await page.keyboard.press('Enter');
await page.keyboard.down('Shift');
await page.keyboard.press('Tab');
await page.keyboard.up('Shift');Form Handling
// Select dropdown
await page.select('select#country', 'us');
// Check checkbox
await page.click('input[type="checkbox"]');
// File upload
const inputFile = await page.$('input[type="file"]');
await inputFile.uploadFile('/path/to/file.pdf');Waiting Strategies
// Wait for selector
await page.waitForSelector('.loaded');
// Wait for selector to disappear
await page.waitForSelector('.loading', { hidden: true });
// Wait for function
await page.waitForFunction(
() => document.querySelector('.count').textContent === '10'
);
// Wait for navigation
await page.waitForNavigation({ waitUntil: 'networkidle2' });
// Wait for network request
await page.waitForRequest(request =>
request.url().includes('/api/data')
);
// Wait for network response
await page.waitForResponse(response =>
response.url().includes('/api/data') && response.status() === 200
);
// Fixed timeout (use sparingly)
await page.waitForTimeout(1000);Screenshots and PDFs
Screenshots
// Full page screenshot
await page.screenshot({
path: 'screenshot.png',
fullPage: true
});
// Element screenshot
const element = await page.$('.chart');
await element.screenshot({ path: 'chart.png' });
// Screenshot options
await page.screenshot({
path: 'screenshot.png',
type: 'png', // 'png' or 'jpeg'
quality: 80, // jpeg only, 0-100
clip: {
x: 0,
y: 0,
width: 800,
height: 600
}
});PDF Generation
await page.pdf({
path: 'document.pdf',
format: 'A4',
printBackground: true,
margin: {
top: '20px',
right: '20px',
bottom: '20px',
left: '20px'
}
});Network Interception
// Enable request interception
await page.setRequestInterception(true);
page.on('request', request => {
// Block images and stylesheets
if (['image', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
// Modify requests
page.on('request', request => {
request.continue({
headers: {
...request.headers(),
'X-Custom-Header': 'value'
}
});
});
// Monitor responses
page.on('response', async response => {
if (response.url().includes('/api/')) {
const data = await response.json();
console.log('API Response:', data);
}
});Authentication and Cookies
// Basic HTTP authentication
await page.authenticate({
username: 'user',
password: 'pass'
});
// Set cookies
await page.setCookie({
name: 'session',
value: 'abc123',
domain: 'example.com'
});
// Get cookies
const cookies = await page.cookies();
// Clear cookies
await page.deleteCookie({ name: 'session' });Browser Context and Multiple Pages
// Create incognito context
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
// Multiple pages
const page1 = await browser.newPage();
const page2 = await browser.newPage();
// Get all pages
const pages = await browser.pages();
// Handle popups
page.on('popup', async popup => {
await popup.waitForLoadState();
console.log('Popup URL:', popup.url());
});Error Handling
async function scrapeWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Set timeout
page.setDefaultTimeout(30000);
await page.goto(url, { waitUntil: 'networkidle2' });
const data = await page.$eval('.content', el => el.textContent);
await browser.close();
return data;
} catch (error) {
console.error(`Attempt ${i + 1} failed:`, error.message);
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 2000 * (i + 1)));
}
}
}Performance Optimization
// Disable unnecessary features
await page.setRequestInterception(true);
page.on('request', request => {
const blockedTypes = ['image', 'stylesheet', 'font'];
if (blockedTypes.includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
// Reuse browser instance
const browser = await puppeteer.launch();
async function scrape(url) {
const page = await browser.newPage();
try {
await page.goto(url);
// ... scraping logic
} finally {
await page.close(); // Close page, not browser
}
}
// Use connection pool for parallel scraping
const cluster = require('puppeteer-cluster');Key Dependencies
- puppeteer
- puppeteer-core (for custom Chrome installations)
- puppeteer-cluster (for parallel scraping)
- puppeteer-extra (for plugins)
- puppeteer-extra-plugin-stealth (anti-detection)
Best Practices
1. Always close browser instances in finally blocks 2. Use waitForSelector before interacting with elements 3. Prefer networkidle2 over networkidle0 for faster loads 4. Use stealth plugin for anti-bot bypass 5. Implement proper error handling and retries 6. Monitor memory usage in long-running scripts 7. Use browser context for isolated sessions 8. Set reasonable timeouts for all operations
Related skills
How it compares
Pick puppeteer-automation when the stack is Node.js with Chromium-only Puppeteer APIs rather than cross-browser Playwright test suites.
FAQ
What is the difference between headless: 'new' and headless: false?
headless: 'new' uses the new headless mode without DevTools emulation; headless: false launches a visible browser window for debugging.
When should I use waitForSelector vs waitForNavigation?
Use waitForSelector for elements appearing on the current page; use waitForNavigation when a click triggers a full page reload or navigation.
How do I prevent memory leaks in long-running Puppeteer scripts?
Close pages (not the browser) after each use, reuse the browser instance across multiple tasks, monitor heap usage, and disable unnecessary resources via request interception.
Is Puppeteer Automation safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.