Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The most dependable browser screenshot script follows a repeatable lifecycle: launch a browser, create an isolated context, navigate, wait for a meaningful application state, capture the viewport, full page, or a specific element, then save or upload the bytes and close every resource. The JavaScript examples below use Playwright, with Cypress and Puppeteer alternatives, CI guidance, masking, deterministic output, and fixes for common failures.

Choose the capture behavior before writing code

Decide what the image will be used for. A viewport screenshot records only the currently visible area. A full-page screenshot captures the complete scrollable document. An element screenshot isolates a locator such as a header, invoice, or order summary. For visual regression, make the browser profile, viewport, fonts, data, and animation state deterministic. For debugging, retain the image with the test report even when the test fails.

  • Viewport: the default screenshot, useful for checking a rendered screen at a known size.
  • Full page: the entire scrollable page, useful for documentation and page-level comparisons.
  • Element: a locator or selector, useful when surrounding navigation is irrelevant.
  • Bytes: omit a file path when an image must be uploaded, hashed, or processed in memory.

Build a complete Playwright screenshot script

Install Playwright in your Node.js project, then install the browser binaries:

npm install -D playwright
npx playwright install

This runnable script sets a fixed viewport, waits for navigation and a meaningful locator, writes a viewport image, writes a full-page image, and captures one element. Create the output directory before running it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
const { chromium } = require('playwright');
const fs = require('fs/promises');

(async () => {
  const outputDir = 'artifacts';
  await fs.mkdir(outputDir, { recursive: true });

  const browser = await chromium.launch();
  const context = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    deviceScaleFactor: 1
  });
  const page = await context.newPage();

  try {
    await page.goto('https://example.com', {
      waitUntil: 'networkidle',
      timeout: 60_000
    });
    await page.locator('h1').waitFor({ state: 'visible', timeout: 15_000 });

    await page.screenshot({ path: `${outputDir}/home.png` });
    await page.screenshot({
      path: `${outputDir}/home-full.png`,
      fullPage: true
    });
    await page.locator('header').screenshot({
      path: `${outputDir}/header.png`
    });
  } finally {
    await page.close();
    await context.close();
    await browser.close();
  }
})();

waitUntil: 'networkidle' is useful for pages that finish loading network requests, but it is not a guarantee that the interface is visually ready. Prefer an application-specific locator, such as a dashboard heading or result row. If animations can change pixels, disable them with a test stylesheet or wait until the animation has finished.

Capture bytes instead of writing a file

Remove path and Playwright returns a buffer. You can send that buffer to object storage, attach it to a test report, or compare it with a baseline.

const image = await page.screenshot({
  type: 'png',
  fullPage: true
});
await uploadToYourStorage(image, 'home-full.png');

Control format and visual variability

  • PNG: lossless and generally the safest choice for pixel comparisons.
  • JPEG or WebP: smaller files when slight compression is acceptable; JPEG quality can be configured.
  • Viewport and scale: set them explicitly so CI and local runs use the same dimensions.
  • Clip: restrict capture to a rectangle when a locator is not suitable.
  • Mask: cover personal data, timestamps, tokens, or other changing regions.
  • Transparent background: use when the output will be composited elsewhere.
await page.screenshot({
  path: 'artifacts/stable.png',
  type: 'png',
  fullPage: true,
  animations: 'disabled',
  mask: [page.locator('[data-testid="timestamp"]')],
  maskColor: '#000000'
});

Use stable test data and deterministic names. Do not overwrite by accident; if replacement is intentional, make that behavior explicit in your test or script.

Wait for the page you actually want to document

Fixed sleeps are fragile: a fast run wastes time, while a slow run still captures an incomplete page. Combine navigation with conditions that represent readiness.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Navigate with a timeout appropriate for your environment.
  2. Wait for a key locator to be visible or attached.
  3. Wait for application data, such as a completed table or chart.
  4. Disable or await CSS and Web Animations when their intermediate frames would change the result.
  5. Only then capture.
await page.goto('https://app.example.test/report', { waitUntil: 'domcontentloaded' });
await page.locator('[data-testid="report-ready"]').waitFor({ state: 'visible' });
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'artifacts/report.png', fullPage: true });

Lazy-loaded images may not exist until they enter the viewport. For a full-page capture, scroll through the page or use a capture service that explicitly loads lazy images. Also ensure web fonts have loaded; otherwise text can reflow after the screenshot.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

Screenshot one element safely

Use a semantic or test-specific locator rather than a brittle positional selector.

const card = page.locator('[data-testid="pricing-card"]').first();
await card.waitFor({ state: 'visible' });
await card.screenshot({
  path: 'artifacts/pricing-card.png',
  animations: 'disabled'
});

