The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →To automate a browser with Puppeteer, install the package, launch a browser, open a page, navigate to a URL, interact with elements using locators, then capture or extract what you need and close the browser. Puppeteer runs headless by default and supports Chrome and Firefox; the exact browser binaries depend on your Puppeteer version.
What Puppeteer does
Puppeteer is a JavaScript library for controlling Chrome or Firefox through the Chrome DevTools Protocol (CDP) or WebDriver BiDi. It can automate browser tasks such as filling forms, clicking controls, running UI tests, capturing screenshots or PDFs, and crawling or prerendering a single-page application. It runs without a visible browser window by default, but you can configure it to show the browser. See the Puppeteer overview.
How do I automate a browser with Puppeteer?
The core workflow is launch, create a page, navigate, act on the page, collect or save the result, and close the browser. This ES module example uses the current recommended locator approach for a basic interaction:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto('https://example.com');
console.log(await page.title());
await page.locator('a').click();
console.log('After click:', page.url());
} finally {
await browser.close();
}
Save it as an .mjs file and run it with Node.js in a project where puppeteer is installed. Replace the example URL and selector with the page and element your task requires. The finally block closes the browser even if a navigation or interaction throws an error.
Recommended Free Tools
#1 Best Overall
Install Puppeteer
For the standard package workflow, install Puppeteer in your project with:
npm install puppeteer
The standard package manages a compatible browser for its workflow. If you use puppeteer-core, you are choosing the library without its usual bundled-browser installation workflow and need to provide a browser executable or connect to a browser yourself. Check the official installation guide for current Node.js requirements and platform setup.
Run visibly when debugging
Headless mode is the default. To see the browser while developing, launch it with headless: false:
const browser = await puppeteer.launch({ headless: false });
Use a visible window to inspect whether the page loads, whether a selector points to the intended element, and whether a dialog or navigation changes the flow.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallHow do I click a button with Puppeteer?
Use a locator for ordinary interactions. Locators wait for an element to exist and check action readiness, including visibility, enabled state, viewport presence, and a stable bounding box before clicking. The interactions guide recommends locators for selecting and interacting with elements.
Rank #2
await page.locator('button[type="submit"]').click();
For a form field, use fill() to set its value:
await page.locator('input[name="email"]').fill('[email protected]');
await page.locator('button[type="submit"]').click();
Choose selectors that survive page changes
Prefer selectors that identify the intended control rather than relying on incidental layout or generated class names. When available, use accessible labels, roles, or text that reflects what a person sees. Puppeteer supports CSS and other selector approaches, including ARIA and text selectors. See the page interactions guide for locator syntax.
A selector such as button.submit-primary-7x2 may break when a site rebuilds its styles. A selector based on a stable form attribute or accessible name is usually easier to understand and maintain.
When to use lower-level APIs
waitForSelector(), ElementHandle, and page-level methods such as page.click(selector) remain available. They can be useful when you need lower-level control, but a wait for a selector does not automatically retry the action that follows it. Dispose of handles when you no longer need them so they do not accumulate and consume memory.
How should I wait for a page to be ready?
Wait for the state your task actually needs, not merely for the URL to change. For example, if a search submission should display results, wait for a result element before reading its text:
await page.locator('button[type="submit"]').click();
await page.locator('[data-testid="search-results"]').wait();
const resultText = await page.locator('[data-testid="search-results"]').map(el => el.textContent).wait();
Adapt the selector to the target site. Puppeteer treats URL changes—including History API changes—as navigation, which is useful for single-page applications, but a URL transition alone does not prove that the content your script needs has rendered. Avoid arbitrary fixed sleeps when a specific element or state can be awaited; a sleep may be too short on a slow response and unnecessarily long on a fast one. See the Puppeteer FAQ for its navigation definition.
How do I take a screenshot with Puppeteer?
Navigate to the page, then call page.screenshot(). This example saves a full-page PNG:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
await browser.close();
}
For just one element, take a screenshot from its locator:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
await page.locator('main').screenshot({ path: 'main.png' });
The page API also supports other image output options. Consult the screenshot API reference for the options available in your installed version.
How do I create a PDF?
Use page.pdf() to create a PDF, for example:
await page.pdf({ path: 'page.pdf', format: 'A4' });
PDF generation uses print CSS media by default. If you need the page’s screen styles instead, switch media before generating the file:
await page.emulateMediaType('screen');
await page.pdf({ path: 'page.pdf', format: 'A4' });
Paper size, margins, landscape orientation, and other PDF options are documented in the PDF API reference.
Rank #4
Does Puppeteer work with Firefox?
Yes. The official FAQ says Puppeteer supports Chrome and Firefox from Puppeteer v23.0.0. Chrome uses CDP by default, while Firefox uses WebDriver BiDi by default. The project describes BiDi support as production-ready for both, while noting that feature support differs between protocols. If your workflow depends on a browser-specific feature, verify it against the protocol and browser you plan to use.
Browser binaries are versioned alongside Puppeteer releases. The documentation’s version 25.12.0 compatibility table maps that release to Chrome for Testing 154.0.8037.57 and Firefox 156.0.1; these are a version-specific snapshot, not permanent browser recommendations. Check the supported browsers table for the release you install before pinning browser versions.
Manage browser binaries when you need a specific version
The @puppeteer/browsers package provides CLI and programmatic browser installation and management. Its CLI can install stable Chrome for Testing:
npx @puppeteer/browsers install chrome@stable
To install a pinned version, specify that version in the install command according to the package’s current CLI syntax. On Linux or macOS, Chrome installation may require unzip; on Windows, the documented utility requirement includes tar.exe. Check the browser management documentation for current requirements and commands.
Common Puppeteer problems and fixes
The browser does not launch
- Check installation and runtime requirements. Confirm that the Node.js version and platform dependencies match the current installation guide.
- Check which browser you are launching. If using
puppeteer-coreor a separately installed browser, provide the correct executable or connection details rather than assuming a managed browser is present. - Check binary compatibility. Use the supported-browser table for your Puppeteer version instead of pinning a browser based on an unrelated release.
A click times out or hits the wrong element
- Verify the selector. Inspect the live page and use a selector tied to the intended control.
- Wait for the task’s actual state. For a dynamic page, wait for the relevant control or result element instead of adding a guessed delay.
- Check overlays and frames. A visible banner, modal, or embedded frame can make an otherwise plausible selector target the wrong context or obstruct the control.
The URL changes but the expected content is missing
On a single-page app, navigation may be a History API or anchor change. Wait for the result element or state your next step depends on, then extract or act.
Best Value
A PDF looks different from the browser window
PDF output uses print media by default. Call page.emulateMediaType('screen') before page.pdf() when you need screen styles.
The process hangs or consumes resources over time
Make sure every launched browser is closed in a finally block. If you retain ElementHandle objects, dispose of them when finished.
Or skip the browser setup
If your goal is to capture a website rather than automate a longer browser workflow, ScreenshotNeo offers a screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF; this cURL example saves a WebP screenshot of Stripe:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for parameters and response details. Cookie banners and consent prompts are accepted and removed before capture, along with known newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo’s free plan.
Performance and cost considerations
Browser automation requires launching or connecting to a real browser and waiting for the page and relevant state to become ready. For repeated tasks, reuse a browser process where the workflow permits, while giving each task an appropriate page and ensuring pages and browsers are closed when done. Avoid adding sleeps that do no useful synchronization; condition-based waits make runs less sensitive to network and rendering variability.
Puppeteer itself does not establish a fixed per-screenshot service cost in this workflow: your costs depend on where you run the browser and the compute resources you allocate. If your requirement is only to fetch screenshots through a service, compare the setup and billing model of an API with running browser infrastructure yourself.
Choosing Chrome or Firefox, and locators or handles
| Choice | Use it when | Trade-off to check |
|---|---|---|
| Chrome with CDP | Your task targets Chrome or needs Chrome-specific CDP behavior. | Confirm the required feature is supported by the Chrome and Puppeteer versions you run. |
| Firefox with WebDriver BiDi | You need to automate Firefox using Puppeteer’s supported BiDi path. | Feature coverage differs by protocol; verify the APIs your workflow depends on. |
| Locators | You want a readable selector and built-in action readiness checks for common interactions. | The target still needs to identify the right element reliably. |
ElementHandle and lower-level APIs |
You need finer-grained control over an element or an existing handle-based workflow. | Manage waits and handle disposal explicitly; selector waiting does not retry a later action. |
Frequently Asked Questions
Can Puppeteer run without opening a browser window?
Yes. Headless execution is the default; set headless: false in puppeteer.launch() when you need a visible browser.
Can I use Puppeteer to capture only part of a page?
Yes. Use an element locator’s screenshot() method to save a screenshot of that element.
Does Puppeteer support single-page applications?
Yes. URL changes caused by History API navigation can count as navigation. Wait for the content your task needs, because a URL transition alone does not ensure that content is ready.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




