ScreenshotNeo

BlogGuides

Selenium findElement vs. findElements: Differences and Examples

Learn when to use Selenium’s findElement or findElements in Java, how missing matches and waits behave, and how to search within a parent element.

By the ScreenshotNeo team4 October 20267 min read

Selenium Java’s findElement(By) returns the first matching element and throws NoSuchElementException if there is no match. findElements(By) returns every match as a list, or an empty list when nothing matches. Use the singular method for a required element; use the plural method when zero or more results are valid or you need to inspect a collection.

Both methods use the same locator strategies and search from the context on which they are called: a WebDriver searches the current page, while a WebElement searches within an element context. Both are affected by implicit waits. [Selenium WebDriver API] [Selenium element finders guide]

1. The difference at a glance

Question findElement findElements
What does it return? The first matching WebElement A List<WebElement> containing all matches
What if nothing matches? Throws NoSuchElementException Returns an empty list
When should you use it? One element is required for the next test step Zero, one, or many results are acceptable, or you need to inspect all matches
Can you call it on a parent element? Yes; it searches from that element context Yes; it searches from that element context

findElement does not return a list or return null when there is no match. findElements does not return null, either: check its list with isEmpty() or size(). [Selenium WebElement API]

2. Complete Java examples

Find one required element

Use findElement when the test cannot proceed without the element. A missing match raises an exception at the lookup.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class FindOne {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        try {
            driver.get("https://example.com");
            WebElement heading = driver.findElement(By.tagName("h1"));
            System.out.println(heading.getText());
        } finally {
            driver.quit();
        }
    }
}

Find zero or more elements

Use findElements for optional content or a collection. The empty-list branch handles absence without exception control flow.

import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class FindMany {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        try {
            driver.get("https://example.com");
            List<WebElement> links = driver.findElements(By.cssSelector("a"));

            if (links.isEmpty()) {
                System.out.println("No links are present");
            } else {
                for (WebElement link : links) {
                    System.out.println(link.getText());
                }
            }
        } finally {
            driver.quit();
        }
    }
}

Search within a parent

Calling a finder on a WebElement scopes the search to that element context. This can make a locator more precise when a page has repeated structures.

WebElement form = driver.findElement(By.cssSelector("form#signup"));
List<WebElement> inputs = form.findElements(By.tagName("input"));

for (WebElement input : inputs) {
    System.out.println(input.getAttribute("name"));
}

For XPath from a WebElement, use .// to search descendants of that element. A locator beginning with // searches the full document under Selenium’s WebDriver conventions, which can escape the parent scope you intended. [Selenium WebElement API]

WebElement form = driver.findElement(By.id("signup"));
WebElement email = form.findElement(By.xpath(".//input[@type='email']"));

3. Choose the method by expected count

  1. Decide whether absence is a test failure. If a required submit button is missing, use findElement so the lookup fails clearly. If a notice may or may not appear, use findElements.
  2. Decide whether you need all matches. A singular lookup returns the first match only. To count, iterate, or validate every row, use findElements.
  3. Choose the search context. Start from the driver for the page, or from a located element to narrow the search. For scoped XPath descendants, use .//.
  4. Account for timing. Both methods are affected by implicit waits. For elements that appear after interaction or asynchronous loading, configure an appropriate wait strategy rather than assuming the first lookup happens after rendering.

4. Missing matches and implicit waits

With no implicit wait configured, a lookup that finds no match returns or fails according to its method’s documented behavior. With an implicit wait, findElement retries until it finds a match or the timeout is reached. findElements can return as soon as it finds one or more matches; if it finds none during the wait, it returns an empty list when the timeout expires. [Selenium WebDriver API]

This distinction matters for optional elements: an empty list means no matching element was found within the lookup’s wait behavior, not necessarily that Selenium performed only one instantaneous check. Avoid using repeated lookups as an ad hoc wait loop; use a deliberate wait appropriate to the condition your test needs.

5. Locators and scope

The choice between singular and plural lookup does not change how a locator is written. Both take a Selenium By locator, including strategies such as ID, name, tag name, CSS selector, and XPath. [Selenium element finders guide]

WebElement byId = driver.findElement(By.id("submit"));
WebElement byCss = driver.findElement(By.cssSelector("button.primary"));
List<WebElement> byClass = driver.findElements(By.className("result"));
List<WebElement> byXPath = driver.findElements(By.xpath("//article"));

Keep locators tied to stable attributes when possible. If a selector is too broad, findElement may silently return the wrong first match; findElements may return more items than the test expects. Scope repeated components through a parent element, and verify the number and identity of matches where they matter.

6. Common errors and fixes

Symptom Likely cause Fix
NoSuchElementException findElement found no matching element within the current lookup and wait behavior. Confirm the locator and search context. If the element is optional, use findElements. If it appears later, wait for the relevant condition.
Code assumes null means absent The Java API does not use null for these no-match outcomes. Catch NoSuchElementException for required singular lookups, or test findElements(...).isEmpty() for optional matches.
Only one of several items is inspected findElement returns the first match. Use findElements and iterate over the returned list.
A parent-scoped XPath finds an element elsewhere The expression begins with //, which searches the full document under WebDriver conventions. Use .// for descendants of the current WebElement.
An optional lookup takes longer than expected An implicit wait applies to element finding. Review the driver’s implicit-wait configuration and choose a timeout consistent with the test’s timing needs.
A collection is empty even though content appears later The content may not yet exist when the lookup runs, or the locator/context is wrong. Wait for the relevant content condition, then locate it; verify the locator against the actual page structure.

7. Performance, reliability, and cost

There is no supported performance percentage in the cited Selenium material that makes one method universally faster. Choose based on the result your test needs. A plural lookup can be useful to inspect a set in one lookup; avoid calling either method repeatedly in tight polling loops when a proper wait can express the condition more clearly.

For reliable tests, distinguish required elements from optional ones, use specific locators, and make timing explicit for dynamic pages. Keep searches scoped to the correct page or parent element. These choices reduce false failures caused by missing content, overly broad selectors, or unexpected page state.

Selenium itself is browser automation code running in your test environment. If the actual task is to obtain a page image or PDF rather than interact with elements, a screenshot API can avoid maintaining browser setup. ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. Its clean-capture flow accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets; those steps can be turned off. It bills only clean shots: bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses include X-Page-Verdict and X-Billed headers. See ScreenshotNeo and the API documentation.

8. Or skip the browser setup

For a direct screenshot or PDF workflow, ScreenshotNeo accepts a URL in one GET request. This cURL example saves a WebP screenshot:

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)
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}`);

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Every feature is on every plan. Read the ScreenshotNeo docs, then sign up for 1,000 free screenshots a month, no card required.

9. FAQ

Does findElements return null or an empty list?

It returns an empty list when there are no matches.

Does findElement return the first match or all matches?

It returns the first matching element. Use findElements to get all matches.

Can I use either method on a WebElement?

Yes. A WebElement is a search context, so either method can search from that element.