Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Use Selenium’s JavaScript binding, call await driver.takeScreenshot(), and write the returned Base64 string with Node’s base64 encoding. For one element, locate it and call await element.takeScreenshot(true). The examples below install the current package, save valid PNG files, explain capture scope and remote-browser behavior, and show how to avoid common failures.
What Selenium returns
Selenium’s WebDriver API defines takeScreenshot() as a screenshot of the current page. In JavaScript, the method resolves to a Base64-encoded PNG string, not a data-URL and not UTF-8 text. The documented best-effort order is:
- the entire page, when the browser can provide it;
- the current browser window;
- the visible portion of the current frame; and
- the entire display containing the browser.
Because the result is Base64, pass 'base64' to Node’s file-writing function. Omitting that argument creates a corrupt image or writes the encoded characters instead of PNG bytes.
Prerequisites and installation
- Node.js 22 or newer, as required by the current official Selenium JavaScript API page.
- A supported browser such as Chrome and a matching WebDriver setup. Selenium Manager can obtain drivers for many local configurations; a remote Selenium server can also be used.
- A project directory with permission to create the output file.
mkdir selenium-shots
cd selenium-shots
npm init -y
npm install selenium-webdriver
The npm package version and download counts change over time, so pin a version in production after reviewing the version your project has validated.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches#1 Best Overall
Capture and save a page screenshot
This complete script opens a page, captures the current browsing context, writes screenshot.png, and always closes the browser.
const { Builder, Browser } = require('selenium-webdriver');
const fs = require('node:fs');
(async function saveScreenshot() {
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.build();
try {
await driver.get('https://example.com');
const encoded = await driver.takeScreenshot();
fs.writeFileSync('./screenshot.png', encoded, 'base64');
console.log('Saved ./screenshot.png');
} finally {
await driver.quit();
}
})();
Save it as page-shot.js and run node page-shot.js. The file is a regular PNG that image viewers and CI artifacts can open.
Wait for the page you actually want to capture
driver.get() waits for the navigation to complete, but applications often render important content afterward. Wait for a specific element before taking the shot.
const { Builder, Browser, By, until } = require('selenium-webdriver');
const fs = require('node:fs');
(async function captureReadyPage() {
const driver = await new Builder().forBrowser(Browser.CHROME).build();
try {
await driver.get('https://example.com/dashboard');
const chart = await driver.wait(
until.elementLocated(By.css('[data-testid="sales-chart"]')),
15000
);
await driver.wait(until.elementIsVisible(chart), 10000);
const encoded = await driver.takeScreenshot();
fs.writeFileSync('./dashboard.png', encoded, 'base64');
} finally {
await driver.quit();
}
})();
Use an application-specific readiness signal rather than an arbitrary sleep whenever possible. If a chart animates, wait for its completed state or add a short, measured delay after it becomes visible.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Capture one element
Locate the element and call takeScreenshot(true). The boolean requests a scroll-into-view operation before capture, which is useful for content below the fold.
Rank #2
const { Builder, Browser, By } = require('selenium-webdriver');
const fs = require('node:fs');
(async function saveElementScreenshot() {
const driver = await new Builder().forBrowser(Browser.CHROME).build();
try {
await driver.get('https://example.com');
const heading = await driver.findElement(By.css('h1'));
const encoded = await heading.takeScreenshot(true);
fs.writeFileSync('./heading.png', encoded, 'base64');
} finally {
await driver.quit();
}
})();
Element capture follows the element’s rendered box, including only what the browser can capture for that element. A selector that matches nothing raises a no-such-element error; a hidden or detached element can produce a stale-element or visibility failure.
Control the capture context
Frames
Selenium captures the current frame context. To capture content inside an iframe, switch into it first, capture, then switch back if later steps use the top document.
const frame = await driver.findElement(By.css('iframe.payment'));
await driver.switchTo().frame(frame);
const encoded = await driver.takeScreenshot();
fs.writeFileSync('./frame.png', encoded, 'base64');
await driver.switchTo().defaultContent();
Windows and tabs
A screenshot applies to the active window handle. After opening a tab, switch to its handle before calling the method; otherwise you will capture whichever tab is currently selected.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
const handles = await driver.getAllWindowHandles();
await driver.switchTo().window(handles[handles.length - 1]);
const encoded = await driver.takeScreenshot();
fs.writeFileSync('./new-tab.png', encoded, 'base64');
Viewport, responsive layout, and pixel density
Set the window size before navigation when visual consistency matters. The exact pixel dimensions and device scale are controlled by the browser and WebDriver environment, so screenshots from local and remote machines can differ.
await driver.manage().window().setRect({ width: 1440, height: 900 });
await driver.get('https://example.com');
Selenium’s screenshot API does not provide a universal “full-page” guarantee across every browser. It asks the driver for the best available result in the order listed earlier. If your test requires a precisely defined long-page image, verify the result on the browser/driver combination used by your pipeline.
Rank #3
Run the same code against a remote Selenium server
Replace the local builder with a remote URL and capabilities appropriate to your Grid or cloud provider. The screenshot still resolves to Base64, so the save code is unchanged.
const { Builder, Browser } = require('selenium-webdriver');
const fs = require('node:fs');
(async function remoteShot() {
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.usingServer('http://localhost:4444/wd/hub')
.build();
try {
await driver.get('https://example.com');
const encoded = await driver.takeScreenshot();
fs.writeFileSync('./remote.png', encoded, 'base64');
} finally {
await driver.quit();
}
})();
With a remote session, the browser runs on the server while the PNG data travels back to your Node process. Network latency and session timeouts therefore affect screenshot duration and reliability.
Reusable screenshot helper
Centralizing file writing makes test code less error-prone and lets you create unique names for parallel runs.
const fs = require('node:fs/promises');
async function savePng(base64, path) {
if (typeof base64 !== 'string' || base64.length === 0) {
throw new Error('WebDriver returned empty screenshot data');
}
await fs.writeFile(path, base64, 'base64');
}
// Example:
// await savePng(await driver.takeScreenshot(), `artifacts/${name}.png`);
Create the artifact directory before writing, sanitize names derived from URLs or test titles, and avoid two workers writing the same path.
Performance, reliability, and cost considerations
- Capture only what you need. An element shot transfers less data than a very tall page and is usually faster.
- Do not screenshot every polling attempt. Capture on failure, at checkpoints, or after a deterministic readiness condition.
- Keep sessions short. Reuse a driver for related steps, but always quit it in a
finallyblock so failed tests do not leak browser processes. - Stabilize rendering. Fix the viewport, fonts, locale, timezone, animation state, and test data when comparing images.
- Budget remote transfer. Remote screenshots consume time and bandwidth in addition to browser execution; retain only the artifacts needed for debugging or review.
- Selenium itself has no screenshot fee. Your costs come from the machine or hosted WebDriver service, storage, and CI runtime.
Troubleshooting common failures
“Cannot find module selenium-webdriver”
Install the dependency in the directory from which the script runs: npm install selenium-webdriver. Confirm that node_modules and package.json are in the current project.
Node version or syntax errors
Use Node.js 22 or newer for the current official JavaScript binding requirements. Check with node --version, then upgrade the runtime used by both your shell and CI job.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Driver or browser session will not start
Verify that Chrome is installed and reachable, that the remote endpoint is correct, and that the server supports the requested browser. In containers, check executable paths, sandbox permissions, and virtual-display configuration.
The PNG is unreadable or contains Base64 text
Write the value with fs.writeFileSync(path, encoded, 'base64') (or the equivalent promise API). Do not prepend a data-URL header and do not use UTF-8 encoding.
The page is blank or incomplete
Wait for a meaningful selector, switch into the correct frame or window, and confirm that authentication and network requests finished. For lazy content, scroll or trigger the application’s own loading condition before capture.
Element screenshot throws an exception
Check that the selector is unique, the element is displayed, and it has not been replaced by a framework render. Locate it again immediately before capture when the DOM is highly dynamic.
Best Value
Different pixels in CI
Use the same browser version, viewport, fonts, locale, timezone, and device configuration. Disable or wait for animations, and compare with a tolerance rather than requiring byte-for-byte identity across different graphics stacks.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo returns a website screenshot or PDF from one GET request. Before the capture it accepts cookie/consent banners and removes more than 60 known consent platforms, 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 identify the page verdict and whether it was billed. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://stripe.com
-o shot.webp
JavaScript:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
See the ScreenshotNeo documentation for output and option details. Every plan includes the features above, including full-page lazy-image loading, element selectors, dark mode, device presets, custom CSS and JavaScript, click and wait actions, request blocking, headers and cookies, geolocation and timezone, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Choosing the right approach
| Need | Best fit | Reason |
|---|---|---|
| Assertions while a test is running | Selenium WebDriver | The browser is already driving the page, so capture the current state directly. |
| One element for a test artifact | element.takeScreenshot(true) |
Produces a focused PNG after scrolling the element into view. |
| Standalone URLs, PDFs, or automated cleanup | ScreenshotNeo | One request handles capture and removes common consent UI before billing only clean results. |
| AI-agent initiated captures | ScreenshotNeo MCP server | Tools are available to MCP clients such as Claude and Cursor. |
FAQ
Can Selenium save JPEG or WebP?
The JavaScript WebDriver screenshot method documented here returns a Base64-encoded PNG. Convert the PNG afterward if another image format is required.
Does takeScreenshot() capture browser chrome?
No. It captures the page or browser display area according to the WebDriver implementation, not operating-system menus or other applications.
Can I capture a screenshot before quitting the driver?
Yes. Capture and write the file while the session is active, then call quit() in cleanup.
Frequently Asked Questions
Can Selenium save JPEG or WebP?
The JavaScript WebDriver screenshot method returns a Base64-encoded PNG. Convert the PNG afterward if another image format is required.
Does takeScreenshot() capture browser chrome?
No. It captures the page or browser display area according to the WebDriver implementation, not operating-system menus or other applications.
Free tools Windows power users keep installed
One-click scans. No signup required.
Can I capture a screenshot before quitting the driver?
Yes. Capture and write the file while the session is active, then call quit() in cleanup.
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.

