Blog Software Testing

Adapting to Change: Best Practices for Dealing with Dynamic Web Elements in Selenium

November 9, 2023
Dynamic Web Elements in Selenium

Handling Dynamic Web Elements in Selenium

Dynamic web elements in Selenium refer to those elements on a web page that change their attributes or even their existence during the application’s lifecycle. These changes can occur due to a variety of reasons, including asynchronous loading via AJAX requests, user interactions that trigger dynamic changes, content refresh, and elements loaded inside iframes. The presence and attributes of these elements may vary, making them a significant pain point in web UI automation.

Challenges with Dynamic Web Elements

Handling dynamic elements can be challenging for web testers and automation engineers. One of the primary pain points is the reliability of test scripts. Dynamic elements can lead to inconsistent test results, causing tests to fail sporadically. This inconsistency can make it difficult to differentiate between genuine application defects and issues within the test scripts. Moreover, dynamic elements necessitate continuous maintenance of test scripts due to changes in the application’s UI or functionality. This frequent upkeep can increase the overall cost of automation.

Another pain point associated with dynamic elements is slower test execution. Test scripts often need to wait for dynamic elements to load or appear, which can extend the execution time of test suites. This delay can impact the efficiency of the CI/CD pipeline, especially in fast-paced development environments.

Related Read: How To Integrate Jenkins With Selenium

Additionally, handling dynamic elements usually requires the creation of complex locators, often relying on intricate XPath or CSS selectors. These complex locators are necessary to ensure that elements are located and interacted with correctly, but they can be challenging to develop and maintain. When dealing with web pages that contain iframes, which are common in modern web applications, the complexity of the automation process is further compounded as testers need to switch frame contexts appropriately.

Finally, dynamic elements can affect how test data is managed. Elements that behave dynamically may interact with test data, leading to complications in the setup and cleanup processes for test data, which are essential for maintaining data integrity throughout the testing process.

Scenario of Dynamic Webelement

Here’s an example of how dynamic elements can be encountered and handled on a real web page:

Consider a scenario where you are automating a login process on a website. On the login page, the “Login” button is initially disabled. When you enter a valid username and password, the “Login” button becomes enabled. This is a classic example of a dynamic web element.

Handling dynamic elements in this context would involve waiting for the “Login” button to become enabled before clicking it. You would use Selenium’s explicit waits to achieve this. 

// Wait for the “Login” button to become clickable
WebDriverWait wait = new WebDriverWait(driver, 10); // Wait for up to 10 seconds
WebElement loginButton = wait.until(ExpectedConditions.elementToBeClickable(By.id(“loginButtonId”)));

// Perform the login action once the button is enabled
loginButton.click();

How to Handle Dynamic Web Elements?

There are many ways to handle dynamic elements, let’s discuss the same with code examples.

Related: Windows In Selenium WebDriver

1. Explicit Waits

Explicit waits are the most common way to handle delayed loading elements. Selenium allows you to wait for a specific condition to be met before proceeding. You can use ExpectedConditions to wait for the element to be clickable, visible, or present.

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement dynamicElement = wait.until(ExpectedConditions.elementToBeClickable(By.id(“dynamicElementId”)));

2. Fluent Waits

Fluent waits provide more flexibility, allowing you to customize polling intervals and exceptions. This is especially useful when dealing with elements that take varying amounts of time to load.

Wait wait = new FluentWait(driver)
    .withTimeout(Duration.ofSeconds(30))
    .pollingEvery(Duration.ofSeconds(2))
    .ignoring(NoSuchElementException.class);

WebElement dynamicElement = (WebElement) wait.until(driver -> driver.findElement(By.id(“dynamicElementId”)));

3. CSS Selectors and XPath

When dealing with elements that change attributes, you can use CSS selectors and XPath to target elements based on other stable attributes. For example, you can locate an element by its class or data attributes.

WebElement dynamicElement = driver.findElement(By.cssSelector(“.dynamic-class”));

4. Handling Elements Inside Frames

When working with elements inside iframes, you must switch to the iframe context first. This ensures that Selenium interacts with the elements inside the frame.

driver.switchTo().frame(“iframeName”);
WebElement dynamicElement = driver.findElement(By.id(“elementInFrame”));

5. Using Relative Element Positions

Sometimes, you can predict the position of a dynamic element relative to a nearby stable element. You can then use XPath to locate the dynamic element relative to the stable one. This strategy can be effective for elements that consistently appear near others.

WebElement nearbyElement = driver.findElement(By.id(“nearbyElementId”));
WebElement dynamicElement = nearbyElement.findElement(By.xpath(“./following-sibling::div”));

6. Multiple Attributes

If a single attribute is not sufficient to uniquely identify the dynamic element, you can combine multiple attributes to create a more robust locator. Using logical operators like and or or in your XPath or CSS selector allows you to match the dynamic element based on multiple attribute values. For example, you can create an XPath that matches a button with an ID that starts with a specific text and also has a specific class. Using multiple attributes increases the specificity of the locator, ensuring that the dynamic element is uniquely identified.

Related: How To Sync Selenium Java BDD Automation

WebElement element = driver.findElement(By.xpath(“//button[starts-with(@id, ‘save’) and contains(@class, ‘publish’)]”));

7. Refresh the Page

In some cases, refreshing the page may be a quick workaround for dealing with dynamic elements, especially if they appear after a page reload.

driver.navigate().refresh();

8. Retrying Mechanism

Implement a retrying mechanism where Selenium repeatedly tries to locate and interact with the element until a timeout is reached. This approach is effective when you anticipate element appearance delays.

Related Read: Selenium WebDriver Tutorial

boolean isDynamicElementPresent = false;
int attempts = 0;
WebDriverWait wait = new WebDriverWait(driver, 10);  // Adjust the timeout as needed

while (!isDynamicElementPresent && attempts < 3) {
    try {
        dynamicElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(“dynamicElementId”)));
        isDynamicElementPresent = true;
    } catch (NoSuchElementException e) {
        attempts++;
    }
}

Conclusion

Handling dynamic web elements in Selenium is crucial for robust test automation. By using explicit waits, fluent waits, selectors, iframe handling, refreshing the page, relative element positions, and retrying mechanisms, you can effectively deal with dynamic elements in your automation scripts. Tailoring your approach to the specific nature of dynamic elements is essential for reliable and stable test automation. Incorporate these strategies into your Selenium projects to ensure robust and reliable automated tests, even when faced with unpredictable dynamic web elements. 

Happy testing and keep learning!

Leave a Reply