Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Protractor’s element(locator) to find the target, resolve the resulting ElementFinder to its WebDriver element, then call the element screenshot method. In current Selenium’s JavaScript API that method is WebElement.takeScreenshot(), which returns a promise containing base64-encoded PNG data for the visible region inside the element’s bounding rectangle.
Because Protractor and many of its dependencies are legacy, the exact unwrapping method and driver support depend on the versions installed in your project. The procedure below shows the usual pattern, includes a compatibility check, and explains what to do when your stack does not expose element screenshots.
The locator-to-screenshot sequence
A locator and a screenshot are separate operations:
Recommended Free Tools
- Locate:
element(by.css('.target'))creates anElementFinder. - Resolve: obtain the underlying WebDriver
WebElementusing the method supported by your Protractor version. - Capture: call
takeScreenshot()on that WebElement. - Persist: decode the returned base64 string and write PNG bytes to disk, or return the string to a test reporter.
The result is an element-region image, not automatically a full-page screenshot. The documented region is the visible area covered by the element’s bounding rectangle. A driver implementation that is not fully W3C-conformant can behave differently, so verify the browser-driver combination used by your test suite.
#1 Best Overall
Working JavaScript example
This example is suitable for a Protractor project whose ElementFinder exposes getWebElement() and whose underlying Selenium binding exposes takeScreenshot(). Those method names are not guaranteed across every historical Protractor/Selenium combination; the explicit checks make a mismatch fail with a useful message rather than a cryptic TypeError.
const fs = require('node:fs/promises');
async function captureElement(locator, outputPath) {
const finder = element(locator);
// Common Protractor API. Confirm this method in your installed version.
if (typeof finder.getWebElement !== 'function') {
throw new Error(
'This Protractor version does not expose ElementFinder.getWebElement(). ' +
'Use the version-specific ElementFinder-to-WebElement adapter for your project.'
);
}
const webElement = await finder.getWebElement();
if (typeof webElement.takeScreenshot !== 'function') {
throw new Error(
'The resolved WebElement has no takeScreenshot() method. ' +
'Check your Selenium JavaScript binding and browser driver.'
);
}
const base64Png = await webElement.takeScreenshot();
await fs.writeFile(outputPath, Buffer.from(base64Png, 'base64'));
return outputPath;
}
// Example: capture the element matched by a CSS locator.
await browser.get('https://example.com');
const file = await captureElement(by.css('.target'), './artifacts/target.png');
console.log(`Saved ${file}`);
The call to browser.get() is only an example page navigation. In a real spec, place the capture after the state you want to document has rendered and after any required login or interaction.
What the code returns
takeScreenshot()resolves to a base64-encoded PNG payload.Buffer.from(..., 'base64')converts that payload into binary PNG data.fs.writeFilesaves the bytes. It does not add a file extension or create missing directories.
Create the artifact directory first if it may not exist:
await fs.mkdir('./artifacts', { recursive: true });
Choosing and validating a locator
CSS locator
const finder = element(by.css('[data-testid="checkout-total"]'));
Stable test attributes such as data-testid are generally less brittle than presentation classes. The locator must identify one element for an element screenshot. If it matches several elements, use element.all(...).get(index) or make the selector more specific.
ID and Angular locators
element(by.id('invoice'));
element(by.cssContainingText('button', 'Continue'));
Angular-specific locator strategies are part of Protractor’s legacy surface. Keep the locator itself independent from the screenshot code so migrating to another runner later only changes the lookup layer.
Rank #2
Wait before capturing
A successful lookup does not guarantee that the pixels are ready. Wait for visibility or a state-specific condition before resolving the WebElement:
const target = element(by.css('.chart'));
await browser.wait(protractor.ExpectedConditions.visibilityOf(target), 10000);
const png = await (await target.getWebElement()).takeScreenshot();
If your project does not expose protractor.ExpectedConditions under that name, use the wait helper supplied by your installed version. Avoid arbitrary sleeps unless the page has no observable readiness condition.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Element screenshot behavior and limits
Visible bounding rectangle
The element capture is based on the element’s bounding rectangle. Content below the fold, clipped by a scroll container, or hidden with CSS may not appear. A very tall element can also produce driver-specific results.
Overlays and covered content
Consent dialogs, chat bubbles, fixed headers, and other overlays can cover pixels in the rectangle. The screenshot records what the browser renders; it does not remove overlays. Close or hide them before capture when the test’s purpose is visual comparison.
Scrolling and animations
Scroll the element into view and wait for transitions, charts, fonts, and lazy images to settle. Otherwise two identical tests can produce different pixels. Disable animations in a test stylesheet when deterministic output matters.
Encoding and formats
The Selenium JavaScript method described here produces PNG data. If you need JPEG or WebP, convert the saved PNG with an image-processing step; do not assume the WebDriver element API can select another format.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsWhen the method is unavailable
Protractor’s ElementFinder and Selenium bindings changed over time, and browser drivers have their own implementation differences. If the checks in the example fail:
- Record the versions of Protractor,
selenium-webdriver, Node.js, the browser, and the driver. - Inspect the installed binding’s
WebElementAPI and confirm whether it documentstakeScreenshot(). - Confirm that your Protractor version has a supported way to resolve an
ElementFinderto a WebElement. Do not copy an unverified unwrapping expression from a different major version. - If only full-browser screenshots are supported, capture the browser and crop the element using its location and size as a fallback. Treat this as a project-specific workaround and test it for device-pixel-ratio and scrolling behavior.
Do not silently replace an element screenshot with a full-page image: downstream visual tests may pass while checking the wrong region.
Reliable test pattern
describe('invoice visual', () => {
it('writes the total element as PNG', async () => {
await browser.get('https://example.com/invoice');
const total = element(by.css('[data-testid="invoice-total"]'));
await browser.wait(protractor.ExpectedConditions.visibilityOf(total), 10000);
await fs.mkdir('./artifacts', { recursive: true });
const webElement = await total.getWebElement();
const png = await webElement.takeScreenshot();
await fs.writeFile('./artifacts/invoice-total.png', Buffer.from(png, 'base64'));
});
});
For parallel workers, include a unique test name or worker identifier in the output filename. Otherwise concurrent specs can overwrite one another.
Performance, determinism, and artifact management
- Capture only what you need: element images are smaller and faster to store than full-page images.
- Wait on conditions: a targeted readiness check usually costs less than repeated retries after premature captures.
- Control the environment: use a fixed viewport, device-pixel ratio, fonts, timezone, and browser version for visual comparisons.
- Keep artifacts on failure: save screenshots when an assertion fails, but avoid committing large generated files to source control.
- Protect sensitive data: screenshots can contain account numbers, tokens, or personal information. Restrict artifact access and clean temporary files.
- Retry cautiously: retries can hide real rendering defects. Log the locator, URL, browser, and exception before retrying.
Troubleshooting common failures
“getWebElement is not a function”
Your installed Protractor version exposes a different resolution path, or the object is not an ElementFinder. Check that you used element(locator), then consult the API for your exact dependency version. Do not assume a method from another Protractor release.
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 #4
“takeScreenshot is not a function”
The resolved object is not the Selenium WebElement expected by the current JavaScript binding, or the binding is too old. Inspect the object type and upgrade or align the Selenium binding and driver only after checking compatibility with the existing suite.
Element not found or stale element
The selector may be wrong, the page may still be rendering, or a framework re-render replaced the node. Wait for the element, then resolve it immediately before capture rather than retaining a WebElement across a re-render.
Blank or partially rendered image
Capture may have occurred before fonts, images, canvas content, or an animation completed. Wait for a meaningful state, scroll the element into view, and check for overlays or a failed network request.
Wrong crop or missing content
Check whether the content is outside the visible bounding rectangle, clipped by an ancestor, or covered by a fixed element. Element screenshots do not guarantee a full scrollable-container capture.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →File cannot be opened
Verify that the base64 string was decoded with the base64 encoding, that the output directory exists, and that the process has write permission. A PNG file should begin with the PNG signature; a text file containing the base64 characters is not a valid image.
Best Value
Protractor’s maintenance status and new projects
Protractor is historical software rather than an actively developed choice for a new suite. The Angular project’s April 2021 discussion said development was planned to end with Angular 15 at the end of 2022 and proposed end of life in August 2023. GitHub later marked the repository archived on July 29, 2024. The same discussion reported that fewer than 20% of nearly 1,000 January 2021 survey respondents used Protractor; that is a dated survey result, not a current adoption measurement.
For an existing suite, preserving a tested version combination may be safer than changing tools solely to obtain screenshots. For new locator-centric tests, evaluate maintained options such as Playwright, Selenium WebDriver, Cypress, Puppeteer, TestCafe, or WebdriverIO against browser coverage, language support, migration cost, and element-screenshot semantics. Playwright’s locator screenshot operation scrolls the element into view and clips to it, although content covered by another element is not made visible.
Or skip the browser setup
ScreenshotNeo provides a URL-based screenshot API when you need a page image rather than a test-runner element handle. It can accept consent banners before capture and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
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 →One request returns an image or PDF:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for selectors, waits, custom CSS and JavaScript, device presets, viewport and retina settings, PDF controls, request blocking, authentication headers and cookies, geolocation, caching, signed links, asynchronous jobs, bulk capture, and usage reporting. The service offers 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
FAQ
Does an element screenshot include the element’s children?
It captures the rendered pixels inside the element’s bounding rectangle, so visible descendants normally appear. Clipping, overflow, and overlays can still hide them.
Can I save the result as JPEG directly?
The documented JavaScript WebElement method returns base64 PNG data. Save the PNG, then convert it separately if another format is required.
Should a new project still adopt Protractor?
No. Treat Protractor as legacy maintenance technology and compare maintained runners before starting new tests.
Frequently Asked Questions
Can I capture several matching elements with one locator?
Resolve and capture each matched element separately, selecting an index from the collection; the WebDriver element screenshot operation applies to one element at a time.
Why does my screenshot differ between headless and headed runs?
Viewport dimensions, device-pixel ratio, fonts, GPU behavior, animations, and browser-driver versions can change rendered pixels. Keep those variables consistent for visual tests.
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.

