Authors browser automation scripts using Puppeteer - Chrome / Chromium-only headless / headed automation, Page object via `page.*` API, network interception, PDF generation, screenshot capture, scraping. Distinct from Playwright (Puppeteer's older sibling, Chrome-only) - use Puppeteer for Chrome-only browser automation tasks (scraping, generating PDFs from HTML, screenshot pipelines) where Playwright's multi-browser support is unneeded overhead. Use when a project already depends on `puppeteer` / `puppeteer-core`, or when a Chrome-only script must emit PDFs, screenshots, or scraped data rather than assert on a page.
79
99%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
High
Do not use without reviewing
Puppeteer controls Chrome / Chromium via the DevTools Protocol - a lightweight fit (no bundled test runner) for Chrome-only browser automation beyond E2E testing: scraping, PDF generation, screenshot pipelines, web crawling.
For E2E testing specifically: Playwright is the recommended successor. Migration is mostly mechanical (similar API).
npm install --save-dev puppeteer
# Auto-downloads matching Chromium
# Or for Chrome-bring-your-own:
npm install --save-dev puppeteer-corepuppeteer (full) bundles Chromium; puppeteer-core (lite) lets
you point at an existing Chrome.
Verify: npm ls puppeteer lists the installed version. If you installed
puppeteer-core, no Chromium is bundled - pass executablePath at launch
or the next step throws Could not find Chromium.
// scripts/screenshot.js
import puppeteer from 'puppeteer';
(async () => {
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'example.png', fullPage: true });
await browser.close();
})();The page.* API mirrors Playwright's: page.goto, page.click,
page.type, page.evaluate, etc.
Verify: after running, example.png exists and is non-empty. If it is
missing or the script threw Could not find Chromium, the bundled download
was skipped - reinstall puppeteer or set executablePath, confirm
headless: 'new', then re-run.
// __tests__/checkout.test.js
import puppeteer from 'puppeteer';
let browser, page;
beforeAll(async () => {
browser = await puppeteer.launch({ headless: 'new' });
});
beforeEach(async () => {
page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
});
afterEach(async () => {
await page.close();
});
afterAll(async () => {
await browser.close();
});
test('checkout flow', async () => {
await page.goto('http://localhost:3000/login');
await page.type('[data-testid=email]', 'user@example.com');
await page.type('[data-testid=password]', 'pwd');
await page.click('button[type=submit]');
await page.waitForSelector('h1');
const heading = await page.$eval('h1', el => el.textContent);
expect(heading).toContain('Welcome');
}, 60000);Beyond the core automation and E2E spine above, Puppeteer covers network interception, server-side PDF generation, multi-viewport screenshot pipelines, and scraping. Copy-paste recipes for each: references/use-cases.md.
node scripts/screenshot.js
# Or as part of test suite
npx jestWhen ready to migrate:
// Puppeteer
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Playwright equivalent
const browser = await chromium.launch();
const page = await browser.newPage();The APIs are similar; mechanical find-replace covers most cases. Playwright adds: cross-browser, web-first assertions, trace viewer, codegen - net win unless Chrome-only is intentional.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Using Puppeteer for cross-browser E2E | Chrome-only; misses Firefox / Safari regressions. | Playwright for cross-browser. |
Forgetting browser.close() | Browser process leaks; CI runner OOM. | afterAll cleanup (Step 3). |
page.waitFor(2000) | Flaky; deprecated. | page.waitForSelector / waitForFunction. |
| Running headed in CI | No display; crashes. | headless: 'new' (Step 2). |
puppeteer-core without specifying executable | "browser not found" errors. | Use puppeteer (bundled) OR specify executablePath. |
waitForSelector patterns.pptr.dev.playwright-testing -
recommended successor.testcafe-testing - alternative
Chrome-friendly E2E.