Use FirefoxDriver’s GetFullPageScreenshot() when you need a complete document image in Selenium .NET. Selenium’s generic ITakesScreenshot.GetScreenshot() is an on-screen (viewport) capture, not a portable full-document API. Chromium can capture beyond the viewport through its Selenium DevTools binding, but that API is browser-version-specific. The examples below show the dependable Firefox path, explain the Chromium route, and cover dynamic pages, lazy loading, failures and alternatives.
Choose the capture method first
| Route | Browser scope | What it does | Main trade-off |
|---|---|---|---|
FirefoxDriver.GetFullPageScreenshot() |
Firefox | Uses Firefox’s native full-page endpoint and returns a Selenium Screenshot. |
Firefox-specific; it is not defined on IWebDriver. |
Selenium DevTools Page capture with CaptureBeyondViewport |
Chrome/Chromium | Requests a screenshot extending beyond the current viewport. | The generated OpenQA.Selenium.DevTools.V### binding must match the installed Selenium package and browser. |
| Scroll and stitch | Potentially cross-browser | Scrolls through the page and combines viewport images. | Sticky headers, animations, lazy loading, nested scroll areas and layout changes can create seams or duplicates; package maintenance must be checked before adding a dependency. |
| ScreenshotNeo API | Any client that can make HTTPS requests | Server-side full-page capture with page preparation options. | Requires an API key and network access. |
If Firefox is acceptable, its native method is the shortest, least coupled implementation. If your test matrix is Chromium-only, use the matching DevTools package and verify the generated namespace against your browser before treating the code as production-ready.
Prerequisites for a C# Selenium capture
- .NET project (for example, a current .NET SDK supported by your Selenium package).
- The
Selenium.WebDriverNuGet package. - A browser installed on the machine. Selenium Manager can resolve drivers in recent Selenium releases; otherwise install and configure the browser driver yourself.
- A page URL and a plan for readiness: full-page capture does not make off-screen application resources load automatically.
Create a console project and add Selenium:
dotnet new console -n FullPageShot
cd FullPageShot
dotnet add package Selenium.WebDriver
dotnet add package Selenium.WebDriver.GeckoDriver
The GeckoDriver package is optional when Selenium Manager or another driver-management approach is already configured.
#1 Best Overall
Firefox: native full-page screenshot in C#
Minimal runnable example
This program opens a URL, waits for the document to reach a usable state, calls the Firefox-only method, and writes a PNG.
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System;
using System.Threading;
var options = new FirefoxOptions();
// options.AddArgument("-headless"); // Enable on CI or servers without a display.
using var driver = new FirefoxDriver(options);
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(60);
driver.Navigate().GoToUrl("https://example.com");
var waitUntil = DateTime.UtcNow.AddSeconds(30);
while (DateTime.UtcNow < waitUntil)
{
var state = ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState")?.ToString();
if (state == "complete") break;
Thread.Sleep(250);
}
var screenshot = driver.GetFullPageScreenshot();
screenshot.SaveAsFile("page-full.png");
Console.WriteLine("Saved page-full.png");
Rank #2
GetFullPageScreenshot() belongs to FirefoxDriver. Keep the variable typed as FirefoxDriver; casting an arbitrary IWebDriver does not make the method available on other browsers.
Wait for the content you actually need
document.readyState only indicates document loading, not that a single-page application has rendered its data or that images below the fold have loaded. Add an explicit wait for a meaningful selector:
using OpenQA.Selenium.Support.UI;
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(d => d.FindElement(By.CssSelector("main article")));
For an image-heavy page, wait for image completion when that is appropriate to the site:
wait.Until(d => (bool)((IJavaScriptExecutor)d).ExecuteScript(@"
return Array.from(document.images).every(i => i.complete);"));
These checks are page-specific. A lazy-loading framework may need scrolling, an application-specific network-idle signal, or a wait for a final data element.
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 reinstallRank #3
Chromium: DevTools capture beyond the viewport
Selenium’s generated DevTools Page screenshot settings expose CaptureBeyondViewport, documented with a default of false. Set it to true when issuing the Page capture command. The .NET type is generated under a versioned namespace such as OpenQA.Selenium.DevTools.V###; the number must correspond to the DevTools binding installed with your Selenium package and be compatible with the running browser.
- Inspect the Selenium package’s installed
OpenQA.Selenium.DevTools.V###assemblies (in your IDE or NuGet assets). - Check the browser’s major version and choose the closest supported generated binding documented by that package.
- Use that versioned namespace’s Page domain and
CaptureScreenshotCommandSettings. - Set
CaptureBeyondViewport = true, execute the command, decode the returned Base64 data and write the bytes to a file.
Because Selenium generates these classes per protocol version, a namespace copied from a different release can fail at compile time or behave incompatibly. Do not describe this as a cross-browser method: it is a Chromium DevTools route. If you cannot pin compatible browser and package versions, Firefox’s native method or an evaluated stitching implementation is safer operationally.
Preparing pages that change while you capture
Lazy-loaded images
Full-document dimensions and image readiness are separate concerns. Scroll through required regions or trigger the application’s own loading mechanism, then wait for the relevant images or content selectors. Verify the output; an API call alone does not guarantee that every off-screen resource was fetched.
Sticky headers and fixed widgets
Native full-page output can include fixed-position elements according to browser behavior. Inspect the image for repeated headers, consent banners, chat controls or clipped overlays. Hiding an element with test-only JavaScript can alter the page you intended to document, so use that only when your capture specification allows it.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Nested scroll containers
A document screenshot may not include the complete contents of an internal overflow: auto panel. Capture that element separately or programmatically scroll the container before taking element screenshots. Test this against the actual layout rather than assuming document height covers it.
Animations and live data
Freeze animations where acceptable, wait for a stable state, and avoid capturing while content is reflowing. Otherwise two regions can be rendered at different moments. Record the URL, viewport and timestamp with the artifact when screenshots are used for visual regression.
Fallback: scrolling and stitching
When a browser lacks a suitable native or DevTools method, a fallback is to capture viewport-sized images while scrolling and combine them vertically. Treat this as an implementation to evaluate, not a universally reliable package recipe. You must account for:
Rank #4
- overlap between tiles and duplicate fixed headers;
- sticky elements that move or remain pinned;
- lazy loading triggered by scroll;
- animations and changing heights;
- inner scroll containers;
- device-pixel-ratio and image-format differences.
The historical package examples commonly cited for this technique do not establish a currently maintained dependency or browser compatibility. Test the exact Selenium, browser and target-site versions before adopting one.
Recommended Free Tools
Saving, validating and diagnosing the output
- Save with a deterministic name that includes the page or test identifier.
- Check that the file exists and has non-zero length.
- Open the image in an automated step or inspect representative pages manually.
- Look specifically for clipped bottom content, missing lazy images, repeated fixed controls and blank sections.
- Keep browser logs and the HTML state when a visual test fails; the screenshot alone may not reveal a timing error.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
“Method not found” on GetFullPageScreenshot |
Driver variable is typed as IWebDriver, or a non-Firefox driver is used. |
Instantiate and retain FirefoxDriver; use the Firefox namespace and method. |
| Only the visible viewport is saved | GetScreenshot() was called. |
Use Firefox’s full-page method or the Chromium DevTools beyond-viewport command. |
| Chromium code will not compile | Versioned DevTools namespace does not match installed Selenium assemblies. | Inspect the package’s generated V### namespace and update the binding/browser combination. |
| Blank or incomplete sections | SPA rendering or lazy loading was still in progress. | Wait for application selectors and image readiness; trigger required scrolling, then recapture. |
| Repeated banner or shifted content | Fixed or sticky elements changed during scrolling/stitching. | Prefer native capture, or add page-specific handling and validate the stitched result. |
| Timeout during navigation | Slow server, blocked resource or page-load strategy. | Set a realistic page-load timeout, wait for the specific content needed, and capture only after the test’s readiness condition is met. |
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
One GET request returns PNG, JPEG, WebP or PDF. The API supports full-page capture with lazy images loaded, CSS-selector element capture, custom waits, JavaScript and CSS, headers, cookies, user agents, geolocation, device presets, PDF controls, caching, signed links, asynchronous jobs and bulk capture. It also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for AI clients.
See the ScreenshotNeo documentation for parameters. The following cURL call captures Stripe as WebP:
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}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Best Value
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
Frequently Asked Questions
Can I call GetFullPageScreenshot through IWebDriver?
No. The documented method is on FirefoxDriver, so keep that concrete type when using the native Firefox implementation.
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 →Does full-page capture include an internal scroll panel?
Not necessarily. An element with its own overflow scrolling may require separate interaction and capture.
Why are off-screen images missing?
Document capture and resource loading are separate. Trigger lazy loading and wait for the page’s relevant selectors or image state before capture.
The Bottom Line
For Selenium in C#, use FirefoxDriver.GetFullPageScreenshot() for a native full-document image. Use Chromium’s version-matched DevTools Page API when you need Chrome, and validate dynamic pages rather than assuming every resource 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.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems




