Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteUse 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
watirgem 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.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →#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.
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:
Rank #2
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.
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.
- Record the Ruby, Watir, Selenium, browser and driver versions used by the failing job.
- Confirm that the call is reaching the underlying driver (
browser.wd) and that the output path is writable. - 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.
- 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.
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 minuteWindows 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 reinstallRank #3
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
html2canvaspath 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.
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.
Rank #4
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.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →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.
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.
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.
Best Value
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.
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.
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.
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.

