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

Use Watir to open the page, wait for its content, then call Selenium through Watir’s underlying driver with full_page: true: browser.wd.save_screenshot("full-page.png", full_page: true). This produces a full-document image only when the active browser driver implements Selenium’s full-page operation. Watir’s normal browser.screenshot.save method captures the viewport and does not add a full-page switch. The complete Ruby recipe, driver checks, Firefox fallback, stitching cautions and an API alternative are below.

What “full page” means in Watir

A normal screenshot is the rectangle currently visible in the browser window. A full-page screenshot includes content below the fold and may require the driver to resize, scroll, or otherwise compose the document. These are different operations:

Operation Ruby call What to expect
Viewport screenshot browser.screenshot.save("viewport.png") Watir’s documented screenshot wrapper delegates to the ordinary WebDriver screenshot method.
Driver full-page screenshot browser.wd.save_screenshot("full-page.png", full_page: true) Works only when the current Selenium driver and browser support the option; an unsupported driver can raise UnsupportedOperationError.
Manual Chrome capture Chrome DevTools “Capture a full size screenshot” Useful for a one-off visual check, but it is a manual DevTools action rather than unattended Ruby automation. See the Chrome DevTools Device Mode guide.

The Selenium Ruby reference documents full_page on save_screenshot and screenshot_as, while warning that the TakesScreenshot module is private API and that full-page behavior is conditional. Treat the call as a capability to verify in your pinned browser/driver combination, not as a guarantee supplied by Watir itself. The API details are in the Selenium Ruby TakesScreenshot documentation.

Prerequisites and a predictable test setup

  • Ruby and the watir gem installed.
  • A browser (the example uses Chrome) and a matching Selenium driver available to the environment.
  • A page you are permitted to automate, plus any authentication, cookies or headers it requires.
  • A writable path ending in .png. Selenium warns when the extension does not match the requested screenshot format.

The Watir project page reports Watir 7.3 and records that Watir 7.2 required at least Selenium 4.2 and Ruby 2.7. Those are release facts, not a current compatibility matrix; pin and test the versions used by your project rather than inferring support from the release page. Refer to Watir’s project page for the project and release information.

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

Method 1: call Selenium’s full-page operation through Watir

This is the shortest unattended solution when your driver supports it. Watir owns navigation and browser lifecycle; browser.wd exposes the underlying WebDriver object that implements Selenium’s screenshot API.

require "watir"

browser = Watir::Browser.new(:chrome)

begin
  browser.goto("https://example.com")

  # document.readyState can be complete while a site is still inserting
  # content or loading lazy images. Add the site's own readiness check below
  # when that matters to your capture.
  browser.wait_until do
    browser.execute_script("return document.readyState") == "complete"
  end

  # This option is driver-dependent. It may raise
  # Selenium::WebDriver::Error::UnsupportedOperationError.
  browser.wd.save_screenshot("full-page.png", full_page: true)
ensure
  browser.close
end

The ensure block closes the session if navigation, waiting or capture fails. Without it, a failed screenshot can leave a Chrome process and WebDriver session running in CI.

Capture bytes instead of writing directly to a file

Selenium also exposes screenshot_as. This is useful when an object store, checksum step or image-processing pipeline should receive bytes before you create a file:

require "watir"

browser = Watir::Browser.new(:chrome)
begin
  browser.goto("https://example.com")
  browser.wait_until { browser.execute_script("return document.readyState") == "complete" }

  png_bytes = browser.wd.screenshot_as(:png, full_page: true)
  File.binwrite("full-page.png", png_bytes)
ensure
  browser.close
end

Both examples use the same driver capability. Changing from save_screenshot to screenshot_as does not make an unsupported driver full-page capable.

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

Make the page ready before taking the shot

Waiting for document.readyState == "complete" covers the browser’s initial document load, not every visual update. Single-page applications, lazy images, consent overlays and content fetched after load can still change the image.

Wait for an application-specific signal

If the page has a stable marker, wait for it in Watir rather than relying only on a timer:

browser.wait_until(timeout: 30) do
  browser.div(id: "report-ready").present?
end

Use the selector your application actually renders. If no marker exists, a bounded delay can be a last resort, but it is less reliable than waiting for a real condition.

Trigger lazy-loaded regions

Some pages request images only when their containers enter the viewport. Before the screenshot, scroll through the document and return to the top:

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.
browser.execute_script(<<~JS)
  (async () => {
    const step = Math.max(window.innerHeight, 600);
    for (let y = 0; y < document.body.scrollHeight; y += step) {
      window.scrollTo(0, y);
      await new Promise(resolve => setTimeout(resolve, 100));
    }
    window.scrollTo(0, 0);
  })();
JS

The script is a practical way to activate viewport-based loading; it is not a promise that every framework has finished rendering. Follow it with a page-specific readiness check when possible.

Consider overlays and fixed elements

Full-page output can repeat a fixed header or include a chat button at every scroll position, depending on how the driver composes the document. Inspect a sample image. If the site supplies a test mode, disable transient overlays there rather than editing production content in the browser.

When full_page: true is rejected

A common failure is Selenium::WebDriver::Error::UnsupportedOperationError. It means the active driver does not implement the requested full-page behavior. Headless mode does not change this capability; it only changes how the browser is launched.

  1. Record the Ruby, Watir, Selenium, browser and driver versions used by the failing job.
  2. Confirm that the call is reaching the underlying driver (browser.wd) and that the output path is writable.
  3. Try the same versions in a clean local or CI run. Do not assume that support in one browser/driver applies to another or to a remote driver.
  4. If the operation remains unsupported, use the Firefox/geckodriver route or a stitching fallback described below.

Because Selenium labels this interface private and support is conditional, pin the combination that works for your project and keep a small capture smoke test in CI.

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

