0
0
Selenium Javatesting~15 mins

findElements for multiple matches in Selenium Java - Deep Dive

Choose your learning style9 modes available
Overview - findElements for multiple matches
What is it?
In Selenium WebDriver, findElements is a method used to locate multiple web elements on a page that match a given locator. Unlike findElement, which returns a single element or throws an error if none is found, findElements returns a list of all matching elements or an empty list if none exist. This allows testers to interact with multiple elements at once, such as all buttons or links of a certain type.
Why it matters
Without findElements, testers would struggle to handle multiple similar elements on a page, making tests fragile and limited. It solves the problem of bulk element handling, enabling efficient verification and interaction with groups of elements. Without it, automation scripts would be less flexible and more prone to errors when pages have dynamic or multiple matching elements.
Where it fits
Before learning findElements, you should understand basic Selenium concepts like WebDriver, locators, and findElement. After mastering findElements, you can explore advanced topics like waiting for elements, filtering element lists, and handling dynamic page content.
Mental Model
Core Idea
findElements collects all matching elements into a list so you can work with many at once, instead of just one.
Think of it like...
It's like using a fishing net to catch all the fish in a pond instead of a single fishing rod that catches only one fish at a time.
┌───────────────┐
│ Web Page DOM  │
├───────────────┤
│ Element A     │
│ Element B     │
│ Element C     │
│ Element D     │
└─────┬─────────┘
      │ findElements(locator)
      ▼
