How to Capture a Website Screenshot with Selenium in C#
Capture a browser page or a single element with Selenium in C#. Save the PNG reliably, handle dynamic pages, and understand screenshot scope and common failures.
To capture a website screenshot with Selenium in C#, navigate to the page, cast the WebDriver to ITakesScreenshot, call GetScreenshot(), and save the result with SaveAsFile(). Selenium’s .NET API documents PNG output; the call captures the current browser context, and does not guarantee a full scrollable-page image across every driver. See Selenium’s screenshot documentation and .NET API reference.
Capture a browser page in C#
This example uses ChromeDriver and saves the screenshot in the process’s current working directory. It disposes the driver even if navigation or capture fails.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://example.com");
var screenshotTaker = (ITakesScreenshot)driver;
Screenshot screenshot = screenshotTaker.GetScreenshot();
screenshot.SaveAsFile("screenshot.png");
Add the Selenium WebDriver and Chrome driver packages to your .NET project, and ensure a compatible Chrome browser and driver are available in the environment. The exact setup varies by .NET target, Selenium package version, and machine. The sample uses only the Selenium namespaces required for these calls.
SaveAsFile("screenshot.png") writes PNG data. The path is relative to the process working directory, which may differ from the project folder when running from an IDE, test runner, service, or CI job. Use an absolute path when the output location matters. The API overwrites an existing file at that path, so choose a unique name if prior captures must be kept.
Capture one element instead
If you need a component such as a heading, chart, or card, locate it and request its screenshot. This avoids capturing the rest of the current browser context.
IWebElement element = driver.FindElement(By.CssSelector("h1"));
Screenshot elementScreenshot = ((ITakesScreenshot)element).GetScreenshot();
elementScreenshot.SaveAsFile("heading.png");
Run this after navigation and after the target element exists. A missing or incorrect selector causes element lookup to fail; use a selector that matches the page and wait for it on dynamic pages.
Wait for the page state you want
A screenshot records the state visible to the browser when the capture command runs. A page load event alone may not mean that client-side rendering, images, or asynchronous content are ready. Prefer waiting for a meaningful element or state over adding an arbitrary long sleep.
using OpenQA.Selenium.Support.UI;
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElement(By.CssSelector("main h1")).Displayed);
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile("ready.png");
This wait checks that a heading is displayed. Change the selector and condition to match the state that matters to your page. If the page updates after the heading appears, wait for the relevant content or application state instead.
What Selenium captures, and what it does not promise
The driver screenshot API is for the current browsing context. The cited .NET reference describes an image of the page loaded in the browser; it does not establish a universal guarantee that every browser and driver captures the full vertically scrollable document. Element screenshots target the located element.
- Use a driver screenshot for the current browser page/context.
- Use an element screenshot when you only need one located element.
- If a full-document image is essential, check support for your particular Selenium version, browser, and driver, then validate the output dimensions and content in your environment.
Do not infer C# behavior from another Selenium language binding’s description of best-effort capture. Implementations and support can vary.
Save output safely in automation
Make the destination explicit in a test or service, create its parent directory if needed, and use a unique filename when each run must be retained. Because the documented save behavior overwrites an existing file, a fixed name is suitable only when replacement is intended.
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var outputDirectory = Path.GetFullPath("artifacts");
Directory.CreateDirectory(outputDirectory);
var outputPath = Path.Combine(outputDirectory, "page.png");
using var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://example.com");
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(outputPath);
For repeatable runs, derive the filename from a test name or run identifier and retain the path in test output. Avoid writing to a directory that is cleaned before artifacts are collected.
Common errors and fixes
| Symptom | Likely cause | What to check |
|---|---|---|
WebDriverException during capture |
The driver may not implement screenshot capture, or its capabilities may indicate capture is unsupported. | Check the concrete driver and its capabilities, and confirm browser/driver compatibility. Selenium’s support API documents this unsupported-capture exception. |
| File not found later | The relative path was resolved against a different working directory than expected. | Log or inspect Directory.GetCurrentDirectory(), use an absolute destination, and ensure the artifact collector reads that location. |
| Old screenshot appears | The same output path was reused and overwritten. | Use a unique filename or confirm replacement is intended. |
| Element lookup fails | The selector does not match, or the element has not appeared yet. | Verify the selector against the current page and wait for the required element/state. |
No Such Window |
The driver is still focused on a tab or window that was closed. | After closing a window, switch to a still-valid window handle before issuing another command. See Selenium’s window and tab guidance. |
| Screenshot misses content or looks incomplete | Capture ran before dynamic content was ready, or the driver’s capture scope differs from the expected full-page behavior. | Wait for the meaningful page state. Check the capabilities of the browser and driver you use, and inspect whether full-document capture is supported. |
Performance, reliability, and cost
Selenium screenshots require a browser session and the time to start or reuse a driver, navigate, wait for page state, and capture. For a small number of captures in an existing browser test, this fits naturally into the test. For repeated captures, avoid launching a new browser for every image unless isolation is needed; reuse a session where your test design allows it, and keep waits specific so they do not delay every capture unnecessarily.
Reliability depends on a usable browser/driver combination, a valid browsing context, the page reaching the intended state, and a writable output path. In CI, collect screenshots as build artifacts and make failures actionable by recording the target URL and output path. Selenium itself does not charge per screenshot; account for the compute and maintenance involved in running browser automation.
Or skip the browser setup
If you need an image without managing WebDriver, ScreenshotNeo returns a website screenshot from one API request. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, no card required.
FAQ
Does SaveAsFile save a JPEG?
The documented Selenium .NET save method specifies PNG output. The examples here use a .png filename.
Can I capture an element that is not visible?
The cited API documentation does not promise behavior for off-screen or hidden elements. Make the target visible and validate the result with your browser and driver.
Do I need a fixed delay before every screenshot?
No. Wait for the specific element or application state that should appear in the image. A fixed delay can be either too short or needlessly long.