Firefox and geckodriver with watir-screenshot-stitch

The watir-screenshot-stitch documentation describes a Firefox/geckodriver mode that uses geckodriver's full-page feature. It also documents repeated viewport captures stitched into one image and an html2canvas alternative. The Firefox route is presented by that gem as having the fewest complications when it is available.

Use the gem's documented installation and invocation for the exact version you pin; its public interface is separate from Watir's built-in browser.screenshot.save. Validate the resulting image with your own pages, especially pages with fixed navigation, canvas content, cross-origin resources or very tall documents.

Stitching trade-offs

  • Seams and duplicates: repeated captures can show joins, repeated fixed headers or overlays.
  • Height limits: the gem's examples include an explicit page-height limit (one example uses 5000 pixels). That value is illustrative, not a universal safe maximum.
  • Memory: a very tall image consumes substantial memory; device-pixel ratio affects the calculations and output size.
  • Canvas rendering: the documented html2canvas path may fail to display certain element types properly.

For a cross-browser fallback, set a deliberate maximum height, capture a representative long page, and inspect for seams before making the workflow unattended.

Choosing an approach

Approach Best fit Limitations to plan for
Selenium Ruby full_page: true via browser.wd Short automated Ruby script with a driver known to support the operation Conditional support; private API; unsupported drivers raise an error.
Firefox/geckodriver through watir-screenshot-stitch Full-page Firefox capture when that route is available Requires Firefox/geckodriver and the gem's version-specific setup.
Viewport stitching Environments without a native full-page call Seams, repeated fixed elements, height limits, device-pixel-ratio calculations and memory pressure.
html2canvas route Canvas-based capture where its rendering model is acceptable Some element types may not render correctly.
Chrome DevTools manual capture One-off human verification Manual and not reusable as an unattended Ruby step.

Evaluate a route against unattended operation, browser/driver requirements, fidelity of fixed elements and canvas, cross-origin content, lazy regions, maximum practical height and resource cost. No single method is universally correct.

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

Troubleshooting checklist

The image is only the visible viewport

Cause: browser.screenshot.save uses the ordinary screenshot operation, or the driver ignored/does not support the full-page option. Fix: call browser.wd.save_screenshot(..., full_page: true), verify support, and switch to a documented Firefox or stitching route if necessary.

UnsupportedOperationError

Cause: the active browser driver has no full-page implementation. Fix: pin and test a supported combination, or use geckodriver/stitching. Do not hide the exception and silently ship a viewport image.

Missing images or sections below the fold

Cause: lazy loading or asynchronous rendering continued after the initial document load. Fix: scroll through the page, wait for a selector or application-ready marker, and capture only after those checks pass.

Repeated headers, chat buttons or visible seams

Cause: fixed-position elements and viewport stitching. Fix: inspect the output, disable test-only overlays where possible, choose a native full-page driver, or adjust the stitch height and method.

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

Blank, truncated or unexpectedly huge files

Cause: a navigation failure, an extreme document height, device-pixel-ratio scaling or insufficient memory. Fix: save to a writable .png path, check page readiness, impose a documented height policy for stitching, and monitor the process memory in CI.

The browser remains running after a failure

Cause: cleanup was not guaranteed. Fix: put browser.close in an ensure block, as in the examples.

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

Or skip the browser setup

If you need a screenshot endpoint rather than a locally managed browser, ScreenshotNeo accepts one GET request and returns PNG, JPEG, WebP or PDF. It handles the browser side for you and is useful when Ruby workers should not carry browser binaries and driver maintenance.

Its cleanup options accept the cookie or consent banner like a visitor and remove more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response reports the result through X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

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

cURL

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

Ruby

require "net/http"
require "uri"

uri = URI("https://api.screenshotneo.com/v1/shot")
uri.query = URI.encode_www_form(
  access_key: "YOUR_API_KEY",
  url: "https://example.com"
)
response = Net::HTTP.get_response(uri)
raise "Screenshot failed: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
File.binwrite("shot.webp", response.body)

For all capture options and authentication details, see the ScreenshotNeo API documentation.

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.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://example.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()));

ScreenshotNeo's Free plan includes 1,000 screenshots 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 try the API without a card.

FAQ

Can Watir's documented screenshot object accept full_page: true?

Not through the documented Watir::Screenshot#save wrapper. Use the underlying Selenium driver call and verify that the driver implements it.

Does a full-page PNG include content blocked by a login or paywall?

No. The screenshot reflects the page state visible to the automated session. Supply the session's permitted cookies or authentication setup, and respect the site's access controls.

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

Should I use PNG or JPEG for a long page?

PNG preserves text and interface edges well but can become large for very tall pages. JPEG can reduce file size at the cost of compression artifacts; choose the format required by your downstream workflow and measure it on representative pages.

Is a PDF the same as a full-page screenshot?

No. A PDF is a paginated document representation, while a screenshot is a raster image of the rendered page. Select the output that matches whether you need pixel comparison or printable pages.

Frequently Asked Questions

Can Watir's documented screenshot object accept full_page: true?

Not through the documented Watir::Screenshot#save wrapper. Use the underlying Selenium driver call and verify that the driver implements it.

Does a full-page PNG include content blocked by a login or paywall?

No. The screenshot reflects the page state visible to the automated session. Supply the session's permitted cookies or authentication setup, and respect the site's access controls.

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.

Should I use PNG or JPEG for a long page?

PNG preserves text and interface edges well but can become large for very tall pages. JPEG can reduce file size at the cost of compression artifacts; choose the format required by your downstream workflow and measure it on representative pages.

Is a PDF the same as a full-page screenshot?

No. A PDF is a paginated document representation, while a screenshot is a raster image of the rendered page. Select the output that matches whether you need pixel comparison or printable pages.

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.