How to Efficiently Handle Dynamic Web Elements In Selenium WebDriver: 6 Strategies
In this blog, I’ll discuss strategies to efficiently handle dynamic web elements in Selenium WebDriver. As a seasoned Test Automation Architect, I’ve encountered numerous challenges while working with dynamic web applications. One of the most frequent issues automation engineers face is identifying and interacting with dynamic web elements. These elements can change their attributes, such as ID, class, or XPath, during runtime. If you rely on static locators, your tests will become brittle, leading to flaky results and false failures.
Why we need to handle dynamic web elements in Selenium WebDriver
In modern web applications, dynamic elements can change based on various factors—such as user actions, page reloading, or asynchronous JavaScript updates. A few common challenges include:
• Dynamically generated IDs that change with every page reload.
• Elements appearing or disappearing depending on user actions or delays.
• Lazy loading elements that are only loaded when scrolled into view.
When tests depend on brittle locators, they start failing due to the inability to find the element at runtime. Solving this requires a combination of better locator strategies, effective waits, and resilience to dynamic behavior.
Strategy 1: Using Robust Locators for Dynamic Elements
The first step in dealing with dynamic elements is using robust locators. Avoid depending on dynamic attributes (like randomly generated IDs) and focus on more stable identifiers such as text, partial attributes, and relative positions in the DOM.
Example: Using contains() in XPath to Handle Dynamic IDs
Consider an element with a dynamic ID that starts with “button_” followed by random characters. Instead of using the entire ID, you can use a partial match with XPath’s contains() function.
// Full dynamic ID: "button_23as78"
// XPath using contains to handle dynamic part:
WebElement dynamicButton = driver.findElement(By.xpath("//button[contains(@id,'button_')]"));
dynamicButton.click();
CSS Selectors with Partial Match
CSS selectors also allow partial matching, which can be highly effective. Here’s an example using *= for a partial match on an attribute:
// Using CSS Selector to handle a dynamic class
WebElement dynamicElement = driver.findElement(By.cssSelector("button[class*='submit-button']"));
dynamicElement.click();
Strategy 2: Implementing Explicit Waits for Synchronization
Dynamic elements often don’t appear immediately after a page load or user interaction. Synchronization issues can cause failures if WebDriver attempts to interact with an element before it’s fully available. The best practice is to implement explicit waits to handle dynamic web elements in Selenium WebDriver.
Example: Using WebDriverWait for Element Visibility
You can use WebDriverWait to wait until an element is visible or clickable before interacting with it. This is crucial in dealing with AJAX-loaded content.
//Using WebDriverWait to handle dynamic web elements in Selenium WebDriver
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait for the button to become clickable
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("dynamicButton")));
button.click();
Fluent Wait for Advanced Synchronization
If you need more flexibility, FluentWait allows you to define polling intervals and ignore certain exceptions while waiting for the condition.
//Using FluentWait to handle dynamic web elements in Selenium WebDriver
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
WebElement dynamicButton = fluentWait.until(driver -> driver.findElement(By.id("dynamicButton")));
dynamicButton.click();
Strategy 3: Handling Stale Element Exceptions
When dealing with dynamic content, especially in pages with heavy JavaScript frameworks (like Angular or React), elements that were once available in the DOM may become “stale.” This happens when the DOM updates, and WebDriver’s reference to the element becomes outdated. In such cases, you need to catch the StaleElementReferenceException and re-fetch the element to handle dynamic web elements in Selenium WebDriver.
Example: Retrying after Stale Element Exception
You can use a loop to retry the action after catching the StaleElementReferenceException:
//Using Try catch to handle dynamic web elements in Selenium WebDriver
WebElement dynamicElement = driver.findElement(By.id("dynamicElement"));
for (int i = 0; i < 3; i++) {
try {
dynamicElement.click();
break; // Exit loop if click is successful
} catch (StaleElementReferenceException e) {
dynamicElement = driver.findElement(By.id("dynamicElement")); // Re-fetch the element
}
}
Strategy 4: Dealing with Shadow DOM Elements
Another challenge in modern web applications is the Shadow DOM—a special DOM tree that hides implementation details and encapsulates certain elements. Standard Selenium locators don’t penetrate the shadow DOM. Instead, you need to use JavaScript to interact with shadow elements.
Example: Accessing Elements Inside Shadow DOM
Here’s how to access a shadow DOM element using JavaScript with Selenium WebDriver:
//Using JavaScriptExecutor to handle dynamic web elements in Selenium WebDriver
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement shadowHost = driver.findElement(By.cssSelector("shadow-host-selector"));
// Use JavaScript to access the shadow DOM
WebElement shadowRoot = (WebElement) js.executeScript("return arguments[0].shadowRoot", shadowHost);
WebElement shadowElement = shadowRoot.findElement(By.cssSelector("button"));
shadowElement.click();
Strategy 5: Scrolling to Lazy-Loaded Elements
Some web pages only load elements once they are in view (lazy loading). Selenium WebDriver can’t interact with elements that aren’t loaded, so you need to scroll to them first. In such cases, See below how to handle dynamic web elements in Selenium WebDriver.
Example: Scrolling to an Element Using JavaScript
You can use JavaScript to scroll to an element, ensuring it’s loaded and ready for interaction:
//Using Scroll to handle dynamic web elements in Selenium WebDriver
WebElement lazyElement = driver.findElement(By.id("lazyElement"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", lazyElement);
lazyElement.click();
Strategy 6: Leveraging Page Object Model (POM) with Dynamic Elements
When dealing with complex web applications, combining the Page Object Model (POM) design pattern with dynamic element handling is essential. This makes your test code maintainable and reduces duplication. Although not a direct way to handle dynamic web elements in Selenium WebDriver, but it is the best practice you can adopt to avoid any probable dynamic element issue up to some degree.
Example: Page Object Model for Dynamic Elements
//handle dynamic web elements in Selenium WebDriver
public class DynamicPage {
private WebDriver driver;
// Constructor
public DynamicPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy(xpath = "//button[contains(@id, 'button_')]")
WebElement dynamicButton;
public void clickDynamicButton() {
dynamicButton.click();
}
}
By abstracting dynamic locators into POM classes, you improve maintainability and make updates easier when the application changes.
Conclusion
To handle dynamic web elements in selenium is one of the key challenges in building resilient Selenium WebDriver automation frameworks. By using robust locator strategies, explicit waits, stale element handling, and POM, you can ensure your tests remain stable and reliable even in the face of frequent application changes.
Automation engineers who proactively adopt these techniques will reduce flaky tests, increase test reliability, and create a strong foundation for scalable test automation suites.
Feel free to drop your thoughts in the comments below, and stay tuned for more insights from the world of test automation!
Discover more from Automation Script
Subscribe to get the latest posts sent to your email.