If the element is outside the viewport, Playwright scrolls it into view. If it is covered by a modal, sticky header, or cookie banner, close or hide that overlay first. When the element has changing content, mask the changing child locator rather than hiding the entire component.

Use Cypress when screenshots belong to Cypress tests

Cypress stores screenshots in cypress/screenshots by default. It can capture a viewport, full page, runner, or element. This example waits for the checkout summary, blacks out an email field, and deliberately permits replacement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
it('captures the checkout state', () => {
  cy.visit('/checkout');
  cy.get('[data-testid="order-summary"]').should('be.visible');
  cy.screenshot('checkout', {
    capture: 'fullPage',
    blackout: ['[data-testid="email"]'],
    overwrite: true
  });
});

Cypress also supports clipping and padding, plus controls for animations and timers. During cypress run, failure screenshots are captured automatically unless screenshotOnRunFailure is disabled. Keep those images as CI artifacts so a failed assertion has visual evidence.

Use Puppeteer for a minimal Node script

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  try {
    await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
    await page.goto('https://example.com', {
      waitUntil: 'networkidle2',
      timeout: 60_000
    });
    await page.screenshot({
      path: 'artifacts/example.png',
      fullPage: true
    });
  } finally {
    await browser.close();
  }
})();

Puppeteer returns a byte array by default; request an encoding when you specifically need a base64 string. Related page and context operations wait for an in-progress screenshot, so avoid starting competing captures against the same page.

Make screenshots reliable in CI

  • Pin the browser and framework versions used by CI.
  • Use a fixed viewport, device scale factor, timezone, locale, and test data.
  • Install the required browser binaries in the CI image.
  • Wait for meaningful UI state, fonts, images, and animations.
  • Mask secrets, personal data, clocks, random IDs, and live counters.
  • Write to a known directory and upload it as a CI artifact.
  • Retain failure images with the test report, even if the main capture is skipped.
  • Use PNG for visual diffs; choose JPEG or WebP when artifact size matters more than lossless pixels.

For very long pages, full-page images can be large and memory-intensive. Capture a target element or several sections when a single tall image is not needed. If a page changes frequently, compare normalized regions instead of treating every pixel difference as a regression.

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Common failures and fixes

Timeout during navigation

The server may be slow, a request may never finish, or the environment may lack network access. Increase the timeout only after checking the cause, use domcontentloaded when persistent connections prevent network idle, and wait separately for the application-ready locator.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Blank or partially rendered image

The script captured before data, fonts, or lazy images were ready. Wait for a specific result element, await document.fonts.ready, and scroll or otherwise trigger lazy loading before capture.

Element is not visible

The locator may match a hidden duplicate, an unmounted component, or an element behind an overlay. Narrow the locator, wait for visibility, close the overlay, and verify that the element has non-zero dimensions.

Flaky pixel differences

Animations, timestamps, ads, random content, and font differences are common causes. Disable animations, mask volatile selectors, block nonessential third-party resources where appropriate, and standardize the browser image.

Missing output directory or overwritten files

Create the directory before capture and include a deterministic test or URL identifier in each filename. Enable overwrite only when replacement is intentional; otherwise fail loudly so an earlier artifact is not silently lost.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient

Browser launch fails in CI

Install the framework’s browser binaries and required system dependencies in the CI image. Confirm that the browser version, sandbox settings, and architecture match the runner.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a URL-only capture, ScreenshotNeo provides a single GET request that returns PNG, JPEG, WebP, or PDF. It accepts the cookie or consent banner like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing result.

Use the complete options and parameter reference in the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

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)

Node.js

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(`HTTP ${res.status}`);
require('fs').writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its 63 options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and page controls, custom CSS and JavaScript, clicks, selector waits, network-idle waits, request and resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Familiar parameter names from other screenshot APIs are accepted to ease migration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to get started.

FAQ

Should automated screenshots be PNG or JPEG?

Use PNG for lossless visual comparison. Use JPEG or WebP when smaller artifacts are more useful and compression differences will not affect your test.

Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.

Can a screenshot script upload images without saving them?

Yes. In Playwright, omit path and pass the returned buffer directly to your upload or comparison function.

How do I protect sensitive information?

Mask or black out selectors containing credentials, personal data, tokens, timestamps, and other volatile values before writing the artifact.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Which framework is best for a new screenshot script?

Playwright is a strong default when you need viewport, full-page, and locator screenshots in one Node.js API. Choose Cypress when screenshots are part of Cypress tests, or Puppeteer when you want a minimal Chromium-oriented script.

Why does network idle still produce an incomplete screenshot?

Network idle describes requests, not application readiness. Wait for a meaningful locator or data condition, then ensure fonts, images, and animations are settled.

How can I capture screenshots for failed CI tests?

Keep failure capture enabled, write images to a deterministic directory, and upload that directory as a CI artifact alongside the test report.

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.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.