┌─────────────────────┐
│ List of Elements     │
│ [Element A, B, C]   │
└─────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding findElement vs findElements
🤔
Concept: Learn the difference between findElement and findElements methods in Selenium.
findElement returns the first matching element or throws an exception if none found. findElements returns a list of all matching elements or an empty list if none found. Example: WebElement single = driver.findElement(By.tagName("button")); List multiple = driver.findElements(By.tagName("button"));
Result
findElement gives one element or error; findElements gives a list (possibly empty).
Knowing this difference prevents test failures due to missing elements and enables handling multiple elements gracefully.
2
FoundationUsing locators to find multiple elements
🤔
Concept: How to use locators like By.className or By.cssSelector with findElements to get multiple matches.
You can use any locator strategy with findElements. For example: List links = driver.findElements(By.cssSelector("a.nav-link")); This finds all anchor tags with class 'nav-link'.
Result
A list of all matching elements is returned, which can be empty if none found.
Understanding locator flexibility lets you target exactly the elements you want in bulk.
3
IntermediateIterating over multiple elements safely
🤔Before reading on: do you think you can call getText() on each element in the list without checking if the list is empty? Commit to your answer.
Concept: Learn to loop through the list returned by findElements and handle cases when the list is empty.
Example: List buttons = driver.findElements(By.tagName("button")); if (!buttons.isEmpty()) { for (WebElement btn : buttons) { System.out.println(btn.getText()); } } else { System.out.println("No buttons found."); }
Result
Prints text of all buttons or a message if none found.
Checking for empty lists avoids NullPointerExceptions and makes tests more robust.
4
IntermediateFiltering elements after retrieval
🤔Before reading on: do you think findElements can filter elements by text content directly? Commit to your answer.
Concept: findElements returns all matches; filtering by text or attribute must be done in code after retrieval.
Example: List allItems = driver.findElements(By.className("item")); List filtered = new ArrayList<>(); for (WebElement item : allItems) { if (item.getText().contains("Sale")) { filtered.add(item); } } System.out.println("Filtered count: " + filtered.size());
Result
Filtered list contains only elements with text containing 'Sale'.
Knowing that filtering happens in code after findElements helps design flexible tests.
5
AdvancedHandling dynamic elements with findElements
🤔Before reading on: do you think findElements waits for elements to appear by default? Commit to your answer.
Concept: findElements does not wait; it returns immediately. Use waits to handle dynamic content.
Example with explicit wait: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); List dynamicElements = wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("dynamic")) );
Result
Waits up to 10 seconds for elements to appear, then returns the list.
Understanding that findElements alone doesn't wait prevents flaky tests on dynamic pages.
6
ExpertAvoiding stale element exceptions with findElements
🤔Before reading on: do you think elements in the list returned by findElements stay valid if the page changes? Commit to your answer.
Concept: Elements can become stale if the page updates; re-find elements or handle exceptions.
Example: List elems = driver.findElements(By.cssSelector(".item")); try { for (WebElement e : elems) { System.out.println(e.getText()); } } catch (StaleElementReferenceException ex) { elems = driver.findElements(By.cssSelector(".item")); // re-find // retry processing }
Result
Prevents test failure by re-fetching elements if they become stale.
Knowing how to handle stale elements is key for stable tests on dynamic web apps.
Under the Hood
When findElements is called, Selenium sends a command to the browser driver to search the page's DOM for all elements matching the locator. The browser returns a list of element references. Selenium wraps these references as WebElement objects in a list. This list is a snapshot at call time; if the page changes, these references may become invalid (stale).
Why designed this way?
Separating findElement and findElements allows clear handling of single vs multiple elements. Returning a list (possibly empty) avoids exceptions for no matches, making tests more robust. This design balances simplicity and flexibility, allowing testers to choose based on their needs.
┌───────────────┐
│ Selenium Code │
└──────┬────────┘
       │ findElements(locator)
       ▼
┌─────────────────────┐
│ Browser Driver       │
│ Searches DOM for all │
│ matching elements    │
└──────┬──────────────┘
       │ List of element references
       ▼
┌─────────────────────┐
│ Selenium wraps refs  │
│ as WebElement list   │
└─────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does findElements throw an exception if no elements match? Commit to yes or no.
Common Belief:findElements throws an exception if no elements are found, just like findElement.
Tap to reveal reality
Reality:findElements returns an empty list if no elements match; it does not throw an exception.
Why it matters:Assuming an exception occurs can lead to unnecessary try-catch blocks and confusion in test logic.
Quick: Does findElements wait for elements to appear before returning? Commit to yes or no.
Common Belief:findElements waits until at least one element appears before returning the list.
Tap to reveal reality
Reality:findElements returns immediately with whatever elements are present; it does not wait.
Why it matters:Not using explicit waits can cause flaky tests when elements load slowly or dynamically.
Quick: If you store the list from findElements, will the elements always stay valid? Commit to yes or no.
Common Belief:Once you get the list from findElements, the elements remain valid even if the page changes.
Tap to reveal reality
Reality:Elements can become stale if the page updates; you must re-find elements or handle exceptions.
Why it matters:Ignoring stale elements causes test failures and confusion during test runs.
Quick: Can findElements filter elements by text content directly? Commit to yes or no.
Common Belief:You can use findElements to find elements by their visible text directly.
Tap to reveal reality
Reality:findElements only uses locators like CSS or XPath; filtering by text must be done after retrieval.
Why it matters:Expecting text filtering in findElements leads to inefficient or incorrect test code.
Expert Zone
1
findElements returns a live list of WebElement references, but these references are not automatically refreshed if the DOM changes.
2
Using XPath with findElements can be powerful but may impact performance; CSS selectors are often faster and preferred.
3
Combining findElements with explicit waits like ExpectedConditions.presenceOfAllElementsLocatedBy improves test stability on dynamic pages.
When NOT to use
Avoid findElements when you only need a single element; use findElement instead for clearer intent and simpler code. For complex filtering by text or attributes, consider retrieving all elements then filtering in code or using XPath functions carefully.
Production Patterns
In real-world tests, findElements is used to verify counts of items, batch-click buttons, or validate lists of search results. It is often combined with waits and exception handling to manage dynamic content and avoid flaky tests.
Connections
Explicit Waits in Selenium
findElements works best combined with explicit waits to handle dynamic elements.
Understanding how findElements returns immediately helps grasp why waits are essential for reliable tests.
List Data Structures
findElements returns a list, so knowledge of list operations helps manipulate multiple elements.
Knowing list handling in Java enables efficient filtering, iteration, and processing of multiple web elements.
Database Query Result Sets
Both findElements and database queries return collections of matches, requiring iteration and filtering.
Recognizing this similarity helps understand handling multiple results and empty sets in different domains.
Common Pitfalls
#1Assuming findElements throws an exception if no elements found.
Wrong approach:List elems = driver.findElements(By.id("missing")); System.out.println(elems.get(0).getText()); // No check for empty list
Correct approach:List elems = driver.findElements(By.id("missing")); if (!elems.isEmpty()) { System.out.println(elems.get(0).getText()); } else { System.out.println("No elements found."); }
Root cause:Misunderstanding that findElements returns empty list, not exception, leads to runtime errors.
#2Not using waits with findElements on dynamic pages.
Wrong approach:List elems = driver.findElements(By.className("dynamic")); // Immediately use elems without waiting
Correct approach:WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); List elems = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("dynamic")));
Root cause:Assuming findElements waits causes flaky tests when elements load slowly.
#3Using stale WebElement references after page updates.
Wrong approach:List elems = driver.findElements(By.cssSelector(".item")); // Page updates here for (WebElement e : elems) { System.out.println(e.getText()); // Throws StaleElementReferenceException }
Correct approach:List elems = driver.findElements(By.cssSelector(".item")); // Page updates here elems = driver.findElements(By.cssSelector(".item")); // Re-find elements for (WebElement e : elems) { System.out.println(e.getText()); }
Root cause:Not realizing elements become stale after DOM changes causes test failures.
Key Takeaways
findElements returns a list of all matching elements or an empty list if none are found, avoiding exceptions.
It does not wait for elements to appear; combine it with explicit waits for dynamic content.
Always check if the returned list is empty before interacting with elements to prevent errors.
Elements returned can become stale if the page changes; re-find elements or handle exceptions accordingly.
Filtering by text or attributes must be done after retrieving elements, as findElements only uses locators.