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 →Check the locator before calling screenshot(), and capture only in the branch that matches your test’s policy. Use count() to check whether anything matches now, isVisible() to check whether it is visible now, or waitFor() when the element is expected to appear. The right choice depends on whether the element is optional and whether you need to wait.
Why an unconditional locator screenshot fails
Locator.screenshot() captures the page clipped to the matched element’s size and position. It is not a “capture if available” operation: if the locator has no usable match, or the matched element detaches during capture, the call can fail. Playwright also performs actionability checks and scrolls the element into view as part of capture, but those behaviors do not make a missing element valid.
For an optional element, make the policy explicit before you call the screenshot method. Is the element allowed to be absent? Must it be visible? Should the test wait for it? If absence is actually a defect, do not silently skip the capture—let an assertion or wait fail so the test reports the missing UI.
Choose the guard that matches the test
| Situation | Guard | Behavior when absent |
|---|---|---|
| Capture only what exists at this instant | count() > 0 |
Skips immediately if there are no matches. |
| Capture only if the element is visible right now | isVisible() |
Skips if absent, hidden, or zero-sized. |
| The element should appear soon | waitFor({ state: 'visible', timeout }) |
Fails on timeout unless you deliberately catch the timeout for a legitimate optional case. |
| The element is required | expect(locator).toBeVisible() |
Fails with test context instead of treating absence as normal. |
These guards answer different questions. count() checks how many elements match; it does not establish visibility. isVisible() checks the current visibility state and returns immediately—its timeout option does not turn it into a wait. waitFor() waits for a specified state up to its timeout. Playwright defines visible as having a non-empty bounding box and no visibility:hidden.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Skip immediately when there is no match
Use this pattern for a best-effort capture of whatever is present at the moment of the check:
import { test } from '@playwright/test';
test('capture the optional panel if it exists', async ({ page }) => {
await page.goto('https://example.com');
const panel = page.getByTestId('optional-panel');
if (await panel.count() > 0) {
await panel.screenshot({ path: 'optional-panel.png' });
}
});
count() returns the number of matching elements. If the count is zero, the screenshot is skipped; if it is positive, the call proceeds. This is a point-in-time presence check, not synchronization: the page can change after the count, so the element may detach before or during capture.
Skip when the element is not visible now
When hidden or zero-sized elements should be skipped along with absent ones, use isVisible():
import { test } from '@playwright/test';
test('capture the panel only when currently visible', async ({ page }) => {
await page.goto('https://example.com');
const panel = page.getByTestId('optional-panel');
if (await panel.isVisible()) {
await panel.screenshot({ path: 'optional-panel.png' });
}
});
This is also an immediate check. It does not wait for an element that may become visible a moment later. Use it when a missing or currently hidden panel is acceptable, such as for an optional diagnostic image. If the panel ought to appear after an asynchronous interaction, use a bounded wait instead.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Wait when the element is expected to appear
If appearance is part of the expected flow, wait for visibility and capture only after the wait succeeds:
import { test } from '@playwright/test';
test('capture the panel after it appears', async ({ page }) => {
await page.goto('https://example.com');
const panel = page.getByTestId('optional-panel');
await panel.waitFor({ state: 'visible', timeout: 5000 });
await panel.screenshot({ path: 'optional-panel.png' });
});
Here the timeout is a failure boundary: if the element does not become visible within five seconds, the test fails. Catch that timeout only if absence is expressly permitted by the test contract. If the panel is required, preserving the failure gives useful coverage rather than disguising a broken page as a successful skipped screenshot.
waitFor() also accepts attached, detached, and hidden. The hidden state includes a detached element, an empty bounding box, or visibility:hidden. Choose the state that describes what the test actually needs; attachment alone does not guarantee that an element is visible.
Use a helper when optional captures recur
A small helper can make best-effort diagnostic capture consistent and report whether it produced an image:
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
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
import type { Locator } from '@playwright/test';
export async function screenshotIfVisible(
locator: Locator,
path: string,
): Promise<boolean> {
if (!(await locator.isVisible())) return false;
await locator.screenshot({ path });
return true;
}
The caller can log or assert on the boolean result. This helper does not suppress a failure that occurs after the visibility check—for example, if the element detaches during capture. That is generally preferable to silently swallowing a real capture problem.
For a required element, use an assertion instead of this optional helper:
import { expect, test } from '@playwright/test';
test('capture the required order summary', async ({ page }) => {
await page.goto('https://example.com');
const summary = page.getByRole('region', { name: 'Order summary' });
await expect(summary).toBeVisible();
await summary.screenshot({ path: 'order-summary.png' });
});
Pick a locator that stays meaningful
Locators are Playwright’s central abstraction for auto-waiting and retryability. Prefer a stable, unique semantic locator when available:
const summary = page.getByRole('region', { name: 'Order summary' });
// Or use an intentional test identifier:
const panel = page.getByTestId('optional-panel');
Role, text, label, placeholder, alt text, title, and test-ID locators are among Playwright’s built-in choices. Choose an identifier that corresponds to the intended element rather than trying to repair an ambiguous locator by filtering for visibility. A locator that matches the wrong element can make a conditional screenshot appear to work while capturing the wrong UI.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesRank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Understand the check-to-capture race
A presence or visibility check is a snapshot, not a lock. The page can re-render between the guard and locator.screenshot(). For example, a panel may be visible when isVisible() returns, then be replaced by a client-side render before the screenshot completes. Playwright documents that the locator screenshot waits for actionability and throws if its element is detached; a successful guard cannot rule out that race.
Handle a capture failure only when the image is genuinely best-effort evidence. Keep the try/catch narrow so that it covers the screenshot operation, not unrelated test steps:
const panel = page.getByTestId('optional-panel');
if (await panel.isVisible()) {
try {
await panel.screenshot({ path: 'optional-panel.png' });
} catch (error) {
console.warn('Optional panel changed before it could be captured:', error);
}
}
This approach trades certainty for continued execution: the test can proceed without an image, so record that outcome if it matters to later diagnosis. Do not swallow the error when the screenshot is part of verifying a required UI state.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Tune the image only after the guard is right
Screenshot options can improve deterministic output, but none of them makes a missing locator capturable. The locator screenshot API exposes options including animations: 'disabled', style for a stylesheet, an explicit type, a timeout, and an abort signal. Use these for capture behavior—for example, reducing animation-related variation or setting a format—not as a substitute for deciding whether the element must exist.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Keep the sequence easy to reason about: select a stable locator, decide whether absence is allowed, check or wait for the required state, then capture. If the page can legitimately change during the capture window, treat a detached-element failure according to the same optional-versus-required policy as the initial check.
Troubleshoot common failures
- The test throws as soon as it calls
screenshot(). The locator may have no match, or the matched element may not be ready or may detach. Guard optional captures, or wait/assert when the element is required. isVisible()returns false even though the panel appears later. That method does not wait. UsewaitFor({ state: 'visible', timeout })for an expected later appearance.count()is positive but capture still fails. The count only describes the DOM at the time of the check. The page may have changed before capture; handle that race only for best-effort images.- The test passes without taking an image, but the panel should always exist. The test policy is too permissive. Replace the optional branch with
expect(locator).toBeVisible()or a wait so absence fails the test. - The screenshot captures the wrong matching element. Make the locator more specific and stable, such as a role with an accessible name or an intentional test ID.
- Waiting for visibility times out. Decide whether the element is truly required, whether the expected UI transition occurred, and whether the timeout is appropriate to that flow. Catch the timeout only when the product behavior allows the element to be absent.
Or skip the browser setup
If you need a screenshot of a page rather than a conditionally selected Playwright element, ScreenshotNeo can return a page screenshot through one GET request. This is not a replacement for checking a Playwright locator or for asserting application behavior: the API captures a URL, not an element selected by your Playwright test.
For example, save a screenshot of a page as WebP with cURL:
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://example.com
-o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets are removed before the shot; those cleanup steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, with response headers identifying the page verdict and billing status. Its MCP server exposes screenshot tools for AI agents, including Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up free for ScreenshotNeo to get 1,000 screenshots a month without a credit card.
Frequently Asked Questions
Does locator.screenshot() wait for an element to appear?
No. It performs capture-related actionability handling, but use waitFor() or an assertion when you need to wait for an element to become visible.
Should I use count() or isVisible()?
Use count() when any match is enough; use isVisible() when the element must be visible now. Both are immediate checks, not waits.
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.
Recommended Free Tools

